parent
62a3c0667a
commit
d7f7df3a8e
@ -1 +1 @@
|
|||||||
SOURCES/krb5-1.19.1.tar.gz
|
SOURCES/krb5-1.20.1.tar.gz
|
||||||
|
@ -1 +1 @@
|
|||||||
65fcedf85595457652cc0d37df65c9258e783d6b SOURCES/krb5-1.19.1.tar.gz
|
06278439a6cd5a2aa861d8e877451b794487534b SOURCES/krb5-1.20.1.tar.gz
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,159 @@
|
|||||||
|
From 3cc9ef956342f55cc9ae283e30fc3ba080248cf3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Wed, 1 Jun 2022 18:02:04 +0200
|
||||||
|
Subject: [PATCH] Set reasonable supportedCMSTypes in PKINIT
|
||||||
|
|
||||||
|
The PKINIT client uses AuthPack.supportedCMSTypes to let the KDC know
|
||||||
|
the algorithms it supports for verification of the CMS data signature.
|
||||||
|
(The MIT krb5 KDC currently ignores this list, but other
|
||||||
|
implementations use it.)
|
||||||
|
|
||||||
|
Replace 3DES with sha512WithRSAEncryption and sha256WithRSAEncryption.
|
||||||
|
|
||||||
|
[ghudson@mit.edu: simplified code and used appropriate helpers; edited
|
||||||
|
commit message]
|
||||||
|
|
||||||
|
ticket: 9066 (new)
|
||||||
|
---
|
||||||
|
src/plugins/preauth/pkinit/pkinit_constants.c | 33 ++++++++++++-
|
||||||
|
src/plugins/preauth/pkinit/pkinit_crypto.h | 4 ++
|
||||||
|
.../preauth/pkinit/pkinit_crypto_openssl.c | 49 ++++++++++---------
|
||||||
|
3 files changed, 60 insertions(+), 26 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/plugins/preauth/pkinit/pkinit_constants.c b/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||||
|
index 652897fa14..1da482e0b4 100644
|
||||||
|
--- a/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||||
|
+++ b/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||||
|
@@ -32,9 +32,14 @@
|
||||||
|
|
||||||
|
#include "pkinit.h"
|
||||||
|
|
||||||
|
-/* statically declare OID constants for all three algorithms */
|
||||||
|
-static char sha1_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x01};
|
||||||
|
+/* RFC 8636 id-pkinit-kdf-ah-sha1: iso(1) identified-organization(3) dod(6)
|
||||||
|
+ * internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha1(1) */
|
||||||
|
+static char sha1_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x01 };
|
||||||
|
+/* RFC 8636 id-pkinit-kdf-ah-sha256: iso(1) identified-organization(3) dod(6)
|
||||||
|
+ * internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha256(2) */
|
||||||
|
static char sha256_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x02 };
|
||||||
|
+/* RFC 8636 id-pkinit-kdf-ah-sha512: iso(1) identified-organization(3) dod(6)
|
||||||
|
+ * internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha512(3) */
|
||||||
|
static char sha512_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x03 };
|
||||||
|
|
||||||
|
const krb5_data sha1_id = { KV5M_DATA, sizeof(sha1_oid), sha1_oid };
|
||||||
|
@@ -48,6 +53,30 @@ krb5_data const * const supported_kdf_alg_ids[] = {
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
+/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840)
|
||||||
|
+ * rsadsi(113549) pkcs(1) 1 11 */
|
||||||
|
+static char sha256WithRSAEncr_oid[9] = {
|
||||||
|
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b
|
||||||
|
+};
|
||||||
|
+/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840)
|
||||||
|
+ * rsadsi(113549) pkcs(1) 1 13 */
|
||||||
|
+static char sha512WithRSAEncr_oid[9] = {
|
||||||
|
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+const krb5_data sha256WithRSAEncr_id = {
|
||||||
|
+ KV5M_DATA, sizeof(sha256WithRSAEncr_oid), sha256WithRSAEncr_oid
|
||||||
|
+};
|
||||||
|
+const krb5_data sha512WithRSAEncr_id = {
|
||||||
|
+ KV5M_DATA, sizeof(sha512WithRSAEncr_oid), sha512WithRSAEncr_oid
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+krb5_data const * const supported_cms_algs[] = {
|
||||||
|
+ &sha512WithRSAEncr_id,
|
||||||
|
+ &sha256WithRSAEncr_id,
|
||||||
|
+ NULL
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
/* RFC 2412 section E.2 (well-known group 2) parameters, DER-encoded as
|
||||||
|
* DomainParameters (RFC 3279 section 2.3.3). */
|
||||||
|
static const uint8_t o1024[] = {
|
||||||
|
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||||
|
index 65f6210727..64300da856 100644
|
||||||
|
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||||
|
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||||
|
@@ -620,6 +620,10 @@ extern const krb5_data oakley_4096;
|
||||||
|
*/
|
||||||
|
extern krb5_data const * const supported_kdf_alg_ids[];
|
||||||
|
|
||||||
|
+/* CMS signature algorithms supported by this implementation, in order of
|
||||||
|
+ * decreasing preference. */
|
||||||
|
+extern krb5_data const * const supported_cms_algs[];
|
||||||
|
+
|
||||||
|
krb5_error_code
|
||||||
|
crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx,
|
||||||
|
uint8_t **der_out, size_t *der_len);
|
||||||
|
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
index d500455dec..1c2aa02827 100644
|
||||||
|
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
@@ -5475,37 +5475,38 @@ create_krb5_supportedCMSTypes(krb5_context context,
|
||||||
|
pkinit_plg_crypto_context plg_cryptoctx,
|
||||||
|
pkinit_req_crypto_context req_cryptoctx,
|
||||||
|
pkinit_identity_crypto_context id_cryptoctx,
|
||||||
|
- krb5_algorithm_identifier ***oids)
|
||||||
|
+ krb5_algorithm_identifier ***algs_out)
|
||||||
|
{
|
||||||
|
+ krb5_error_code ret;
|
||||||
|
+ krb5_algorithm_identifier **algs = NULL;
|
||||||
|
+ size_t i, count;
|
||||||
|
|
||||||
|
- krb5_error_code retval = ENOMEM;
|
||||||
|
- krb5_algorithm_identifier **loids = NULL;
|
||||||
|
- krb5_data des3oid = {0, 8, "\x2A\x86\x48\x86\xF7\x0D\x03\x07" };
|
||||||
|
+ *algs_out = NULL;
|
||||||
|
|
||||||
|
- *oids = NULL;
|
||||||
|
- loids = malloc(2 * sizeof(krb5_algorithm_identifier *));
|
||||||
|
- if (loids == NULL)
|
||||||
|
- goto cleanup;
|
||||||
|
- loids[1] = NULL;
|
||||||
|
- loids[0] = malloc(sizeof(krb5_algorithm_identifier));
|
||||||
|
- if (loids[0] == NULL) {
|
||||||
|
- free(loids);
|
||||||
|
- goto cleanup;
|
||||||
|
- }
|
||||||
|
- retval = pkinit_copy_krb5_data(&loids[0]->algorithm, &des3oid);
|
||||||
|
- if (retval) {
|
||||||
|
- free(loids[0]);
|
||||||
|
- free(loids);
|
||||||
|
+ /* Count supported OIDs and allocate list (including null terminator). */
|
||||||
|
+ for (count = 0; supported_cms_algs[count] != NULL; count++);
|
||||||
|
+ algs = k5calloc(count + 1, sizeof(*algs), &ret);
|
||||||
|
+ if (algs == NULL)
|
||||||
|
goto cleanup;
|
||||||
|
+
|
||||||
|
+ /* Add an algorithm identifier for each OID, with no parameters. */
|
||||||
|
+ for (i = 0; i < count; i++) {
|
||||||
|
+ algs[i] = k5alloc(sizeof(*algs[i]), &ret);
|
||||||
|
+ if (algs[i] == NULL)
|
||||||
|
+ goto cleanup;
|
||||||
|
+ ret = krb5int_copy_data_contents(context, supported_cms_algs[i],
|
||||||
|
+ &algs[i]->algorithm);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto cleanup;
|
||||||
|
+ algs[i]->parameters = empty_data();
|
||||||
|
}
|
||||||
|
- loids[0]->parameters.length = 0;
|
||||||
|
- loids[0]->parameters.data = NULL;
|
||||||
|
|
||||||
|
- *oids = loids;
|
||||||
|
- retval = 0;
|
||||||
|
-cleanup:
|
||||||
|
+ *algs_out = algs;
|
||||||
|
+ algs = NULL;
|
||||||
|
|
||||||
|
- return retval;
|
||||||
|
+cleanup:
|
||||||
|
+ free_krb5_algorithm_identifiers(&algs);
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_error_code
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,622 @@
|
|||||||
|
From 593109802b52e3f89c3a65436bfdba78f8c517c4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Greg Hudson <ghudson@mit.edu>
|
||||||
|
Date: Thu, 23 Jun 2022 16:41:40 -0400
|
||||||
|
Subject: [PATCH] Simplify plugin loading code
|
||||||
|
|
||||||
|
Remove the USE_CFBUNDLE code, which was only used by KfM. Handle
|
||||||
|
platform conditionals according to current practice. Use
|
||||||
|
k5_dir_filenames() instead of opendir() and remove the Windows
|
||||||
|
implementation of opendir().
|
||||||
|
---
|
||||||
|
src/util/support/plugins.c | 507 +++++++++++--------------------------
|
||||||
|
1 file changed, 150 insertions(+), 357 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/util/support/plugins.c b/src/util/support/plugins.c
|
||||||
|
index c6a9a21d57..0850565687 100644
|
||||||
|
--- a/src/util/support/plugins.c
|
||||||
|
+++ b/src/util/support/plugins.c
|
||||||
|
@@ -29,16 +29,6 @@
|
||||||
|
#if USE_DLOPEN
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
-#include <sys/types.h>
|
||||||
|
-#ifdef HAVE_SYS_STAT_H
|
||||||
|
-#include <sys/stat.h>
|
||||||
|
-#endif
|
||||||
|
-#ifdef HAVE_SYS_PARAM_H
|
||||||
|
-#include <sys/param.h>
|
||||||
|
-#endif
|
||||||
|
-#ifdef HAVE_UNISTD_H
|
||||||
|
-#include <unistd.h>
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
#if USE_DLOPEN
|
||||||
|
#ifdef RTLD_GROUP
|
||||||
|
@@ -68,16 +58,6 @@
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#if USE_DLOPEN && USE_CFBUNDLE
|
||||||
|
-#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
-
|
||||||
|
-/* Currently CoreFoundation only exists on the Mac so we just use
|
||||||
|
- * pthreads directly to avoid creating empty function calls on other
|
||||||
|
- * platforms. If a thread initializer ever gets created in the common
|
||||||
|
- * plugin code, move this there */
|
||||||
|
-static pthread_mutex_t krb5int_bundle_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
#include <stdarg.h>
|
||||||
|
static void Tprintf (const char *fmt, ...)
|
||||||
|
{
|
||||||
|
@@ -90,374 +70,193 @@ static void Tprintf (const char *fmt, ...)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct plugin_file_handle {
|
||||||
|
-#if USE_DLOPEN
|
||||||
|
+#if defined(USE_DLOPEN)
|
||||||
|
void *dlhandle;
|
||||||
|
-#endif
|
||||||
|
-#ifdef _WIN32
|
||||||
|
- HMODULE hinstPlugin;
|
||||||
|
-#endif
|
||||||
|
-#if !defined (USE_DLOPEN) && !defined (_WIN32)
|
||||||
|
+#elif defined(_WIN32)
|
||||||
|
+ HMODULE module;
|
||||||
|
+#else
|
||||||
|
char dummy;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
-#ifdef _WIN32
|
||||||
|
-struct dirent {
|
||||||
|
- long d_ino; /* inode (always 1 in WIN32) */
|
||||||
|
- off_t d_off; /* offset to this dirent */
|
||||||
|
- unsigned short d_reclen; /* length of d_name */
|
||||||
|
- char d_name[_MAX_FNAME+1]; /* filename (null terminated) */
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-typedef struct {
|
||||||
|
- intptr_t handle; /* _findfirst/_findnext handle */
|
||||||
|
- short offset; /* offset into directory */
|
||||||
|
- short finished; /* 1 if there are not more files */
|
||||||
|
- struct _finddata_t fileinfo;/* from _findfirst/_findnext */
|
||||||
|
- char *dir; /* the dir we are reading */
|
||||||
|
- struct dirent dent; /* the dirent to return */
|
||||||
|
-} DIR;
|
||||||
|
+#if defined(USE_DLOPEN)
|
||||||
|
|
||||||
|
-DIR * opendir(const char *dir)
|
||||||
|
+static long
|
||||||
|
+open_plugin_dlfcn(struct plugin_file_handle *h, const char *filename,
|
||||||
|
+ struct errinfo *ep)
|
||||||
|
{
|
||||||
|
- DIR *dp;
|
||||||
|
- char *filespec;
|
||||||
|
- intptr_t handle;
|
||||||
|
- int index;
|
||||||
|
-
|
||||||
|
- filespec = malloc(strlen(dir) + 2 + 1);
|
||||||
|
- strcpy(filespec, dir);
|
||||||
|
- index = strlen(filespec) - 1;
|
||||||
|
- if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
|
||||||
|
- filespec[index] = '\0';
|
||||||
|
- strcat(filespec, "/*");
|
||||||
|
-
|
||||||
|
- dp = (DIR *)malloc(sizeof(DIR));
|
||||||
|
- dp->offset = 0;
|
||||||
|
- dp->finished = 0;
|
||||||
|
- dp->dir = strdup(dir);
|
||||||
|
-
|
||||||
|
- if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) {
|
||||||
|
- if (errno == ENOENT)
|
||||||
|
- dp->finished = 1;
|
||||||
|
- else {
|
||||||
|
- free(filespec);
|
||||||
|
- free(dp->dir);
|
||||||
|
- free(dp);
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
+ const char *e;
|
||||||
|
+
|
||||||
|
+ h->dlhandle = dlopen(filename, PLUGIN_DLOPEN_FLAGS);
|
||||||
|
+ if (h->dlhandle == NULL) {
|
||||||
|
+ e = dlerror();
|
||||||
|
+ if (e == NULL)
|
||||||
|
+ e = _("unknown failure");
|
||||||
|
+ Tprintf("dlopen(%s): %s\n", filename, e);
|
||||||
|
+ k5_set_error(ep, ENOENT, _("unable to load plugin [%s]: %s"),
|
||||||
|
+ filename, e);
|
||||||
|
+ return ENOENT;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- dp->handle = handle;
|
||||||
|
- free(filespec);
|
||||||
|
-
|
||||||
|
- return dp;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
+#define open_plugin open_plugin_dlfcn
|
||||||
|
|
||||||
|
-struct dirent * readdir(DIR *dp)
|
||||||
|
+static long
|
||||||
|
+get_sym_dlfcn(struct plugin_file_handle *h, const char *csymname,
|
||||||
|
+ void **sym_out, struct errinfo *ep)
|
||||||
|
{
|
||||||
|
- if (!dp || dp->finished) return NULL;
|
||||||
|
-
|
||||||
|
- if (dp->offset != 0) {
|
||||||
|
- if (_findnext(dp->handle, &(dp->fileinfo)) < 0) {
|
||||||
|
- dp->finished = 1;
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
+ const char *e;
|
||||||
|
+
|
||||||
|
+ if (h->dlhandle == NULL)
|
||||||
|
+ return ENOENT;
|
||||||
|
+ *sym_out = dlsym(h->dlhandle, csymname);
|
||||||
|
+ if (*sym_out == NULL) {
|
||||||
|
+ e = dlerror();
|
||||||
|
+ if (e == NULL)
|
||||||
|
+ e = _("unknown failure");
|
||||||
|
+ Tprintf("dlsym(%s): %s\n", csymname, e);
|
||||||
|
+ k5_set_error(ep, ENOENT, "%s", e);
|
||||||
|
+ return ENOENT;
|
||||||
|
}
|
||||||
|
- dp->offset++;
|
||||||
|
-
|
||||||
|
- strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
|
||||||
|
- dp->dent.d_ino = 1;
|
||||||
|
- dp->dent.d_reclen = (unsigned short)strlen(dp->dent.d_name);
|
||||||
|
- dp->dent.d_off = dp->offset;
|
||||||
|
-
|
||||||
|
- return &(dp->dent);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-int closedir(DIR *dp)
|
||||||
|
-{
|
||||||
|
- if (!dp) return 0;
|
||||||
|
- _findclose(dp->handle);
|
||||||
|
- free(dp->dir);
|
||||||
|
- free(dp);
|
||||||
|
-
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
-#endif
|
||||||
|
+#define get_sym get_sym_dlfcn
|
||||||
|
|
||||||
|
-long KRB5_CALLCONV
|
||||||
|
-krb5int_open_plugin (const char *filepath, struct plugin_file_handle **h, struct errinfo *ep)
|
||||||
|
+static void
|
||||||
|
+close_plugin_dlfcn(struct plugin_file_handle *h)
|
||||||
|
{
|
||||||
|
- long err = 0;
|
||||||
|
- struct plugin_file_handle *htmp = NULL;
|
||||||
|
- int got_plugin = 0;
|
||||||
|
-#if defined(USE_CFBUNDLE) || defined(_WIN32)
|
||||||
|
- struct stat statbuf;
|
||||||
|
-
|
||||||
|
- if (!err) {
|
||||||
|
- if (stat (filepath, &statbuf) < 0) {
|
||||||
|
- err = errno;
|
||||||
|
- Tprintf ("stat(%s): %s\n", filepath, strerror (err));
|
||||||
|
- k5_set_error(ep, err, _("unable to find plugin [%s]: %s"),
|
||||||
|
- filepath, strerror(err));
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
- if (!err) {
|
||||||
|
- htmp = calloc (1, sizeof (*htmp)); /* calloc initializes ptrs to NULL */
|
||||||
|
- if (htmp == NULL) { err = ENOMEM; }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-#if USE_DLOPEN
|
||||||
|
- if (!err
|
||||||
|
-#if USE_CFBUNDLE
|
||||||
|
- && ((statbuf.st_mode & S_IFMT) == S_IFREG
|
||||||
|
- || (statbuf.st_mode & S_IFMT) == S_IFDIR)
|
||||||
|
-#endif /* USE_CFBUNDLE */
|
||||||
|
- ) {
|
||||||
|
- void *handle = NULL;
|
||||||
|
-
|
||||||
|
-#if USE_CFBUNDLE
|
||||||
|
- char executablepath[MAXPATHLEN];
|
||||||
|
-
|
||||||
|
- if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
|
||||||
|
- int lock_err = 0;
|
||||||
|
- CFStringRef pluginString = NULL;
|
||||||
|
- CFURLRef pluginURL = NULL;
|
||||||
|
- CFBundleRef pluginBundle = NULL;
|
||||||
|
- CFURLRef executableURL = NULL;
|
||||||
|
-
|
||||||
|
- /* Lock around CoreFoundation calls since objects are refcounted
|
||||||
|
- * and the refcounts are not thread-safe. Using pthreads directly
|
||||||
|
- * because this code is Mac-specific */
|
||||||
|
- lock_err = pthread_mutex_lock(&krb5int_bundle_mutex);
|
||||||
|
- if (lock_err) { err = lock_err; }
|
||||||
|
-
|
||||||
|
- if (!err) {
|
||||||
|
- pluginString = CFStringCreateWithCString (kCFAllocatorDefault,
|
||||||
|
- filepath,
|
||||||
|
- kCFStringEncodingASCII);
|
||||||
|
- if (pluginString == NULL) { err = ENOMEM; }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!err) {
|
||||||
|
- pluginURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault,
|
||||||
|
- pluginString,
|
||||||
|
- kCFURLPOSIXPathStyle,
|
||||||
|
- true);
|
||||||
|
- if (pluginURL == NULL) { err = ENOMEM; }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!err) {
|
||||||
|
- pluginBundle = CFBundleCreate (kCFAllocatorDefault, pluginURL);
|
||||||
|
- if (pluginBundle == NULL) { err = ENOENT; } /* XXX need better error */
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!err) {
|
||||||
|
- executableURL = CFBundleCopyExecutableURL (pluginBundle);
|
||||||
|
- if (executableURL == NULL) { err = ENOMEM; }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!err) {
|
||||||
|
- if (!CFURLGetFileSystemRepresentation (executableURL,
|
||||||
|
- true, /* absolute */
|
||||||
|
- (UInt8 *)executablepath,
|
||||||
|
- sizeof (executablepath))) {
|
||||||
|
- err = ENOMEM;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!err) {
|
||||||
|
- /* override the path the caller passed in */
|
||||||
|
- filepath = executablepath;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (executableURL != NULL) { CFRelease (executableURL); }
|
||||||
|
- if (pluginBundle != NULL) { CFRelease (pluginBundle); }
|
||||||
|
- if (pluginURL != NULL) { CFRelease (pluginURL); }
|
||||||
|
- if (pluginString != NULL) { CFRelease (pluginString); }
|
||||||
|
-
|
||||||
|
- /* unlock after CFRelease calls since they modify refcounts */
|
||||||
|
- if (!lock_err) { pthread_mutex_unlock (&krb5int_bundle_mutex); }
|
||||||
|
- }
|
||||||
|
-#endif /* USE_CFBUNDLE */
|
||||||
|
-
|
||||||
|
- if (!err) {
|
||||||
|
- handle = dlopen(filepath, PLUGIN_DLOPEN_FLAGS);
|
||||||
|
- if (handle == NULL) {
|
||||||
|
- const char *e = dlerror();
|
||||||
|
- if (e == NULL)
|
||||||
|
- e = _("unknown failure");
|
||||||
|
- Tprintf ("dlopen(%s): %s\n", filepath, e);
|
||||||
|
- err = ENOENT; /* XXX */
|
||||||
|
- k5_set_error(ep, err, _("unable to load plugin [%s]: %s"),
|
||||||
|
- filepath, e);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ if (h->dlhandle != NULL)
|
||||||
|
+ dlclose(h->dlhandle);
|
||||||
|
+}
|
||||||
|
+#define close_plugin close_plugin_dlfcn
|
||||||
|
|
||||||
|
- if (!err) {
|
||||||
|
- got_plugin = 1;
|
||||||
|
- htmp->dlhandle = handle;
|
||||||
|
- handle = NULL;
|
||||||
|
- }
|
||||||
|
+#elif defined(_WIN32)
|
||||||
|
|
||||||
|
- if (handle != NULL) { dlclose (handle); }
|
||||||
|
+static long
|
||||||
|
+open_plugin_win32(struct plugin_file_handle *h, const char *filename,
|
||||||
|
+ struct errinfo *ep)
|
||||||
|
+{
|
||||||
|
+ h->module = LoadLibrary(filename);
|
||||||
|
+ if (h == NULL) {
|
||||||
|
+ Tprintf("Unable to load dll: %s\n", filename);
|
||||||
|
+ k5_set_error(ep, ENOENT, _("unable to load DLL [%s]"), filename);
|
||||||
|
+ return ENOENT;
|
||||||
|
}
|
||||||
|
-#endif /* USE_DLOPEN */
|
||||||
|
-
|
||||||
|
-#ifdef _WIN32
|
||||||
|
- if (!err && (statbuf.st_mode & S_IFMT) == S_IFREG) {
|
||||||
|
- HMODULE handle = NULL;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+#define open_plugin open_plugin_win32
|
||||||
|
|
||||||
|
- handle = LoadLibrary(filepath);
|
||||||
|
- if (handle == NULL) {
|
||||||
|
- Tprintf ("Unable to load dll: %s\n", filepath);
|
||||||
|
- err = ENOENT; /* XXX */
|
||||||
|
- k5_set_error(ep, err, _("unable to load DLL [%s]"), filepath);
|
||||||
|
- }
|
||||||
|
+static long
|
||||||
|
+get_sym_win32(struct plugin_file_handle *h, const char *csymname,
|
||||||
|
+ void **sym_out, struct errinfo *ep)
|
||||||
|
+{
|
||||||
|
+ LPVOID lpMsgBuf;
|
||||||
|
+ DWORD dw;
|
||||||
|
|
||||||
|
- if (!err) {
|
||||||
|
- got_plugin = 1;
|
||||||
|
- htmp->hinstPlugin = handle;
|
||||||
|
- handle = NULL;
|
||||||
|
+ if (h->module == NULL)
|
||||||
|
+ return ENOENT;
|
||||||
|
+ *sym_out = GetProcAddress(h->module, csymname);
|
||||||
|
+ if (*sym_out == NULL) {
|
||||||
|
+ Tprintf("GetProcAddress(%s): %i\n", csymname, GetLastError());
|
||||||
|
+ dw = GetLastError();
|
||||||
|
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
+ FORMAT_MESSAGE_FROM_SYSTEM,
|
||||||
|
+ NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
+ (LPTSTR)&lpMsgBuf, 0, NULL)) {
|
||||||
|
+ k5_set_error(ep, ENOENT, _("unable to get DLL Symbol: %s"),
|
||||||
|
+ (char *)lpMsgBuf);
|
||||||
|
+ LocalFree(lpMsgBuf);
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- if (handle != NULL)
|
||||||
|
- FreeLibrary(handle);
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
- if (!err && !got_plugin) {
|
||||||
|
- err = ENOENT; /* no plugin or no way to load plugins */
|
||||||
|
- k5_set_error(ep, err, _("plugin unavailable: %s"), strerror(err));
|
||||||
|
+ return ENOENT;
|
||||||
|
}
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+#define get_sym get_sym_win32
|
||||||
|
|
||||||
|
- if (!err) {
|
||||||
|
- *h = htmp;
|
||||||
|
- htmp = NULL; /* h takes ownership */
|
||||||
|
- }
|
||||||
|
+static void
|
||||||
|
+close_plugin_win32(struct plugin_file_handle *h)
|
||||||
|
+{
|
||||||
|
+ if (h->module != NULL)
|
||||||
|
+ FreeLibrary(h->module);
|
||||||
|
+}
|
||||||
|
+#define close_plugin close_plugin_win32
|
||||||
|
|
||||||
|
- free(htmp);
|
||||||
|
+#else
|
||||||
|
|
||||||
|
- return err;
|
||||||
|
+static long
|
||||||
|
+open_plugin_dummy(struct plugin_file_handle *h, const char *filename,
|
||||||
|
+ struct errinfo *ep)
|
||||||
|
+{
|
||||||
|
+ k5_set_error(ep, ENOENT, _("plugin loading unavailable"));
|
||||||
|
+ return ENOENT;
|
||||||
|
}
|
||||||
|
+#define open_plugin open_plugin_dummy
|
||||||
|
|
||||||
|
static long
|
||||||
|
-krb5int_get_plugin_sym (struct plugin_file_handle *h,
|
||||||
|
- const char *csymname, int isfunc, void **ptr,
|
||||||
|
- struct errinfo *ep)
|
||||||
|
+get_sym_dummy(struct plugin_file_handle *h, const char *csymname,
|
||||||
|
+ void **sym_out, struct errinfo *ep)
|
||||||
|
{
|
||||||
|
- long err = 0;
|
||||||
|
- void *sym = NULL;
|
||||||
|
+ return ENOENT;
|
||||||
|
+}
|
||||||
|
+#define get_sym get_sym_dummy
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+close_plugin_dummy(struct plugin_file_handle *h)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+#define close_plugin close_plugin_dummy
|
||||||
|
|
||||||
|
-#if USE_DLOPEN
|
||||||
|
- if (!err && !sym && (h->dlhandle != NULL)) {
|
||||||
|
- /* XXX Do we need to add a leading "_" to the symbol name on any
|
||||||
|
- modern platforms? */
|
||||||
|
- sym = dlsym (h->dlhandle, csymname);
|
||||||
|
- if (sym == NULL) {
|
||||||
|
- const char *e = dlerror (); /* XXX copy and save away */
|
||||||
|
- if (e == NULL)
|
||||||
|
- e = "unknown failure";
|
||||||
|
- Tprintf ("dlsym(%s): %s\n", csymname, e);
|
||||||
|
- err = ENOENT; /* XXX */
|
||||||
|
- k5_set_error(ep, err, "%s", e);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#ifdef _WIN32
|
||||||
|
- LPVOID lpMsgBuf;
|
||||||
|
- DWORD dw;
|
||||||
|
+long KRB5_CALLCONV
|
||||||
|
+krb5int_open_plugin(const char *filename,
|
||||||
|
+ struct plugin_file_handle **handle_out, struct errinfo *ep)
|
||||||
|
+{
|
||||||
|
+ long ret;
|
||||||
|
+ struct plugin_file_handle *h;
|
||||||
|
|
||||||
|
- if (!err && !sym && (h->hinstPlugin != NULL)) {
|
||||||
|
- sym = GetProcAddress(h->hinstPlugin, csymname);
|
||||||
|
- if (sym == NULL) {
|
||||||
|
- const char *e = "unable to get dll symbol"; /* XXX copy and save away */
|
||||||
|
- Tprintf ("GetProcAddress(%s): %i\n", csymname, GetLastError());
|
||||||
|
- err = ENOENT; /* XXX */
|
||||||
|
- k5_set_error(ep, err, "%s", e);
|
||||||
|
-
|
||||||
|
- dw = GetLastError();
|
||||||
|
- if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
- FORMAT_MESSAGE_FROM_SYSTEM,
|
||||||
|
- NULL,
|
||||||
|
- dw,
|
||||||
|
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
- (LPTSTR) &lpMsgBuf,
|
||||||
|
- 0, NULL )) {
|
||||||
|
-
|
||||||
|
- fprintf (stderr, "unable to get dll symbol, %s\n", (LPCTSTR)lpMsgBuf);
|
||||||
|
- LocalFree(lpMsgBuf);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
+ *handle_out = NULL;
|
||||||
|
|
||||||
|
- if (!err && (sym == NULL)) {
|
||||||
|
- err = ENOENT; /* unimplemented */
|
||||||
|
- }
|
||||||
|
+ h = calloc(1, sizeof(*h));
|
||||||
|
+ if (h == NULL)
|
||||||
|
+ return ENOMEM;
|
||||||
|
|
||||||
|
- if (!err) {
|
||||||
|
- *ptr = sym;
|
||||||
|
+ ret = open_plugin(h, filename, ep);
|
||||||
|
+ if (ret) {
|
||||||
|
+ free(h);
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return err;
|
||||||
|
+ *handle_out = h;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long KRB5_CALLCONV
|
||||||
|
-krb5int_get_plugin_data (struct plugin_file_handle *h, const char *csymname,
|
||||||
|
- void **ptr, struct errinfo *ep)
|
||||||
|
+krb5int_get_plugin_data(struct plugin_file_handle *h, const char *csymname,
|
||||||
|
+ void **sym_out, struct errinfo *ep)
|
||||||
|
{
|
||||||
|
- return krb5int_get_plugin_sym (h, csymname, 0, ptr, ep);
|
||||||
|
+ return get_sym(h, csymname, sym_out, ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
long KRB5_CALLCONV
|
||||||
|
-krb5int_get_plugin_func (struct plugin_file_handle *h, const char *csymname,
|
||||||
|
- void (**ptr)(), struct errinfo *ep)
|
||||||
|
+krb5int_get_plugin_func(struct plugin_file_handle *h, const char *csymname,
|
||||||
|
+ void (**sym_out)(), struct errinfo *ep)
|
||||||
|
{
|
||||||
|
void *dptr = NULL;
|
||||||
|
- long err = krb5int_get_plugin_sym (h, csymname, 1, &dptr, ep);
|
||||||
|
- if (!err) {
|
||||||
|
- /* Cast function pointers to avoid code duplication */
|
||||||
|
- *ptr = (void (*)()) dptr;
|
||||||
|
- }
|
||||||
|
- return err;
|
||||||
|
+ long ret = get_sym(h, csymname, &dptr, ep);
|
||||||
|
+
|
||||||
|
+ if (!ret)
|
||||||
|
+ *sym_out = (void (*)())dptr;
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KRB5_CALLCONV
|
||||||
|
krb5int_close_plugin (struct plugin_file_handle *h)
|
||||||
|
{
|
||||||
|
-#if USE_DLOPEN
|
||||||
|
- if (h->dlhandle != NULL) { dlclose(h->dlhandle); }
|
||||||
|
-#endif
|
||||||
|
-#ifdef _WIN32
|
||||||
|
- if (h->hinstPlugin != NULL) { FreeLibrary(h->hinstPlugin); }
|
||||||
|
-#endif
|
||||||
|
- free (h);
|
||||||
|
+ close_plugin(h);
|
||||||
|
+ free(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* autoconf docs suggest using this preference order */
|
||||||
|
-#if HAVE_DIRENT_H || USE_DIRENT_H
|
||||||
|
-#include <dirent.h>
|
||||||
|
-#define NAMELEN(D) strlen((D)->d_name)
|
||||||
|
-#else
|
||||||
|
-#ifndef _WIN32
|
||||||
|
-#define dirent direct
|
||||||
|
-#define NAMELEN(D) ((D)->d->namlen)
|
||||||
|
-#else
|
||||||
|
-#define NAMELEN(D) strlen((D)->d_name)
|
||||||
|
-#endif
|
||||||
|
-#if HAVE_SYS_NDIR_H
|
||||||
|
-# include <sys/ndir.h>
|
||||||
|
-#elif HAVE_SYS_DIR_H
|
||||||
|
-# include <sys/dir.h>
|
||||||
|
-#elif HAVE_NDIR_H
|
||||||
|
-# include <ndir.h>
|
||||||
|
-#endif
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
static long
|
||||||
|
krb5int_plugin_file_handle_array_init (struct plugin_file_handle ***harray)
|
||||||
|
{
|
||||||
|
@@ -619,42 +418,36 @@ krb5int_open_plugin_dirs (const char * const *dirnames,
|
||||||
|
if (handle != NULL) { krb5int_close_plugin (handle); }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- /* load all plugins in each directory */
|
||||||
|
- DIR *dir = opendir (dirnames[i]);
|
||||||
|
+ char **fnames = NULL;
|
||||||
|
+ int j;
|
||||||
|
|
||||||
|
- while (dir != NULL && !err) {
|
||||||
|
- struct dirent *d = NULL;
|
||||||
|
+ err = k5_dir_filenames(dirnames[i], &fnames);
|
||||||
|
+ for (j = 0; !err && fnames[j] != NULL; j++) {
|
||||||
|
char *filepath = NULL;
|
||||||
|
struct plugin_file_handle *handle = NULL;
|
||||||
|
|
||||||
|
- d = readdir (dir);
|
||||||
|
- if (d == NULL) { break; }
|
||||||
|
-
|
||||||
|
- if ((strcmp (d->d_name, ".") == 0) ||
|
||||||
|
- (strcmp (d->d_name, "..") == 0)) {
|
||||||
|
+ if (strcmp(fnames[j], ".") == 0 ||
|
||||||
|
+ strcmp(fnames[j], "..") == 0)
|
||||||
|
continue;
|
||||||
|
- }
|
||||||
|
|
||||||
|
- if (!err) {
|
||||||
|
- int len = NAMELEN (d);
|
||||||
|
- if (asprintf(&filepath, "%s/%*s", dirnames[i], len, d->d_name) < 0) {
|
||||||
|
- filepath = NULL;
|
||||||
|
- err = ENOMEM;
|
||||||
|
- }
|
||||||
|
+ if (asprintf(&filepath, "%s/%s", dirnames[i], fnames[j]) < 0) {
|
||||||
|
+ filepath = NULL;
|
||||||
|
+ err = ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!err) {
|
||||||
|
- if (krb5int_open_plugin (filepath, &handle, ep) == 0) {
|
||||||
|
- err = krb5int_plugin_file_handle_array_add (&h, &count, handle);
|
||||||
|
- if (!err) { handle = NULL; } /* h takes ownership */
|
||||||
|
- }
|
||||||
|
+ if (!err && krb5int_open_plugin(filepath, &handle, ep) == 0) {
|
||||||
|
+ err = krb5int_plugin_file_handle_array_add(&h, &count,
|
||||||
|
+ handle);
|
||||||
|
+ if (!err)
|
||||||
|
+ handle = NULL; /* h takes ownership */
|
||||||
|
}
|
||||||
|
|
||||||
|
free(filepath);
|
||||||
|
- if (handle != NULL) { krb5int_close_plugin (handle); }
|
||||||
|
+ if (handle != NULL)
|
||||||
|
+ krb5int_close_plugin(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (dir != NULL) { closedir (dir); }
|
||||||
|
+ k5_free_filenames(fnames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
From 75f71ace74449a6e5154314229bfa61960cd326c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Thu, 28 Jul 2022 15:20:12 +0200
|
||||||
|
Subject: [PATCH] Update error checking for OpenSSL CMS_verify
|
||||||
|
|
||||||
|
The code for CMS data verification was initially written for OpenSSL's
|
||||||
|
PKCS7_verify() function. It now uses CMS_verify(), but error handling
|
||||||
|
is still done using PKCS7_verify() error identifiers. Update the
|
||||||
|
recognized error codes so that the KDC generates
|
||||||
|
KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED errors when appropriate.
|
||||||
|
Use ERR_peek_last_error() to observe the error generated closest to
|
||||||
|
the API surface.
|
||||||
|
|
||||||
|
[ghudson@mit.edu: edited commit message]
|
||||||
|
|
||||||
|
ticket: 9069 (new)
|
||||||
|
tags: pullup
|
||||||
|
target_version: 1.20-next
|
||||||
|
---
|
||||||
|
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 9 ++++++---
|
||||||
|
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
index 1c2aa02827..16edf15cb2 100644
|
||||||
|
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
@@ -2102,12 +2102,15 @@ cms_signeddata_verify(krb5_context context,
|
||||||
|
goto cleanup;
|
||||||
|
out = BIO_new(BIO_s_mem());
|
||||||
|
if (CMS_verify(cms, NULL, store, NULL, out, flags) == 0) {
|
||||||
|
- unsigned long err = ERR_peek_error();
|
||||||
|
+ unsigned long err = ERR_peek_last_error();
|
||||||
|
switch(ERR_GET_REASON(err)) {
|
||||||
|
- case PKCS7_R_DIGEST_FAILURE:
|
||||||
|
+ case RSA_R_DIGEST_NOT_ALLOWED:
|
||||||
|
+ case CMS_R_UNKNOWN_DIGEST_ALGORITHM:
|
||||||
|
+ case CMS_R_NO_MATCHING_DIGEST:
|
||||||
|
+ case CMS_R_NO_MATCHING_SIGNATURE:
|
||||||
|
retval = KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED;
|
||||||
|
break;
|
||||||
|
- case PKCS7_R_SIGNATURE_FAILURE:
|
||||||
|
+ case CMS_R_VERIFICATION_FAILURE:
|
||||||
|
default:
|
||||||
|
retval = KRB5KDC_ERR_INVALID_SIG;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,28 @@
|
|||||||
|
From 3f8a3b57cf0e057635e570d5038fb52c19ca5744 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Fri, 19 Aug 2022 10:34:52 +0200
|
||||||
|
Subject: [PATCH] [downstream] Catch SHA-1 digest disallowed error for
|
||||||
|
PKINIT
|
||||||
|
|
||||||
|
An OpenSSL patch causes EVP_R_INVALID_DIGEST error to be raised if
|
||||||
|
CMS_verify is called to verify a SHA-1 signature. If this error is
|
||||||
|
caught, it will now return KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED.
|
||||||
|
---
|
||||||
|
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
index 16edf15cb2..bfa3fe8e91 100644
|
||||||
|
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
@@ -2104,6 +2104,7 @@ cms_signeddata_verify(krb5_context context,
|
||||||
|
if (CMS_verify(cms, NULL, store, NULL, out, flags) == 0) {
|
||||||
|
unsigned long err = ERR_peek_last_error();
|
||||||
|
switch(ERR_GET_REASON(err)) {
|
||||||
|
+ case EVP_R_INVALID_DIGEST:
|
||||||
|
case RSA_R_DIGEST_NOT_ALLOWED:
|
||||||
|
case CMS_R_UNKNOWN_DIGEST_ALGORITHM:
|
||||||
|
case CMS_R_NO_MATCHING_DIGEST:
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,239 @@
|
|||||||
|
From 6ba011d89f9cf4661eb7110bf810cfdb514b69fa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Greg Hudson <ghudson@mit.edu>
|
||||||
|
Date: Mon, 19 Sep 2022 15:18:50 -0400
|
||||||
|
Subject: [PATCH] Add and use ts_interval() helper
|
||||||
|
|
||||||
|
ts_delta() returns a signed result, which cannot hold an interval
|
||||||
|
larger than 2^31-1 seconds. Intervals like this have been seen when
|
||||||
|
admins set password expiration dates more than 68 years in the future.
|
||||||
|
|
||||||
|
Add a second helper ts_interval() which returns a signed result, and
|
||||||
|
has the arguments reversed so that the start time is first. Use it in
|
||||||
|
warn_pw_expiry() to handle the password expiration case, in the GSS
|
||||||
|
krb5 mech where we return an unsigned context or credential lifetime
|
||||||
|
to the caller, and in the KEYRING ccache type where we compute an
|
||||||
|
unsigned keyring timeout.
|
||||||
|
|
||||||
|
ticket: 9071 (new)
|
||||||
|
---
|
||||||
|
src/include/k5-int.h | 9 +++++++++
|
||||||
|
src/lib/gssapi/krb5/accept_sec_context.c | 10 ++++++----
|
||||||
|
src/lib/gssapi/krb5/acquire_cred.c | 3 +--
|
||||||
|
src/lib/gssapi/krb5/context_time.c | 2 +-
|
||||||
|
src/lib/gssapi/krb5/init_sec_context.c | 4 ++--
|
||||||
|
src/lib/gssapi/krb5/inq_context.c | 2 +-
|
||||||
|
src/lib/gssapi/krb5/inq_cred.c | 2 +-
|
||||||
|
src/lib/gssapi/krb5/s4u_gss_glue.c | 2 +-
|
||||||
|
src/lib/krb5/ccache/cc_keyring.c | 4 ++--
|
||||||
|
src/lib/krb5/krb/get_in_tkt.c | 15 +++++++--------
|
||||||
|
10 files changed, 31 insertions(+), 22 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||||||
|
index c3aecba7d4..768110e5ef 100644
|
||||||
|
--- a/src/include/k5-int.h
|
||||||
|
+++ b/src/include/k5-int.h
|
||||||
|
@@ -2325,6 +2325,15 @@ ts_delta(krb5_timestamp a, krb5_timestamp b)
|
||||||
|
return (krb5_deltat)((uint32_t)a - (uint32_t)b);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Return (end - start) as an unsigned 32-bit value, or 0 if start > end. */
|
||||||
|
+static inline uint32_t
|
||||||
|
+ts_interval(krb5_timestamp start, krb5_timestamp end)
|
||||||
|
+{
|
||||||
|
+ if ((uint32_t)start > (uint32_t)end)
|
||||||
|
+ return 0;
|
||||||
|
+ return (uint32_t)end - (uint32_t)start;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Increment a timestamp by a signed 32-bit interval, without relying on
|
||||||
|
* undefined behavior. */
|
||||||
|
static inline krb5_timestamp
|
||||||
|
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||||
|
index 1bc807172b..7de2c9fd77 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/accept_sec_context.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||||
|
@@ -353,8 +353,8 @@ kg_accept_dce(minor_status, context_handle, verifier_cred_handle,
|
||||||
|
*mech_type = ctx->mech_used;
|
||||||
|
|
||||||
|
if (time_rec) {
|
||||||
|
- *time_rec = ts_delta(ctx->krb_times.endtime, now) +
|
||||||
|
- ctx->k5_context->clockskew;
|
||||||
|
+ *time_rec = ts_interval(now - ctx->k5_context->clockskew,
|
||||||
|
+ ctx->krb_times.endtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Never return GSS_C_DELEG_FLAG since we don't support DCE credential
|
||||||
|
@@ -1151,8 +1151,10 @@ kg_accept_krb5(minor_status, context_handle,
|
||||||
|
|
||||||
|
/* Add the maximum allowable clock skew as a grace period for context
|
||||||
|
* expiration, just as we do for the ticket. */
|
||||||
|
- if (time_rec)
|
||||||
|
- *time_rec = ts_delta(ctx->krb_times.endtime, now) + context->clockskew;
|
||||||
|
+ if (time_rec) {
|
||||||
|
+ *time_rec = ts_interval(now - context->clockskew,
|
||||||
|
+ ctx->krb_times.endtime);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (ret_flags)
|
||||||
|
*ret_flags = ctx->gss_flags;
|
||||||
|
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
|
||||||
|
index e226a02692..006eba114d 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/acquire_cred.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/acquire_cred.c
|
||||||
|
@@ -879,8 +879,7 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status,
|
||||||
|
GSS_C_NO_NAME);
|
||||||
|
if (GSS_ERROR(ret))
|
||||||
|
goto error_out;
|
||||||
|
- *time_rec = ts_after(cred->expire, now) ?
|
||||||
|
- ts_delta(cred->expire, now) : 0;
|
||||||
|
+ *time_rec = ts_interval(now, cred->expire);
|
||||||
|
k5_mutex_unlock(&cred->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c
|
||||||
|
index 1fdb5a16f2..5469d8154c 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/context_time.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/context_time.c
|
||||||
|
@@ -51,7 +51,7 @@ krb5_gss_context_time(minor_status, context_handle, time_rec)
|
||||||
|
return(GSS_S_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
- lifetime = ts_delta(ctx->krb_times.endtime, now);
|
||||||
|
+ lifetime = ts_interval(now, ctx->krb_times.endtime);
|
||||||
|
if (!ctx->initiate)
|
||||||
|
lifetime += ctx->k5_context->clockskew;
|
||||||
|
if (lifetime <= 0) {
|
||||||
|
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
|
||||||
|
index ea87cf6432..f0f094ccb7 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/init_sec_context.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/init_sec_context.c
|
||||||
|
@@ -664,7 +664,7 @@ kg_new_connection(
|
||||||
|
if (time_rec) {
|
||||||
|
if ((code = krb5_timeofday(context, &now)))
|
||||||
|
goto cleanup;
|
||||||
|
- *time_rec = ts_delta(ctx->krb_times.endtime, now);
|
||||||
|
+ *time_rec = ts_interval(now, ctx->krb_times.endtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the other returns */
|
||||||
|
@@ -878,7 +878,7 @@ mutual_auth(
|
||||||
|
if (time_rec) {
|
||||||
|
if ((code = krb5_timeofday(context, &now)))
|
||||||
|
goto fail;
|
||||||
|
- *time_rec = ts_delta(ctx->krb_times.endtime, now);
|
||||||
|
+ *time_rec = ts_interval(now, ctx->krb_times.endtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret_flags)
|
||||||
|
diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c
|
||||||
|
index cac024da1f..51c484fdfe 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/inq_context.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/inq_context.c
|
||||||
|
@@ -120,7 +120,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
|
||||||
|
|
||||||
|
/* Add the maximum allowable clock skew as a grace period for context
|
||||||
|
* expiration, just as we do for the ticket during authentication. */
|
||||||
|
- lifetime = ts_delta(ctx->krb_times.endtime, now);
|
||||||
|
+ lifetime = ts_interval(now, ctx->krb_times.endtime);
|
||||||
|
if (!ctx->initiate)
|
||||||
|
lifetime += context->clockskew;
|
||||||
|
if (lifetime < 0)
|
||||||
|
diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c
|
||||||
|
index bb63b726c8..0e675959a3 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/inq_cred.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/inq_cred.c
|
||||||
|
@@ -131,7 +131,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cred->expire != 0) {
|
||||||
|
- lifetime = ts_delta(cred->expire, now);
|
||||||
|
+ lifetime = ts_interval(now, cred->expire);
|
||||||
|
if (lifetime < 0)
|
||||||
|
lifetime = 0;
|
||||||
|
}
|
||||||
|
diff --git a/src/lib/gssapi/krb5/s4u_gss_glue.c b/src/lib/gssapi/krb5/s4u_gss_glue.c
|
||||||
|
index 7dcfe4e1eb..fa7f980af7 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/s4u_gss_glue.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/s4u_gss_glue.c
|
||||||
|
@@ -279,7 +279,7 @@ kg_compose_deleg_cred(OM_uint32 *minor_status,
|
||||||
|
if (code != 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
- *time_rec = ts_delta(cred->expire, now);
|
||||||
|
+ *time_rec = ts_interval(now, cred->expire);
|
||||||
|
}
|
||||||
|
|
||||||
|
major_status = GSS_S_COMPLETE;
|
||||||
|
diff --git a/src/lib/krb5/ccache/cc_keyring.c b/src/lib/krb5/ccache/cc_keyring.c
|
||||||
|
index ebef37d607..1dadeef64f 100644
|
||||||
|
--- a/src/lib/krb5/ccache/cc_keyring.c
|
||||||
|
+++ b/src/lib/krb5/ccache/cc_keyring.c
|
||||||
|
@@ -762,7 +762,7 @@ update_keyring_expiration(krb5_context context, krb5_ccache id)
|
||||||
|
|
||||||
|
/* Setting the timeout to zero would reset the timeout, so we set it to one
|
||||||
|
* second instead if creds are already expired. */
|
||||||
|
- timeout = ts_after(endtime, now) ? ts_delta(endtime, now) : 1;
|
||||||
|
+ timeout = ts_after(endtime, now) ? ts_interval(now, endtime) : 1;
|
||||||
|
(void)keyctl_set_timeout(data->cache_id, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1343,7 +1343,7 @@ krcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds)
|
||||||
|
|
||||||
|
if (ts_after(creds->times.endtime, now)) {
|
||||||
|
(void)keyctl_set_timeout(cred_key,
|
||||||
|
- ts_delta(creds->times.endtime, now));
|
||||||
|
+ ts_interval(now, creds->times.endtime));
|
||||||
|
}
|
||||||
|
|
||||||
|
update_keyring_expiration(context, id);
|
||||||
|
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
|
||||||
|
index 8b5ab595e9..1b420a3ac2 100644
|
||||||
|
--- a/src/lib/krb5/krb/get_in_tkt.c
|
||||||
|
+++ b/src/lib/krb5/krb/get_in_tkt.c
|
||||||
|
@@ -1522,7 +1522,7 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
|
||||||
|
void *expire_data;
|
||||||
|
krb5_timestamp pw_exp, acct_exp, now;
|
||||||
|
krb5_boolean is_last_req;
|
||||||
|
- krb5_deltat delta;
|
||||||
|
+ uint32_t interval;
|
||||||
|
char ts[256], banner[1024];
|
||||||
|
|
||||||
|
if (as_reply == NULL || as_reply->enc_part2 == NULL)
|
||||||
|
@@ -1553,8 +1553,8 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
|
||||||
|
ret = krb5_timeofday(context, &now);
|
||||||
|
if (ret != 0)
|
||||||
|
return;
|
||||||
|
- if (!is_last_req &&
|
||||||
|
- (ts_after(now, pw_exp) || ts_delta(pw_exp, now) > 7 * 24 * 60 * 60))
|
||||||
|
+ interval = ts_interval(now, pw_exp);
|
||||||
|
+ if (!is_last_req && (!interval || interval > 7 * 24 * 60 * 60))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!prompter)
|
||||||
|
@@ -1564,19 +1564,18 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
|
||||||
|
if (ret != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- delta = ts_delta(pw_exp, now);
|
||||||
|
- if (delta < 3600) {
|
||||||
|
+ if (interval < 3600) {
|
||||||
|
snprintf(banner, sizeof(banner),
|
||||||
|
_("Warning: Your password will expire in less than one hour "
|
||||||
|
"on %s"), ts);
|
||||||
|
- } else if (delta < 86400 * 2) {
|
||||||
|
+ } else if (interval < 86400 * 2) {
|
||||||
|
snprintf(banner, sizeof(banner),
|
||||||
|
_("Warning: Your password will expire in %d hour%s on %s"),
|
||||||
|
- delta / 3600, delta < 7200 ? "" : "s", ts);
|
||||||
|
+ interval / 3600, interval < 7200 ? "" : "s", ts);
|
||||||
|
} else {
|
||||||
|
snprintf(banner, sizeof(banner),
|
||||||
|
_("Warning: Your password will expire in %d days on %s"),
|
||||||
|
- delta / 86400, ts);
|
||||||
|
+ interval / 86400, ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PROMPTER_INVOCATION */
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,41 @@
|
|||||||
|
From 9aa12e932f08651785519890896647069e7a30b1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Wed, 7 Dec 2022 13:22:42 +0100
|
||||||
|
Subject: [PATCH] [downstream] Make tests compatible with
|
||||||
|
sssd_krb5_locator_plugin.so
|
||||||
|
|
||||||
|
The sssd_krb5_locator_plugin.so plugin provided by sssd-client conflicts
|
||||||
|
with the upstream test t_discover_uri.py. The test has to be modified in
|
||||||
|
order to avoid false positive.
|
||||||
|
---
|
||||||
|
src/lib/krb5/os/t_discover_uri.py | 9 ++++++++-
|
||||||
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/lib/krb5/os/t_discover_uri.py b/src/lib/krb5/os/t_discover_uri.py
|
||||||
|
index 87bac17929..26bc95a8dc 100644
|
||||||
|
--- a/src/lib/krb5/os/t_discover_uri.py
|
||||||
|
+++ b/src/lib/krb5/os/t_discover_uri.py
|
||||||
|
@@ -1,3 +1,4 @@
|
||||||
|
+from os.path import exists
|
||||||
|
from k5test import *
|
||||||
|
|
||||||
|
entries = ('URI _kerberos.TEST krb5srv::kkdcp:https://kdc1 1 1\n',
|
||||||
|
@@ -37,8 +38,14 @@ realm.env['RESOLV_WRAPPER_HOSTS'] = hosts_filename
|
||||||
|
out = realm.run(['./t_locate_kdc', 'TEST'], env=realm.env)
|
||||||
|
l = out.splitlines()
|
||||||
|
|
||||||
|
+if (exists('/usr/lib/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.so')
|
||||||
|
+ or exists('/usr/lib64/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.so')):
|
||||||
|
+ line_range = range(6, 14)
|
||||||
|
+else:
|
||||||
|
+ line_range = range(4, 12)
|
||||||
|
+
|
||||||
|
j = 0
|
||||||
|
-for i in range(4, 12):
|
||||||
|
+for i in line_range:
|
||||||
|
if l[i].strip() != expected[j]:
|
||||||
|
fail('URI answers do not match')
|
||||||
|
j += 1
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From fb13766f8fbd78acfcf7a150332a4e5474e4f52a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Mon, 9 Jan 2023 22:39:52 +0100
|
||||||
|
Subject: [PATCH] [downstream] Do not set root as ksu file owner
|
||||||
|
|
||||||
|
Upstream Makefile uses the install command to set root as owner of the
|
||||||
|
ksu executable file. However, this is no longer supported on latest
|
||||||
|
versions of the Mock build environment.
|
||||||
|
|
||||||
|
In case of ksu, the owner, group, and mode are already set using %attr()
|
||||||
|
in the specfile.
|
||||||
|
---
|
||||||
|
src/config/pre.in | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/config/pre.in b/src/config/pre.in
|
||||||
|
index 7eaa2f351c..e9ae71471e 100644
|
||||||
|
--- a/src/config/pre.in
|
||||||
|
+++ b/src/config/pre.in
|
||||||
|
@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP)
|
||||||
|
INSTALL_SCRIPT=@INSTALL_PROGRAM@
|
||||||
|
INSTALL_DATA=@INSTALL_DATA@
|
||||||
|
INSTALL_SHLIB=@INSTALL_SHLIB@
|
||||||
|
-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root
|
||||||
|
+INSTALL_SETUID=$(INSTALL)
|
||||||
|
## This is needed because autoconf will sometimes define @exec_prefix@ to be
|
||||||
|
## ${prefix}.
|
||||||
|
prefix=@prefix@
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,165 @@
|
|||||||
|
From 6aea69170c2064aaea73ad3283b6d7dd0cae47e1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Thu, 19 Jan 2023 19:22:27 +0100
|
||||||
|
Subject: [PATCH] [downstream] Allow KRB5KDF, MD5, and MD4 in FIPS mode
|
||||||
|
|
||||||
|
OpenSSL's restrictions to use KRB5KDF, MD5, and MD4 in FIPS mode are
|
||||||
|
bypassed in case AES SHA-1 HMAC or RC4 encryption types are allowed by
|
||||||
|
the crypto policy.
|
||||||
|
---
|
||||||
|
.../crypto/openssl/hash_provider/hash_evp.c | 97 +++++++++++++++++--
|
||||||
|
src/lib/crypto/openssl/kdf.c | 2 +-
|
||||||
|
2 files changed, 89 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||||
|
index 11659908bb..eb2e693e9f 100644
|
||||||
|
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||||
|
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||||
|
@@ -44,6 +44,49 @@
|
||||||
|
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#include <openssl/provider.h>
|
||||||
|
+#include <openssl/fips.h>
|
||||||
|
+#include <threads.h>
|
||||||
|
+
|
||||||
|
+typedef struct ossl_lib_md_context {
|
||||||
|
+ OSSL_LIB_CTX *libctx;
|
||||||
|
+ OSSL_PROVIDER *default_provider;
|
||||||
|
+ OSSL_PROVIDER *legacy_provider;
|
||||||
|
+} ossl_md_context_t;
|
||||||
|
+
|
||||||
|
+static thread_local ossl_md_context_t *ossl_md_ctx = NULL;
|
||||||
|
+
|
||||||
|
+static krb5_error_code
|
||||||
|
+init_ossl_md_ctx(ossl_md_context_t *ctx, const char *algo)
|
||||||
|
+{
|
||||||
|
+ ctx->libctx = OSSL_LIB_CTX_new();
|
||||||
|
+ if (!ctx->libctx)
|
||||||
|
+ return KRB5_CRYPTO_INTERNAL;
|
||||||
|
+
|
||||||
|
+ /* Load both legacy and default provider as both may be needed. */
|
||||||
|
+ ctx->default_provider = OSSL_PROVIDER_load(ctx->libctx, "default");
|
||||||
|
+ ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy");
|
||||||
|
+
|
||||||
|
+ if (!(ctx->default_provider && ctx->legacy_provider))
|
||||||
|
+ return KRB5_CRYPTO_INTERNAL;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+deinit_ossl_ctx(ossl_md_context_t *ctx)
|
||||||
|
+{
|
||||||
|
+ if (ctx->legacy_provider)
|
||||||
|
+ OSSL_PROVIDER_unload(ctx->legacy_provider);
|
||||||
|
+
|
||||||
|
+ if (ctx->default_provider)
|
||||||
|
+ OSSL_PROVIDER_unload(ctx->default_provider);
|
||||||
|
+
|
||||||
|
+ if (ctx->libctx)
|
||||||
|
+ OSSL_LIB_CTX_free(ctx->libctx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
static krb5_error_code
|
||||||
|
hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||||
|
krb5_data *output)
|
||||||
|
@@ -60,11 +103,6 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||||
|
if (ctx == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
- if (type == EVP_md4() || type == EVP_md5()) {
|
||||||
|
- /* See comments below in hash_md4() and hash_md5(). */
|
||||||
|
- EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
ok = EVP_DigestInit_ex(ctx, type, NULL);
|
||||||
|
for (i = 0; i < num_data; i++) {
|
||||||
|
if (!SIGN_IOV(&data[i]))
|
||||||
|
@@ -77,6 +115,43 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||||
|
return ok ? 0 : KRB5_CRYPTO_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static krb5_error_code
|
||||||
|
+hash_legacy_evp(const char *algo, const krb5_crypto_iov *data, size_t num_data,
|
||||||
|
+ krb5_data *output)
|
||||||
|
+{
|
||||||
|
+ krb5_error_code err;
|
||||||
|
+ EVP_MD *md = NULL;
|
||||||
|
+
|
||||||
|
+ if (!ossl_md_ctx) {
|
||||||
|
+ ossl_md_ctx = malloc(sizeof(ossl_md_context_t));
|
||||||
|
+ if (!ossl_md_ctx) {
|
||||||
|
+ err = ENOMEM;
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ err = init_ossl_md_ctx(ossl_md_ctx, algo);
|
||||||
|
+ if (err) {
|
||||||
|
+ deinit_ossl_ctx(ossl_md_ctx);
|
||||||
|
+ free(ossl_md_ctx);
|
||||||
|
+ ossl_md_ctx = NULL;
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ md = EVP_MD_fetch(ossl_md_ctx->libctx, algo, NULL);
|
||||||
|
+ if (!md) {
|
||||||
|
+ err = KRB5_CRYPTO_INTERNAL;
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ err = hash_evp(md, data, num_data, output);
|
||||||
|
+
|
||||||
|
+end:
|
||||||
|
+ if (md)
|
||||||
|
+ EVP_MD_free(md);
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef K5_OPENSSL_MD4
|
||||||
|
@@ -88,7 +163,8 @@ hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
|
||||||
|
* by IPA. These keys are only used along a (separately) secured channel
|
||||||
|
* for legacy reasons when performing trusts to Active Directory.
|
||||||
|
*/
|
||||||
|
- return hash_evp(EVP_md4(), data, num_data, output);
|
||||||
|
+ return FIPS_mode() ? hash_legacy_evp("MD4", data, num_data, output)
|
||||||
|
+ : hash_evp(EVP_md4(), data, num_data, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct krb5_hash_provider krb5int_hash_md4 = {
|
||||||
|
@@ -100,9 +176,12 @@ const struct krb5_hash_provider krb5int_hash_md4 = {
|
||||||
|
static krb5_error_code
|
||||||
|
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
|
||||||
|
{
|
||||||
|
- /* MD5 is needed in FIPS mode for communication with RADIUS servers. This
|
||||||
|
- * is gated in libkrad by libdefaults->radius_md5_fips_override. */
|
||||||
|
- return hash_evp(EVP_md5(), data, num_data, output);
|
||||||
|
+ /*
|
||||||
|
+ * MD5 is needed in FIPS mode for communication with RADIUS servers. This
|
||||||
|
+ * is gated in libkrad by libdefaults->radius_md5_fips_override.
|
||||||
|
+ */
|
||||||
|
+ return FIPS_mode() ? hash_legacy_evp("MD5", data, num_data, output)
|
||||||
|
+ : hash_evp(EVP_md5(), data, num_data, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct krb5_hash_provider krb5int_hash_md5 = {
|
||||||
|
diff --git a/src/lib/crypto/openssl/kdf.c b/src/lib/crypto/openssl/kdf.c
|
||||||
|
index 5a43c3d9eb..8528ddc4a9 100644
|
||||||
|
--- a/src/lib/crypto/openssl/kdf.c
|
||||||
|
+++ b/src/lib/crypto/openssl/kdf.c
|
||||||
|
@@ -198,7 +198,7 @@ k5_derive_random_rfc3961(const struct krb5_enc_provider *enc, krb5_key key,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- kdf = EVP_KDF_fetch(NULL, "KRB5KDF", NULL);
|
||||||
|
+ kdf = EVP_KDF_fetch(NULL, "KRB5KDF", "-fips");
|
||||||
|
if (kdf == NULL) {
|
||||||
|
ret = KRB5_CRYPTO_INTERNAL;
|
||||||
|
goto done;
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,672 @@
|
|||||||
|
From f09300d9a9988215263775ac122b7ea2898d04db Mon Sep 17 00:00:00 2001
|
||||||
|
From: Greg Hudson <ghudson@mit.edu>
|
||||||
|
Date: Thu, 22 Dec 2022 03:05:23 -0500
|
||||||
|
Subject: [PATCH] Add PAC full checksums
|
||||||
|
|
||||||
|
A paper by Tom Tervoort noted that computing the PAC privsvr checksum
|
||||||
|
over only the server checksum is vulnerable to collision attacks
|
||||||
|
(CVE-2022-37967). In response, Microsoft has added a second KDC
|
||||||
|
checksum over the full contents of the PAC. Generate and verify full
|
||||||
|
KDC checksums in PACs for service tickets. Update the t_pac.c ticket
|
||||||
|
test case to use a ticket issued by a recent version of Active
|
||||||
|
Directory (provided by Stefan Metzmacher).
|
||||||
|
|
||||||
|
ticket: 9084 (new)
|
||||||
|
---
|
||||||
|
doc/appdev/refs/macros/index.rst | 1 +
|
||||||
|
src/include/krb5/krb5.hin | 1 +
|
||||||
|
src/lib/krb5/krb/pac.c | 92 +++++++++--------
|
||||||
|
src/lib/krb5/krb/pac_sign.c | 146 +++++++++++++++-----------
|
||||||
|
src/lib/krb5/krb/t_pac.c | 171 ++++++++++++++++++-------------
|
||||||
|
src/tests/t_authdata.py | 4 +-
|
||||||
|
6 files changed, 240 insertions(+), 175 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/doc/appdev/refs/macros/index.rst b/doc/appdev/refs/macros/index.rst
|
||||||
|
index 5f34dea5e8..3eeee25593 100644
|
||||||
|
--- a/doc/appdev/refs/macros/index.rst
|
||||||
|
+++ b/doc/appdev/refs/macros/index.rst
|
||||||
|
@@ -247,6 +247,7 @@ Public
|
||||||
|
KRB5_PAC_SERVER_CHECKSUM.rst
|
||||||
|
KRB5_PAC_TICKET_CHECKSUM.rst
|
||||||
|
KRB5_PAC_UPN_DNS_INFO.rst
|
||||||
|
+ KRB5_PAC_FULL_CHECKSUM.rst
|
||||||
|
KRB5_PADATA_AFS3_SALT.rst
|
||||||
|
KRB5_PADATA_AP_REQ.rst
|
||||||
|
KRB5_PADATA_AS_CHECKSUM.rst
|
||||||
|
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
|
||||||
|
index fb9f2a366c..2ba4010514 100644
|
||||||
|
--- a/src/include/krb5/krb5.hin
|
||||||
|
+++ b/src/include/krb5/krb5.hin
|
||||||
|
@@ -8164,6 +8164,7 @@ krb5_verify_authdata_kdc_issued(krb5_context context,
|
||||||
|
#define KRB5_PAC_TICKET_CHECKSUM 16 /**< Ticket checksum */
|
||||||
|
#define KRB5_PAC_ATTRIBUTES_INFO 17 /**< PAC attributes */
|
||||||
|
#define KRB5_PAC_REQUESTOR 18 /**< PAC requestor SID */
|
||||||
|
+#define KRB5_PAC_FULL_CHECKSUM 19 /**< KDC full checksum */
|
||||||
|
|
||||||
|
struct krb5_pac_data;
|
||||||
|
/** PAC data structure to convey authorization information */
|
||||||
|
diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c
|
||||||
|
index f6c4373de0..954482e0c7 100644
|
||||||
|
--- a/src/lib/krb5/krb/pac.c
|
||||||
|
+++ b/src/lib/krb5/krb/pac.c
|
||||||
|
@@ -490,7 +490,8 @@ zero_signature(krb5_context context, const krb5_pac pac, krb5_ui_4 type,
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
assert(type == KRB5_PAC_SERVER_CHECKSUM ||
|
||||||
|
- type == KRB5_PAC_PRIVSVR_CHECKSUM);
|
||||||
|
+ type == KRB5_PAC_PRIVSVR_CHECKSUM ||
|
||||||
|
+ type == KRB5_PAC_FULL_CHECKSUM);
|
||||||
|
assert(data->length >= pac->data.length);
|
||||||
|
|
||||||
|
for (i = 0; i < pac->pac->cBuffers; i++) {
|
||||||
|
@@ -557,17 +558,17 @@ verify_checksum(krb5_context context, const krb5_pac pac, uint32_t buffer_type,
|
||||||
|
}
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
-verify_server_checksum(krb5_context context, const krb5_pac pac,
|
||||||
|
- const krb5_keyblock *server)
|
||||||
|
+verify_pac_checksums(krb5_context context, const krb5_pac pac,
|
||||||
|
+ krb5_boolean expect_full_checksum,
|
||||||
|
+ const krb5_keyblock *server, const krb5_keyblock *privsvr)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
- krb5_data copy; /* PAC with zeroed checksums */
|
||||||
|
+ krb5_data copy, server_checksum;
|
||||||
|
|
||||||
|
+ /* Make a copy of the PAC with zeroed out server and privsvr checksums. */
|
||||||
|
ret = krb5int_copy_data_contents(context, &pac->data, ©);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
-
|
||||||
|
- /* Zero out both checksum buffers */
|
||||||
|
ret = zero_signature(context, pac, KRB5_PAC_SERVER_CHECKSUM, ©);
|
||||||
|
if (ret)
|
||||||
|
goto cleanup;
|
||||||
|
@@ -575,32 +576,46 @@ verify_server_checksum(krb5_context context, const krb5_pac pac,
|
||||||
|
if (ret)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
- ret = verify_checksum(context, pac, KRB5_PAC_SERVER_CHECKSUM, server,
|
||||||
|
- KRB5_KEYUSAGE_APP_DATA_CKSUM, ©);
|
||||||
|
+ if (server != NULL) {
|
||||||
|
+ /* Verify the server checksum over the PAC copy. */
|
||||||
|
+ ret = verify_checksum(context, pac, KRB5_PAC_SERVER_CHECKSUM, server,
|
||||||
|
+ KRB5_KEYUSAGE_APP_DATA_CKSUM, ©);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
-cleanup:
|
||||||
|
- free(copy.data);
|
||||||
|
- return ret;
|
||||||
|
-}
|
||||||
|
+ if (privsvr != NULL && expect_full_checksum) {
|
||||||
|
+ /* Zero the full checksum buffer in the copy and verify the full
|
||||||
|
+ * checksum over the copy with all three checksums zeroed. */
|
||||||
|
+ ret = zero_signature(context, pac, KRB5_PAC_FULL_CHECKSUM, ©);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto cleanup;
|
||||||
|
+ ret = verify_checksum(context, pac, KRB5_PAC_FULL_CHECKSUM, privsvr,
|
||||||
|
+ KRB5_KEYUSAGE_APP_DATA_CKSUM, ©);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
-static krb5_error_code
|
||||||
|
-verify_kdc_checksum(krb5_context context, const krb5_pac pac,
|
||||||
|
- const krb5_keyblock *privsvr)
|
||||||
|
-{
|
||||||
|
- krb5_error_code ret;
|
||||||
|
- krb5_data server_checksum;
|
||||||
|
+ if (privsvr != NULL) {
|
||||||
|
+ /* Verify the privsvr checksum over the server checksum. */
|
||||||
|
+ ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_SERVER_CHECKSUM,
|
||||||
|
+ &server_checksum);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+ if (server_checksum.length < PAC_SIGNATURE_DATA_LENGTH)
|
||||||
|
+ return KRB5_BAD_MSIZE;
|
||||||
|
+ server_checksum.data += PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
+ server_checksum.length -= PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
|
||||||
|
- ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_SERVER_CHECKSUM,
|
||||||
|
- &server_checksum);
|
||||||
|
- if (ret)
|
||||||
|
- return ret;
|
||||||
|
- if (server_checksum.length < PAC_SIGNATURE_DATA_LENGTH)
|
||||||
|
- return KRB5_BAD_MSIZE;
|
||||||
|
- server_checksum.data += PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
- server_checksum.length -= PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
+ ret = verify_checksum(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM, privsvr,
|
||||||
|
+ KRB5_KEYUSAGE_APP_DATA_CKSUM, &server_checksum);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pac->verified = TRUE;
|
||||||
|
|
||||||
|
- return verify_checksum(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM, privsvr,
|
||||||
|
- KRB5_KEYUSAGE_APP_DATA_CKSUM, &server_checksum);
|
||||||
|
+cleanup:
|
||||||
|
+ free(copy.data);
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Per MS-PAC 2.8.3, tickets encrypted to TGS and password change principals
|
||||||
|
@@ -628,6 +643,7 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||||
|
krb5_authdata **authdata, *orig, **ifrel = NULL, **recoded_ifrel = NULL;
|
||||||
|
uint8_t z = 0;
|
||||||
|
krb5_authdata zpac = { KV5M_AUTHDATA, KRB5_AUTHDATA_WIN2K_PAC, 1, &z };
|
||||||
|
+ krb5_boolean is_service_tkt;
|
||||||
|
size_t i, j;
|
||||||
|
|
||||||
|
*pac_out = NULL;
|
||||||
|
@@ -669,7 +685,8 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||||
|
if (ret)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
- if (privsvr != NULL && k5_pac_should_have_ticket_signature(server_princ)) {
|
||||||
|
+ is_service_tkt = k5_pac_should_have_ticket_signature(server_princ);
|
||||||
|
+ if (privsvr != NULL && is_service_tkt) {
|
||||||
|
/* To check the PAC ticket signatures, re-encode the ticket with the
|
||||||
|
* PAC contents replaced by a single zero. */
|
||||||
|
orig = ifrel[j];
|
||||||
|
@@ -693,8 +710,9 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = krb5_pac_verify_ext(context, pac, enc_tkt->times.authtime, NULL,
|
||||||
|
- server, privsvr, FALSE);
|
||||||
|
+ ret = verify_pac_checksums(context, pac, is_service_tkt, server, privsvr);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto cleanup;
|
||||||
|
|
||||||
|
*pac_out = pac;
|
||||||
|
pac = NULL;
|
||||||
|
@@ -730,14 +748,8 @@ krb5_pac_verify_ext(krb5_context context,
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
|
||||||
|
- if (server != NULL) {
|
||||||
|
- ret = verify_server_checksum(context, pac, server);
|
||||||
|
- if (ret != 0)
|
||||||
|
- return ret;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (privsvr != NULL) {
|
||||||
|
- ret = verify_kdc_checksum(context, pac, privsvr);
|
||||||
|
+ if (server != NULL || privsvr != NULL) {
|
||||||
|
+ ret = verify_pac_checksums(context, pac, FALSE, server, privsvr);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@@ -749,8 +761,6 @@ krb5_pac_verify_ext(krb5_context context,
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- pac->verified = TRUE;
|
||||||
|
-
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/lib/krb5/krb/pac_sign.c b/src/lib/krb5/krb/pac_sign.c
|
||||||
|
index 0f9581abbb..8ea61ac17b 100644
|
||||||
|
--- a/src/lib/krb5/krb/pac_sign.c
|
||||||
|
+++ b/src/lib/krb5/krb/pac_sign.c
|
||||||
|
@@ -187,26 +187,41 @@ k5_pac_encode_header(krb5_context context, krb5_pac pac)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-krb5_error_code KRB5_CALLCONV
|
||||||
|
-krb5_pac_sign(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
- krb5_const_principal principal, const krb5_keyblock *server_key,
|
||||||
|
- const krb5_keyblock *privsvr_key, krb5_data *data)
|
||||||
|
+/* Find the buffer of type buftype in pac and write within it a checksum of
|
||||||
|
+ * type cksumtype over data. Set *cksum_out to the checksum. */
|
||||||
|
+static krb5_error_code
|
||||||
|
+compute_pac_checksum(krb5_context context, krb5_pac pac, uint32_t buftype,
|
||||||
|
+ const krb5_keyblock *key, krb5_cksumtype cksumtype,
|
||||||
|
+ const krb5_data *data, krb5_data *cksum_out)
|
||||||
|
{
|
||||||
|
- return krb5_pac_sign_ext(context, pac, authtime, principal, server_key,
|
||||||
|
- privsvr_key, FALSE, data);
|
||||||
|
+ krb5_error_code ret;
|
||||||
|
+ krb5_data buf;
|
||||||
|
+ krb5_crypto_iov iov[2];
|
||||||
|
+
|
||||||
|
+ ret = k5_pac_locate_buffer(context, pac, buftype, &buf);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ assert(buf.length > PAC_SIGNATURE_DATA_LENGTH);
|
||||||
|
+ *cksum_out = make_data(buf.data + PAC_SIGNATURE_DATA_LENGTH,
|
||||||
|
+ buf.length - PAC_SIGNATURE_DATA_LENGTH);
|
||||||
|
+ iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||||
|
+ iov[0].data = *data;
|
||||||
|
+ iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
|
||||||
|
+ iov[1].data = *cksum_out;
|
||||||
|
+ return krb5_c_make_checksum_iov(context, cksumtype, key,
|
||||||
|
+ KRB5_KEYUSAGE_APP_DATA_CKSUM, iov, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
-krb5_error_code KRB5_CALLCONV
|
||||||
|
-krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
- krb5_const_principal principal,
|
||||||
|
- const krb5_keyblock *server_key,
|
||||||
|
- const krb5_keyblock *privsvr_key, krb5_boolean with_realm,
|
||||||
|
- krb5_data *data)
|
||||||
|
+static krb5_error_code
|
||||||
|
+sign_pac(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
+ krb5_const_principal principal, const krb5_keyblock *server_key,
|
||||||
|
+ const krb5_keyblock *privsvr_key, krb5_boolean with_realm,
|
||||||
|
+ krb5_boolean is_service_tkt, krb5_data *data)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
- krb5_data server_cksum, privsvr_cksum;
|
||||||
|
+ krb5_data full_cksum, server_cksum, privsvr_cksum;
|
||||||
|
krb5_cksumtype server_cksumtype, privsvr_cksumtype;
|
||||||
|
- krb5_crypto_iov iov[2];
|
||||||
|
|
||||||
|
data->length = 0;
|
||||||
|
data->data = NULL;
|
||||||
|
@@ -214,67 +229,53 @@ krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
if (principal != NULL) {
|
||||||
|
ret = k5_insert_client_info(context, pac, authtime, principal,
|
||||||
|
with_realm);
|
||||||
|
- if (ret != 0)
|
||||||
|
+ if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Create zeroed buffers for both checksums */
|
||||||
|
+ /* Create zeroed buffers for all checksums. */
|
||||||
|
ret = k5_insert_checksum(context, pac, KRB5_PAC_SERVER_CHECKSUM,
|
||||||
|
server_key, &server_cksumtype);
|
||||||
|
- if (ret != 0)
|
||||||
|
+ if (ret)
|
||||||
|
return ret;
|
||||||
|
-
|
||||||
|
ret = k5_insert_checksum(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM,
|
||||||
|
privsvr_key, &privsvr_cksumtype);
|
||||||
|
- if (ret != 0)
|
||||||
|
+ if (ret)
|
||||||
|
return ret;
|
||||||
|
+ if (is_service_tkt) {
|
||||||
|
+ ret = k5_insert_checksum(context, pac, KRB5_PAC_FULL_CHECKSUM,
|
||||||
|
+ privsvr_key, &privsvr_cksumtype);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- /* Now, encode the PAC header so that the checksums will include it */
|
||||||
|
+ /* Encode the PAC header so that the checksums will include it. */
|
||||||
|
ret = k5_pac_encode_header(context, pac);
|
||||||
|
- if (ret != 0)
|
||||||
|
- return ret;
|
||||||
|
-
|
||||||
|
- /* Generate the server checksum over the entire PAC */
|
||||||
|
- ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_SERVER_CHECKSUM,
|
||||||
|
- &server_cksum);
|
||||||
|
- if (ret != 0)
|
||||||
|
+ if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- assert(server_cksum.length > PAC_SIGNATURE_DATA_LENGTH);
|
||||||
|
-
|
||||||
|
- iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||||
|
- iov[0].data = pac->data;
|
||||||
|
-
|
||||||
|
- iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
|
||||||
|
- iov[1].data.data = server_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
- iov[1].data.length = server_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
+ if (is_service_tkt) {
|
||||||
|
+ /* Generate a full KDC checksum over the whole PAC. */
|
||||||
|
+ ret = compute_pac_checksum(context, pac, KRB5_PAC_FULL_CHECKSUM,
|
||||||
|
+ privsvr_key, privsvr_cksumtype,
|
||||||
|
+ &pac->data, &full_cksum);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- ret = krb5_c_make_checksum_iov(context, server_cksumtype,
|
||||||
|
- server_key, KRB5_KEYUSAGE_APP_DATA_CKSUM,
|
||||||
|
- iov, sizeof(iov)/sizeof(iov[0]));
|
||||||
|
- if (ret != 0)
|
||||||
|
+ /* Generate the server checksum over the whole PAC, including the full KDC
|
||||||
|
+ * checksum if we added one. */
|
||||||
|
+ ret = compute_pac_checksum(context, pac, KRB5_PAC_SERVER_CHECKSUM,
|
||||||
|
+ server_key, server_cksumtype, &pac->data,
|
||||||
|
+ &server_cksum);
|
||||||
|
+ if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- /* Generate the privsvr checksum over the server checksum buffer */
|
||||||
|
- ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM,
|
||||||
|
+ /* Generate the privsvr checksum over the server checksum buffer. */
|
||||||
|
+ ret = compute_pac_checksum(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM,
|
||||||
|
+ privsvr_key, privsvr_cksumtype, &server_cksum,
|
||||||
|
&privsvr_cksum);
|
||||||
|
- if (ret != 0)
|
||||||
|
- return ret;
|
||||||
|
-
|
||||||
|
- assert(privsvr_cksum.length > PAC_SIGNATURE_DATA_LENGTH);
|
||||||
|
-
|
||||||
|
- iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||||
|
- iov[0].data.data = server_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
- iov[0].data.length = server_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
-
|
||||||
|
- iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
|
||||||
|
- iov[1].data.data = privsvr_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
- iov[1].data.length = privsvr_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
-
|
||||||
|
- ret = krb5_c_make_checksum_iov(context, privsvr_cksumtype,
|
||||||
|
- privsvr_key, KRB5_KEYUSAGE_APP_DATA_CKSUM,
|
||||||
|
- iov, sizeof(iov)/sizeof(iov[0]));
|
||||||
|
- if (ret != 0)
|
||||||
|
+ if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
data->data = k5memdup(pac->data.data, pac->data.length, &ret);
|
||||||
|
@@ -288,6 +289,26 @@ krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+krb5_error_code KRB5_CALLCONV
|
||||||
|
+krb5_pac_sign(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
+ krb5_const_principal principal, const krb5_keyblock *server_key,
|
||||||
|
+ const krb5_keyblock *privsvr_key, krb5_data *data)
|
||||||
|
+{
|
||||||
|
+ return sign_pac(context, pac, authtime, principal, server_key,
|
||||||
|
+ privsvr_key, FALSE, FALSE, data);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+krb5_error_code KRB5_CALLCONV
|
||||||
|
+krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
+ krb5_const_principal principal,
|
||||||
|
+ const krb5_keyblock *server_key,
|
||||||
|
+ const krb5_keyblock *privsvr_key, krb5_boolean with_realm,
|
||||||
|
+ krb5_data *data)
|
||||||
|
+{
|
||||||
|
+ return sign_pac(context, pac, authtime, principal, server_key, privsvr_key,
|
||||||
|
+ with_realm, FALSE, data);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Add a signature over der_enc_tkt in privsvr to pac. der_enc_tkt should be
|
||||||
|
* encoded with a dummy PAC authdata element containing a single zero byte. */
|
||||||
|
static krb5_error_code
|
||||||
|
@@ -359,6 +380,7 @@ krb5_kdc_sign_ticket(krb5_context context, krb5_enc_tkt_part *enc_tkt,
|
||||||
|
krb5_error_code ret;
|
||||||
|
krb5_data *der_enc_tkt = NULL, pac_data = empty_data();
|
||||||
|
krb5_authdata **list, *pac_ad;
|
||||||
|
+ krb5_boolean is_service_tkt;
|
||||||
|
size_t count;
|
||||||
|
|
||||||
|
/* Reallocate space for another authdata element in enc_tkt. */
|
||||||
|
@@ -377,7 +399,8 @@ krb5_kdc_sign_ticket(krb5_context context, krb5_enc_tkt_part *enc_tkt,
|
||||||
|
memmove(list + 1, list, (count + 1) * sizeof(*list));
|
||||||
|
list[0] = pac_ad;
|
||||||
|
|
||||||
|
- if (k5_pac_should_have_ticket_signature(server_princ)) {
|
||||||
|
+ is_service_tkt = k5_pac_should_have_ticket_signature(server_princ);
|
||||||
|
+ if (is_service_tkt) {
|
||||||
|
ret = encode_krb5_enc_tkt_part(enc_tkt, &der_enc_tkt);
|
||||||
|
if (ret)
|
||||||
|
goto cleanup;
|
||||||
|
@@ -388,9 +411,8 @@ krb5_kdc_sign_ticket(krb5_context context, krb5_enc_tkt_part *enc_tkt,
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = krb5_pac_sign_ext(context, pac, enc_tkt->times.authtime,
|
||||||
|
- client_princ, server, privsvr, with_realm,
|
||||||
|
- &pac_data);
|
||||||
|
+ ret = sign_pac(context, pac, enc_tkt->times.authtime, client_princ, server,
|
||||||
|
+ privsvr, with_realm, is_service_tkt, &pac_data);
|
||||||
|
if (ret)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
diff --git a/src/lib/krb5/krb/t_pac.c b/src/lib/krb5/krb/t_pac.c
|
||||||
|
index 173bde7bab..81f1642ab0 100644
|
||||||
|
--- a/src/lib/krb5/krb/t_pac.c
|
||||||
|
+++ b/src/lib/krb5/krb/t_pac.c
|
||||||
|
@@ -607,78 +607,102 @@ check_pac(krb5_context context, int index, const unsigned char *pdata,
|
||||||
|
|
||||||
|
static const krb5_keyblock ticket_sig_krbtgt_key = {
|
||||||
|
0, ENCTYPE_AES256_CTS_HMAC_SHA1_96,
|
||||||
|
- 32, U("\x7a\x58\x98\xd2\xaf\xa6\xaf\xc0\x6a\xce\x06\x04\x4b\xc2\x70\x84"
|
||||||
|
- "\x9b\x8e\x0a\x6c\x4c\x07\xdc\x6f\xbb\x48\x43\xe1\xd2\xaa\x97\xf7")
|
||||||
|
+ 32, U("\x03\x73\x81\xEC\x43\x96\x7B\xC2\xAC\x3D\xF5\x2A\xAE\x95\xA6\x8E"
|
||||||
|
+ "\xBE\x24\x58\xDB\xCE\x52\x28\x20\xAF\x5E\xB7\x04\xA2\x22\x71\x4F")
|
||||||
|
};
|
||||||
|
|
||||||
|
static const krb5_keyblock ticket_sig_server_key = {
|
||||||
|
- 0, ENCTYPE_ARCFOUR_HMAC,
|
||||||
|
- 16, U("\xed\x23\x11\x20\x7a\x21\x44\x20\xbf\xc0\x8d\x36\xf7\xf6\xb2\x3e")
|
||||||
|
+ 0, ENCTYPE_AES256_CTS_HMAC_SHA1_96,
|
||||||
|
+ 32, U("\x11\x4A\x84\xE3\x14\x8F\xAA\xB1\xFA\x7B\x53\x51\xB2\x8A\xC2\xF1"
|
||||||
|
+ "\xFD\x19\x6D\x61\xE0\xF3\xF2\x3E\x1F\xDB\xD3\xC1\x79\x7D\xC1\xEE")
|
||||||
|
};
|
||||||
|
|
||||||
|
+/* A ticket issued by an Active Directory KDC (Windows Server 2022), containing
|
||||||
|
+ * a PAC with a full checksum. */
|
||||||
|
static const krb5_data ticket_data = {
|
||||||
|
- .length = 972, .data =
|
||||||
|
- "\x61\x82\x03\xC8\x30\x82\x03\xC4\xA0\x03\x02\x01\x05\xA1\x0A\x1B"
|
||||||
|
- "\x08\x43\x44\x4F\x4D\x2E\x43\x4F\x4D\xA2\x0F\x30\x0D\xA0\x03\x02"
|
||||||
|
- "\x01\x01\xA1\x06\x30\x04\x1B\x02\x73\x31\xA3\x82\x03\x9E\x30\x82"
|
||||||
|
- "\x03\x9A\xA0\x03\x02\x01\x17\xA1\x03\x02\x01\x03\xA2\x82\x03\x8C"
|
||||||
|
- "\x04\x82\x03\x88\x44\x31\x61\x20\x17\xC9\xFE\xBC\xAC\x46\xB5\x77"
|
||||||
|
- "\xE9\x68\x04\x4C\x9B\x31\x91\x0C\xC1\xD4\xDD\xEF\xC7\x34\x20\x08"
|
||||||
|
- "\x90\x91\xE8\x79\xE0\xB5\x03\x26\xA4\x65\xDE\xEC\x47\x03\x2A\x8F"
|
||||||
|
- "\x61\xE7\x4D\x38\x5A\x42\x95\x5A\xF9\x2F\x41\x2C\x2A\x6E\x60\xA1"
|
||||||
|
- "\xEB\x51\xB3\xBD\x4C\x00\x41\x2A\x44\x76\x08\x37\x1A\x51\xFD\x65"
|
||||||
|
- "\x67\x7E\xBF\x3D\x90\x86\xE3\x9A\x54\x6B\x67\xA8\x08\x7A\x73\xCC"
|
||||||
|
- "\xC3\xB7\x4B\xD5\x5C\x3A\x14\x6C\xC1\x5F\x54\x4B\x92\x55\xB4\xB7"
|
||||||
|
- "\x92\x23\x3F\x53\x89\x47\x8E\x1F\x8B\xB9\xDB\x3B\x93\xE8\x70\xE4"
|
||||||
|
- "\x24\xB8\x9D\xF0\x0E\x35\x28\xF8\x7A\x27\x5D\xF7\x25\x97\x9C\xF5"
|
||||||
|
- "\x9F\x9F\x64\x04\xF2\xA3\xAB\x11\x15\xB6\xDA\x18\xD6\x46\xD5\xE6"
|
||||||
|
- "\xB8\x08\xDE\x0A\x62\xFD\xF8\xAA\x52\x90\xD9\x67\x29\xB2\xCD\x06"
|
||||||
|
- "\xB6\xB0\x50\x2B\x3F\x0F\xA3\xA5\xBF\xAA\x6E\x40\x03\xD6\x5F\x02"
|
||||||
|
- "\xBC\xD8\x18\x47\x97\x09\xD7\xE4\x96\x3B\xCB\xEB\x92\x2C\x3C\x49"
|
||||||
|
- "\xFF\x1F\x71\xE0\x52\x94\x0F\x8B\x9F\xB8\x2A\xBB\x9C\xE2\xA3\xDD"
|
||||||
|
- "\x38\x89\xE2\xB1\x0B\x9E\x1F\x7A\xB3\xE3\xD2\xB0\x94\xDC\x87\xBE"
|
||||||
|
- "\x37\xA6\xD3\xB3\x29\x35\x9A\x72\xC3\x7A\xF1\xA9\xE6\xC5\xD1\x26"
|
||||||
|
- "\x83\x65\x44\x17\xBA\x55\xA8\x5E\x94\x26\xED\xE9\x8A\x93\x11\x5D"
|
||||||
|
- "\x7E\x20\x1B\x9C\x15\x9E\x13\x37\x03\x4D\xDD\x99\x51\xD8\x66\x29"
|
||||||
|
- "\x6A\xB9\xFB\x49\xFE\x52\x78\xDA\x86\x85\xA9\xA3\xB9\xEF\xEC\xAD"
|
||||||
|
- "\x35\xA6\x8D\xAC\x0F\x75\x22\xBB\x0B\x49\x1C\x13\x52\x40\xC9\x52"
|
||||||
|
- "\x69\x09\x54\xD1\x0F\x94\x3F\x22\x48\x67\xB0\x96\x28\xAA\xE6\x28"
|
||||||
|
- "\xD9\x0C\x08\xEF\x51\xED\x15\x5E\xA2\x53\x59\xA5\x03\xB4\x06\x20"
|
||||||
|
- "\x3D\xCC\xB4\xC5\xF8\x8C\x73\x67\xA3\x21\x3D\x19\xCD\xD4\x12\x28"
|
||||||
|
- "\xD2\x93\xDE\x0D\xF0\x71\x10\x50\xD6\x33\x35\x04\x11\x64\x43\x39"
|
||||||
|
- "\xC3\xDF\x96\xE3\x66\xE3\x85\xCA\xE7\x67\x14\x3A\xF0\x43\xAA\xBB"
|
||||||
|
- "\xD4\x1D\xB5\x24\xB5\x74\x90\x25\xA7\x87\x7E\xDB\xD3\x83\x8A\x3A"
|
||||||
|
- "\x69\xA8\x2D\xAF\xB7\xB8\xF3\xDC\x13\xAF\x45\x61\x3F\x59\x39\x7E"
|
||||||
|
- "\x69\xDE\x0C\x04\xF1\x10\x6B\xB4\x56\xFA\x21\x9F\x72\x2B\x60\x86"
|
||||||
|
- "\xE3\x23\x0E\xC4\x51\xF6\xBE\xD8\xE1\x5F\xEE\x73\x4C\x17\x4C\x2C"
|
||||||
|
- "\x1B\xFB\x9F\x1F\x7A\x3B\x07\x5B\x8E\xF1\x01\xAC\xD6\x30\x94\x8A"
|
||||||
|
- "\x5D\x22\x6F\x08\xCE\xED\x5E\xB6\xDB\x86\x8C\x87\xEB\x8D\x91\xFF"
|
||||||
|
- "\x0A\x86\x30\xBD\xC0\xF8\x25\xE7\xAE\x24\x35\xF2\xFC\xE5\xFD\x1B"
|
||||||
|
- "\xB0\x05\x4A\xA3\xE5\xEB\x2E\x05\xAD\x99\x67\x49\x87\xE6\xB3\x87"
|
||||||
|
- "\x82\xA4\x59\xA7\x6E\xDD\xF2\xB6\x66\xE8\xF7\x70\xF5\xBD\xC9\x0E"
|
||||||
|
- "\xFA\x9C\x79\x84\xD4\x9B\x05\x0E\xBB\xF5\xDB\xEF\xFC\xCC\x26\xF2"
|
||||||
|
- "\x93\xCF\xD2\x04\x3C\xA9\x2C\x65\x42\x97\x86\xD8\x38\x0A\x1E\xF6"
|
||||||
|
- "\xD6\xCA\x30\xB5\x1A\xEC\xFB\xBA\x3B\x84\x57\xB0\xFD\xFB\xE6\xBC"
|
||||||
|
- "\xF2\x76\xF6\x4C\xBB\xAB\xB1\x31\xA1\x27\x7C\xE6\xE6\x81\xB6\xCE"
|
||||||
|
- "\x84\x86\x40\xB6\x40\x33\xC4\xF8\xB4\x15\xCF\xAA\xA5\x51\x78\xB9"
|
||||||
|
- "\x8B\x50\x25\xB2\x88\x86\x96\x72\x8C\x71\x4D\xB5\x3A\x94\x86\x77"
|
||||||
|
- "\x0E\x95\x9B\x16\x93\xEF\x3A\x11\x79\xBA\x83\xF7\x74\xD3\x8D\xBA"
|
||||||
|
- "\x15\xE1\x2C\x04\x57\xA8\x92\x1E\x9D\x00\x8E\x20\xFD\x30\x70\xE7"
|
||||||
|
- "\xF5\x65\x2F\x19\x0C\x94\xBA\x03\x71\x12\x96\xCD\xC8\xB4\x96\xDB"
|
||||||
|
- "\xCE\x19\xC2\xDF\x3C\xC2\xF6\x3D\x53\xED\x98\xA5\x41\x72\x2A\x22"
|
||||||
|
- "\x7B\xF3\x2B\x17\x6C\xE1\x39\x7D\xAE\x9B\x11\xF9\xC1\xA6\x9E\x9F"
|
||||||
|
- "\x89\x3C\x12\xAA\x94\x74\xA7\x4F\x70\xE8\xB9\xDE\x04\xF0\x9D\x39"
|
||||||
|
- "\x24\x2D\x92\xE8\x46\x2D\x2E\xF0\x40\x66\x1A\xD9\x27\xF9\x98\xF1"
|
||||||
|
- "\x81\x1D\x70\x62\x63\x30\x6D\xCD\x84\x04\x5F\xFA\x83\xD3\xEC\x8D"
|
||||||
|
- "\x86\xFB\x40\x61\xC1\x8A\x45\xFF\x7B\xD9\xD4\x18\x61\x7F\x51\xE3"
|
||||||
|
- "\xFC\x1E\x18\xF0\xAF\xC6\x18\x2C\xE1\x6D\x5D\xF9\x62\xFC\x20\xA3"
|
||||||
|
- "\xB2\x8A\x5F\xE5\xBB\x29\x0F\x99\x63\x07\x88\x38\x3A\x3B\x73\x2A"
|
||||||
|
- "\x6D\xDA\x3D\xA8\x0D\x8F\x56\x41\x89\x82\xE5\xB8\x61\x00\x64\x7D"
|
||||||
|
- "\x17\x0C\xCE\x03\x55\x8F\xF4\x5B\x0D\x50\xF2\xEB\x05\x67\xBE\xDB"
|
||||||
|
- "\x7B\x75\xC5\xEA\xA1\xAB\x1D\xB0\x3C\x6D\x42\x08\x0B\x9A\x45\x20"
|
||||||
|
- "\xA8\x8F\xE5\x67\x47\x30\xDE\x93\x5F\x43\x05\xEB\xA8\x2D\x80\xF5"
|
||||||
|
- "\x1A\xB8\x4A\x4E\x42\x2D\x0B\x7A\xDC\x46\x20\x2D\x13\x17\xDD\x4B"
|
||||||
|
- "\x94\x96\xAA\x1F\x06\x0C\x1F\x62\x07\x9C\x40\xA1"
|
||||||
|
+ .length = 1307, .data =
|
||||||
|
+ "\x61\x82\x05\x17\x30\x82\x05\x13\xA0\x03\x02\x01\x05\xA1\x0F\x1B"
|
||||||
|
+ "\x0D\x57\x32\x30\x32\x32\x2D\x4C\x37\x2E\x42\x41\x53\x45\xA2\x2A"
|
||||||
|
+ "\x30\x28\xA0\x03\x02\x01\x01\xA1\x21\x30\x1F\x1B\x04\x63\x69\x66"
|
||||||
|
+ "\x73\x1B\x17\x77\x32\x30\x32\x32\x2D\x31\x31\x38\x2E\x77\x32\x30"
|
||||||
|
+ "\x32\x32\x2D\x6C\x37\x2E\x62\x61\x73\x65\xA3\x82\x04\xCD\x30\x82"
|
||||||
|
+ "\x04\xC9\xA0\x03\x02\x01\x12\xA1\x03\x02\x01\x05\xA2\x82\x04\xBB"
|
||||||
|
+ "\x04\x82\x04\xB7\x44\x5C\x7B\x5A\x3F\x2E\xA3\x50\x34\xDE\xB0\x69"
|
||||||
|
+ "\x23\x2D\x47\x89\x2C\xC0\xA3\xF9\xDD\x70\xAA\xA5\x1E\xFE\x74\xE5"
|
||||||
|
+ "\x19\xA2\x4F\x65\x6C\x9E\x00\xB4\x60\x00\x7C\x0C\x29\x43\x31\x99"
|
||||||
|
+ "\x77\x02\x73\xED\xB9\x40\xF5\xD2\xD1\xC9\x20\x0F\xE3\x38\xF9\xCC"
|
||||||
|
+ "\x5E\x2A\xBD\x1F\x91\x66\x1A\xD8\x2A\x80\x3C\x2C\x00\x3C\x1E\xC9"
|
||||||
|
+ "\x2A\x29\x19\x19\x96\x18\x54\x03\x97\x8F\x1D\x5F\xDB\xE9\x66\x68"
|
||||||
|
+ "\xCD\xB1\xD5\x00\x35\x69\x49\x45\xF1\x6A\x78\x7B\x37\x71\x87\x14"
|
||||||
|
+ "\x1C\x98\x4D\x69\xCB\x1B\xD8\xF5\xA3\xD8\x53\x4A\x75\x76\x62\xBA"
|
||||||
|
+ "\x6C\x3F\xEA\x8B\x97\x21\xCA\x8A\x46\x4B\x38\xDA\x09\x9F\x5A\xC8"
|
||||||
|
+ "\x38\xFF\x34\x97\x5B\xA2\xE5\xBA\xC9\x87\x17\xD8\x08\x05\x7A\x83"
|
||||||
|
+ "\x04\xD6\x02\x8E\x9B\x18\xB6\x40\x1A\xF7\x47\x25\x24\x3E\x37\x1E"
|
||||||
|
+ "\xF6\xC1\x3A\x1F\xCA\xB3\x43\x5A\xAE\x94\x83\x31\xAF\xFB\xEE\xED"
|
||||||
|
+ "\x46\x71\xEF\xE2\x37\x37\x15\xFE\x1B\x0B\x9E\xF8\x3E\x0C\x43\x96"
|
||||||
|
+ "\xB6\x0A\x04\x78\xF8\x5E\xAA\x33\x1F\xE2\x07\x5A\x8D\xC4\x4E\x32"
|
||||||
|
+ "\x6D\xD6\xA0\xC5\xEA\x3D\x12\x59\xD4\x41\x40\x4E\xA1\xD8\xBE\xED"
|
||||||
|
+ "\x17\xCB\x68\xCC\x59\xCB\x53\xB2\x0E\x58\x8A\xA9\x33\x7F\x6F\x2B"
|
||||||
|
+ "\x37\x89\x08\x44\xBA\xC7\x67\x17\xBB\x91\xF7\xC3\x0F\x00\xF8\xAA"
|
||||||
|
+ "\xA1\x33\xA6\x08\x47\xCA\xFA\xE8\x49\x27\x45\x46\xF1\xC1\xC3\x5F"
|
||||||
|
+ "\xE2\x45\x0A\x7D\x64\x52\x8C\x2E\xE1\xDE\xFF\xB2\x64\xEC\x69\x98"
|
||||||
|
+ "\x15\xDF\x9E\xB1\xEB\xD6\x9D\x08\x06\x4E\x73\xC1\x0B\x71\x21\x05"
|
||||||
|
+ "\x9E\xBC\xA2\x17\xCF\xB3\x70\xF4\xEF\xB8\x69\xA9\x94\x27\xFD\x5E"
|
||||||
|
+ "\x72\xB1\x2D\xD2\x20\x1B\x57\x80\xAB\x38\x97\xCF\x22\x68\x4F\xB8"
|
||||||
|
+ "\xB7\x17\x53\x25\x67\x0B\xED\xD1\x58\x20\x0D\x45\xF9\x09\xFA\xE7"
|
||||||
|
+ "\x61\x3E\xDB\xC2\x59\x7B\x3A\x3B\x59\x81\x51\xAA\xA4\x81\xF4\x96"
|
||||||
|
+ "\x3B\xE1\x6F\x6F\xF4\x8E\x68\x9E\xBA\x1E\x0F\xF2\x44\x68\x11\xFC"
|
||||||
|
+ "\x2B\x5F\xBE\xF2\xEA\x07\x80\xB9\xCA\x9E\x41\xBD\x2F\x81\xF5\x11"
|
||||||
|
+ "\x2A\x12\xF3\x4F\xD6\x12\x16\x0F\x21\x90\xF1\xD3\x1E\xF1\xA4\x94"
|
||||||
|
+ "\x46\xEA\x30\xF3\x84\x06\xC1\xA4\x51\xFC\x43\x35\xBD\xEF\x4D\x89"
|
||||||
|
+ "\x1D\xA5\x44\xB2\x69\xC4\x0F\xBF\x86\x01\x08\x44\x77\xD5\xB4\xB7"
|
||||||
|
+ "\x5C\x3F\xA7\xD4\x2F\x39\x73\x85\x88\xEE\xB1\x64\x1D\x80\x6C\xEE"
|
||||||
|
+ "\x6E\x31\x90\x92\x0D\xA1\xB7\xC4\x5C\xCC\xEE\x91\xC8\xCB\x11\x2D"
|
||||||
|
+ "\x4A\x1A\x7D\x43\x8F\xEB\x60\x09\xED\x1B\x07\x58\xBE\xBC\xBD\x29"
|
||||||
|
+ "\xF3\xB3\xA3\x4F\xC5\x8A\x30\x33\xB9\xA9\x9F\x43\x08\x27\x15\xC4"
|
||||||
|
+ "\x9C\x5D\x8E\xBD\x5C\x05\xC6\x05\x9C\x87\x60\x08\x1E\xE2\x52\xB8"
|
||||||
|
+ "\x45\x8D\x28\xB6\x2C\x15\x46\x74\x9F\x0E\xAA\x6B\x70\x3A\x2A\x55"
|
||||||
|
+ "\x45\x26\xB2\x58\x4D\x35\xA6\xF1\x96\xBE\x60\xB2\x71\x7B\xF8\x54"
|
||||||
|
+ "\xB9\x90\x21\x8E\xB9\x0F\x35\x98\x5E\x88\xEB\x1A\x53\xB4\x59\x7F"
|
||||||
|
+ "\xAF\x69\x1C\x61\x67\xF4\xF6\xBD\xAC\x24\xCD\xB7\xA9\x67\xE8\xA1"
|
||||||
|
+ "\x83\x85\x5F\x11\x74\x1F\xF7\x4C\x78\x36\xEF\x50\x74\x88\x58\x4B"
|
||||||
|
+ "\x1A\x9F\x84\x9A\x9A\x05\x92\xEC\x1D\xD5\xF3\xC4\x95\x51\x28\xE2"
|
||||||
|
+ "\x3F\x32\x87\xB2\xFD\x21\x27\x66\xE4\x6B\x85\x2F\xDC\x7B\xC0\x22"
|
||||||
|
+ "\xEB\x7A\x94\x20\x5A\x7B\xD3\x7A\xB9\x5B\xF8\x1A\x5A\x84\x4E\xA1"
|
||||||
|
+ "\x73\x41\x53\xD2\x60\xF7\x7C\xEE\x68\x59\x85\x80\xFC\x3D\x70\x4B"
|
||||||
|
+ "\x04\x32\xE7\xF2\xFD\xBD\xB3\xD9\x21\xE2\x37\x56\xA2\x16\xCC\xDE"
|
||||||
|
+ "\x8A\xD3\xBC\x71\xEF\x58\x19\x0E\x45\x8A\x5B\x53\xD6\x77\x30\x6A"
|
||||||
|
+ "\xA7\xF8\x68\x06\x4E\x07\xCA\xCE\x30\xD7\x35\xAB\x1A\xC7\x18\xD4"
|
||||||
|
+ "\xC6\x2F\x1A\xFF\xE9\x7A\x94\x0B\x76\x5E\x7E\x29\x0C\xE6\xD3\x3B"
|
||||||
|
+ "\x5B\x44\x96\xA8\xF1\x29\x23\x95\xD9\x79\xB3\x39\xFC\x76\xED\xE1"
|
||||||
|
+ "\x1E\x67\x4E\xF7\xE8\x7B\x7A\x12\x9E\xD8\x4B\x35\x09\x0A\xF2\xC1"
|
||||||
|
+ "\x63\x5B\xEE\xFD\x2A\xC2\xA6\x66\x30\x3C\x1F\x95\xAF\x65\x22\x95"
|
||||||
|
+ "\x14\x1D\xF5\xD5\xDC\x38\x79\x35\x1C\xCD\x24\x47\xE0\xFD\x08\xC8"
|
||||||
|
+ "\xF4\x15\x55\x9F\xD9\xC7\xAC\x3F\x67\xB3\x4F\xEB\x26\x7C\x8E\xD6"
|
||||||
|
+ "\x74\xB3\x0A\xCD\xE7\xFA\xBE\x7E\xA3\x3E\xEC\x61\x50\x77\x52\x56"
|
||||||
|
+ "\xCF\x90\x5D\x48\xFB\xD4\x2C\x6C\x61\x8B\xDD\x2B\xF5\x92\x1F\x30"
|
||||||
|
+ "\xBF\x3F\x80\x0D\x31\xDB\xB2\x0B\x7D\x84\xE3\xA6\x42\x7F\x00\x38"
|
||||||
|
+ "\x44\x02\xC5\xB8\xD9\x58\x29\x9D\x68\x5C\x32\x8B\x76\xAE\xED\x15"
|
||||||
|
+ "\xF9\x7C\xAE\x7B\xB6\x8E\xD6\x54\x24\xFF\xFA\x87\x05\xEF\x15\x08"
|
||||||
|
+ "\x5E\x4B\x21\xA2\x2F\x49\xE7\x0F\xC3\xD0\xB9\x49\x22\xEF\xD5\xCA"
|
||||||
|
+ "\xB2\x11\xF2\x17\xB6\x77\x24\x68\x76\xB2\x07\xF8\x0A\x73\xDD\x65"
|
||||||
|
+ "\x9C\x75\x64\xF7\xA1\xC6\x23\x08\x84\x72\x3E\x54\x2E\xEB\x9B\x40"
|
||||||
|
+ "\xA6\x83\x87\xEB\xB5\x00\x40\x4F\xE1\x72\x2A\x59\x3A\x06\x60\x29"
|
||||||
|
+ "\x7E\x25\x2F\xD8\x80\x40\x8C\x59\xCA\xCF\x8E\x44\xE4\x2D\x84\x7E"
|
||||||
|
+ "\xCB\xFD\x1E\x3B\xD5\xFF\x9A\xB9\x66\x93\x6D\x5E\xC8\xB7\x13\x26"
|
||||||
|
+ "\xD6\x38\x1B\x2B\xE1\x87\x96\x05\xD5\xF3\xAB\x68\xF7\x12\x62\x2C"
|
||||||
|
+ "\x58\xC1\xC9\x85\x3C\x72\xF1\x26\xEE\xC0\x09\x5F\x1D\x4B\xAC\x01"
|
||||||
|
+ "\x41\xC8\x12\xF8\xF3\x93\x43\x41\xFF\xEC\x0B\x80\xE2\xEE\x20\x85"
|
||||||
|
+ "\x25\xCD\x6C\x30\x8C\x0D\x24\x2E\xBA\x19\xEA\x28\x7F\xCF\xD5\x10"
|
||||||
|
+ "\x5C\xE9\xB2\x9D\x5F\x16\xE4\xC0\xF3\xCC\xD9\x68\x4A\x05\x08\x70"
|
||||||
|
+ "\x17\x26\xC8\x5C\x4A\xBF\x94\x6A\x0E\xD5\xDA\x67\x47\x4B\xAF\x44"
|
||||||
|
+ "\xE3\x94\xAA\x05\xDB\xA2\x49\x74\xFA\x5C\x69\xAB\x44\xB7\xF7\xBA"
|
||||||
|
+ "\xAE\x7A\x23\x87\xEB\x54\x7E\x80\xF1\x5B\x60\xA5\x93\xE5\xD4\x24"
|
||||||
|
+ "\x84\xF7\x0A\x16\x10\xBE\xE9\x4D\xD8\x6B\x15\x40\x5D\x74\xDA\x1B"
|
||||||
|
+ "\xFF\x2E\x4D\x17\x9D\x35\xF7\x0D\xCF\x66\x38\x0D\x8A\xE4\xDD\x6B"
|
||||||
|
+ "\xE1\x0F\x1F\xBD\xFD\x4F\x30\x37\x3F\x96\xB4\x92\x54\xD3\x9A\x7A"
|
||||||
|
+ "\xD1\x5B\x5B\xA9\x54\x16\xE6\x24\xAB\xD4\x23\x39\x7D\xD2\xC7\x09"
|
||||||
|
+ "\xFA\xD4\x86\x55\x4D\x60\xC2\x87\x67\x6B\xE6"
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -686,7 +710,7 @@ test_pac_ticket_signature(krb5_context context)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
krb5_ticket *ticket;
|
||||||
|
- krb5_principal sprinc;
|
||||||
|
+ krb5_principal cprinc, sprinc;
|
||||||
|
krb5_authdata **authdata1, **authdata2;
|
||||||
|
krb5_pac pac, pac2, pac3;
|
||||||
|
uint32_t *list;
|
||||||
|
@@ -701,7 +725,13 @@ test_pac_ticket_signature(krb5_context context)
|
||||||
|
if (ret)
|
||||||
|
err(context, ret, "while decrypting ticket");
|
||||||
|
|
||||||
|
- ret = krb5_parse_name(context, "s1@CDOM.COM", &sprinc);
|
||||||
|
+ ret = krb5_parse_name(context, "administrator@W2022-L7.BASE", &cprinc);
|
||||||
|
+ if (ret)
|
||||||
|
+ err(context, ret, "krb5_parse_name");
|
||||||
|
+
|
||||||
|
+ ret = krb5_parse_name(context,
|
||||||
|
+ "cifs/w2022-118.w2022-l7.base@W2022-L7.BASE",
|
||||||
|
+ &sprinc);
|
||||||
|
if (ret)
|
||||||
|
err(context, ret, "krb5_parse_name");
|
||||||
|
|
||||||
|
@@ -713,7 +743,7 @@ test_pac_ticket_signature(krb5_context context)
|
||||||
|
|
||||||
|
/* In this test, the server is also the client. */
|
||||||
|
ret = krb5_pac_verify(context, pac, ticket->enc_part2->times.authtime,
|
||||||
|
- ticket->server, NULL, NULL);
|
||||||
|
+ cprinc, NULL, NULL);
|
||||||
|
if (ret)
|
||||||
|
err(context, ret, "while verifying PAC client info");
|
||||||
|
|
||||||
|
@@ -722,7 +752,7 @@ test_pac_ticket_signature(krb5_context context)
|
||||||
|
ticket->enc_part2->authorization_data = NULL;
|
||||||
|
|
||||||
|
ret = krb5_kdc_sign_ticket(context, ticket->enc_part2, pac, sprinc,
|
||||||
|
- sprinc, &ticket_sig_server_key,
|
||||||
|
+ cprinc, &ticket_sig_server_key,
|
||||||
|
&ticket_sig_krbtgt_key, FALSE);
|
||||||
|
if (ret)
|
||||||
|
err(context, ret, "while signing ticket");
|
||||||
|
@@ -781,6 +811,7 @@ test_pac_ticket_signature(krb5_context context)
|
||||||
|
krb5_pac_free(context, pac);
|
||||||
|
krb5_pac_free(context, pac2);
|
||||||
|
krb5_pac_free(context, pac3);
|
||||||
|
+ krb5_free_principal(context, cprinc);
|
||||||
|
krb5_free_principal(context, sprinc);
|
||||||
|
krb5_free_ticket(context, ticket);
|
||||||
|
}
|
||||||
|
diff --git a/src/tests/t_authdata.py b/src/tests/t_authdata.py
|
||||||
|
index 47ea9e4b47..e934799268 100644
|
||||||
|
--- a/src/tests/t_authdata.py
|
||||||
|
+++ b/src/tests/t_authdata.py
|
||||||
|
@@ -11,7 +11,7 @@ realm = K5Realm(krb5_conf=conf)
|
||||||
|
# container.
|
||||||
|
mark('baseline authdata')
|
||||||
|
out = realm.run(['./adata', realm.host_princ])
|
||||||
|
-if '?128: [6, 7, 10, 16]' not in out or '^-42: Hello' not in out:
|
||||||
|
+if '?128: [6, 7, 10, 16, 19]' not in out or '^-42: Hello' not in out:
|
||||||
|
fail('expected authdata not seen for basic request')
|
||||||
|
|
||||||
|
# Requested authdata is copied into the ticket, with KDC-only types
|
||||||
|
@@ -243,7 +243,7 @@ out = realm.run(['./adata', '-p', realm.user_princ, 'service/2'])
|
||||||
|
if '+97: [indcl]' not in out or '[inds1]' in out:
|
||||||
|
fail('correct auth-indicator not seen for S4U2Proxy req')
|
||||||
|
# Make sure a PAC with an S4U_DELEGATION_INFO(11) buffer is included.
|
||||||
|
-if '?128: [1, 6, 7, 10, 11, 16]' not in out:
|
||||||
|
+if '?128: [1, 6, 7, 10, 11, 16, 19]' not in out:
|
||||||
|
fail('PAC with delegation info not seen for S4U2Proxy req')
|
||||||
|
|
||||||
|
# Get another S4U2Proxy ticket including request-authdata.
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From ff9c99b689855a646c371379d30a668dfd7a87a7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Wed, 1 Feb 2023 15:57:26 +0100
|
||||||
|
Subject: [PATCH] Fix possible double-free during KDB creation
|
||||||
|
|
||||||
|
In krb5_dbe_def_encrypt_key_data(), when we free
|
||||||
|
key_data->key_data_contents[0], reset it to null so the caller doesn't
|
||||||
|
free it as well.
|
||||||
|
|
||||||
|
Since commit a06945b4ec267e8b80e5e8c95edd89930ff12103 this bug
|
||||||
|
manifests as a double-free during KDB creation if master key
|
||||||
|
encryption fails.
|
||||||
|
|
||||||
|
[ghudson@mit.edu: edited commit message]
|
||||||
|
|
||||||
|
ticket: 9086 (new)
|
||||||
|
tags: pullup
|
||||||
|
target_version: 1.20-next
|
||||||
|
---
|
||||||
|
src/lib/kdb/encrypt_key.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/lib/kdb/encrypt_key.c b/src/lib/kdb/encrypt_key.c
|
||||||
|
index dc612c810e..91debea533 100644
|
||||||
|
--- a/src/lib/kdb/encrypt_key.c
|
||||||
|
+++ b/src/lib/kdb/encrypt_key.c
|
||||||
|
@@ -109,6 +109,7 @@ krb5_dbe_def_encrypt_key_data( krb5_context context,
|
||||||
|
if ((retval = krb5_c_encrypt(context, mkey, /* XXX */ 0, 0,
|
||||||
|
&plain, &cipher))) {
|
||||||
|
free(key_data->key_data_contents[0]);
|
||||||
|
+ key_data->key_data_contents[0] = NULL;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -121,6 +122,7 @@ krb5_dbe_def_encrypt_key_data( krb5_context context,
|
||||||
|
key_data->key_data_contents[1] = malloc(keysalt->data.length);
|
||||||
|
if (key_data->key_data_contents[1] == NULL) {
|
||||||
|
free(key_data->key_data_contents[0]);
|
||||||
|
+ key_data->key_data_contents[0] = NULL;
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
memcpy(key_data->key_data_contents[1], keysalt->data.data,
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From 604fce63b468d0efce4438df4ba0286f00bfce8d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Tue, 21 Feb 2023 10:03:35 +0100
|
||||||
|
Subject: [PATCH] Fix meridian type in kadmin datetime parser
|
||||||
|
|
||||||
|
The meridian suffix is typed as "Number" in kadmin YACC file for
|
||||||
|
datetime parsing, while it should be using the "Meridian" enumeration
|
||||||
|
one.
|
||||||
|
|
||||||
|
This results in invalid Meridian value on 64-bit IBM zSystems (s390x),
|
||||||
|
causing core dumped errors on most kadmin commands where meridian
|
||||||
|
suffices are used.
|
||||||
|
|
||||||
|
Upstream PR:
|
||||||
|
https://github.com/krb5/krb5/pull/1290
|
||||||
|
---
|
||||||
|
src/kadmin/cli/getdate.y | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/kadmin/cli/getdate.y b/src/kadmin/cli/getdate.y
|
||||||
|
index b9dceec1ee..d14cf963c5 100644
|
||||||
|
--- a/src/kadmin/cli/getdate.y
|
||||||
|
+++ b/src/kadmin/cli/getdate.y
|
||||||
|
@@ -181,7 +181,8 @@ static time_t yyRelSeconds;
|
||||||
|
|
||||||
|
%token tAGO tID tDST tNEVER
|
||||||
|
%token <Number> tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT
|
||||||
|
-%token <Number> tSEC_UNIT tSNUMBER tUNUMBER tZONE tMERIDIAN
|
||||||
|
+%token <Number> tSEC_UNIT tSNUMBER tUNUMBER tZONE
|
||||||
|
+%token <Meridian> tMERIDIAN
|
||||||
|
%type <Meridian> o_merid
|
||||||
|
|
||||||
|
%%
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -1,220 +0,0 @@
|
|||||||
From 3d11179707923b033fa413387a33296b673ff52d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
Date: Thu, 14 Jan 2021 18:13:09 -0500
|
|
||||||
Subject: [PATCH] Add APIs for marshalling credentials
|
|
||||||
|
|
||||||
Faciliate KCM daemon implementations by providing functions to
|
|
||||||
deserialize and reserialize credentials in the FILE v4 format.
|
|
||||||
|
|
||||||
[ghudson@mit.edu: minor editorial changes]
|
|
||||||
|
|
||||||
ticket: 8980 (new)
|
|
||||||
(cherry picked from commit 18ea3bd2fca55b789b7de9c663624bc11d348fa6)
|
|
||||||
---
|
|
||||||
doc/appdev/refs/api/index.rst | 2 ++
|
|
||||||
src/include/krb5/krb5.hin | 36 ++++++++++++++++++++++
|
|
||||||
src/lib/krb5/ccache/ccmarshal.c | 53 +++++++++++++++++++++++++++++++++
|
|
||||||
src/lib/krb5/ccache/t_marshal.c | 15 +++++++++-
|
|
||||||
src/lib/krb5/libkrb5.exports | 2 ++
|
|
||||||
src/lib/krb5_32.def | 4 +++
|
|
||||||
6 files changed, 111 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/doc/appdev/refs/api/index.rst b/doc/appdev/refs/api/index.rst
|
|
||||||
index 727d9b492..9e03fd386 100644
|
|
||||||
--- a/doc/appdev/refs/api/index.rst
|
|
||||||
+++ b/doc/appdev/refs/api/index.rst
|
|
||||||
@@ -232,6 +232,7 @@ Rarely used public interfaces
|
|
||||||
krb5_kt_remove_entry.rst
|
|
||||||
krb5_kt_start_seq_get.rst
|
|
||||||
krb5_make_authdata_kdc_issued.rst
|
|
||||||
+ krb5_marshal_credentials.rst
|
|
||||||
krb5_merge_authdata.rst
|
|
||||||
krb5_mk_1cred.rst
|
|
||||||
krb5_mk_error.rst
|
|
||||||
@@ -285,6 +286,7 @@ Rarely used public interfaces
|
|
||||||
krb5_tkt_creds_get_times.rst
|
|
||||||
krb5_tkt_creds_init.rst
|
|
||||||
krb5_tkt_creds_step.rst
|
|
||||||
+ krb5_unmarshal_credentials.rst
|
|
||||||
krb5_verify_init_creds.rst
|
|
||||||
krb5_verify_init_creds_opt_init.rst
|
|
||||||
krb5_verify_init_creds_opt_set_ap_req_nofail.rst
|
|
||||||
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
|
|
||||||
index 63e67a2ba..c26dde535 100644
|
|
||||||
--- a/src/include/krb5/krb5.hin
|
|
||||||
+++ b/src/include/krb5/krb5.hin
|
|
||||||
@@ -3125,6 +3125,42 @@ krb5_get_credentials(krb5_context context, krb5_flags options,
|
|
||||||
krb5_ccache ccache, krb5_creds *in_creds,
|
|
||||||
krb5_creds **out_creds);
|
|
||||||
|
|
||||||
+/**
|
|
||||||
+ * Serialize a @c krb5_creds object.
|
|
||||||
+ *
|
|
||||||
+ * @param [in] context Library context
|
|
||||||
+ * @param [in] creds The credentials object to serialize
|
|
||||||
+ * @param [out] data_out The serialized credentials
|
|
||||||
+ *
|
|
||||||
+ * Serialize @a creds in the format used by the FILE ccache format (vesion 4)
|
|
||||||
+ * and KCM ccache protocol.
|
|
||||||
+ *
|
|
||||||
+ * Use krb5_free_data() to free @a data_out when it is no longer needed.
|
|
||||||
+ *
|
|
||||||
+ * @retval 0 Success; otherwise - Kerberos error codes
|
|
||||||
+ */
|
|
||||||
+krb5_error_code KRB5_CALLCONV
|
|
||||||
+krb5_marshal_credentials(krb5_context context, krb5_creds *in_creds,
|
|
||||||
+ krb5_data **data_out);
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * Deserialize a @c krb5_creds object.
|
|
||||||
+ *
|
|
||||||
+ * @param [in] context Library context
|
|
||||||
+ * @param [in] data The serialized credentials
|
|
||||||
+ * @param [out] creds_out The resulting creds object
|
|
||||||
+ *
|
|
||||||
+ * Deserialize @a data to credentials in the format used by the FILE ccache
|
|
||||||
+ * format (vesion 4) and KCM ccache protocol.
|
|
||||||
+ *
|
|
||||||
+ * Use krb5_free_creds() to free @a creds_out when it is no longer needed.
|
|
||||||
+ *
|
|
||||||
+ * @retval 0 Success; otherwise - Kerberos error codes
|
|
||||||
+ */
|
|
||||||
+krb5_error_code KRB5_CALLCONV
|
|
||||||
+krb5_unmarshal_credentials(krb5_context context, const krb5_data *data,
|
|
||||||
+ krb5_creds **creds_out);
|
|
||||||
+
|
|
||||||
/** @deprecated Replaced by krb5_get_validated_creds. */
|
|
||||||
krb5_error_code KRB5_CALLCONV
|
|
||||||
krb5_get_credentials_validate(krb5_context context, krb5_flags options,
|
|
||||||
diff --git a/src/lib/krb5/ccache/ccmarshal.c b/src/lib/krb5/ccache/ccmarshal.c
|
|
||||||
index ae634ccab..ab284e721 100644
|
|
||||||
--- a/src/lib/krb5/ccache/ccmarshal.c
|
|
||||||
+++ b/src/lib/krb5/ccache/ccmarshal.c
|
|
||||||
@@ -515,3 +515,56 @@ k5_marshal_mcred(struct k5buf *buf, krb5_creds *mcred)
|
|
||||||
if (mcred->second_ticket.length > 0)
|
|
||||||
put_data(buf, version, &mcred->second_ticket);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+krb5_error_code KRB5_CALLCONV
|
|
||||||
+krb5_marshal_credentials(krb5_context context, krb5_creds *in_creds,
|
|
||||||
+ krb5_data **data_out)
|
|
||||||
+{
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+ krb5_data *data;
|
|
||||||
+ struct k5buf buf;
|
|
||||||
+
|
|
||||||
+ *data_out = NULL;
|
|
||||||
+
|
|
||||||
+ data = k5alloc(sizeof(krb5_data), &ret);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ k5_buf_init_dynamic(&buf);
|
|
||||||
+ k5_marshal_cred(&buf, 4, in_creds);
|
|
||||||
+
|
|
||||||
+ ret = k5_buf_status(&buf);
|
|
||||||
+ if (ret) {
|
|
||||||
+ free(data);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Steal payload from buf. */
|
|
||||||
+ *data = make_data(buf.data, buf.len);
|
|
||||||
+ *data_out = data;
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+krb5_error_code KRB5_CALLCONV
|
|
||||||
+krb5_unmarshal_credentials(krb5_context context, const krb5_data *data,
|
|
||||||
+ krb5_creds **creds_out)
|
|
||||||
+{
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+ krb5_creds *creds;
|
|
||||||
+
|
|
||||||
+ *creds_out = NULL;
|
|
||||||
+
|
|
||||||
+ creds = k5alloc(sizeof(krb5_creds), &ret);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ ret = k5_unmarshal_cred((unsigned char *)data->data, data->length, 4,
|
|
||||||
+ creds);
|
|
||||||
+ if (ret) {
|
|
||||||
+ free(creds);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ *creds_out = creds;
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
diff --git a/src/lib/krb5/ccache/t_marshal.c b/src/lib/krb5/ccache/t_marshal.c
|
|
||||||
index bd0284afa..96e0931a2 100644
|
|
||||||
--- a/src/lib/krb5/ccache/t_marshal.c
|
|
||||||
+++ b/src/lib/krb5/ccache/t_marshal.c
|
|
||||||
@@ -268,13 +268,14 @@ main(int argc, char **argv)
|
|
||||||
krb5_context context;
|
|
||||||
krb5_ccache cache;
|
|
||||||
krb5_principal princ;
|
|
||||||
- krb5_creds cred1, cred2;
|
|
||||||
+ krb5_creds cred1, cred2, *alloc_cred;
|
|
||||||
krb5_cc_cursor cursor;
|
|
||||||
const char *filename;
|
|
||||||
char *ccname, filebuf[256];
|
|
||||||
int version, fd;
|
|
||||||
const struct test *t;
|
|
||||||
struct k5buf buf;
|
|
||||||
+ krb5_data ser_data, *alloc_data;
|
|
||||||
|
|
||||||
if (argc != 2)
|
|
||||||
abort();
|
|
||||||
@@ -285,6 +286,18 @@ main(int argc, char **argv)
|
|
||||||
if (krb5_init_context(&context) != 0)
|
|
||||||
abort();
|
|
||||||
|
|
||||||
+ /* Test public functions for unmarshalling and marshalling. */
|
|
||||||
+ ser_data = make_data((char *)tests[3].cred1, tests[3].cred1len);
|
|
||||||
+ if (krb5_unmarshal_credentials(context, &ser_data, &alloc_cred) != 0)
|
|
||||||
+ abort();
|
|
||||||
+ verify_cred1(alloc_cred);
|
|
||||||
+ if (krb5_marshal_credentials(context, alloc_cred, &alloc_data) != 0)
|
|
||||||
+ abort();
|
|
||||||
+ assert(alloc_data->length == tests[3].cred1len);
|
|
||||||
+ assert(memcmp(tests[3].cred1, alloc_data->data, alloc_data->length) == 0);
|
|
||||||
+ krb5_free_data(context, alloc_data);
|
|
||||||
+ krb5_free_creds(context, alloc_cred);
|
|
||||||
+
|
|
||||||
for (version = FIRST_VERSION; version <= 4; version++) {
|
|
||||||
t = &tests[version - 1];
|
|
||||||
|
|
||||||
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
|
|
||||||
index 2d9d56530..adbfa332b 100644
|
|
||||||
--- a/src/lib/krb5/libkrb5.exports
|
|
||||||
+++ b/src/lib/krb5/libkrb5.exports
|
|
||||||
@@ -489,6 +489,7 @@ krb5_lock_file
|
|
||||||
krb5_make_authdata_kdc_issued
|
|
||||||
krb5_make_full_ipaddr
|
|
||||||
krb5_make_fulladdr
|
|
||||||
+krb5_marshal_credentials
|
|
||||||
krb5_mcc_ops
|
|
||||||
krb5_merge_authdata
|
|
||||||
krb5_mk_1cred
|
|
||||||
@@ -592,6 +593,7 @@ krb5_timeofday
|
|
||||||
krb5_timestamp_to_sfstring
|
|
||||||
krb5_timestamp_to_string
|
|
||||||
krb5_unlock_file
|
|
||||||
+krb5_unmarshal_credentials
|
|
||||||
krb5_unpack_full_ipaddr
|
|
||||||
krb5_unparse_name
|
|
||||||
krb5_unparse_name_ext
|
|
||||||
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
|
|
||||||
index 4953907aa..60b8dd311 100644
|
|
||||||
--- a/src/lib/krb5_32.def
|
|
||||||
+++ b/src/lib/krb5_32.def
|
|
||||||
@@ -503,3 +503,7 @@ EXPORTS
|
|
||||||
; new in 1.19
|
|
||||||
k5_cc_store_primary_cred @470 ; PRIVATE
|
|
||||||
k5_kt_have_match @471 ; PRIVATE GSSAPI
|
|
||||||
+
|
|
||||||
+; new in 1.20
|
|
||||||
+ krb5_marshal_credentials @472
|
|
||||||
+ krb5_unmarshal_credentials @473
|
|
@ -1,359 +0,0 @@
|
|||||||
From 418e64100d1e3f8c8e3f773909347bad270a2921 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
|
||||||
Date: Thu, 11 Feb 2021 15:33:10 +0100
|
|
||||||
Subject: [PATCH] Add KCM_OP_GET_CRED_LIST for faster iteration
|
|
||||||
|
|
||||||
For large caches, one IPC operation per credential dominates the cost
|
|
||||||
of iteration. Instead transfer the whole list of credentials to the
|
|
||||||
client in one IPC operation.
|
|
||||||
|
|
||||||
Add optional support for the new opcode to the test KCM server to
|
|
||||||
allow testing of the main and fallback code paths.
|
|
||||||
|
|
||||||
[ghudson@mit.edu: fixed memory leaks and potential memory errors;
|
|
||||||
adjusted code style and comments; rewrote commit message; added
|
|
||||||
kcmserver.py support and tests]
|
|
||||||
|
|
||||||
ticket: 8990 (new)
|
|
||||||
(cherry picked from commit 81bdb47d8ded390263d8ee48f71d5c312b4f1736)
|
|
||||||
(cherry picked from commit a0ee8b02e56c65e5dcd569caed0e151cef004ef4)
|
|
||||||
---
|
|
||||||
src/include/kcm.h | 12 ++-
|
|
||||||
src/lib/krb5/ccache/cc_kcm.c | 144 ++++++++++++++++++++++++++++++++---
|
|
||||||
src/tests/kcmserver.py | 28 ++++++-
|
|
||||||
src/tests/t_ccache.py | 10 ++-
|
|
||||||
4 files changed, 175 insertions(+), 19 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/include/kcm.h b/src/include/kcm.h
|
|
||||||
index 5ea1447cd..e4140c3a0 100644
|
|
||||||
--- a/src/include/kcm.h
|
|
||||||
+++ b/src/include/kcm.h
|
|
||||||
@@ -51,9 +51,9 @@
|
|
||||||
*
|
|
||||||
* All replies begin with a 32-bit big-endian reply code.
|
|
||||||
*
|
|
||||||
- * Parameters are appended to the request or reply with no delimiters. Flags
|
|
||||||
- * and time offsets are stored as 32-bit big-endian integers. Names are
|
|
||||||
- * marshalled as zero-terminated strings. Principals and credentials are
|
|
||||||
+ * Parameters are appended to the request or reply with no delimiters. Flags,
|
|
||||||
+ * time offsets, and lengths are stored as 32-bit big-endian integers. Names
|
|
||||||
+ * are marshalled as zero-terminated strings. Principals and credentials are
|
|
||||||
* marshalled in the v4 FILE ccache format. UUIDs are 16 bytes. UUID lists
|
|
||||||
* are not delimited, so nothing can come after them.
|
|
||||||
*/
|
|
||||||
@@ -89,7 +89,11 @@ typedef enum kcm_opcode {
|
|
||||||
KCM_OP_HAVE_NTLM_CRED,
|
|
||||||
KCM_OP_DEL_NTLM_CRED,
|
|
||||||
KCM_OP_DO_NTLM_AUTH,
|
|
||||||
- KCM_OP_GET_NTLM_USER_LIST
|
|
||||||
+ KCM_OP_GET_NTLM_USER_LIST,
|
|
||||||
+
|
|
||||||
+ /* MIT extensions */
|
|
||||||
+ KCM_OP_MIT_EXTENSION_BASE = 13000,
|
|
||||||
+ KCM_OP_GET_CRED_LIST, /* (name) -> (count, count*{len, cred}) */
|
|
||||||
} kcm_opcode;
|
|
||||||
|
|
||||||
#endif /* KCM_H */
|
|
||||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
index 9093f894d..772928e4d 100644
|
|
||||||
--- a/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
+++ b/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
@@ -61,6 +61,17 @@ struct uuid_list {
|
|
||||||
size_t pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
+struct cred_list {
|
|
||||||
+ krb5_creds *creds;
|
|
||||||
+ size_t count;
|
|
||||||
+ size_t pos;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+struct kcm_cursor {
|
|
||||||
+ struct uuid_list *uuids;
|
|
||||||
+ struct cred_list *creds;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
struct kcmio {
|
|
||||||
SOCKET fd;
|
|
||||||
#ifdef __APPLE__
|
|
||||||
@@ -489,6 +500,69 @@ free_uuid_list(struct uuid_list *uuids)
|
|
||||||
free(uuids);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void
|
|
||||||
+free_cred_list(struct cred_list *list)
|
|
||||||
+{
|
|
||||||
+ size_t i;
|
|
||||||
+
|
|
||||||
+ if (list == NULL)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ /* Creds are transferred to the caller as list->pos is incremented, so we
|
|
||||||
+ * can start freeing there. */
|
|
||||||
+ for (i = list->pos; i < list->count; i++)
|
|
||||||
+ krb5_free_cred_contents(NULL, &list->creds[i]);
|
|
||||||
+ free(list->creds);
|
|
||||||
+ free(list);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/* Fetch a cred list from req->reply. */
|
|
||||||
+static krb5_error_code
|
|
||||||
+kcmreq_get_cred_list(struct kcmreq *req, struct cred_list **creds_out)
|
|
||||||
+{
|
|
||||||
+ struct cred_list *list;
|
|
||||||
+ const unsigned char *data;
|
|
||||||
+ krb5_error_code ret = 0;
|
|
||||||
+ size_t count, len, i;
|
|
||||||
+
|
|
||||||
+ *creds_out = NULL;
|
|
||||||
+
|
|
||||||
+ /* Check a rough bound on the count to prevent very large allocations. */
|
|
||||||
+ count = k5_input_get_uint32_be(&req->reply);
|
|
||||||
+ if (count > req->reply.len / 4)
|
|
||||||
+ return KRB5_KCM_MALFORMED_REPLY;
|
|
||||||
+
|
|
||||||
+ list = malloc(sizeof(*list));
|
|
||||||
+ if (list == NULL)
|
|
||||||
+ return ENOMEM;
|
|
||||||
+
|
|
||||||
+ list->creds = NULL;
|
|
||||||
+ list->count = count;
|
|
||||||
+ list->pos = 0;
|
|
||||||
+ list->creds = k5calloc(count, sizeof(*list->creds), &ret);
|
|
||||||
+ if (list->creds == NULL) {
|
|
||||||
+ free(list);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < count; i++) {
|
|
||||||
+ len = k5_input_get_uint32_be(&req->reply);
|
|
||||||
+ data = k5_input_get_bytes(&req->reply, len);
|
|
||||||
+ if (data == NULL)
|
|
||||||
+ break;
|
|
||||||
+ ret = k5_unmarshal_cred(data, len, 4, &list->creds[i]);
|
|
||||||
+ if (ret)
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ if (i < count) {
|
|
||||||
+ free_cred_list(list);
|
|
||||||
+ return (ret == ENOMEM) ? ENOMEM : KRB5_KCM_MALFORMED_REPLY;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ *creds_out = list;
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void
|
|
||||||
kcmreq_free(struct kcmreq *req)
|
|
||||||
{
|
|
||||||
@@ -753,33 +827,53 @@ kcm_start_seq_get(krb5_context context, krb5_ccache cache,
|
|
||||||
{
|
|
||||||
krb5_error_code ret;
|
|
||||||
struct kcmreq req = EMPTY_KCMREQ;
|
|
||||||
- struct uuid_list *uuids;
|
|
||||||
+ struct uuid_list *uuids = NULL;
|
|
||||||
+ struct cred_list *creds = NULL;
|
|
||||||
+ struct kcm_cursor *cursor;
|
|
||||||
|
|
||||||
*cursor_out = NULL;
|
|
||||||
|
|
||||||
get_kdc_offset(context, cache);
|
|
||||||
|
|
||||||
- kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache);
|
|
||||||
+ kcmreq_init(&req, KCM_OP_GET_CRED_LIST, cache);
|
|
||||||
ret = cache_call(context, cache, &req);
|
|
||||||
- if (ret)
|
|
||||||
+ if (ret == 0) {
|
|
||||||
+ /* GET_CRED_LIST is available. */
|
|
||||||
+ ret = kcmreq_get_cred_list(&req, &creds);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+ } else if (ret == KRB5_FCC_INTERNAL) {
|
|
||||||
+ /* Fall back to GET_CRED_UUID_LIST. */
|
|
||||||
+ kcmreq_free(&req);
|
|
||||||
+ kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache);
|
|
||||||
+ ret = cache_call(context, cache, &req);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+ ret = kcmreq_get_uuid_list(&req, &uuids);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+ } else {
|
|
||||||
goto cleanup;
|
|
||||||
- ret = kcmreq_get_uuid_list(&req, &uuids);
|
|
||||||
- if (ret)
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ cursor = k5alloc(sizeof(*cursor), &ret);
|
|
||||||
+ if (cursor == NULL)
|
|
||||||
goto cleanup;
|
|
||||||
- *cursor_out = (krb5_cc_cursor)uuids;
|
|
||||||
+ cursor->uuids = uuids;
|
|
||||||
+ cursor->creds = creds;
|
|
||||||
+ *cursor_out = (krb5_cc_cursor)cursor;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
kcmreq_free(&req);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static krb5_error_code KRB5_CALLCONV
|
|
||||||
-kcm_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor,
|
|
||||||
- krb5_creds *cred_out)
|
|
||||||
+static krb5_error_code
|
|
||||||
+next_cred_by_uuid(krb5_context context, krb5_ccache cache,
|
|
||||||
+ struct uuid_list *uuids, krb5_creds *cred_out)
|
|
||||||
{
|
|
||||||
krb5_error_code ret;
|
|
||||||
struct kcmreq req;
|
|
||||||
- struct uuid_list *uuids = (struct uuid_list *)*cursor;
|
|
||||||
|
|
||||||
memset(cred_out, 0, sizeof(*cred_out));
|
|
||||||
|
|
||||||
@@ -797,11 +891,39 @@ kcm_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor,
|
|
||||||
return map_invalid(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static krb5_error_code KRB5_CALLCONV
|
|
||||||
+kcm_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor,
|
|
||||||
+ krb5_creds *cred_out)
|
|
||||||
+{
|
|
||||||
+ struct kcm_cursor *c = (struct kcm_cursor *)*cursor;
|
|
||||||
+ struct cred_list *list;
|
|
||||||
+
|
|
||||||
+ if (c->uuids != NULL)
|
|
||||||
+ return next_cred_by_uuid(context, cache, c->uuids, cred_out);
|
|
||||||
+
|
|
||||||
+ list = c->creds;
|
|
||||||
+ if (list->pos >= list->count)
|
|
||||||
+ return KRB5_CC_END;
|
|
||||||
+
|
|
||||||
+ /* Transfer memory ownership of one cred to the caller. */
|
|
||||||
+ *cred_out = list->creds[list->pos];
|
|
||||||
+ memset(&list->creds[list->pos], 0, sizeof(*list->creds));
|
|
||||||
+ list->pos++;
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static krb5_error_code KRB5_CALLCONV
|
|
||||||
kcm_end_seq_get(krb5_context context, krb5_ccache cache,
|
|
||||||
krb5_cc_cursor *cursor)
|
|
||||||
{
|
|
||||||
- free_uuid_list((struct uuid_list *)*cursor);
|
|
||||||
+ struct kcm_cursor *c = *cursor;
|
|
||||||
+
|
|
||||||
+ if (c == NULL)
|
|
||||||
+ return 0;
|
|
||||||
+ free_uuid_list(c->uuids);
|
|
||||||
+ free_cred_list(c->creds);
|
|
||||||
+ free(c);
|
|
||||||
*cursor = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
diff --git a/src/tests/kcmserver.py b/src/tests/kcmserver.py
|
|
||||||
index 57432e5a7..8c5e66ff1 100644
|
|
||||||
--- a/src/tests/kcmserver.py
|
|
||||||
+++ b/src/tests/kcmserver.py
|
|
||||||
@@ -23,6 +23,7 @@
|
|
||||||
# traceback.print_exception(etype, value, tb, file=f)
|
|
||||||
# sys.excepthook = ehook
|
|
||||||
|
|
||||||
+import optparse
|
|
||||||
import select
|
|
||||||
import socket
|
|
||||||
import struct
|
|
||||||
@@ -49,12 +50,14 @@ class KCMOpcodes(object):
|
|
||||||
SET_DEFAULT_CACHE = 21
|
|
||||||
GET_KDC_OFFSET = 22
|
|
||||||
SET_KDC_OFFSET = 23
|
|
||||||
+ GET_CRED_LIST = 13001
|
|
||||||
|
|
||||||
|
|
||||||
class KRB5Errors(object):
|
|
||||||
KRB5_CC_END = -1765328242
|
|
||||||
KRB5_CC_NOSUPP = -1765328137
|
|
||||||
KRB5_FCC_NOFILE = -1765328189
|
|
||||||
+ KRB5_FCC_INTERNAL = -1765328188
|
|
||||||
|
|
||||||
|
|
||||||
def make_uuid():
|
|
||||||
@@ -183,6 +186,14 @@ def op_set_kdc_offset(argbytes):
|
|
||||||
return 0, b''
|
|
||||||
|
|
||||||
|
|
||||||
+def op_get_cred_list(argbytes):
|
|
||||||
+ name, rest = unmarshal_name(argbytes)
|
|
||||||
+ cache = get_cache(name)
|
|
||||||
+ creds = [cache.creds[u] for u in cache.cred_uuids]
|
|
||||||
+ return 0, (struct.pack('>L', len(creds)) +
|
|
||||||
+ b''.join(struct.pack('>L', len(c)) + c for c in creds))
|
|
||||||
+
|
|
||||||
+
|
|
||||||
ophandlers = {
|
|
||||||
KCMOpcodes.GEN_NEW : op_gen_new,
|
|
||||||
KCMOpcodes.INITIALIZE : op_initialize,
|
|
||||||
@@ -197,7 +208,8 @@ ophandlers = {
|
|
||||||
KCMOpcodes.GET_DEFAULT_CACHE : op_get_default_cache,
|
|
||||||
KCMOpcodes.SET_DEFAULT_CACHE : op_set_default_cache,
|
|
||||||
KCMOpcodes.GET_KDC_OFFSET : op_get_kdc_offset,
|
|
||||||
- KCMOpcodes.SET_KDC_OFFSET : op_set_kdc_offset
|
|
||||||
+ KCMOpcodes.SET_KDC_OFFSET : op_set_kdc_offset,
|
|
||||||
+ KCMOpcodes.GET_CRED_LIST : op_get_cred_list
|
|
||||||
}
|
|
||||||
|
|
||||||
# Read and respond to a request from the socket s.
|
|
||||||
@@ -215,7 +227,11 @@ def service_request(s):
|
|
||||||
|
|
||||||
majver, minver, op = struct.unpack('>BBH', req[:4])
|
|
||||||
argbytes = req[4:]
|
|
||||||
- code, payload = ophandlers[op](argbytes)
|
|
||||||
+
|
|
||||||
+ if op in ophandlers:
|
|
||||||
+ code, payload = ophandlers[op](argbytes)
|
|
||||||
+ else:
|
|
||||||
+ code, payload = KRB5Errors.KRB5_FCC_INTERNAL, b''
|
|
||||||
|
|
||||||
# The KCM response is the code (4 bytes) and the response payload.
|
|
||||||
# The Heimdal IPC response is the length of the KCM response (4
|
|
||||||
@@ -226,9 +242,15 @@ def service_request(s):
|
|
||||||
s.sendall(hipc_response)
|
|
||||||
return True
|
|
||||||
|
|
||||||
+parser = optparse.OptionParser()
|
|
||||||
+parser.add_option('-c', '--credlist', action='store_true', dest='credlist',
|
|
||||||
+ default=False, help='Support KCM_OP_GET_CRED_LIST')
|
|
||||||
+(options, args) = parser.parse_args()
|
|
||||||
+if not options.credlist:
|
|
||||||
+ del ophandlers[KCMOpcodes.GET_CRED_LIST]
|
|
||||||
|
|
||||||
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
||||||
-server.bind(sys.argv[1])
|
|
||||||
+server.bind(args[0])
|
|
||||||
server.listen(5)
|
|
||||||
select_input = [server,]
|
|
||||||
sys.stderr.write('starting...\n')
|
|
||||||
diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py
|
|
||||||
index 66804afa5..90040fb7b 100755
|
|
||||||
--- a/src/tests/t_ccache.py
|
|
||||||
+++ b/src/tests/t_ccache.py
|
|
||||||
@@ -125,10 +125,18 @@ def collection_test(realm, ccname):
|
|
||||||
|
|
||||||
|
|
||||||
collection_test(realm, 'DIR:' + os.path.join(realm.testdir, 'cc'))
|
|
||||||
+
|
|
||||||
+# Test KCM without and with GET_CRED_LIST support.
|
|
||||||
kcmserver_path = os.path.join(srctop, 'tests', 'kcmserver.py')
|
|
||||||
-realm.start_server([sys.executable, kcmserver_path, kcm_socket_path],
|
|
||||||
+kcmd = realm.start_server([sys.executable, kcmserver_path, kcm_socket_path],
|
|
||||||
+ 'starting...')
|
|
||||||
+collection_test(realm, 'KCM:')
|
|
||||||
+stop_daemon(kcmd)
|
|
||||||
+os.remove(kcm_socket_path)
|
|
||||||
+realm.start_server([sys.executable, kcmserver_path, '-c', kcm_socket_path],
|
|
||||||
'starting...')
|
|
||||||
collection_test(realm, 'KCM:')
|
|
||||||
+
|
|
||||||
if test_keyring:
|
|
||||||
def cleanup_keyring(anchor, name):
|
|
||||||
out = realm.run(['keyctl', 'list', anchor])
|
|
@ -1,25 +0,0 @@
|
|||||||
From 2f039fc910022c9569fe6941a194f0b26bd6c894 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
Date: Fri, 20 Sep 2019 16:11:29 -0400
|
|
||||||
Subject: [PATCH] Add buildsystem detection of the OpenSSL-3 KDF interface
|
|
||||||
|
|
||||||
(cherry picked from commit a3e03dfd40928c4615bd9b8546eac0c104377850)
|
|
||||||
---
|
|
||||||
src/configure.ac | 4 ++++
|
|
||||||
1 file changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/configure.ac b/src/configure.ac
|
|
||||||
index eb6307468..9c2e816fe 100644
|
|
||||||
--- a/src/configure.ac
|
|
||||||
+++ b/src/configure.ac
|
|
||||||
@@ -282,6 +282,10 @@ AC_SUBST(CRYPTO_IMPL)
|
|
||||||
AC_SUBST(CRYPTO_IMPL_CFLAGS)
|
|
||||||
AC_SUBST(CRYPTO_IMPL_LIBS)
|
|
||||||
|
|
||||||
+if test "$CRYPTO_IMPL" = openssl; then
|
|
||||||
+ AC_CHECK_FUNCS(EVP_KDF_fetch)
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
AC_ARG_WITH([prng-alg],
|
|
||||||
AC_HELP_STRING([--with-prng-alg=ALG], [use specified PRNG algorithm. @<:@fortuna@:>@]),
|
|
||||||
[PRNG_ALG=$withval
|
|
@ -1,84 +0,0 @@
|
|||||||
From c76a01279bbbbcfd296d2ead8f6e2a5bee7e8443 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Greg Hudson <ghudson@mit.edu>
|
|
||||||
Date: Fri, 15 Jan 2021 14:43:34 -0500
|
|
||||||
Subject: [PATCH] Add hostname canonicalization helper to k5test.py
|
|
||||||
|
|
||||||
To facilitate fallback tests, add a canonicalize_hostname() function
|
|
||||||
to k5test.py which works similarly to krb5_expand_hostname(). Use it
|
|
||||||
in t_gssapi.py for the recently-added acceptor name fallback test.
|
|
||||||
|
|
||||||
(cherry picked from commit 225fffe4e912772acea3a01d45bafb60bfb80948)
|
|
||||||
---
|
|
||||||
src/tests/gssapi/t_gssapi.py | 11 +++--------
|
|
||||||
src/util/k5test.py | 22 ++++++++++++++++++++++
|
|
||||||
2 files changed, 25 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py
|
|
||||||
index 1af6f31c2..e22cec427 100755
|
|
||||||
--- a/src/tests/gssapi/t_gssapi.py
|
|
||||||
+++ b/src/tests/gssapi/t_gssapi.py
|
|
||||||
@@ -8,7 +8,7 @@ for realm in multipass_realms():
|
|
||||||
realm.run(['./t_iov', '-s', 'p:' + realm.host_princ])
|
|
||||||
realm.run(['./t_pcontok', 'p:' + realm.host_princ])
|
|
||||||
|
|
||||||
-realm = K5Realm(krb5_conf={'libdefaults': {'rdns': 'false'}})
|
|
||||||
+realm = K5Realm()
|
|
||||||
|
|
||||||
# Test gss_add_cred().
|
|
||||||
realm.run(['./t_add_cred'])
|
|
||||||
@@ -62,13 +62,8 @@ realm.run(['./t_accname', 'p:host/-nomatch-',
|
|
||||||
expected_msg=' not found in keytab')
|
|
||||||
|
|
||||||
# If possible, test with an acceptor name requiring fallback to match
|
|
||||||
-# against a keytab entry. Forward-canonicalize the hostname, relying
|
|
||||||
-# on the rdns=false realm setting.
|
|
||||||
-try:
|
|
||||||
- ai = socket.getaddrinfo(hostname, None, 0, 0, 0, socket.AI_CANONNAME)
|
|
||||||
- (family, socktype, proto, canonname, sockaddr) = ai[0]
|
|
||||||
-except socket.gaierror:
|
|
||||||
- canonname = hostname
|
|
||||||
+# against a keytab entry.
|
|
||||||
+canonname = canonicalize_hostname(hostname)
|
|
||||||
if canonname != hostname:
|
|
||||||
os.rename(realm.keytab, realm.keytab + '.save')
|
|
||||||
canonprinc = 'host/' + canonname
|
|
||||||
diff --git a/src/util/k5test.py b/src/util/k5test.py
|
|
||||||
index 789b0f4b9..251d11a9d 100644
|
|
||||||
--- a/src/util/k5test.py
|
|
||||||
+++ b/src/util/k5test.py
|
|
||||||
@@ -155,6 +155,10 @@ Scripts may use the following functions and variables:
|
|
||||||
* password(name): Return a weakly random password based on name. The
|
|
||||||
password will be consistent across calls with the same name.
|
|
||||||
|
|
||||||
+* canonicalize_hostname(name, rdns=True): Return the DNS
|
|
||||||
+ canonicalization of name, optionally using reverse DNS. On error,
|
|
||||||
+ return name converted to lowercase.
|
|
||||||
+
|
|
||||||
* stop_daemon(proc): Stop a daemon process started with
|
|
||||||
realm.start_server() or realm.start_in_inetd(). Only necessary if
|
|
||||||
the port needs to be reused; daemon processes will be stopped
|
|
||||||
@@ -458,6 +462,24 @@ def password(name):
|
|
||||||
return name + str(os.getpid())
|
|
||||||
|
|
||||||
|
|
||||||
+def canonicalize_hostname(name, rdns=True):
|
|
||||||
+ """Canonicalize name using DNS, optionally with reverse DNS."""
|
|
||||||
+ try:
|
|
||||||
+ ai = socket.getaddrinfo(name, None, 0, 0, 0, socket.AI_CANONNAME)
|
|
||||||
+ except socket.gaierror as e:
|
|
||||||
+ return name.lower()
|
|
||||||
+ (family, socktype, proto, canonname, sockaddr) = ai[0]
|
|
||||||
+
|
|
||||||
+ if not rdns:
|
|
||||||
+ return canonname.lower()
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ rname = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD)
|
|
||||||
+ except socket.gaierror:
|
|
||||||
+ return canonname.lower()
|
|
||||||
+ return rname[0].lower()
|
|
||||||
+
|
|
||||||
+
|
|
||||||
# Exit handler which ensures processes are cleaned up and, on failure,
|
|
||||||
# prints messages to help developers debug the problem.
|
|
||||||
def _onexit():
|
|
@ -1,61 +0,0 @@
|
|||||||
From 4c2f596da5ddb8a1687a4f9c969d5a8dcd2cbcc7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
Date: Thu, 3 Jun 2021 16:03:07 -0400
|
|
||||||
Subject: [PATCH] Allow kinit with keytab to defer canonicalization
|
|
||||||
|
|
||||||
[ghudson@mit.edu: added tests]
|
|
||||||
|
|
||||||
ticket: 9012 (new)
|
|
||||||
(cherry picked from commit 5e6a6efc5df689d9fb8730d0227167ffbb6ece0e)
|
|
||||||
(cherry picked from commit 090c7319652466339e3e6482bdd1b5a294638dff)
|
|
||||||
---
|
|
||||||
src/clients/kinit/kinit.c | 11 -----------
|
|
||||||
src/tests/t_keytab.py | 13 +++++++++++++
|
|
||||||
2 files changed, 13 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c
|
|
||||||
index d1f5d74c3..5a6d7237c 100644
|
|
||||||
--- a/src/clients/kinit/kinit.c
|
|
||||||
+++ b/src/clients/kinit/kinit.c
|
|
||||||
@@ -510,17 +510,6 @@ k5_begin(struct k_opts *opts, struct k5_data *k5)
|
|
||||||
_("when creating default server principal name"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
- if (k5->me->realm.data[0] == 0) {
|
|
||||||
- ret = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
|
|
||||||
- if (ret == 0) {
|
|
||||||
- com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
|
|
||||||
- _("(principal %s)"), k5->name);
|
|
||||||
- } else {
|
|
||||||
- com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
|
|
||||||
- _("for local services"));
|
|
||||||
- }
|
|
||||||
- goto cleanup;
|
|
||||||
- }
|
|
||||||
} else if (k5->out_cc != NULL) {
|
|
||||||
/* If the output ccache is initialized, use its principal. */
|
|
||||||
if (krb5_cc_get_principal(k5->ctx, k5->out_cc, &princ) == 0)
|
|
||||||
diff --git a/src/tests/t_keytab.py b/src/tests/t_keytab.py
|
|
||||||
index 850375c92..a9adebb26 100755
|
|
||||||
--- a/src/tests/t_keytab.py
|
|
||||||
+++ b/src/tests/t_keytab.py
|
|
||||||
@@ -41,6 +41,19 @@ realm.kinit(realm.user_princ, flags=['-i'],
|
|
||||||
expected_msg='keytab specified, forcing -k')
|
|
||||||
realm.klist(realm.user_princ)
|
|
||||||
|
|
||||||
+# Test default principal for -k. This operation requires
|
|
||||||
+# canonicalization against the keytab in krb5_get_init_creds_keytab()
|
|
||||||
+# as the krb5_sname_to_principal() result won't have a realm. Try
|
|
||||||
+# with and without without fallback processing since the code paths
|
|
||||||
+# are different.
|
|
||||||
+mark('default principal for -k')
|
|
||||||
+realm.run([kinit, '-k'])
|
|
||||||
+realm.klist(realm.host_princ)
|
|
||||||
+no_canon_conf = {'libdefaults': {'dns_canonicalize_hostname': 'false'}}
|
|
||||||
+no_canon = realm.special_env('no_canon', False, krb5_conf=no_canon_conf)
|
|
||||||
+realm.run([kinit, '-k'], env=no_canon)
|
|
||||||
+realm.klist(realm.host_princ)
|
|
||||||
+
|
|
||||||
# Test extracting keys with multiple key versions present.
|
|
||||||
mark('multi-kvno extract')
|
|
||||||
os.remove(realm.keytab)
|
|
@ -1,104 +0,0 @@
|
|||||||
From 92a4b760d741494dacbb4d9db4cf2db9e3b01f2c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Greg Hudson <ghudson@mit.edu>
|
|
||||||
Date: Mon, 29 Mar 2021 14:32:56 -0400
|
|
||||||
Subject: [PATCH] Fix KCM flag transmission for remove_cred
|
|
||||||
|
|
||||||
MIT krb5 uses low bits for KRB5_TC flags, while Heimdal uses high bits
|
|
||||||
so that the same flag word can also hold KRB5_GC flags. Add a mapping
|
|
||||||
function and send the Heimdal flag values when performing a
|
|
||||||
remove_cred operation.
|
|
||||||
|
|
||||||
ticket: 8995
|
|
||||||
(cherry picked from commit 11a82cf424f9c905bb73680c64524f087090d4ef)
|
|
||||||
(cherry picked from commit 04f0de4420508161ce439f262f2761ff51a07ab0)
|
|
||||||
---
|
|
||||||
src/include/kcm.h | 19 +++++++++++++++++++
|
|
||||||
src/lib/krb5/ccache/cc_kcm.c | 36 +++++++++++++++++++++++++++++++++++-
|
|
||||||
2 files changed, 54 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/include/kcm.h b/src/include/kcm.h
|
|
||||||
index e4140c3a0..9b66f1cbd 100644
|
|
||||||
--- a/src/include/kcm.h
|
|
||||||
+++ b/src/include/kcm.h
|
|
||||||
@@ -56,8 +56,27 @@
|
|
||||||
* are marshalled as zero-terminated strings. Principals and credentials are
|
|
||||||
* marshalled in the v4 FILE ccache format. UUIDs are 16 bytes. UUID lists
|
|
||||||
* are not delimited, so nothing can come after them.
|
|
||||||
+ *
|
|
||||||
+ * Flag words must use Heimdal flag values, which are not the same as MIT krb5
|
|
||||||
+ * values for KRB5_GC and KRB5_TC constants. The same flag word may contain
|
|
||||||
+ * both kinds of flags in Heimdal, but not in MIT krb5. Defines for the
|
|
||||||
+ * applicable Heimdal flag values are given below using KCM_GC and KCM_TC
|
|
||||||
+ * prefixes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
+#define KCM_GC_CACHED (1U << 0)
|
|
||||||
+
|
|
||||||
+#define KCM_TC_DONT_MATCH_REALM (1U << 31)
|
|
||||||
+#define KCM_TC_MATCH_KEYTYPE (1U << 30)
|
|
||||||
+#define KCM_TC_MATCH_SRV_NAMEONLY (1U << 29)
|
|
||||||
+#define KCM_TC_MATCH_FLAGS_EXACT (1U << 28)
|
|
||||||
+#define KCM_TC_MATCH_FLAGS (1U << 27)
|
|
||||||
+#define KCM_TC_MATCH_TIMES_EXACT (1U << 26)
|
|
||||||
+#define KCM_TC_MATCH_TIMES (1U << 25)
|
|
||||||
+#define KCM_TC_MATCH_AUTHDATA (1U << 24)
|
|
||||||
+#define KCM_TC_MATCH_2ND_TKT (1U << 23)
|
|
||||||
+#define KCM_TC_MATCH_IS_SKEY (1U << 22)
|
|
||||||
+
|
|
||||||
/* Opcodes without comments are currently unused in the MIT client
|
|
||||||
* implementation. */
|
|
||||||
typedef enum kcm_opcode {
|
|
||||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
index 772928e4d..1f81a2190 100644
|
|
||||||
--- a/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
+++ b/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
@@ -110,6 +110,40 @@ map_invalid(krb5_error_code code)
|
|
||||||
KRB5_KCM_MALFORMED_REPLY : code;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * Map an MIT krb5 KRB5_TC flag word to the equivalent Heimdal flag word. Note
|
|
||||||
+ * that there is no MIT krb5 equivalent for Heimdal's KRB5_TC_DONT_MATCH_REALM
|
|
||||||
+ * (which is like KRB5_TC_MATCH_SRV_NAMEONLY but also applies to the client
|
|
||||||
+ * principal) and no Heimdal equivalent for MIT krb5's KRB5_TC_SUPPORTED_KTYPES
|
|
||||||
+ * (which matches against enctypes from the krb5_context rather than the
|
|
||||||
+ * matching cred).
|
|
||||||
+ */
|
|
||||||
+static inline krb5_flags
|
|
||||||
+map_tcflags(krb5_flags mitflags)
|
|
||||||
+{
|
|
||||||
+ krb5_flags heimflags = 0;
|
|
||||||
+
|
|
||||||
+ if (mitflags & KRB5_TC_MATCH_TIMES)
|
|
||||||
+ heimflags |= KCM_TC_MATCH_TIMES;
|
|
||||||
+ if (mitflags & KRB5_TC_MATCH_IS_SKEY)
|
|
||||||
+ heimflags |= KCM_TC_MATCH_IS_SKEY;
|
|
||||||
+ if (mitflags & KRB5_TC_MATCH_FLAGS)
|
|
||||||
+ heimflags |= KCM_TC_MATCH_FLAGS;
|
|
||||||
+ if (mitflags & KRB5_TC_MATCH_TIMES_EXACT)
|
|
||||||
+ heimflags |= KCM_TC_MATCH_TIMES_EXACT;
|
|
||||||
+ if (mitflags & KRB5_TC_MATCH_FLAGS_EXACT)
|
|
||||||
+ heimflags |= KCM_TC_MATCH_FLAGS_EXACT;
|
|
||||||
+ if (mitflags & KRB5_TC_MATCH_AUTHDATA)
|
|
||||||
+ heimflags |= KCM_TC_MATCH_AUTHDATA;
|
|
||||||
+ if (mitflags & KRB5_TC_MATCH_SRV_NAMEONLY)
|
|
||||||
+ heimflags |= KCM_TC_MATCH_SRV_NAMEONLY;
|
|
||||||
+ if (mitflags & KRB5_TC_MATCH_2ND_TKT)
|
|
||||||
+ heimflags |= KCM_TC_MATCH_2ND_TKT;
|
|
||||||
+ if (mitflags & KRB5_TC_MATCH_KTYPE)
|
|
||||||
+ heimflags |= KCM_TC_MATCH_KEYTYPE;
|
|
||||||
+ return heimflags;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* Begin a request for the given opcode. If cache is non-null, supply the
|
|
||||||
* cache name as a request parameter. */
|
|
||||||
static void
|
|
||||||
@@ -936,7 +970,7 @@ kcm_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags,
|
|
||||||
struct kcmreq req;
|
|
||||||
|
|
||||||
kcmreq_init(&req, KCM_OP_REMOVE_CRED, cache);
|
|
||||||
- k5_buf_add_uint32_be(&req.reqbuf, flags);
|
|
||||||
+ k5_buf_add_uint32_be(&req.reqbuf, map_tcflags(flags));
|
|
||||||
k5_marshal_mcred(&req.reqbuf, mcred);
|
|
||||||
ret = cache_call(context, cache, &req);
|
|
||||||
kcmreq_free(&req);
|
|
@ -1,63 +0,0 @@
|
|||||||
From b4f3df953015bf6d2d4c973b458f778f31615c11 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Greg Hudson <ghudson@mit.edu>
|
|
||||||
Date: Tue, 11 May 2021 14:04:07 -0400
|
|
||||||
Subject: [PATCH] Fix KCM retrieval support for sssd
|
|
||||||
|
|
||||||
Commit 795ebba8c039be172ab93cd41105c73ffdba0fdb added a retrieval
|
|
||||||
handler using KCM_OP_RETRIEVE, falling back on the same error codes as
|
|
||||||
the previous KCM_OP_GET_CRED_LIST support. But sssd (as of 2.4)
|
|
||||||
returns KRB5_CC_NOSUPP instead of KRB5_CC_IO if it recognizes an
|
|
||||||
opcode but does not implement it. Add a helper function to recognize
|
|
||||||
all known unsupported-opcode error codes, and use it in kcm_retrieve()
|
|
||||||
and kcm_start_seq_get().
|
|
||||||
|
|
||||||
ticket: 8997
|
|
||||||
(cherry picked from commit da103e36e13f3c846bcddbe38dd518a21e5260a0)
|
|
||||||
(cherry picked from commit a5b2cff51808cd86fe8195e7ac074ecd25c3344d)
|
|
||||||
---
|
|
||||||
src/lib/krb5/ccache/cc_kcm.c | 18 ++++++++++++++++--
|
|
||||||
1 file changed, 16 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
index 23fcf13ea..18505cd3d 100644
|
|
||||||
--- a/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
+++ b/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
@@ -144,6 +144,20 @@ map_tcflags(krb5_flags mitflags)
|
|
||||||
return heimflags;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * Return true if code could indicate an unsupported operation. Heimdal's KCM
|
|
||||||
+ * returns KRB5_FCC_INTERNAL. sssd's KCM daemon (as of sssd 2.4) returns
|
|
||||||
+ * KRB5_CC_NO_SUPP if it recognizes the operation but does not implement it,
|
|
||||||
+ * and KRB5_CC_IO if it doesn't recognize the operation (which is unfortunate
|
|
||||||
+ * since it could also indicate a communication failure).
|
|
||||||
+ */
|
|
||||||
+static krb5_boolean
|
|
||||||
+unsupported_op_error(krb5_error_code code)
|
|
||||||
+{
|
|
||||||
+ return code == KRB5_FCC_INTERNAL || code == KRB5_CC_IO ||
|
|
||||||
+ code == KRB5_CC_NOSUPP;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* Begin a request for the given opcode. If cache is non-null, supply the
|
|
||||||
* cache name as a request parameter. */
|
|
||||||
static void
|
|
||||||
@@ -841,7 +855,7 @@ kcm_retrieve(krb5_context context, krb5_ccache cache, krb5_flags flags,
|
|
||||||
ret = cache_call(context, cache, &req);
|
|
||||||
|
|
||||||
/* Fall back to iteration if the server does not support retrieval. */
|
|
||||||
- if (ret == KRB5_FCC_INTERNAL || ret == KRB5_CC_IO) {
|
|
||||||
+ if (unsupported_op_error(ret)) {
|
|
||||||
ret = k5_cc_retrieve_cred_default(context, cache, flags, mcred,
|
|
||||||
cred_out);
|
|
||||||
goto cleanup;
|
|
||||||
@@ -922,7 +936,7 @@ kcm_start_seq_get(krb5_context context, krb5_ccache cache,
|
|
||||||
ret = kcmreq_get_cred_list(&req, &creds);
|
|
||||||
if (ret)
|
|
||||||
goto cleanup;
|
|
||||||
- } else if (ret == KRB5_FCC_INTERNAL || ret == KRB5_CC_IO) {
|
|
||||||
+ } else if (unsupported_op_error(ret)) {
|
|
||||||
/* Fall back to GET_CRED_UUID_LIST. */
|
|
||||||
kcmreq_free(&req);
|
|
||||||
kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache);
|
|
@ -1,47 +0,0 @@
|
|||||||
From 0a8dfc380fe3b210662ba1b1d452fcec2f84841b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Greg Hudson <ghudson@mit.edu>
|
|
||||||
Date: Tue, 3 Aug 2021 01:15:27 -0400
|
|
||||||
Subject: [PATCH] Fix KDC null deref on TGS inner body null server
|
|
||||||
|
|
||||||
After the KDC decodes a FAST inner body, it does not check for a null
|
|
||||||
server. Prior to commit 39548a5b17bbda9eeb63625a201cfd19b9de1c5b this
|
|
||||||
would typically result in an error from krb5_unparse_name(), but with
|
|
||||||
the addition of get_local_tgt() it results in a null dereference. Add
|
|
||||||
a null check.
|
|
||||||
|
|
||||||
Reported by Joseph Sutton of Catalyst.
|
|
||||||
|
|
||||||
CVE-2021-37750:
|
|
||||||
|
|
||||||
In MIT krb5 releases 1.14 and later, an authenticated attacker can
|
|
||||||
cause a null dereference in the KDC by sending a FAST TGS request with
|
|
||||||
no server field.
|
|
||||||
|
|
||||||
ticket: 9008 (new)
|
|
||||||
tags: pullup
|
|
||||||
target_version: 1.19-next
|
|
||||||
target_version: 1.18-next
|
|
||||||
|
|
||||||
(cherry picked from commit d775c95af7606a51bf79547a94fa52ddd1cb7f49)
|
|
||||||
(cherry picked from commit bb8fa495d00ccd931eec87a01b8920636cf7903e)
|
|
||||||
(cherry picked from commit dfe383f8251d0edc7e5e08ec5e4fdd9b7f902b2a)
|
|
||||||
---
|
|
||||||
src/kdc/do_tgs_req.c | 5 +++++
|
|
||||||
1 file changed, 5 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
|
|
||||||
index 463a9c0dd..7c596a111 100644
|
|
||||||
--- a/src/kdc/do_tgs_req.c
|
|
||||||
+++ b/src/kdc/do_tgs_req.c
|
|
||||||
@@ -208,6 +208,11 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
|
|
||||||
status = "FIND_FAST";
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
+ if (sprinc == NULL) {
|
|
||||||
+ status = "NULL_SERVER";
|
|
||||||
+ errcode = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
errcode = get_local_tgt(kdc_context, &sprinc->realm, header_server,
|
|
||||||
&local_tgt, &local_tgt_storage, &local_tgt_key);
|
|
@ -1,114 +0,0 @@
|
|||||||
From 3fe94b5854c56da38ba14994b6c371c3e3b9094e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Joseph Sutton <josephsutton@catalyst.net.nz>
|
|
||||||
Date: Wed, 7 Jul 2021 11:47:44 +1200
|
|
||||||
Subject: [PATCH] Fix KDC null deref on bad encrypted challenge
|
|
||||||
|
|
||||||
The function ec_verify() in src/kdc/kdc_preauth_ec.c contains a check
|
|
||||||
to avoid further processing if the armor key is NULL. However, this
|
|
||||||
check is bypassed by a call to k5memdup0() which overwrites retval
|
|
||||||
with 0 if the allocation succeeds. If the armor key is NULL, a call
|
|
||||||
to krb5_c_fx_cf2_simple() will then dereference it, resulting in a
|
|
||||||
crash. Add a check before the k5memdup0() call to avoid overwriting
|
|
||||||
retval.
|
|
||||||
|
|
||||||
CVE-2021-36222:
|
|
||||||
|
|
||||||
In MIT krb5 releases 1.16 and later, an unauthenticated attacker can
|
|
||||||
cause a null dereference in the KDC by sending a request containing a
|
|
||||||
PA-ENCRYPTED-CHALLENGE padata element without using FAST.
|
|
||||||
|
|
||||||
[ghudson@mit.edu: trimmed patch; added test case; edited commit
|
|
||||||
message]
|
|
||||||
|
|
||||||
ticket: 9007 (new)
|
|
||||||
tags: pullup
|
|
||||||
target_version: 1.19-next
|
|
||||||
target_version: 1.18-next
|
|
||||||
|
|
||||||
(cherry picked from commit fc98f520caefff2e5ee9a0026fdf5109944b3562)
|
|
||||||
(cherry picked from commit 791211b00a53b394376d096c881b725ee739a936)
|
|
||||||
---
|
|
||||||
src/kdc/kdc_preauth_ec.c | 3 ++-
|
|
||||||
src/tests/Makefile.in | 1 +
|
|
||||||
src/tests/t_cve-2021-36222.py | 46 +++++++++++++++++++++++++++++++++++
|
|
||||||
3 files changed, 49 insertions(+), 1 deletion(-)
|
|
||||||
create mode 100644 src/tests/t_cve-2021-36222.py
|
|
||||||
|
|
||||||
diff --git a/src/kdc/kdc_preauth_ec.c b/src/kdc/kdc_preauth_ec.c
|
|
||||||
index 7e636b3f9..43a9902cc 100644
|
|
||||||
--- a/src/kdc/kdc_preauth_ec.c
|
|
||||||
+++ b/src/kdc/kdc_preauth_ec.c
|
|
||||||
@@ -87,7 +87,8 @@ ec_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request,
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for a configured FAST ec auth indicator. */
|
|
||||||
- realmstr = k5memdup0(realm.data, realm.length, &retval);
|
|
||||||
+ if (retval == 0)
|
|
||||||
+ realmstr = k5memdup0(realm.data, realm.length, &retval);
|
|
||||||
if (realmstr != NULL)
|
|
||||||
retval = profile_get_string(context->profile, KRB5_CONF_REALMS,
|
|
||||||
realmstr,
|
|
||||||
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
|
|
||||||
index ab416cc5f..20f27d748 100644
|
|
||||||
--- a/src/tests/Makefile.in
|
|
||||||
+++ b/src/tests/Makefile.in
|
|
||||||
@@ -159,6 +159,7 @@ check-pytests: unlockiter s4u2self
|
|
||||||
$(RUNPYTEST) $(srcdir)/t_cve-2012-1015.py $(PYTESTFLAGS)
|
|
||||||
$(RUNPYTEST) $(srcdir)/t_cve-2013-1416.py $(PYTESTFLAGS)
|
|
||||||
$(RUNPYTEST) $(srcdir)/t_cve-2013-1417.py $(PYTESTFLAGS)
|
|
||||||
+ $(RUNPYTEST) $(srcdir)/t_cve-2021-36222.py $(PYTESTFLAGS)
|
|
||||||
$(RM) au.log
|
|
||||||
$(RUNPYTEST) $(srcdir)/t_audit.py $(PYTESTFLAGS)
|
|
||||||
$(RUNPYTEST) $(srcdir)/jsonwalker.py -d $(srcdir)/au_dict.json \
|
|
||||||
diff --git a/src/tests/t_cve-2021-36222.py b/src/tests/t_cve-2021-36222.py
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..57e04993b
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/src/tests/t_cve-2021-36222.py
|
|
||||||
@@ -0,0 +1,46 @@
|
|
||||||
+import socket
|
|
||||||
+from k5test import *
|
|
||||||
+
|
|
||||||
+realm = K5Realm()
|
|
||||||
+
|
|
||||||
+# CVE-2021-36222 KDC null dereference on encrypted challenge preauth
|
|
||||||
+# without FAST
|
|
||||||
+
|
|
||||||
+s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
+a = (hostname, realm.portbase)
|
|
||||||
+
|
|
||||||
+m = ('6A81A0' '30819D' # [APPLICATION 10] SEQUENCE
|
|
||||||
+ 'A103' '0201' '05' # [1] pvno = 5
|
|
||||||
+ 'A203' '0201' '0A' # [2] msg-type = 10
|
|
||||||
+ 'A30E' '300C' # [3] padata = SEQUENCE OF
|
|
||||||
+ '300A' # SEQUENCE
|
|
||||||
+ 'A104' '0202' '008A' # [1] padata-type = PA-ENCRYPTED-CHALLENGE
|
|
||||||
+ 'A202' '0400' # [2] padata-value = ""
|
|
||||||
+ 'A48180' '307E' # [4] req-body = SEQUENCE
|
|
||||||
+ 'A007' '0305' '0000000000' # [0] kdc-options = 0
|
|
||||||
+ 'A120' '301E' # [1] cname = SEQUENCE
|
|
||||||
+ 'A003' '0201' '01' # [0] name-type = NT-PRINCIPAL
|
|
||||||
+ 'A117' '3015' # [1] name-string = SEQUENCE-OF
|
|
||||||
+ '1B06' '6B7262746774' # krbtgt
|
|
||||||
+ '1B0B' '4B5242544553542E434F4D'
|
|
||||||
+ # KRBTEST.COM
|
|
||||||
+ 'A20D' '1B0B' '4B5242544553542E434F4D'
|
|
||||||
+ # [2] realm = KRBTEST.COM
|
|
||||||
+ 'A320' '301E' # [3] sname = SEQUENCE
|
|
||||||
+ 'A003' '0201' '01' # [0] name-type = NT-PRINCIPAL
|
|
||||||
+ 'A117' '3015' # [1] name-string = SEQUENCE-OF
|
|
||||||
+ '1B06' '6B7262746774' # krbtgt
|
|
||||||
+ '1B0B' '4B5242544553542E434F4D'
|
|
||||||
+ # KRBTEST.COM
|
|
||||||
+ 'A511' '180F' '31393934303631303036303331375A'
|
|
||||||
+ # [5] till = 19940610060317Z
|
|
||||||
+ 'A703' '0201' '00' # [7] nonce = 0
|
|
||||||
+ 'A808' '3006' # [8] etype = SEQUENCE OF
|
|
||||||
+ '020112' '020111') # aes256-cts aes128-cts
|
|
||||||
+
|
|
||||||
+s.sendto(bytes.fromhex(m), a)
|
|
||||||
+
|
|
||||||
+# Make sure kinit still works.
|
|
||||||
+realm.kinit(realm.user_princ, password('user'))
|
|
||||||
+
|
|
||||||
+success('CVE-2021-36222 regression test')
|
|
@ -1,106 +0,0 @@
|
|||||||
From 7d68cfc84cd7d0657c01afa52dfe69181b401a4a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Greg Hudson <ghudson@mit.edu>
|
|
||||||
Date: Mon, 17 Oct 2022 20:25:11 -0400
|
|
||||||
Subject: [PATCH] Fix integer overflows in PAC parsing
|
|
||||||
|
|
||||||
In krb5_parse_pac(), check for buffer counts large enough to threaten
|
|
||||||
integer overflow in the header length and memory length calculations.
|
|
||||||
Avoid potential integer overflows when checking the length of each
|
|
||||||
buffer.
|
|
||||||
|
|
||||||
CVE-2022-42898:
|
|
||||||
|
|
||||||
In MIT krb5 releases 1.8 and later, an authenticated attacker may be
|
|
||||||
able to cause a KDC or kadmind process to crash by reading beyond the
|
|
||||||
bounds of allocated memory, creating a denial of service. A
|
|
||||||
privileged attacker may similarly be able to cause a Kerberos or GSS
|
|
||||||
application service to crash. On 32-bit platforms, an attacker can
|
|
||||||
also cause insufficient memory to be allocated for the result,
|
|
||||||
potentially leading to remote code execution in a KDC, kadmind, or GSS
|
|
||||||
or Kerberos application server process. An attacker with the
|
|
||||||
privileges of a cross-realm KDC may be able to extract secrets from
|
|
||||||
the KDC process's memory by having them copied into the PAC of a new
|
|
||||||
ticket.
|
|
||||||
|
|
||||||
ticket: 9074 (new)
|
|
||||||
tags: pullup
|
|
||||||
target_version: 1.20-next
|
|
||||||
target_version: 1.19-next
|
|
||||||
---
|
|
||||||
src/lib/krb5/krb/pac.c | 9 +++++++--
|
|
||||||
src/lib/krb5/krb/t_pac.c | 18 ++++++++++++++++++
|
|
||||||
2 files changed, 25 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c
|
|
||||||
index 950beda657..1b9ef12276 100644
|
|
||||||
--- a/src/lib/krb5/krb/pac.c
|
|
||||||
+++ b/src/lib/krb5/krb/pac.c
|
|
||||||
@@ -27,6 +27,8 @@
|
|
||||||
#include "k5-int.h"
|
|
||||||
#include "authdata.h"
|
|
||||||
|
|
||||||
+#define MAX_BUFFERS 4096
|
|
||||||
+
|
|
||||||
/* draft-brezak-win2k-krb-authz-00 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -316,6 +318,9 @@ krb5_pac_parse(krb5_context context,
|
|
||||||
if (version != 0)
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
+ if (cbuffers < 1 || cbuffers > MAX_BUFFERS)
|
|
||||||
+ return ERANGE;
|
|
||||||
+
|
|
||||||
header_len = PACTYPE_LENGTH + (cbuffers * PAC_INFO_BUFFER_LENGTH);
|
|
||||||
if (len < header_len)
|
|
||||||
return ERANGE;
|
|
||||||
@@ -348,8 +353,8 @@ krb5_pac_parse(krb5_context context,
|
|
||||||
krb5_pac_free(context, pac);
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
- if (buffer->Offset < header_len ||
|
|
||||||
- buffer->Offset + buffer->cbBufferSize > len) {
|
|
||||||
+ if (buffer->Offset < header_len || buffer->Offset > len ||
|
|
||||||
+ buffer->cbBufferSize > len - buffer->Offset) {
|
|
||||||
krb5_pac_free(context, pac);
|
|
||||||
return ERANGE;
|
|
||||||
}
|
|
||||||
diff --git a/src/lib/krb5/krb/t_pac.c b/src/lib/krb5/krb/t_pac.c
|
|
||||||
index ee47152ee4..ccd165380d 100644
|
|
||||||
--- a/src/lib/krb5/krb/t_pac.c
|
|
||||||
+++ b/src/lib/krb5/krb/t_pac.c
|
|
||||||
@@ -431,6 +431,16 @@ static const unsigned char s4u_pac_ent_xrealm[] = {
|
|
||||||
0x8a, 0x81, 0x9c, 0x9c, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
+static const unsigned char fuzz1[] = {
|
|
||||||
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
+ 0x06, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf5
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const unsigned char fuzz2[] = {
|
|
||||||
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
+ 0x20, 0x20
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static const char *s4u_principal = "w2k8u@ACME.COM";
|
|
||||||
static const char *s4u_enterprise = "w2k8u@abc@ACME.COM";
|
|
||||||
|
|
||||||
@@ -646,6 +656,14 @@ main(int argc, char **argv)
|
|
||||||
krb5_free_principal(context, sep);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* Check problematic PACs found by fuzzing. */
|
|
||||||
+ ret = krb5_pac_parse(context, fuzz1, sizeof(fuzz1), &pac);
|
|
||||||
+ if (!ret)
|
|
||||||
+ err(context, ret, "krb5_pac_parse should have failed");
|
|
||||||
+ ret = krb5_pac_parse(context, fuzz2, sizeof(fuzz2), &pac);
|
|
||||||
+ if (!ret)
|
|
||||||
+ err(context, ret, "krb5_pac_parse should have failed");
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Test empty free
|
|
||||||
*/
|
|
||||||
--
|
|
||||||
2.37.3
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
|||||||
From 51938a8b731740299fe47d132b8840edba4141bc Mon Sep 17 00:00:00 2001
|
|
||||||
From: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
Date: Sat, 29 May 2021 12:05:49 -0400
|
|
||||||
Subject: [PATCH] Fix k5tls module for OpenSSL 3
|
|
||||||
|
|
||||||
Starting in OpenSSL 3, connection termination without a close_notify
|
|
||||||
alert causes SSL_read() to return SSL_ERROR_SSL instead of
|
|
||||||
SSL_ERROR_SYSCALL. OpenSSL 3 also provides a new option
|
|
||||||
SSL_OP_IGNORE_UNEXPECTED_EOF which allows an application to explicitly
|
|
||||||
ignore possible truncation attacks and receive SSL_ERROR_ZERO_RETURN
|
|
||||||
instead.
|
|
||||||
|
|
||||||
Remove the call to SSL_CTX_get_options() since SSL_CTX_set_options()
|
|
||||||
doesn't clear existing options.
|
|
||||||
|
|
||||||
[ghudson@mit.edu: edited commit message and comment]
|
|
||||||
|
|
||||||
(cherry picked from commit aa9b4a2a64046afd2fab7cb49c346295874a5fb6)
|
|
||||||
(cherry picked from commit 201e38845e9f70234bcaa9ba7c25b28e38169b0a)
|
|
||||||
---
|
|
||||||
src/plugins/tls/k5tls/openssl.c | 17 ++++++++++++++---
|
|
||||||
1 file changed, 14 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/plugins/tls/k5tls/openssl.c b/src/plugins/tls/k5tls/openssl.c
|
|
||||||
index 76a43b3cd..99fda7ffc 100644
|
|
||||||
--- a/src/plugins/tls/k5tls/openssl.c
|
|
||||||
+++ b/src/plugins/tls/k5tls/openssl.c
|
|
||||||
@@ -433,7 +433,7 @@ setup(krb5_context context, SOCKET fd, const char *servername,
|
|
||||||
char **anchors, k5_tls_handle *handle_out)
|
|
||||||
{
|
|
||||||
int e;
|
|
||||||
- long options;
|
|
||||||
+ long options = SSL_OP_NO_SSLv2;
|
|
||||||
SSL_CTX *ctx = NULL;
|
|
||||||
SSL *ssl = NULL;
|
|
||||||
k5_tls_handle handle = NULL;
|
|
||||||
@@ -448,8 +448,19 @@ setup(krb5_context context, SOCKET fd, const char *servername,
|
|
||||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
|
||||||
if (ctx == NULL)
|
|
||||||
goto error;
|
|
||||||
- options = SSL_CTX_get_options(ctx);
|
|
||||||
- SSL_CTX_set_options(ctx, options | SSL_OP_NO_SSLv2);
|
|
||||||
+
|
|
||||||
+#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
|
|
||||||
+ /*
|
|
||||||
+ * For OpenSSL 3 and later, mark close_notify alerts as optional. We don't
|
|
||||||
+ * need to worry about truncation attacks because the protocols this module
|
|
||||||
+ * is used with (Kerberos and change-password) receive a single
|
|
||||||
+ * length-delimited message from the server. For prior versions of OpenSSL
|
|
||||||
+ * we check for SSL_ERROR_SYSCALL when reading instead (this error changes
|
|
||||||
+ * to SSL_ERROR_SSL in OpenSSL 3).
|
|
||||||
+ */
|
|
||||||
+ options |= SSL_OP_IGNORE_UNEXPECTED_EOF;
|
|
||||||
+#endif
|
|
||||||
+ SSL_CTX_set_options(ctx, options);
|
|
||||||
|
|
||||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);
|
|
||||||
X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), 0);
|
|
@ -1,65 +0,0 @@
|
|||||||
From ddbd548562d951d327a10c9dcb975418427f6fea Mon Sep 17 00:00:00 2001
|
|
||||||
From: Greg Hudson <ghudson@mit.edu>
|
|
||||||
Date: Mon, 7 Jun 2021 15:00:41 -0400
|
|
||||||
Subject: [PATCH] Fix kadmin -k with fallback or referral realm
|
|
||||||
|
|
||||||
kadmin -k produces a client principal name with
|
|
||||||
krb5_sname_to_principal(), but it gets converted to a string and back
|
|
||||||
due to the signature of kadm5_init_with_skey(), which loses track of
|
|
||||||
the name type, so no canonicalization is performed.
|
|
||||||
|
|
||||||
In libkadm5clnt initialization, recognize the important subset of this
|
|
||||||
case--an empty realm indicates either fallback processing or the
|
|
||||||
referral realm--and restore the host-based name type so that the
|
|
||||||
client principal can be canonicalized against the keytab.
|
|
||||||
|
|
||||||
ticket: 9013 (new)
|
|
||||||
(cherry picked from commit dcb79089276624d7ddf44e08d35bd6d7d7e557d2)
|
|
||||||
(cherry picked from commit cd8ff035f5b4720a8fc457355726f7bd0eab5eaa)
|
|
||||||
---
|
|
||||||
src/lib/kadm5/clnt/client_init.c | 7 +++++++
|
|
||||||
src/tests/t_kadmin.py | 12 ++++++++++++
|
|
||||||
2 files changed, 19 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c
|
|
||||||
index aa1223bb3..0aaca701f 100644
|
|
||||||
--- a/src/lib/kadm5/clnt/client_init.c
|
|
||||||
+++ b/src/lib/kadm5/clnt/client_init.c
|
|
||||||
@@ -221,9 +221,16 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
|
||||||
return KADM5_MISSING_KRB5_CONF_PARAMS;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * Parse the client name. If it has an empty realm, it is almost certainly
|
|
||||||
+ * a host-based principal using DNS fallback processing or the referral
|
|
||||||
+ * realm, so give it the appropriate name type for canonicalization.
|
|
||||||
+ */
|
|
||||||
code = krb5_parse_name(handle->context, client_name, &client);
|
|
||||||
if (code)
|
|
||||||
goto error;
|
|
||||||
+ if (init_type == INIT_SKEY && client->realm.length == 0)
|
|
||||||
+ client->type = KRB5_NT_SRV_HST;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get credentials. Also does some fallbacks in case kadmin/fqdn
|
|
||||||
diff --git a/src/tests/t_kadmin.py b/src/tests/t_kadmin.py
|
|
||||||
index fe6a3cc2e..98453d92e 100644
|
|
||||||
--- a/src/tests/t_kadmin.py
|
|
||||||
+++ b/src/tests/t_kadmin.py
|
|
||||||
@@ -51,4 +51,16 @@ for i in range(200):
|
|
||||||
realm.run_kadmin(['addprinc', '-randkey', 'foo%d' % i])
|
|
||||||
realm.run_kadmin(['listprincs'], expected_msg='foo199')
|
|
||||||
|
|
||||||
+# Test kadmin -k with the default principal, with and without
|
|
||||||
+# fallback. This operation requires canonicalization against the
|
|
||||||
+# keytab in krb5_get_init_creds_keytab() as the
|
|
||||||
+# krb5_sname_to_principal() result won't have a realm. Try with and
|
|
||||||
+# without without fallback processing since the code paths are
|
|
||||||
+# different.
|
|
||||||
+mark('kadmin -k')
|
|
||||||
+realm.run([kadmin, '-k', 'getprinc', realm.host_princ])
|
|
||||||
+no_canon_conf = {'libdefaults': {'dns_canonicalize_hostname': 'false'}}
|
|
||||||
+no_canon = realm.special_env('no_canon', False, krb5_conf=no_canon_conf)
|
|
||||||
+realm.run([kadmin, '-k', 'getprinc', realm.host_princ], env=no_canon)
|
|
||||||
+
|
|
||||||
success('kadmin and kpasswd tests')
|
|
@ -1,552 +0,0 @@
|
|||||||
From f85a818fe1a7438db7e1ea579818da67e0be017d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
Date: Sat, 15 May 2021 17:35:25 -0400
|
|
||||||
Subject: [PATCH] Fix softpkcs11 build issues with openssl 3.0
|
|
||||||
|
|
||||||
EVP_PKEY_get0_RSA() has been modified to have const return type. Remove
|
|
||||||
its usages in favor of the EVP_PKEY interface. Also remove calls to
|
|
||||||
RSA_blinding_off(), which we don't need and would require a non-const
|
|
||||||
object. Similarly, remove RSA_set_method() calls that set a pre-existing
|
|
||||||
default.
|
|
||||||
|
|
||||||
Since softpkcs11 doesn't link against krb5 and can't use zap(), allocate
|
|
||||||
buffers with OPENSSL_malloc() so can use OPENSSL_clear_free().
|
|
||||||
|
|
||||||
Move several argument validation checks to the top of their functions.
|
|
||||||
|
|
||||||
Fix some incorrect/inconsistent log messages.
|
|
||||||
|
|
||||||
(cherry picked from commit 00de1aad7b3647b91017c7009b0bc65cd0c8b2e0)
|
|
||||||
(cherry picked from commit a86b780ef275b35e8dc1e6d1886ec8e8d941f7c4)
|
|
||||||
---
|
|
||||||
src/tests/softpkcs11/main.c | 360 ++++++++++++++----------------------
|
|
||||||
1 file changed, 141 insertions(+), 219 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c
|
|
||||||
index 1cccdfb43..caa537b68 100644
|
|
||||||
--- a/src/tests/softpkcs11/main.c
|
|
||||||
+++ b/src/tests/softpkcs11/main.c
|
|
||||||
@@ -375,10 +375,9 @@ add_st_object(void)
|
|
||||||
return NULL;
|
|
||||||
soft_token.object.objs = objs;
|
|
||||||
|
|
||||||
- o = malloc(sizeof(*o));
|
|
||||||
+ o = calloc(1, sizeof(*o));
|
|
||||||
if (o == NULL)
|
|
||||||
return NULL;
|
|
||||||
- memset(o, 0, sizeof(*o));
|
|
||||||
o->attrs = NULL;
|
|
||||||
o->num_attributes = 0;
|
|
||||||
o->object_handle = soft_token.object.num_objs;
|
|
||||||
@@ -424,7 +423,7 @@ add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
|
|
||||||
CK_ULONG modulus_bits = 0;
|
|
||||||
CK_BYTE *exponent = NULL;
|
|
||||||
size_t exponent_len = 0;
|
|
||||||
- RSA *rsa;
|
|
||||||
+ const RSA *rsa;
|
|
||||||
const BIGNUM *n, *e;
|
|
||||||
|
|
||||||
rsa = EVP_PKEY_get0_RSA(key);
|
|
||||||
@@ -445,8 +444,6 @@ add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
|
|
||||||
add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT,
|
|
||||||
exponent, exponent_len);
|
|
||||||
|
|
||||||
- RSA_set_method(rsa, RSA_PKCS1_OpenSSL());
|
|
||||||
-
|
|
||||||
free(modulus);
|
|
||||||
free(exponent);
|
|
||||||
}
|
|
||||||
@@ -679,10 +676,6 @@ add_certificate(char *label,
|
|
||||||
} else {
|
|
||||||
/* XXX verify keytype */
|
|
||||||
|
|
||||||
- if (key_type == CKK_RSA)
|
|
||||||
- RSA_set_method(EVP_PKEY_get0_RSA(o->u.private_key.key),
|
|
||||||
- RSA_PKCS1_OpenSSL());
|
|
||||||
-
|
|
||||||
if (X509_check_private_key(cert, o->u.private_key.key) != 1) {
|
|
||||||
EVP_PKEY_free(o->u.private_key.key);
|
|
||||||
o->u.private_key.key = NULL;
|
|
||||||
@@ -695,7 +688,7 @@ add_certificate(char *label,
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = CKR_OK;
|
|
||||||
- out:
|
|
||||||
+out:
|
|
||||||
if (ret != CKR_OK) {
|
|
||||||
st_logf("something went wrong when adding cert!\n");
|
|
||||||
|
|
||||||
@@ -1224,8 +1217,6 @@ C_Login(CK_SESSION_HANDLE hSession,
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX check keytype */
|
|
||||||
- RSA_set_method(EVP_PKEY_get0_RSA(o->u.private_key.key),
|
|
||||||
- RSA_PKCS1_OpenSSL());
|
|
||||||
|
|
||||||
if (X509_check_private_key(o->u.private_key.cert, o->u.private_key.key) != 1) {
|
|
||||||
EVP_PKEY_free(o->u.private_key.key);
|
|
||||||
@@ -1495,8 +1486,9 @@ C_Encrypt(CK_SESSION_HANDLE hSession,
|
|
||||||
struct st_object *o;
|
|
||||||
void *buffer = NULL;
|
|
||||||
CK_RV ret;
|
|
||||||
- RSA *rsa;
|
|
||||||
- int padding, len, buffer_len, padding_len;
|
|
||||||
+ size_t buffer_len = 0;
|
|
||||||
+ int padding;
|
|
||||||
+ EVP_PKEY_CTX *ctx = NULL;
|
|
||||||
|
|
||||||
st_logf("Encrypt\n");
|
|
||||||
|
|
||||||
@@ -1512,70 +1504,58 @@ C_Encrypt(CK_SESSION_HANDLE hSession,
|
|
||||||
return CKR_ARGUMENTS_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
- rsa = EVP_PKEY_get0_RSA(o->u.public_key);
|
|
||||||
-
|
|
||||||
- if (rsa == NULL)
|
|
||||||
- return CKR_ARGUMENTS_BAD;
|
|
||||||
-
|
|
||||||
- RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
|
|
||||||
-
|
|
||||||
- buffer_len = RSA_size(rsa);
|
|
||||||
-
|
|
||||||
- buffer = malloc(buffer_len);
|
|
||||||
- if (buffer == NULL) {
|
|
||||||
- ret = CKR_DEVICE_MEMORY;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ret = CKR_OK;
|
|
||||||
- switch(state->encrypt_mechanism->mechanism) {
|
|
||||||
- case CKM_RSA_PKCS:
|
|
||||||
- padding = RSA_PKCS1_PADDING;
|
|
||||||
- padding_len = RSA_PKCS1_PADDING_SIZE;
|
|
||||||
- break;
|
|
||||||
- case CKM_RSA_X_509:
|
|
||||||
- padding = RSA_NO_PADDING;
|
|
||||||
- padding_len = 0;
|
|
||||||
- break;
|
|
||||||
- default:
|
|
||||||
- ret = CKR_FUNCTION_NOT_SUPPORTED;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if ((CK_ULONG)buffer_len + padding_len < ulDataLen) {
|
|
||||||
- ret = CKR_ARGUMENTS_BAD;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
if (pulEncryptedDataLen == NULL) {
|
|
||||||
st_logf("pulEncryptedDataLen NULL\n");
|
|
||||||
ret = CKR_ARGUMENTS_BAD;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (pData == NULL_PTR) {
|
|
||||||
+ if (pData == NULL) {
|
|
||||||
st_logf("data NULL\n");
|
|
||||||
ret = CKR_ARGUMENTS_BAD;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
- len = RSA_public_encrypt(ulDataLen, pData, buffer, rsa, padding);
|
|
||||||
- if (len <= 0) {
|
|
||||||
+ switch(state->encrypt_mechanism->mechanism) {
|
|
||||||
+ case CKM_RSA_PKCS:
|
|
||||||
+ padding = RSA_PKCS1_PADDING;
|
|
||||||
+ break;
|
|
||||||
+ case CKM_RSA_X_509:
|
|
||||||
+ padding = RSA_NO_PADDING;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ ret = CKR_FUNCTION_NOT_SUPPORTED;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ctx = EVP_PKEY_CTX_new(o->u.public_key, NULL);
|
|
||||||
+ if (ctx == NULL || EVP_PKEY_encrypt_init(ctx) <= 0 ||
|
|
||||||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
|
|
||||||
+ EVP_PKEY_encrypt(ctx, NULL, &buffer_len, pData, ulDataLen) <= 0) {
|
|
||||||
ret = CKR_DEVICE_ERROR;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
- if (len > buffer_len)
|
|
||||||
- abort();
|
|
||||||
|
|
||||||
- if (pEncryptedData != NULL_PTR)
|
|
||||||
- memcpy(pEncryptedData, buffer, len);
|
|
||||||
- *pulEncryptedDataLen = len;
|
|
||||||
-
|
|
||||||
- out:
|
|
||||||
- if (buffer) {
|
|
||||||
- memset(buffer, 0, buffer_len);
|
|
||||||
- free(buffer);
|
|
||||||
+ buffer = OPENSSL_malloc(buffer_len);
|
|
||||||
+ if (buffer == NULL) {
|
|
||||||
+ ret = CKR_DEVICE_MEMORY;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ if (EVP_PKEY_encrypt(ctx, buffer, &buffer_len, pData, ulDataLen) <= 0) {
|
|
||||||
+ ret = CKR_DEVICE_ERROR;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+ st_logf("Encrypt done\n");
|
|
||||||
+
|
|
||||||
+ if (pEncryptedData != NULL)
|
|
||||||
+ memcpy(pEncryptedData, buffer, buffer_len);
|
|
||||||
+ *pulEncryptedDataLen = buffer_len;
|
|
||||||
+
|
|
||||||
+ ret = CKR_OK;
|
|
||||||
+out:
|
|
||||||
+ OPENSSL_clear_free(buffer, buffer_len);
|
|
||||||
+ EVP_PKEY_CTX_free(ctx);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1646,8 +1626,9 @@ C_Decrypt(CK_SESSION_HANDLE hSession,
|
|
||||||
struct st_object *o;
|
|
||||||
void *buffer = NULL;
|
|
||||||
CK_RV ret;
|
|
||||||
- RSA *rsa;
|
|
||||||
- int padding, len, buffer_len, padding_len;
|
|
||||||
+ size_t buffer_len = 0;
|
|
||||||
+ int padding;
|
|
||||||
+ EVP_PKEY_CTX *ctx = NULL;
|
|
||||||
|
|
||||||
st_logf("Decrypt\n");
|
|
||||||
|
|
||||||
@@ -1663,41 +1644,6 @@ C_Decrypt(CK_SESSION_HANDLE hSession,
|
|
||||||
return CKR_ARGUMENTS_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
- rsa = EVP_PKEY_get0_RSA(o->u.private_key.key);
|
|
||||||
-
|
|
||||||
- if (rsa == NULL)
|
|
||||||
- return CKR_ARGUMENTS_BAD;
|
|
||||||
-
|
|
||||||
- RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
|
|
||||||
-
|
|
||||||
- buffer_len = RSA_size(rsa);
|
|
||||||
-
|
|
||||||
- buffer = malloc(buffer_len);
|
|
||||||
- if (buffer == NULL) {
|
|
||||||
- ret = CKR_DEVICE_MEMORY;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ret = CKR_OK;
|
|
||||||
- switch(state->decrypt_mechanism->mechanism) {
|
|
||||||
- case CKM_RSA_PKCS:
|
|
||||||
- padding = RSA_PKCS1_PADDING;
|
|
||||||
- padding_len = RSA_PKCS1_PADDING_SIZE;
|
|
||||||
- break;
|
|
||||||
- case CKM_RSA_X_509:
|
|
||||||
- padding = RSA_NO_PADDING;
|
|
||||||
- padding_len = 0;
|
|
||||||
- break;
|
|
||||||
- default:
|
|
||||||
- ret = CKR_FUNCTION_NOT_SUPPORTED;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if ((CK_ULONG)buffer_len + padding_len < ulEncryptedDataLen) {
|
|
||||||
- ret = CKR_ARGUMENTS_BAD;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
if (pulDataLen == NULL) {
|
|
||||||
st_logf("pulDataLen NULL\n");
|
|
||||||
ret = CKR_ARGUMENTS_BAD;
|
|
||||||
@@ -1710,24 +1656,48 @@ C_Decrypt(CK_SESSION_HANDLE hSession,
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
- len = RSA_private_decrypt(ulEncryptedDataLen, pEncryptedData, buffer,
|
|
||||||
- rsa, padding);
|
|
||||||
- if (len <= 0) {
|
|
||||||
+ switch(state->decrypt_mechanism->mechanism) {
|
|
||||||
+ case CKM_RSA_PKCS:
|
|
||||||
+ padding = RSA_PKCS1_PADDING;
|
|
||||||
+ break;
|
|
||||||
+ case CKM_RSA_X_509:
|
|
||||||
+ padding = RSA_NO_PADDING;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ ret = CKR_FUNCTION_NOT_SUPPORTED;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ctx = EVP_PKEY_CTX_new(o->u.private_key.key, NULL);
|
|
||||||
+ if (ctx == NULL || EVP_PKEY_decrypt_init(ctx) <= 0 ||
|
|
||||||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
|
|
||||||
+ EVP_PKEY_decrypt(ctx, NULL, &buffer_len, pEncryptedData,
|
|
||||||
+ ulEncryptedDataLen) <= 0) {
|
|
||||||
ret = CKR_DEVICE_ERROR;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
- if (len > buffer_len)
|
|
||||||
- abort();
|
|
||||||
+
|
|
||||||
+ buffer = OPENSSL_malloc(buffer_len);
|
|
||||||
+ if (buffer == NULL) {
|
|
||||||
+ ret = CKR_DEVICE_MEMORY;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (EVP_PKEY_decrypt(ctx, buffer, &buffer_len, pEncryptedData,
|
|
||||||
+ ulEncryptedDataLen) <= 0) {
|
|
||||||
+ ret = CKR_DEVICE_ERROR;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+ st_logf("Decrypt done\n");
|
|
||||||
|
|
||||||
if (pData != NULL_PTR)
|
|
||||||
- memcpy(pData, buffer, len);
|
|
||||||
- *pulDataLen = len;
|
|
||||||
+ memcpy(pData, buffer, buffer_len);
|
|
||||||
+ *pulDataLen = buffer_len;
|
|
||||||
|
|
||||||
- out:
|
|
||||||
- if (buffer) {
|
|
||||||
- memset(buffer, 0, buffer_len);
|
|
||||||
- free(buffer);
|
|
||||||
- }
|
|
||||||
+ ret = CKR_OK;
|
|
||||||
+out:
|
|
||||||
+ OPENSSL_clear_free(buffer, buffer_len);
|
|
||||||
+ EVP_PKEY_CTX_free(ctx);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1806,8 +1776,9 @@ C_Sign(CK_SESSION_HANDLE hSession,
|
|
||||||
struct st_object *o;
|
|
||||||
void *buffer = NULL;
|
|
||||||
CK_RV ret;
|
|
||||||
- RSA *rsa;
|
|
||||||
- int padding, len, buffer_len, padding_len;
|
|
||||||
+ int padding;
|
|
||||||
+ size_t buffer_len = 0;
|
|
||||||
+ EVP_PKEY_CTX *ctx = NULL;
|
|
||||||
|
|
||||||
st_logf("Sign\n");
|
|
||||||
VERIFY_SESSION_HANDLE(hSession, &state);
|
|
||||||
@@ -1822,40 +1793,6 @@ C_Sign(CK_SESSION_HANDLE hSession,
|
|
||||||
return CKR_ARGUMENTS_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
- rsa = EVP_PKEY_get0_RSA(o->u.private_key.key);
|
|
||||||
-
|
|
||||||
- if (rsa == NULL)
|
|
||||||
- return CKR_ARGUMENTS_BAD;
|
|
||||||
-
|
|
||||||
- RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
|
|
||||||
-
|
|
||||||
- buffer_len = RSA_size(rsa);
|
|
||||||
-
|
|
||||||
- buffer = malloc(buffer_len);
|
|
||||||
- if (buffer == NULL) {
|
|
||||||
- ret = CKR_DEVICE_MEMORY;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- switch(state->sign_mechanism->mechanism) {
|
|
||||||
- case CKM_RSA_PKCS:
|
|
||||||
- padding = RSA_PKCS1_PADDING;
|
|
||||||
- padding_len = RSA_PKCS1_PADDING_SIZE;
|
|
||||||
- break;
|
|
||||||
- case CKM_RSA_X_509:
|
|
||||||
- padding = RSA_NO_PADDING;
|
|
||||||
- padding_len = 0;
|
|
||||||
- break;
|
|
||||||
- default:
|
|
||||||
- ret = CKR_FUNCTION_NOT_SUPPORTED;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if ((CK_ULONG)buffer_len < ulDataLen + padding_len) {
|
|
||||||
- ret = CKR_ARGUMENTS_BAD;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
if (pulSignatureLen == NULL) {
|
|
||||||
st_logf("signature len NULL\n");
|
|
||||||
ret = CKR_ARGUMENTS_BAD;
|
|
||||||
@@ -1868,26 +1805,46 @@ C_Sign(CK_SESSION_HANDLE hSession,
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
- len = RSA_private_encrypt(ulDataLen, pData, buffer, rsa, padding);
|
|
||||||
- st_logf("private encrypt done\n");
|
|
||||||
- if (len <= 0) {
|
|
||||||
+ switch(state->sign_mechanism->mechanism) {
|
|
||||||
+ case CKM_RSA_PKCS:
|
|
||||||
+ padding = RSA_PKCS1_PADDING;
|
|
||||||
+ break;
|
|
||||||
+ case CKM_RSA_X_509:
|
|
||||||
+ padding = RSA_NO_PADDING;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ ret = CKR_FUNCTION_NOT_SUPPORTED;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ctx = EVP_PKEY_CTX_new(o->u.private_key.key, NULL);
|
|
||||||
+ if (ctx == NULL || EVP_PKEY_sign_init(ctx) <= 0 ||
|
|
||||||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
|
|
||||||
+ EVP_PKEY_sign(ctx, NULL, &buffer_len, pData, ulDataLen) <= 0) {
|
|
||||||
ret = CKR_DEVICE_ERROR;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
- if (len > buffer_len)
|
|
||||||
- abort();
|
|
||||||
|
|
||||||
- if (pSignature != NULL_PTR)
|
|
||||||
- memcpy(pSignature, buffer, len);
|
|
||||||
- *pulSignatureLen = len;
|
|
||||||
+ buffer = OPENSSL_malloc(buffer_len);
|
|
||||||
+ if (buffer == NULL) {
|
|
||||||
+ ret = CKR_DEVICE_MEMORY;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (EVP_PKEY_sign(ctx, buffer, &buffer_len, pData, ulDataLen) <= 0) {
|
|
||||||
+ ret = CKR_DEVICE_ERROR;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+ st_logf("Sign done\n");
|
|
||||||
+
|
|
||||||
+ if (pSignature != NULL)
|
|
||||||
+ memcpy(pSignature, buffer, buffer_len);
|
|
||||||
+ *pulSignatureLen = buffer_len;
|
|
||||||
|
|
||||||
ret = CKR_OK;
|
|
||||||
-
|
|
||||||
- out:
|
|
||||||
- if (buffer) {
|
|
||||||
- memset(buffer, 0, buffer_len);
|
|
||||||
- free(buffer);
|
|
||||||
- }
|
|
||||||
+out:
|
|
||||||
+ OPENSSL_clear_free(buffer, buffer_len);
|
|
||||||
+ EVP_PKEY_CTX_free(ctx);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1951,10 +1908,9 @@ C_Verify(CK_SESSION_HANDLE hSession,
|
|
||||||
{
|
|
||||||
struct session_state *state;
|
|
||||||
struct st_object *o;
|
|
||||||
- void *buffer = NULL;
|
|
||||||
CK_RV ret;
|
|
||||||
- RSA *rsa;
|
|
||||||
- int padding, len, buffer_len;
|
|
||||||
+ int padding;
|
|
||||||
+ EVP_PKEY_CTX *ctx = NULL;
|
|
||||||
|
|
||||||
st_logf("Verify\n");
|
|
||||||
VERIFY_SESSION_HANDLE(hSession, &state);
|
|
||||||
@@ -1969,39 +1925,6 @@ C_Verify(CK_SESSION_HANDLE hSession,
|
|
||||||
return CKR_ARGUMENTS_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
- rsa = EVP_PKEY_get0_RSA(o->u.public_key);
|
|
||||||
-
|
|
||||||
- if (rsa == NULL)
|
|
||||||
- return CKR_ARGUMENTS_BAD;
|
|
||||||
-
|
|
||||||
- RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
|
|
||||||
-
|
|
||||||
- buffer_len = RSA_size(rsa);
|
|
||||||
-
|
|
||||||
- buffer = malloc(buffer_len);
|
|
||||||
- if (buffer == NULL) {
|
|
||||||
- ret = CKR_DEVICE_MEMORY;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ret = CKR_OK;
|
|
||||||
- switch(state->verify_mechanism->mechanism) {
|
|
||||||
- case CKM_RSA_PKCS:
|
|
||||||
- padding = RSA_PKCS1_PADDING;
|
|
||||||
- break;
|
|
||||||
- case CKM_RSA_X_509:
|
|
||||||
- padding = RSA_NO_PADDING;
|
|
||||||
- break;
|
|
||||||
- default:
|
|
||||||
- ret = CKR_FUNCTION_NOT_SUPPORTED;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if ((CK_ULONG)buffer_len < ulDataLen) {
|
|
||||||
- ret = CKR_ARGUMENTS_BAD;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
if (pSignature == NULL) {
|
|
||||||
st_logf("signature NULL\n");
|
|
||||||
ret = CKR_ARGUMENTS_BAD;
|
|
||||||
@@ -2014,34 +1937,34 @@ C_Verify(CK_SESSION_HANDLE hSession,
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
- len = RSA_public_decrypt(ulDataLen, pData, buffer, rsa, padding);
|
|
||||||
- st_logf("private encrypt done\n");
|
|
||||||
- if (len <= 0) {
|
|
||||||
+ switch(state->verify_mechanism->mechanism) {
|
|
||||||
+ case CKM_RSA_PKCS:
|
|
||||||
+ padding = RSA_PKCS1_PADDING;
|
|
||||||
+ break;
|
|
||||||
+ case CKM_RSA_X_509:
|
|
||||||
+ padding = RSA_NO_PADDING;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ ret = CKR_FUNCTION_NOT_SUPPORTED;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ctx = EVP_PKEY_CTX_new(o->u.public_key, NULL);
|
|
||||||
+ if (ctx == NULL || EVP_PKEY_verify_init(ctx) <= 0 ||
|
|
||||||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
|
|
||||||
+ EVP_PKEY_verify(ctx, pSignature, ulSignatureLen, pData,
|
|
||||||
+ ulDataLen) <= 0) {
|
|
||||||
ret = CKR_DEVICE_ERROR;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
- if (len > buffer_len)
|
|
||||||
- abort();
|
|
||||||
+ st_logf("Verify done\n");
|
|
||||||
|
|
||||||
- if ((CK_ULONG)len != ulSignatureLen) {
|
|
||||||
- ret = CKR_GENERAL_ERROR;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (memcmp(pSignature, buffer, len) != 0) {
|
|
||||||
- ret = CKR_GENERAL_ERROR;
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- out:
|
|
||||||
- if (buffer) {
|
|
||||||
- memset(buffer, 0, buffer_len);
|
|
||||||
- free(buffer);
|
|
||||||
- }
|
|
||||||
+ ret = CKR_OK;
|
|
||||||
+out:
|
|
||||||
+ EVP_PKEY_CTX_free(ctx);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
-
|
|
||||||
CK_RV
|
|
||||||
C_VerifyUpdate(CK_SESSION_HANDLE hSession,
|
|
||||||
CK_BYTE_PTR pPart,
|
|
||||||
@@ -2072,7 +1995,6 @@ C_GenerateRandom(CK_SESSION_HANDLE hSession,
|
|
||||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
-
|
|
||||||
CK_FUNCTION_LIST funcs = {
|
|
||||||
{ 2, 11 },
|
|
||||||
C_Initialize,
|
|
@ -1,97 +0,0 @@
|
|||||||
From 8f70ad82a645ccb7fb1677d260baa5e4112890d4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Greg Hudson <ghudson@mit.edu>
|
|
||||||
Date: Mon, 7 Jun 2021 13:27:29 -0400
|
|
||||||
Subject: [PATCH] Fix some principal realm canonicalization cases
|
|
||||||
|
|
||||||
The no_hostrealm and subst_defrealm flags in struct canonprinc were
|
|
||||||
only applied when dns_canonicalize_hostname=fallback; in the other
|
|
||||||
cases, the initial krb5_sname_to_principal() result is treated as
|
|
||||||
canonical. For no_hostrealm this limitation doesn't currently matter,
|
|
||||||
because all uses pass a principal with no realm as input. However,
|
|
||||||
subst_defrealm is used to convert the referral realm to the default
|
|
||||||
realm in krb5_get_init_creds_keytab(), krb5_cc_cache_match(), and
|
|
||||||
gss_acquire_cred() when it needs to check the desired name against a
|
|
||||||
specified ccache.
|
|
||||||
|
|
||||||
In k5_canonprinc(), if the input principal is a
|
|
||||||
krb5_sname_to_principal() result and fallback isn't in effect, apply
|
|
||||||
subst_defrealm. Document in os-proto.h that no_hostrealm doesn't
|
|
||||||
remove an existing realm and that krb5_sname_to_principal() may
|
|
||||||
already have looked one up.
|
|
||||||
|
|
||||||
ticket: 9011 (new)
|
|
||||||
(cherry picked from commit c077d0c6430c4ac163443aacc03d14d206a4cbb8)
|
|
||||||
(cherry picked from commit 5ae9bc98f23aeaa2ce17debe5a9b0cf1130e54ed)
|
|
||||||
---
|
|
||||||
src/lib/krb5/os/os-proto.h | 13 +++++++++----
|
|
||||||
src/lib/krb5/os/sn2princ.c | 24 +++++++++++++++++++++---
|
|
||||||
2 files changed, 30 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
|
|
||||||
index 7d5e7978f..a985f2aec 100644
|
|
||||||
--- a/src/lib/krb5/os/os-proto.h
|
|
||||||
+++ b/src/lib/krb5/os/os-proto.h
|
|
||||||
@@ -85,10 +85,15 @@ struct sendto_callback_info {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize with all zeros except for princ. Set no_hostrealm to disable
|
|
||||||
- * host-to-realm lookup, which ordinarily happens after canonicalizing the host
|
|
||||||
- * part. Set subst_defrealm to substitute the default realm for the referral
|
|
||||||
- * realm after realm lookup (this has no effect if no_hostrealm is set). Free
|
|
||||||
- * with free_canonprinc() when done.
|
|
||||||
+ * host-to-realm lookup, which ordinarily happens during fallback processing
|
|
||||||
+ * after canonicalizing the host part. Set subst_defrealm to substitute the
|
|
||||||
+ * default realm for the referral realm after realm lookup. Do not set both
|
|
||||||
+ * flags. Free with free_canonprinc() when done.
|
|
||||||
+ *
|
|
||||||
+ * no_hostrealm only applies if fallback processing is in use
|
|
||||||
+ * (dns_canonicalize_hostname = fallback). It will not remove the realm if
|
|
||||||
+ * krb5_sname_to_principal() already canonicalized the hostname and looked up a
|
|
||||||
+ * realm. subst_defrealm applies whether or not fallback processing is in use.
|
|
||||||
*/
|
|
||||||
struct canonprinc {
|
|
||||||
krb5_const_principal princ;
|
|
||||||
diff --git a/src/lib/krb5/os/sn2princ.c b/src/lib/krb5/os/sn2princ.c
|
|
||||||
index c99b7da17..93c155932 100644
|
|
||||||
--- a/src/lib/krb5/os/sn2princ.c
|
|
||||||
+++ b/src/lib/krb5/os/sn2princ.c
|
|
||||||
@@ -271,18 +271,36 @@ krb5_error_code
|
|
||||||
k5_canonprinc(krb5_context context, struct canonprinc *iter,
|
|
||||||
krb5_const_principal *princ_out)
|
|
||||||
{
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
int step = ++iter->step;
|
|
||||||
|
|
||||||
*princ_out = NULL;
|
|
||||||
|
|
||||||
- /* If we're not doing fallback, the input principal is canonical. */
|
|
||||||
- if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK ||
|
|
||||||
- iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2 ||
|
|
||||||
+ /* If the hostname isn't from krb5_sname_to_principal(), the input
|
|
||||||
+ * principal is canonical. */
|
|
||||||
+ if (iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2 ||
|
|
||||||
iter->princ->data[1].length == 0) {
|
|
||||||
*princ_out = (step == 1) ? iter->princ : NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* If we're not doing fallback, the hostname is canonical, but we may need
|
|
||||||
+ * to substitute the default realm. */
|
|
||||||
+ if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK) {
|
|
||||||
+ if (step > 1)
|
|
||||||
+ return 0;
|
|
||||||
+ iter->copy = *iter->princ;
|
|
||||||
+ if (iter->subst_defrealm && iter->copy.realm.length == 0) {
|
|
||||||
+ ret = krb5_get_default_realm(context, &iter->realm);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+ iter->copy = *iter->princ;
|
|
||||||
+ iter->copy.realm = string2data(iter->realm);
|
|
||||||
+ }
|
|
||||||
+ *princ_out = &iter->copy;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Canonicalize without DNS at step 1, with DNS at step 2. */
|
|
||||||
if (step > 2)
|
|
||||||
return 0;
|
|
@ -1,301 +0,0 @@
|
|||||||
From e3f3d31a3db23f6c8437cd0efe45f67a7f4fc6aa Mon Sep 17 00:00:00 2001
|
|
||||||
From: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
Date: Sat, 15 May 2021 21:18:06 -0400
|
|
||||||
Subject: [PATCH] Handle OpenSSL 3's providers
|
|
||||||
|
|
||||||
OpenSSL 3 compartmentalizes what algorithms it uses, which for us means
|
|
||||||
another hoop to jump through to use dubious cryptography. (Right now,
|
|
||||||
we need to load "legacy" in order to access MD4 and RC4.)
|
|
||||||
|
|
||||||
Use our normal initializer logic to set up providers both in the OpenSSL
|
|
||||||
provider an the PKINIT plugin. Since DT_FINI is too late, release them
|
|
||||||
using atexit() as OpenSSL does.
|
|
||||||
|
|
||||||
(cherry picked from commit bea5a703a06da1f1ab56821b77a2d3661cb0dda4)
|
|
||||||
[rharwood@redhat.com: work around des3 removal and rc4 fips changes]
|
|
||||||
---
|
|
||||||
src/configure.ac | 1 +
|
|
||||||
src/lib/crypto/openssl/enc_provider/aes.c | 16 ++++++
|
|
||||||
.../crypto/openssl/enc_provider/camellia.c | 16 ++++++
|
|
||||||
src/lib/crypto/openssl/enc_provider/rc4.c | 4 ++
|
|
||||||
.../crypto/openssl/hash_provider/hash_evp.c | 5 ++
|
|
||||||
src/lib/crypto/openssl/init.c | 53 +++++++++++++++++++
|
|
||||||
src/plugins/preauth/pkinit/Makefile.in | 1 +
|
|
||||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 33 ++++++++++--
|
|
||||||
8 files changed, 126 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/configure.ac b/src/configure.ac
|
|
||||||
index 9c2e816fe..20066918b 100644
|
|
||||||
--- a/src/configure.ac
|
|
||||||
+++ b/src/configure.ac
|
|
||||||
@@ -284,6 +284,7 @@ AC_SUBST(CRYPTO_IMPL_LIBS)
|
|
||||||
|
|
||||||
if test "$CRYPTO_IMPL" = openssl; then
|
|
||||||
AC_CHECK_FUNCS(EVP_KDF_fetch)
|
|
||||||
+ AC_CHECK_FUNCS(OSSL_PROVIDER_load)
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_ARG_WITH([prng-alg],
|
|
||||||
diff --git a/src/lib/crypto/openssl/enc_provider/aes.c b/src/lib/crypto/openssl/enc_provider/aes.c
|
|
||||||
index 6b4622fe9..31c90a69d 100644
|
|
||||||
--- a/src/lib/crypto/openssl/enc_provider/aes.c
|
|
||||||
+++ b/src/lib/crypto/openssl/enc_provider/aes.c
|
|
||||||
@@ -68,6 +68,10 @@ cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
|
||||||
EVP_CIPHER_CTX *ctx;
|
|
||||||
struct iov_cursor cursor;
|
|
||||||
|
|
||||||
+ ret = krb5int_crypto_init();
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
ctx = EVP_CIPHER_CTX_new();
|
|
||||||
if (ctx == NULL)
|
|
||||||
return ENOMEM;
|
|
||||||
@@ -102,6 +106,10 @@ cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
|
||||||
EVP_CIPHER_CTX *ctx;
|
|
||||||
struct iov_cursor cursor;
|
|
||||||
|
|
||||||
+ ret = krb5int_crypto_init();
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
ctx = EVP_CIPHER_CTX_new();
|
|
||||||
if (ctx == NULL)
|
|
||||||
return ENOMEM;
|
|
||||||
@@ -137,6 +145,10 @@ cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
|
||||||
struct iov_cursor cursor;
|
|
||||||
AES_KEY enck;
|
|
||||||
|
|
||||||
+ ret = krb5int_crypto_init();
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
memset(iv_cts,0,sizeof(iv_cts));
|
|
||||||
if (ivec && ivec->data){
|
|
||||||
if (ivec->length != sizeof(iv_cts))
|
|
||||||
@@ -190,6 +202,10 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
|
||||||
struct iov_cursor cursor;
|
|
||||||
AES_KEY deck;
|
|
||||||
|
|
||||||
+ ret = krb5int_crypto_init();
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
memset(iv_cts,0,sizeof(iv_cts));
|
|
||||||
if (ivec && ivec->data){
|
|
||||||
if (ivec->length != sizeof(iv_cts))
|
|
||||||
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
|
|
||||||
index f79679a0b..7cc7fc6fb 100644
|
|
||||||
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
|
|
||||||
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
|
|
||||||
@@ -92,6 +92,10 @@ cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
|
||||||
EVP_CIPHER_CTX *ctx;
|
|
||||||
struct iov_cursor cursor;
|
|
||||||
|
|
||||||
+ ret = krb5int_crypto_init();
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
ctx = EVP_CIPHER_CTX_new();
|
|
||||||
if (ctx == NULL)
|
|
||||||
return ENOMEM;
|
|
||||||
@@ -126,6 +130,10 @@ cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
|
||||||
EVP_CIPHER_CTX *ctx;
|
|
||||||
struct iov_cursor cursor;
|
|
||||||
|
|
||||||
+ ret = krb5int_crypto_init();
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
ctx = EVP_CIPHER_CTX_new();
|
|
||||||
if (ctx == NULL)
|
|
||||||
return ENOMEM;
|
|
||||||
@@ -161,6 +169,10 @@ cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
|
||||||
struct iov_cursor cursor;
|
|
||||||
CAMELLIA_KEY enck;
|
|
||||||
|
|
||||||
+ ret = krb5int_crypto_init();
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
memset(iv_cts,0,sizeof(iv_cts));
|
|
||||||
if (ivec && ivec->data){
|
|
||||||
if (ivec->length != sizeof(iv_cts))
|
|
||||||
@@ -214,6 +226,10 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
|
||||||
struct iov_cursor cursor;
|
|
||||||
CAMELLIA_KEY deck;
|
|
||||||
|
|
||||||
+ ret = krb5int_crypto_init();
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
memset(iv_cts,0,sizeof(iv_cts));
|
|
||||||
if (ivec && ivec->data){
|
|
||||||
if (ivec->length != sizeof(iv_cts))
|
|
||||||
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
|
|
||||||
index 9bf407899..a10cb5192 100644
|
|
||||||
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
|
|
||||||
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
|
|
||||||
@@ -66,6 +66,10 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
|
|
||||||
EVP_CIPHER_CTX *ctx = NULL;
|
|
||||||
struct arcfour_state *arcstate;
|
|
||||||
|
|
||||||
+ ret = krb5int_crypto_init();
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
if (FIPS_mode())
|
|
||||||
return KRB5_CRYPTO_INTERNAL;
|
|
||||||
|
|
||||||
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
|
||||||
index 2eb5139c0..09d7b3896 100644
|
|
||||||
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
|
||||||
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
|
||||||
@@ -41,6 +41,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
|
||||||
const krb5_data *d;
|
|
||||||
size_t i;
|
|
||||||
int ok;
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+
|
|
||||||
+ ret = krb5int_crypto_init();
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
|
|
||||||
if (output->length != (unsigned int)EVP_MD_size(type))
|
|
||||||
return KRB5_CRYPTO_INTERNAL;
|
|
||||||
diff --git a/src/lib/crypto/openssl/init.c b/src/lib/crypto/openssl/init.c
|
|
||||||
index 1139bce53..f72dbfe81 100644
|
|
||||||
--- a/src/lib/crypto/openssl/init.c
|
|
||||||
+++ b/src/lib/crypto/openssl/init.c
|
|
||||||
@@ -26,12 +26,65 @@
|
|
||||||
|
|
||||||
#include "crypto_int.h"
|
|
||||||
|
|
||||||
+#ifdef HAVE_OSSL_PROVIDER_LOAD
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Starting in OpenSSL 3, algorithms are grouped into containers called
|
|
||||||
+ * "providers", not all of which are loaded by default. At time of writing,
|
|
||||||
+ * we need MD4 and RC4 from the legacy provider. Oddly, 3DES is not in
|
|
||||||
+ * legacy.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#include <openssl/provider.h>
|
|
||||||
+
|
|
||||||
+static OSSL_PROVIDER *legacy_provider = NULL;
|
|
||||||
+static OSSL_PROVIDER *default_provider = NULL;
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+unload_providers(void)
|
|
||||||
+{
|
|
||||||
+ if (default_provider != NULL)
|
|
||||||
+ (void)OSSL_PROVIDER_unload(default_provider);
|
|
||||||
+ if (legacy_provider != NULL)
|
|
||||||
+ (void)OSSL_PROVIDER_unload(legacy_provider);
|
|
||||||
+ default_provider = NULL;
|
|
||||||
+ legacy_provider = NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int
|
|
||||||
+krb5int_crypto_impl_init(void)
|
|
||||||
+{
|
|
||||||
+ legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
|
|
||||||
+ default_provider = OSSL_PROVIDER_load(NULL, "default");
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Someone might build openssl without the legacy provider. They will
|
|
||||||
+ * have a bad time, but some things will still work. I don't know think
|
|
||||||
+ * this configuration is worth supporting.
|
|
||||||
+ */
|
|
||||||
+ if (legacy_provider == NULL || default_provider == NULL)
|
|
||||||
+ abort();
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * If we attempt to do this with our normal LIBFINIFUNC logic (DT_FINI),
|
|
||||||
+ * OpenSSL will have cleaned itself up by the time we're invoked. OpenSSL
|
|
||||||
+ * registers its cleanup (OPENSSL_cleanup) with atexit() - do the same and
|
|
||||||
+ * we'll be higher on the stack.
|
|
||||||
+ */
|
|
||||||
+ atexit(unload_providers);
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#else /* !HAVE_OSSL_PROVIDER_LOAD */
|
|
||||||
+
|
|
||||||
int
|
|
||||||
krb5int_crypto_impl_init(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
void
|
|
||||||
krb5int_crypto_impl_cleanup(void)
|
|
||||||
{
|
|
||||||
diff --git a/src/plugins/preauth/pkinit/Makefile.in b/src/plugins/preauth/pkinit/Makefile.in
|
|
||||||
index 15ca0eb48..d20fb18a8 100644
|
|
||||||
--- a/src/plugins/preauth/pkinit/Makefile.in
|
|
||||||
+++ b/src/plugins/preauth/pkinit/Makefile.in
|
|
||||||
@@ -5,6 +5,7 @@ MODULE_INSTALL_DIR = $(KRB5_PA_MODULE_DIR)
|
|
||||||
LIBBASE=pkinit
|
|
||||||
LIBMAJOR=0
|
|
||||||
LIBMINOR=0
|
|
||||||
+LIBINITFUNC=pkinit_openssl_init
|
|
||||||
RELDIR=../plugins/preauth/pkinit
|
|
||||||
# Depends on libk5crypto and libkrb5
|
|
||||||
SHLIB_EXPDEPS = \
|
|
||||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
||||||
index 350c2118a..42e5c581d 100644
|
|
||||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
||||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
||||||
@@ -44,6 +44,13 @@
|
|
||||||
#include <openssl/params.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+#ifdef HAVE_OSSL_PROVIDER_LOAD
|
|
||||||
+#include <openssl/provider.h>
|
|
||||||
+
|
|
||||||
+static OSSL_PROVIDER *legacy_provider = NULL;
|
|
||||||
+static OSSL_PROVIDER *default_provider = NULL;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
|
|
||||||
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
|
|
||||||
|
|
||||||
@@ -2937,12 +2944,32 @@ cleanup:
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* pkinit_openssl_init() and unload_providers() are largely duplicated from
|
|
||||||
+ * lib/crypto/openssl/init.c - see explanations there. */
|
|
||||||
+static void
|
|
||||||
+unload_providers(void)
|
|
||||||
+{
|
|
||||||
+ if (default_provider != NULL)
|
|
||||||
+ (void)OSSL_PROVIDER_unload(default_provider);
|
|
||||||
+ if (legacy_provider != NULL)
|
|
||||||
+ (void)OSSL_PROVIDER_unload(legacy_provider);
|
|
||||||
+ default_provider = NULL;
|
|
||||||
+ legacy_provider = NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int
|
|
||||||
pkinit_openssl_init()
|
|
||||||
{
|
|
||||||
- /* Initialize OpenSSL. */
|
|
||||||
- ERR_load_crypto_strings();
|
|
||||||
- OpenSSL_add_all_algorithms();
|
|
||||||
+#ifdef HAVE_OSSL_PROVIDER_LOAD
|
|
||||||
+ legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
|
|
||||||
+ default_provider = OSSL_PROVIDER_load(NULL, "default");
|
|
||||||
+
|
|
||||||
+ if (legacy_provider == NULL || default_provider == NULL)
|
|
||||||
+ abort();
|
|
||||||
+
|
|
||||||
+ atexit(unload_providers);
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
From 68a557557ab8a3208fab8a70daf4d970b9fc4787 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
|
||||||
Date: Tue, 30 Mar 2021 14:35:28 +0200
|
|
||||||
Subject: [PATCH] Make KCM iteration fallback work with sssd-kcm
|
|
||||||
|
|
||||||
sssd-kcm returns KRB5_CC_IO if the operation code is not known.
|
|
||||||
|
|
||||||
ticket: 8990
|
|
||||||
(cherry picked from commit 06afae820a44c1dc96ad88a0b16c3e50bc938b2a)
|
|
||||||
(cherry picked from commit 2dbca7e14c945d6394e0e05f285a068dcd541295)
|
|
||||||
---
|
|
||||||
src/lib/krb5/ccache/cc_kcm.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
index 1f81a2190..46705f1da 100644
|
|
||||||
--- a/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
+++ b/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
@@ -876,7 +876,7 @@ kcm_start_seq_get(krb5_context context, krb5_ccache cache,
|
|
||||||
ret = kcmreq_get_cred_list(&req, &creds);
|
|
||||||
if (ret)
|
|
||||||
goto cleanup;
|
|
||||||
- } else if (ret == KRB5_FCC_INTERNAL) {
|
|
||||||
+ } else if (ret == KRB5_FCC_INTERNAL || ret == KRB5_CC_IO) {
|
|
||||||
/* Fall back to GET_CRED_UUID_LIST. */
|
|
||||||
kcmreq_free(&req);
|
|
||||||
kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache);
|
|
@ -1,365 +0,0 @@
|
|||||||
From b778f10e31e566269768cba92a0005f35e134333 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Julien Rische <jrische@redhat.com>
|
|
||||||
Date: Wed, 19 Jan 2022 19:46:08 +0100
|
|
||||||
Subject: [PATCH] Make kprop work for dump files larger than 4GB
|
|
||||||
|
|
||||||
If the dump file size does not fit in 32 bits, encode four zero bytes
|
|
||||||
(forcing an error for unmodified kpropd) followed by the size in the
|
|
||||||
next 64 bits.
|
|
||||||
|
|
||||||
Add a functional test case, but only run it when an environment
|
|
||||||
variable is set, as processing a 4GB dump file is too
|
|
||||||
resource-intensive for make check.
|
|
||||||
|
|
||||||
[ghudson@mit.edu: edited comments and commit message; eliminated use
|
|
||||||
of defined constant in some cases; added test case]
|
|
||||||
|
|
||||||
ticket: 9053 (new)
|
|
||||||
---
|
|
||||||
src/kprop/kprop.c | 37 +++++++++++++++++++++----------------
|
|
||||||
src/kprop/kprop.h | 12 ++++++++++++
|
|
||||||
src/kprop/kprop_util.c | 42 ++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
src/kprop/kpropd.c | 33 +++++++++++++++++++++------------
|
|
||||||
src/tests/t_kprop.py | 34 ++++++++++++++++++++++++++++++++++
|
|
||||||
5 files changed, 130 insertions(+), 28 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/kprop/kprop.c b/src/kprop/kprop.c
|
|
||||||
index 0b53aae7e..5adb4d31f 100644
|
|
||||||
--- a/src/kprop/kprop.c
|
|
||||||
+++ b/src/kprop/kprop.c
|
|
||||||
@@ -25,6 +25,7 @@
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "k5-int.h"
|
|
||||||
+#include <inttypes.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <sys/file.h>
|
|
||||||
#include <signal.h>
|
|
||||||
@@ -71,11 +72,11 @@ static void open_connection(krb5_context context, char *host, int *fd_out);
|
|
||||||
static void kerberos_authenticate(krb5_context context,
|
|
||||||
krb5_auth_context *auth_context, int fd,
|
|
||||||
krb5_principal me, krb5_creds **new_creds);
|
|
||||||
-static int open_database(krb5_context context, char *data_fn, int *size);
|
|
||||||
+static int open_database(krb5_context context, char *data_fn, off_t *size);
|
|
||||||
static void close_database(krb5_context context, int fd);
|
|
||||||
static void xmit_database(krb5_context context,
|
|
||||||
krb5_auth_context auth_context, krb5_creds *my_creds,
|
|
||||||
- int fd, int database_fd, int in_database_size);
|
|
||||||
+ int fd, int database_fd, off_t in_database_size);
|
|
||||||
static void send_error(krb5_context context, krb5_creds *my_creds, int fd,
|
|
||||||
char *err_text, krb5_error_code err_code);
|
|
||||||
static void update_last_prop_file(char *hostname, char *file_name);
|
|
||||||
@@ -90,7 +91,8 @@ static void usage()
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
- int fd, database_fd, database_size;
|
|
||||||
+ int fd, database_fd;
|
|
||||||
+ off_t database_size;
|
|
||||||
krb5_error_code retval;
|
|
||||||
krb5_context context;
|
|
||||||
krb5_creds *my_creds;
|
|
||||||
@@ -339,7 +341,7 @@ kerberos_authenticate(krb5_context context, krb5_auth_context *auth_context,
|
|
||||||
* in the size of the database file.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
-open_database(krb5_context context, char *data_fn, int *size)
|
|
||||||
+open_database(krb5_context context, char *data_fn, off_t *size)
|
|
||||||
{
|
|
||||||
struct stat stbuf, stbuf_ok;
|
|
||||||
char *data_ok_fn;
|
|
||||||
@@ -413,19 +415,18 @@ close_database(krb5_context context, int fd)
|
|
||||||
static void
|
|
||||||
xmit_database(krb5_context context, krb5_auth_context auth_context,
|
|
||||||
krb5_creds *my_creds, int fd, int database_fd,
|
|
||||||
- int in_database_size)
|
|
||||||
+ off_t in_database_size)
|
|
||||||
{
|
|
||||||
krb5_int32 n;
|
|
||||||
krb5_data inbuf, outbuf;
|
|
||||||
- char buf[KPROP_BUFSIZ];
|
|
||||||
+ char buf[KPROP_BUFSIZ], dbsize_buf[KPROP_DBSIZE_MAX_BUFSIZ];
|
|
||||||
krb5_error_code retval;
|
|
||||||
krb5_error *error;
|
|
||||||
- krb5_ui_4 database_size = in_database_size, send_size, sent_size;
|
|
||||||
+ uint64_t database_size = in_database_size, send_size, sent_size;
|
|
||||||
|
|
||||||
/* Send over the size. */
|
|
||||||
- send_size = htonl(database_size);
|
|
||||||
- inbuf.data = (char *)&send_size;
|
|
||||||
- inbuf.length = sizeof(send_size); /* must be 4, really */
|
|
||||||
+ inbuf = make_data(dbsize_buf, sizeof(dbsize_buf));
|
|
||||||
+ encode_database_size(database_size, &inbuf);
|
|
||||||
/* KPROP_CKSUMTYPE */
|
|
||||||
retval = krb5_mk_safe(context, auth_context, &inbuf, &outbuf, NULL);
|
|
||||||
if (retval) {
|
|
||||||
@@ -460,7 +461,7 @@ xmit_database(krb5_context context, krb5_auth_context auth_context,
|
|
||||||
retval = krb5_mk_priv(context, auth_context, &inbuf, &outbuf, NULL);
|
|
||||||
if (retval) {
|
|
||||||
snprintf(buf, sizeof(buf),
|
|
||||||
- "while encoding database block starting at %d",
|
|
||||||
+ "while encoding database block starting at %"PRIu64,
|
|
||||||
sent_size);
|
|
||||||
com_err(progname, retval, "%s", buf);
|
|
||||||
send_error(context, my_creds, fd, buf, retval);
|
|
||||||
@@ -471,14 +472,14 @@ xmit_database(krb5_context context, krb5_auth_context auth_context,
|
|
||||||
if (retval) {
|
|
||||||
krb5_free_data_contents(context, &outbuf);
|
|
||||||
com_err(progname, retval,
|
|
||||||
- _("while sending database block starting at %d"),
|
|
||||||
+ _("while sending database block starting at %"PRIu64),
|
|
||||||
sent_size);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
krb5_free_data_contents(context, &outbuf);
|
|
||||||
sent_size += n;
|
|
||||||
if (debug)
|
|
||||||
- printf("%d bytes sent.\n", sent_size);
|
|
||||||
+ printf("%"PRIu64" bytes sent.\n", sent_size);
|
|
||||||
}
|
|
||||||
if (sent_size != database_size) {
|
|
||||||
com_err(progname, 0, _("Premature EOF found for database file!"));
|
|
||||||
@@ -533,10 +534,14 @@ xmit_database(krb5_context context, krb5_auth_context auth_context,
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
- memcpy(&send_size, outbuf.data, sizeof(send_size));
|
|
||||||
- send_size = ntohl(send_size);
|
|
||||||
+ retval = decode_database_size(&outbuf, &send_size);
|
|
||||||
+ if (retval) {
|
|
||||||
+ com_err(progname, retval, _("malformed sent database size message"));
|
|
||||||
+ exit(1);
|
|
||||||
+ }
|
|
||||||
if (send_size != database_size) {
|
|
||||||
- com_err(progname, 0, _("Kpropd sent database size %d, expecting %d"),
|
|
||||||
+ com_err(progname, 0, _("Kpropd sent database size %"PRIu64
|
|
||||||
+ ", expecting %"PRIu64),
|
|
||||||
send_size, database_size);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
diff --git a/src/kprop/kprop.h b/src/kprop/kprop.h
|
|
||||||
index 75331cc8a..3a319b535 100644
|
|
||||||
--- a/src/kprop/kprop.h
|
|
||||||
+++ b/src/kprop/kprop.h
|
|
||||||
@@ -32,6 +32,7 @@
|
|
||||||
#define KPROP_PROT_VERSION "kprop5_01"
|
|
||||||
|
|
||||||
#define KPROP_BUFSIZ 32768
|
|
||||||
+#define KPROP_DBSIZE_MAX_BUFSIZ 12 /* max length of an encoded DB size */
|
|
||||||
|
|
||||||
/* pathnames are in osconf.h, included via k5-int.h */
|
|
||||||
|
|
||||||
@@ -41,3 +42,14 @@ int sockaddr2krbaddr(krb5_context context, int family, struct sockaddr *sa,
|
|
||||||
krb5_error_code
|
|
||||||
sn2princ_realm(krb5_context context, const char *hostname, const char *sname,
|
|
||||||
const char *realm, krb5_principal *princ_out);
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Encode size in four bytes (for backward compatibility) if it fits; otherwise
|
|
||||||
+ * use the larger encoding. buf must be allocated with at least
|
|
||||||
+ * KPROP_DBSIZE_MAX_BUFSIZ bytes.
|
|
||||||
+ */
|
|
||||||
+void encode_database_size(uint64_t size, krb5_data *buf);
|
|
||||||
+
|
|
||||||
+/* Decode a database size. Return KRB5KRB_ERR_GENERIC if buf has an invalid
|
|
||||||
+ * length or did not encode a 32-bit size compactly. */
|
|
||||||
+krb5_error_code decode_database_size(const krb5_data *buf, uint64_t *size_out);
|
|
||||||
diff --git a/src/kprop/kprop_util.c b/src/kprop/kprop_util.c
|
|
||||||
index c2b2e8764..c0aa2c89b 100644
|
|
||||||
--- a/src/kprop/kprop_util.c
|
|
||||||
+++ b/src/kprop/kprop_util.c
|
|
||||||
@@ -92,3 +92,45 @@ sn2princ_realm(krb5_context context, const char *hostname, const char *sname,
|
|
||||||
*princ_out = princ;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+encode_database_size(uint64_t size, krb5_data *buf)
|
|
||||||
+{
|
|
||||||
+ assert(buf->length >= 12);
|
|
||||||
+ if (size > 0 && size <= UINT32_MAX) {
|
|
||||||
+ /* Encode in 32 bits for backward compatibility. */
|
|
||||||
+ store_32_be(size, buf->data);
|
|
||||||
+ buf->length = 4;
|
|
||||||
+ } else {
|
|
||||||
+ /* Set the first 32 bits to 0 and encode in the following 64 bits. */
|
|
||||||
+ store_32_be(0, buf->data);
|
|
||||||
+ store_64_be(size, buf->data + 4);
|
|
||||||
+ buf->length = 12;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+krb5_error_code
|
|
||||||
+decode_database_size(const krb5_data *buf, uint64_t *size_out)
|
|
||||||
+{
|
|
||||||
+ uint64_t size;
|
|
||||||
+
|
|
||||||
+ if (buf->length == 12) {
|
|
||||||
+ /* A 12-byte buffer must have the first four bytes zeroed. */
|
|
||||||
+ if (load_32_be(buf->data) != 0)
|
|
||||||
+ return KRB5KRB_ERR_GENERIC;
|
|
||||||
+
|
|
||||||
+ /* The size is stored in the next 64 bits. Values from 1..2^32-1 must
|
|
||||||
+ * be encoded in four bytes. */
|
|
||||||
+ size = load_64_be(buf->data + 4);
|
|
||||||
+ if (size > 0 && size <= UINT32_MAX)
|
|
||||||
+ return KRB5KRB_ERR_GENERIC;
|
|
||||||
+ } else if (buf->length == 4) {
|
|
||||||
+ size = load_32_be(buf->data);
|
|
||||||
+ } else {
|
|
||||||
+ /* Invalid buffer size. */
|
|
||||||
+ return KRB5KRB_ERR_GENERIC;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ *size_out = size;
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
|
|
||||||
index c6b8efc28..dd6c697c0 100644
|
|
||||||
--- a/src/kprop/kpropd.c
|
|
||||||
+++ b/src/kprop/kpropd.c
|
|
||||||
@@ -55,6 +55,7 @@
|
|
||||||
#include "com_err.h"
|
|
||||||
#include "fake-addrinfo.h"
|
|
||||||
|
|
||||||
+#include <inttypes.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <sys/file.h>
|
|
||||||
@@ -1358,9 +1359,10 @@ static void
|
|
||||||
recv_database(krb5_context context, int fd, int database_fd,
|
|
||||||
krb5_data *confmsg)
|
|
||||||
{
|
|
||||||
- krb5_ui_4 database_size, received_size;
|
|
||||||
+ uint64_t database_size, received_size;
|
|
||||||
int n;
|
|
||||||
char buf[1024];
|
|
||||||
+ char dbsize_buf[KPROP_DBSIZE_MAX_BUFSIZ];
|
|
||||||
krb5_data inbuf, outbuf;
|
|
||||||
krb5_error_code retval;
|
|
||||||
|
|
||||||
@@ -1382,10 +1384,17 @@ recv_database(krb5_context context, int fd, int database_fd,
|
|
||||||
_("while decoding database size from client"));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
- memcpy(&database_size, outbuf.data, sizeof(database_size));
|
|
||||||
+
|
|
||||||
+ retval = decode_database_size(&outbuf, &database_size);
|
|
||||||
+ if (retval) {
|
|
||||||
+ send_error(context, fd, retval, "malformed database size message");
|
|
||||||
+ com_err(progname, retval,
|
|
||||||
+ _("malformed database size message from client"));
|
|
||||||
+ exit(1);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
krb5_free_data_contents(context, &inbuf);
|
|
||||||
krb5_free_data_contents(context, &outbuf);
|
|
||||||
- database_size = ntohl(database_size);
|
|
||||||
|
|
||||||
/* Initialize the initial vector. */
|
|
||||||
retval = krb5_auth_con_initivector(context, auth_context);
|
|
||||||
@@ -1405,7 +1414,7 @@ recv_database(krb5_context context, int fd, int database_fd,
|
|
||||||
retval = krb5_read_message(context, &fd, &inbuf);
|
|
||||||
if (retval) {
|
|
||||||
snprintf(buf, sizeof(buf),
|
|
||||||
- "while reading database block starting at offset %d",
|
|
||||||
+ "while reading database block starting at offset %"PRIu64,
|
|
||||||
received_size);
|
|
||||||
com_err(progname, retval, "%s", buf);
|
|
||||||
send_error(context, fd, retval, buf);
|
|
||||||
@@ -1416,8 +1425,8 @@ recv_database(krb5_context context, int fd, int database_fd,
|
|
||||||
retval = krb5_rd_priv(context, auth_context, &inbuf, &outbuf, NULL);
|
|
||||||
if (retval) {
|
|
||||||
snprintf(buf, sizeof(buf),
|
|
||||||
- "while decoding database block starting at offset %d",
|
|
||||||
- received_size);
|
|
||||||
+ "while decoding database block starting at offset %"
|
|
||||||
+ PRIu64, received_size);
|
|
||||||
com_err(progname, retval, "%s", buf);
|
|
||||||
send_error(context, fd, retval, buf);
|
|
||||||
krb5_free_data_contents(context, &inbuf);
|
|
||||||
@@ -1427,13 +1436,13 @@ recv_database(krb5_context context, int fd, int database_fd,
|
|
||||||
krb5_free_data_contents(context, &inbuf);
|
|
||||||
if (n < 0) {
|
|
||||||
snprintf(buf, sizeof(buf),
|
|
||||||
- "while writing database block starting at offset %d",
|
|
||||||
+ "while writing database block starting at offset %"PRIu64,
|
|
||||||
received_size);
|
|
||||||
send_error(context, fd, errno, buf);
|
|
||||||
} else if ((unsigned int)n != outbuf.length) {
|
|
||||||
snprintf(buf, sizeof(buf),
|
|
||||||
"incomplete write while writing database block starting "
|
|
||||||
- "at \noffset %d (%d written, %d expected)",
|
|
||||||
+ "at \noffset %"PRIu64" (%d written, %d expected)",
|
|
||||||
received_size, n, outbuf.length);
|
|
||||||
send_error(context, fd, KRB5KRB_ERR_GENERIC, buf);
|
|
||||||
}
|
|
||||||
@@ -1444,7 +1453,8 @@ recv_database(krb5_context context, int fd, int database_fd,
|
|
||||||
/* OK, we've seen the entire file. Did we get too many bytes? */
|
|
||||||
if (received_size > database_size) {
|
|
||||||
snprintf(buf, sizeof(buf),
|
|
||||||
- "Received %d bytes, expected %d bytes for database file",
|
|
||||||
+ "Received %"PRIu64" bytes, expected %"PRIu64
|
|
||||||
+ " bytes for database file",
|
|
||||||
received_size, database_size);
|
|
||||||
send_error(context, fd, KRB5KRB_ERR_GENERIC, buf);
|
|
||||||
}
|
|
||||||
@@ -1454,9 +1464,8 @@ recv_database(krb5_context context, int fd, int database_fd,
|
|
||||||
|
|
||||||
/* Create message acknowledging number of bytes received, but
|
|
||||||
* don't send it until kdb5_util returns successfully. */
|
|
||||||
- database_size = htonl(database_size);
|
|
||||||
- inbuf.data = (char *)&database_size;
|
|
||||||
- inbuf.length = sizeof(database_size);
|
|
||||||
+ inbuf = make_data(dbsize_buf, sizeof(dbsize_buf));
|
|
||||||
+ encode_database_size(database_size, &inbuf);
|
|
||||||
retval = krb5_mk_safe(context,auth_context,&inbuf,confmsg,NULL);
|
|
||||||
if (retval) {
|
|
||||||
com_err(progname, retval, "while encoding # of received bytes");
|
|
||||||
diff --git a/src/tests/t_kprop.py b/src/tests/t_kprop.py
|
|
||||||
index d96f7c560..4421a7c35 100755
|
|
||||||
--- a/src/tests/t_kprop.py
|
|
||||||
+++ b/src/tests/t_kprop.py
|
|
||||||
@@ -87,5 +87,39 @@ realm.run([kdb5_util, 'dump', dumpfile])
|
|
||||||
realm.run([kprop, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname])
|
|
||||||
check_output(kpropd)
|
|
||||||
realm.run([kadminl, 'listprincs'], replica3, expected_msg='wakawaka')
|
|
||||||
+stop_daemon(kpropd)
|
|
||||||
+
|
|
||||||
+# This test is too resource-intensive to be included in "make check"
|
|
||||||
+# by default, but it can be enabled in the environment to test the
|
|
||||||
+# propagation of databases large enough to require a 12-byte encoding
|
|
||||||
+# of the database size.
|
|
||||||
+if 'KPROP_LARGE_DB_TEST' in os.environ:
|
|
||||||
+ output('Generating >4GB dumpfile\n')
|
|
||||||
+ with open(dumpfile, 'w') as f:
|
|
||||||
+ f.write('kdb5_util load_dump version 6\n')
|
|
||||||
+ f.write('princ\t38\t15\t3\t1\t0\tK/M@KRBTEST.COM\t64\t86400\t0\t0\t0'
|
|
||||||
+ '\t0\t0\t0\t8\t2\t0100\t9\t8\t0100010000000000\t2\t28'
|
|
||||||
+ '\tb93e105164625f6372656174696f6e404b5242544553542e434f4d00'
|
|
||||||
+ '\t1\t1\t18\t62\t2000408c027c250e8cc3b81476414f2214d57c1ce'
|
|
||||||
+ '38891e29792e87258247c73547df4d5756266931dd6686b62270e6568'
|
|
||||||
+ '95a31ec66bfe913b4f15226227\t-1;\n')
|
|
||||||
+ for i in range(1, 20000000):
|
|
||||||
+ f.write('princ\t38\t21\t1\t1\t0\tp%08d@KRBTEST.COM' % i)
|
|
||||||
+ f.write('\t0\t86400\t0\t0\t0\t0\t0\t0\t2\t27'
|
|
||||||
+ '\td73e1051757365722f61646d696e404b5242544553542e434f4d00'
|
|
||||||
+ '\t1\t1\t17\t46'
|
|
||||||
+ '\t10009c8ab7b3f89ccf3ca3ad98352a461b7f4f1b0c49'
|
|
||||||
+ '5605117591d9ad52ba4da0adef7a902126973ed2bdc3ffbf\t-1;\n')
|
|
||||||
+ assert os.path.getsize(dumpfile) > 4 * 1024 * 1024 * 1024
|
|
||||||
+ with open(dumpfile + '.dump_ok', 'w') as f:
|
|
||||||
+ f.write('\0')
|
|
||||||
+ conf_large = {'dbmodules': {'db': {'database_name': '$testdir/db.large'}},
|
|
||||||
+ 'realms': {'$realm': {'iprop_resync_timeout': '3600'}}}
|
|
||||||
+ large = realm.special_env('large', True, kdc_conf=conf_large)
|
|
||||||
+ kpropd = realm.start_kpropd(large, ['-d'])
|
|
||||||
+ realm.run([kprop, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname])
|
|
||||||
+ check_output(kpropd)
|
|
||||||
+ realm.run([kadminl, 'getprinc', 'p19999999'], env=large,
|
|
||||||
+ expected_msg='Principal: p19999999')
|
|
||||||
|
|
||||||
success('kprop tests')
|
|
||||||
--
|
|
||||||
2.37.3
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -1,150 +0,0 @@
|
|||||||
From c99ecf1bb49e2fbd0bf30a7b357cf06407b9588a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
Date: Sat, 15 May 2021 18:04:58 -0400
|
|
||||||
Subject: [PATCH] Remove deprecated OpenSSL calls from softpkcs11
|
|
||||||
|
|
||||||
Rewrite add_pubkey_info() in terms of the EVP_PKEY interface. In this
|
|
||||||
process, fix its unchecked allocations and fail fast for non-RSA keys.
|
|
||||||
|
|
||||||
(cherry picked from commit d6bf42279675100e3e4fe7c6e08eef74d49624cb)
|
|
||||||
(cherry picked from commit 5072bfdfaddae762680d0f9d97afa6dbf8274760)
|
|
||||||
---
|
|
||||||
src/configure.ac | 1 +
|
|
||||||
src/tests/softpkcs11/main.c | 106 ++++++++++++++++++++++++------------
|
|
||||||
2 files changed, 72 insertions(+), 35 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/configure.ac b/src/configure.ac
|
|
||||||
index 3e1052db7..eb6307468 100644
|
|
||||||
--- a/src/configure.ac
|
|
||||||
+++ b/src/configure.ac
|
|
||||||
@@ -1114,6 +1114,7 @@ int i = 1;
|
|
||||||
])], k5_cv_openssl_version_okay=yes, k5_cv_openssl_version_okay=no)])
|
|
||||||
old_LIBS="$LIBS"
|
|
||||||
AC_CHECK_LIB(crypto, PKCS7_get_signer_info)
|
|
||||||
+ AC_CHECK_FUNCS(EVP_PKEY_get_bn_param)
|
|
||||||
LIBS="$old_LIBS"
|
|
||||||
fi
|
|
||||||
if test "$k5_cv_openssl_version_okay" = yes && (test "$enable_pkinit" = yes || test "$enable_pkinit" = try); then
|
|
||||||
diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c
|
|
||||||
index caa537b68..86b4ef711 100644
|
|
||||||
--- a/src/tests/softpkcs11/main.c
|
|
||||||
+++ b/src/tests/softpkcs11/main.c
|
|
||||||
@@ -413,47 +413,83 @@ add_object_attribute(struct st_object *o,
|
|
||||||
return CKR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
+#ifdef HAVE_EVP_PKEY_GET_BN_PARAM
|
|
||||||
+
|
|
||||||
+/* Declare owner pointers since EVP_PKEY_get_bn_param() gives us copies. */
|
|
||||||
+#define DECLARE_BIGNUM(name) BIGNUM *name = NULL
|
|
||||||
+#define RELEASE_BIGNUM(bn) BN_clear_free(bn)
|
|
||||||
static CK_RV
|
|
||||||
-add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
|
|
||||||
+get_bignums(EVP_PKEY *key, BIGNUM **n, BIGNUM **e)
|
|
||||||
{
|
|
||||||
- switch (key_type) {
|
|
||||||
- case CKK_RSA: {
|
|
||||||
- CK_BYTE *modulus = NULL;
|
|
||||||
- size_t modulus_len = 0;
|
|
||||||
- CK_ULONG modulus_bits = 0;
|
|
||||||
- CK_BYTE *exponent = NULL;
|
|
||||||
- size_t exponent_len = 0;
|
|
||||||
- const RSA *rsa;
|
|
||||||
- const BIGNUM *n, *e;
|
|
||||||
+ if (EVP_PKEY_get_bn_param(key, "n", n) == 0 ||
|
|
||||||
+ EVP_PKEY_get_bn_param(key, "e", e) == 0)
|
|
||||||
+ return CKR_DEVICE_ERROR;
|
|
||||||
|
|
||||||
- rsa = EVP_PKEY_get0_RSA(key);
|
|
||||||
- RSA_get0_key(rsa, &n, &e, NULL);
|
|
||||||
- modulus_bits = BN_num_bits(n);
|
|
||||||
-
|
|
||||||
- modulus_len = BN_num_bytes(n);
|
|
||||||
- modulus = malloc(modulus_len);
|
|
||||||
- BN_bn2bin(n, modulus);
|
|
||||||
-
|
|
||||||
- exponent_len = BN_num_bytes(e);
|
|
||||||
- exponent = malloc(exponent_len);
|
|
||||||
- BN_bn2bin(e, exponent);
|
|
||||||
-
|
|
||||||
- add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
|
|
||||||
- add_object_attribute(o, 0, CKA_MODULUS_BITS,
|
|
||||||
- &modulus_bits, sizeof(modulus_bits));
|
|
||||||
- add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT,
|
|
||||||
- exponent, exponent_len);
|
|
||||||
-
|
|
||||||
- free(modulus);
|
|
||||||
- free(exponent);
|
|
||||||
- }
|
|
||||||
- default:
|
|
||||||
- /* XXX */
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
return CKR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
+#else
|
|
||||||
+
|
|
||||||
+/* Declare const pointers since the old API gives us aliases. */
|
|
||||||
+#define DECLARE_BIGNUM(name) const BIGNUM *name
|
|
||||||
+#define RELEASE_BIGNUM(bn)
|
|
||||||
+static CK_RV
|
|
||||||
+get_bignums(EVP_PKEY *key, const BIGNUM **n, const BIGNUM **e)
|
|
||||||
+{
|
|
||||||
+ const RSA *rsa;
|
|
||||||
+
|
|
||||||
+ rsa = EVP_PKEY_get0_RSA(key);
|
|
||||||
+ RSA_get0_key(rsa, n, e, NULL);
|
|
||||||
+
|
|
||||||
+ return CKR_OK;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+static CK_RV
|
|
||||||
+add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
|
|
||||||
+{
|
|
||||||
+ CK_BYTE *modulus = NULL, *exponent = 0;
|
|
||||||
+ size_t modulus_len = 0, exponent_len = 0;
|
|
||||||
+ CK_ULONG modulus_bits = 0;
|
|
||||||
+ CK_RV ret;
|
|
||||||
+ DECLARE_BIGNUM(n);
|
|
||||||
+ DECLARE_BIGNUM(e);
|
|
||||||
+
|
|
||||||
+ if (key_type != CKK_RSA)
|
|
||||||
+ abort();
|
|
||||||
+
|
|
||||||
+ ret = get_bignums(key, &n, &e);
|
|
||||||
+ if (ret != CKR_OK)
|
|
||||||
+ goto done;
|
|
||||||
+
|
|
||||||
+ modulus_bits = BN_num_bits(n);
|
|
||||||
+ modulus_len = BN_num_bytes(n);
|
|
||||||
+ exponent_len = BN_num_bytes(e);
|
|
||||||
+
|
|
||||||
+ modulus = malloc(modulus_len);
|
|
||||||
+ exponent = malloc(exponent_len);
|
|
||||||
+ if (modulus == NULL || exponent == NULL) {
|
|
||||||
+ ret = CKR_DEVICE_MEMORY;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ BN_bn2bin(n, modulus);
|
|
||||||
+ BN_bn2bin(e, exponent);
|
|
||||||
+
|
|
||||||
+ add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
|
|
||||||
+ add_object_attribute(o, 0, CKA_MODULUS_BITS, &modulus_bits,
|
|
||||||
+ sizeof(modulus_bits));
|
|
||||||
+ add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT, exponent, exponent_len);
|
|
||||||
+
|
|
||||||
+ ret = CKR_OK;
|
|
||||||
+done:
|
|
||||||
+ free(modulus);
|
|
||||||
+ free(exponent);
|
|
||||||
+ RELEASE_BIGNUM(n);
|
|
||||||
+ RELEASE_BIGNUM(e);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
|
|
||||||
static int
|
|
||||||
pem_callback(char *buf, int num, int w, void *key)
|
|
@ -1,188 +0,0 @@
|
|||||||
From dea9421ccdbe5c8f63aae85341a8f091c6019407 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Julien Rische <jrische@redhat.com>
|
|
||||||
Date: Wed, 1 Jun 2022 18:02:04 +0200
|
|
||||||
Subject: [PATCH] Set reasonable supportedCMSTypes in PKINIT
|
|
||||||
|
|
||||||
The PKINIT client uses AuthPack.supportedCMSTypes to let the KDC know
|
|
||||||
the algorithms it supports for verification of the CMS data signature.
|
|
||||||
(The MIT krb5 KDC currently ignores this list, but other
|
|
||||||
implementations use it.)
|
|
||||||
|
|
||||||
Replace 3DES with sha512WithRSAEncryption and sha256WithRSAEncryption.
|
|
||||||
|
|
||||||
[ghudson@mit.edu: simplified code and used appropriate helpers; edited
|
|
||||||
commit message]
|
|
||||||
|
|
||||||
ticket: 9066 (new)
|
|
||||||
---
|
|
||||||
src/plugins/preauth/pkinit/Makefile.in | 4 +-
|
|
||||||
src/plugins/preauth/pkinit/pkinit_clnt.c | 8 ++++
|
|
||||||
...nit_kdf_constants.c => pkinit_constants.c} | 24 ++++++++++++
|
|
||||||
src/plugins/preauth/pkinit/pkinit_crypto.h | 16 ++++++++
|
|
||||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 39 +++++++++++++++++++
|
|
||||||
5 files changed, 89 insertions(+), 2 deletions(-)
|
|
||||||
rename src/plugins/preauth/pkinit/{pkinit_kdf_constants.c => pkinit_constants.c} (76%)
|
|
||||||
|
|
||||||
diff --git a/src/plugins/preauth/pkinit/Makefile.in b/src/plugins/preauth/pkinit/Makefile.in
|
|
||||||
index d20fb18a8..97aaded03 100644
|
|
||||||
--- a/src/plugins/preauth/pkinit/Makefile.in
|
|
||||||
+++ b/src/plugins/preauth/pkinit/Makefile.in
|
|
||||||
@@ -18,7 +18,7 @@ STLIBOBJS= \
|
|
||||||
pkinit_srv.o \
|
|
||||||
pkinit_lib.o \
|
|
||||||
pkinit_clnt.o \
|
|
||||||
- pkinit_kdf_constants.o \
|
|
||||||
+ pkinit_constants.o \
|
|
||||||
pkinit_profile.o \
|
|
||||||
pkinit_identity.o \
|
|
||||||
pkinit_matching.o \
|
|
||||||
@@ -29,7 +29,7 @@ SRCS= \
|
|
||||||
$(srcdir)/pkinit_srv.c \
|
|
||||||
$(srcdir)/pkinit_lib.c \
|
|
||||||
$(srcdir)/pkinit_kdf_test.c \
|
|
||||||
- $(srcdir)/pkinit_kdf_constants.c \
|
|
||||||
+ $(srcdir)/pkinit_constants.c \
|
|
||||||
$(srcdir)/pkinit_clnt.c \
|
|
||||||
$(srcdir)/pkinit_profile.c \
|
|
||||||
$(srcdir)/pkinit_identity.c \
|
|
||||||
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
|
|
||||||
index a385da7c3..2817cc213 100644
|
|
||||||
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
|
|
||||||
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
|
|
||||||
@@ -212,6 +212,14 @@ pkinit_as_req_create(krb5_context context,
|
|
||||||
auth_pack.clientPublicValue = &info;
|
|
||||||
auth_pack.supportedKDFs = (krb5_data **)supported_kdf_alg_ids;
|
|
||||||
|
|
||||||
+ /* add List of CMS algorithms */
|
|
||||||
+ retval = create_krb5_supportedCMSTypes(context, plgctx->cryptoctx,
|
|
||||||
+ reqctx->cryptoctx,
|
|
||||||
+ reqctx->idctx, &cmstypes);
|
|
||||||
+ auth_pack.supportedCMSTypes = cmstypes;
|
|
||||||
+ if (retval)
|
|
||||||
+ goto cleanup;
|
|
||||||
+
|
|
||||||
switch(protocol) {
|
|
||||||
case DH_PROTOCOL:
|
|
||||||
TRACE_PKINIT_CLIENT_REQ_DH(context);
|
|
||||||
diff --git a/src/plugins/preauth/pkinit/pkinit_kdf_constants.c b/src/plugins/preauth/pkinit/pkinit_constants.c
|
|
||||||
similarity index 76%
|
|
||||||
rename from src/plugins/preauth/pkinit/pkinit_kdf_constants.c
|
|
||||||
rename to src/plugins/preauth/pkinit/pkinit_constants.c
|
|
||||||
index 1604f1670..1832e8f7b 100644
|
|
||||||
--- a/src/plugins/preauth/pkinit/pkinit_kdf_constants.c
|
|
||||||
+++ b/src/plugins/preauth/pkinit/pkinit_constants.c
|
|
||||||
@@ -57,3 +57,27 @@ krb5_data const * const supported_kdf_alg_ids[] = {
|
|
||||||
&sha512_id,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
+
|
|
||||||
+/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840)
|
|
||||||
+ * rsadsi(113549) pkcs(1) 1 11 */
|
|
||||||
+static char sha256WithRSAEncr_oid[9] = {
|
|
||||||
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b
|
|
||||||
+};
|
|
||||||
+/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840)
|
|
||||||
+ * rsadsi(113549) pkcs(1) 1 13 */
|
|
||||||
+static char sha512WithRSAEncr_oid[9] = {
|
|
||||||
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+const krb5_data sha256WithRSAEncr_id = {
|
|
||||||
+ KV5M_DATA, sizeof(sha256WithRSAEncr_oid), sha256WithRSAEncr_oid
|
|
||||||
+};
|
|
||||||
+const krb5_data sha512WithRSAEncr_id = {
|
|
||||||
+ KV5M_DATA, sizeof(sha512WithRSAEncr_oid), sha512WithRSAEncr_oid
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+krb5_data const * const supported_cms_algs[] = {
|
|
||||||
+ &sha512WithRSAEncr_id,
|
|
||||||
+ &sha256WithRSAEncr_id,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
|
||||||
index 1f9868351..f38a77093 100644
|
|
||||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
|
|
||||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
|
||||||
@@ -380,6 +380,18 @@ krb5_error_code server_process_dh
|
|
||||||
unsigned int *server_key_len_out); /* OUT
|
|
||||||
receives length of DH secret key */
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * this functions takes in crypto specific representation of
|
|
||||||
+ * supportedCMSTypes and creates a list of
|
|
||||||
+ * krb5_algorithm_identifier
|
|
||||||
+ */
|
|
||||||
+krb5_error_code create_krb5_supportedCMSTypes
|
|
||||||
+ (krb5_context context, /* IN */
|
|
||||||
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
|
|
||||||
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
|
|
||||||
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
|
|
||||||
+ krb5_algorithm_identifier ***supportedCMSTypes); /* OUT */
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* this functions takes in crypto specific representation of
|
|
||||||
* trustedCertifiers and creates a list of
|
|
||||||
@@ -617,6 +629,10 @@ extern const size_t krb5_pkinit_sha512_oid_len;
|
|
||||||
*/
|
|
||||||
extern krb5_data const * const supported_kdf_alg_ids[];
|
|
||||||
|
|
||||||
+/* CMS signature algorithms supported by this implementation, in order of
|
|
||||||
+ * decreasing preference. */
|
|
||||||
+extern krb5_data const * const supported_cms_algs[];
|
|
||||||
+
|
|
||||||
krb5_error_code
|
|
||||||
crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx,
|
|
||||||
uint8_t **der_out, size_t *der_len);
|
|
||||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
||||||
index 2a6ef4aaa..41a7464b5 100644
|
|
||||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
||||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
||||||
@@ -5582,6 +5582,45 @@ cleanup:
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
+krb5_error_code
|
|
||||||
+create_krb5_supportedCMSTypes(krb5_context context,
|
|
||||||
+ pkinit_plg_crypto_context plg_cryptoctx,
|
|
||||||
+ pkinit_req_crypto_context req_cryptoctx,
|
|
||||||
+ pkinit_identity_crypto_context id_cryptoctx,
|
|
||||||
+ krb5_algorithm_identifier ***algs_out)
|
|
||||||
+{
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+ krb5_algorithm_identifier **algs = NULL;
|
|
||||||
+ size_t i, count;
|
|
||||||
+
|
|
||||||
+ *algs_out = NULL;
|
|
||||||
+
|
|
||||||
+ /* Count supported OIDs and allocate list (including null terminator). */
|
|
||||||
+ for (count = 0; supported_cms_algs[count] != NULL; count++);
|
|
||||||
+ algs = k5calloc(count + 1, sizeof(*algs), &ret);
|
|
||||||
+ if (algs == NULL)
|
|
||||||
+ goto cleanup;
|
|
||||||
+
|
|
||||||
+ /* Add an algorithm identifier for each OID, with no parameters. */
|
|
||||||
+ for (i = 0; i < count; i++) {
|
|
||||||
+ algs[i] = k5alloc(sizeof(*algs[i]), &ret);
|
|
||||||
+ if (algs[i] == NULL)
|
|
||||||
+ goto cleanup;
|
|
||||||
+ ret = krb5int_copy_data_contents(context, supported_cms_algs[i],
|
|
||||||
+ &algs[i]->algorithm);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+ algs[i]->parameters = empty_data();
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ *algs_out = algs;
|
|
||||||
+ algs = NULL;
|
|
||||||
+
|
|
||||||
+cleanup:
|
|
||||||
+ free_krb5_algorithm_identifiers(&algs);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
krb5_error_code
|
|
||||||
create_krb5_trustedCertifiers(krb5_context context,
|
|
||||||
pkinit_plg_crypto_context plg_cryptoctx,
|
|
||||||
--
|
|
||||||
2.35.3
|
|
||||||
|
|
@ -1,578 +0,0 @@
|
|||||||
From e33835c4b6c6ce71757e9f659db03afa4bfd9a9a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Greg Hudson <ghudson@mit.edu>
|
|
||||||
Date: Fri, 15 Jan 2021 13:51:34 -0500
|
|
||||||
Subject: [PATCH] Support host-based GSS initiator names
|
|
||||||
|
|
||||||
When checking if we can get initial credentials in the GSS krb5 mech,
|
|
||||||
use krb5_kt_have_match() to support fallback iteration. When scanning
|
|
||||||
the ccache or getting initial credentials, rewrite cred->name->princ
|
|
||||||
to the canonical client name. When a name check is necessary (such as
|
|
||||||
when the caller specifies both a name and ccache), use a new internal
|
|
||||||
API k5_sname_compare() to support fallback iteration. Add fallback
|
|
||||||
iteration to krb5_cc_cache_match() to allow host-based names to be
|
|
||||||
canonicalized against the cache collection.
|
|
||||||
|
|
||||||
Create and store the matching principal for acceptor names in
|
|
||||||
acquire_accept_cred() so that it isn't affected by changes in
|
|
||||||
cred->name->princ during acquire_init_cred().
|
|
||||||
|
|
||||||
ticket: 8978 (new)
|
|
||||||
(cherry picked from commit c374ab40dd059a5938ffc0440d87457ac5da3a46)
|
|
||||||
---
|
|
||||||
src/include/k5-int.h | 9 +++
|
|
||||||
src/include/k5-trace.h | 3 +
|
|
||||||
src/lib/gssapi/krb5/accept_sec_context.c | 15 +---
|
|
||||||
src/lib/gssapi/krb5/acquire_cred.c | 89 ++++++++++++++----------
|
|
||||||
src/lib/gssapi/krb5/gssapiP_krb5.h | 1 +
|
|
||||||
src/lib/gssapi/krb5/rel_cred.c | 1 +
|
|
||||||
src/lib/krb5/ccache/cccursor.c | 57 +++++++++++----
|
|
||||||
src/lib/krb5/libkrb5.exports | 1 +
|
|
||||||
src/lib/krb5/os/sn2princ.c | 23 +++++-
|
|
||||||
src/lib/krb5_32.def | 1 +
|
|
||||||
src/tests/gssapi/t_client_keytab.py | 44 ++++++++++++
|
|
||||||
src/tests/gssapi/t_credstore.py | 32 +++++++++
|
|
||||||
12 files changed, 214 insertions(+), 62 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
|
||||||
index efb523689..46f2ce2d3 100644
|
|
||||||
--- a/src/include/k5-int.h
|
|
||||||
+++ b/src/include/k5-int.h
|
|
||||||
@@ -2411,4 +2411,13 @@ void k5_change_error_message_code(krb5_context ctx, krb5_error_code oldcode,
|
|
||||||
#define k5_prependmsg krb5_prepend_error_message
|
|
||||||
#define k5_wrapmsg krb5_wrap_error_message
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * Like krb5_principal_compare(), but with canonicalization of sname if
|
|
||||||
+ * fallback is enabled. This function should be avoided if multiple matches
|
|
||||||
+ * are required, since repeated canonicalization is inefficient.
|
|
||||||
+ */
|
|
||||||
+krb5_boolean
|
|
||||||
+k5_sname_compare(krb5_context context, krb5_const_principal sname,
|
|
||||||
+ krb5_const_principal princ);
|
|
||||||
+
|
|
||||||
#endif /* _KRB5_INT_H */
|
|
||||||
diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
|
|
||||||
index b3e039dc8..79b5a7a85 100644
|
|
||||||
--- a/src/include/k5-trace.h
|
|
||||||
+++ b/src/include/k5-trace.h
|
|
||||||
@@ -105,6 +105,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
|
|
||||||
|
|
||||||
#endif /* DISABLE_TRACING */
|
|
||||||
|
|
||||||
+#define TRACE_CC_CACHE_MATCH(c, princ, ret) \
|
|
||||||
+ TRACE(c, "Matching {princ} in collection with result: {kerr}", \
|
|
||||||
+ princ, ret)
|
|
||||||
#define TRACE_CC_DESTROY(c, cache) \
|
|
||||||
TRACE(c, "Destroying ccache {ccache}", cache)
|
|
||||||
#define TRACE_CC_GEN_NEW(c, cache) \
|
|
||||||
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
|
|
||||||
index fcf2c2152..a1d7e0d96 100644
|
|
||||||
--- a/src/lib/gssapi/krb5/accept_sec_context.c
|
|
||||||
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
|
|
||||||
@@ -683,7 +683,6 @@ kg_accept_krb5(minor_status, context_handle,
|
|
||||||
krb5_flags ap_req_options = 0;
|
|
||||||
krb5_enctype negotiated_etype;
|
|
||||||
krb5_authdata_context ad_context = NULL;
|
|
||||||
- krb5_principal accprinc = NULL;
|
|
||||||
krb5_ap_req *request = NULL;
|
|
||||||
|
|
||||||
code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
|
|
||||||
@@ -849,17 +848,9 @@ kg_accept_krb5(minor_status, context_handle,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!cred->default_identity) {
|
|
||||||
- if ((code = kg_acceptor_princ(context, cred->name, &accprinc))) {
|
|
||||||
- major_status = GSS_S_FAILURE;
|
|
||||||
- goto fail;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- code = krb5_rd_req_decoded(context, &auth_context, request, accprinc,
|
|
||||||
- cred->keytab, &ap_req_options, NULL);
|
|
||||||
-
|
|
||||||
- krb5_free_principal(context, accprinc);
|
|
||||||
+ code = krb5_rd_req_decoded(context, &auth_context, request,
|
|
||||||
+ cred->acceptor_mprinc, cred->keytab,
|
|
||||||
+ &ap_req_options, NULL);
|
|
||||||
if (code) {
|
|
||||||
major_status = GSS_S_FAILURE;
|
|
||||||
goto fail;
|
|
||||||
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
|
|
||||||
index 632ee7def..e226a0269 100644
|
|
||||||
--- a/src/lib/gssapi/krb5/acquire_cred.c
|
|
||||||
+++ b/src/lib/gssapi/krb5/acquire_cred.c
|
|
||||||
@@ -123,11 +123,11 @@ gss_krb5int_register_acceptor_identity(OM_uint32 *minor_status,
|
|
||||||
/* Try to verify that keytab contains at least one entry for name. Return 0 if
|
|
||||||
* it does, KRB5_KT_NOTFOUND if it doesn't, or another error as appropriate. */
|
|
||||||
static krb5_error_code
|
|
||||||
-check_keytab(krb5_context context, krb5_keytab kt, krb5_gss_name_t name)
|
|
||||||
+check_keytab(krb5_context context, krb5_keytab kt, krb5_gss_name_t name,
|
|
||||||
+ krb5_principal mprinc)
|
|
||||||
{
|
|
||||||
krb5_error_code code;
|
|
||||||
krb5_keytab_entry ent;
|
|
||||||
- krb5_principal accprinc = NULL;
|
|
||||||
char *princname;
|
|
||||||
|
|
||||||
if (name->service == NULL) {
|
|
||||||
@@ -141,21 +141,15 @@ check_keytab(krb5_context context, krb5_keytab kt, krb5_gss_name_t name)
|
|
||||||
if (kt->ops->start_seq_get == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- /* Get the partial principal for the acceptor name. */
|
|
||||||
- code = kg_acceptor_princ(context, name, &accprinc);
|
|
||||||
- if (code)
|
|
||||||
- return code;
|
|
||||||
-
|
|
||||||
- /* Scan the keytab for host-based entries matching accprinc. */
|
|
||||||
- code = k5_kt_have_match(context, kt, accprinc);
|
|
||||||
+ /* Scan the keytab for host-based entries matching mprinc. */
|
|
||||||
+ code = k5_kt_have_match(context, kt, mprinc);
|
|
||||||
if (code == KRB5_KT_NOTFOUND) {
|
|
||||||
- if (krb5_unparse_name(context, accprinc, &princname) == 0) {
|
|
||||||
+ if (krb5_unparse_name(context, mprinc, &princname) == 0) {
|
|
||||||
k5_setmsg(context, code, _("No key table entry found matching %s"),
|
|
||||||
princname);
|
|
||||||
free(princname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- krb5_free_principal(context, accprinc);
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -202,8 +196,14 @@ acquire_accept_cred(krb5_context context, OM_uint32 *minor_status,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cred->name != NULL) {
|
|
||||||
+ code = kg_acceptor_princ(context, cred->name, &cred->acceptor_mprinc);
|
|
||||||
+ if (code) {
|
|
||||||
+ major = GSS_S_FAILURE;
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Make sure we have keys matching the desired name in the keytab. */
|
|
||||||
- code = check_keytab(context, kt, cred->name);
|
|
||||||
+ code = check_keytab(context, kt, cred->name, cred->acceptor_mprinc);
|
|
||||||
if (code) {
|
|
||||||
if (code == KRB5_KT_NOTFOUND) {
|
|
||||||
k5_change_error_message_code(context, code, KG_KEYTAB_NOMATCH);
|
|
||||||
@@ -324,7 +324,6 @@ static krb5_boolean
|
|
||||||
can_get_initial_creds(krb5_context context, krb5_gss_cred_id_rec *cred)
|
|
||||||
{
|
|
||||||
krb5_error_code code;
|
|
||||||
- krb5_keytab_entry entry;
|
|
||||||
|
|
||||||
if (cred->password != NULL)
|
|
||||||
return TRUE;
|
|
||||||
@@ -336,20 +335,21 @@ can_get_initial_creds(krb5_context context, krb5_gss_cred_id_rec *cred)
|
|
||||||
if (cred->name == NULL)
|
|
||||||
return !krb5_kt_have_content(context, cred->client_keytab);
|
|
||||||
|
|
||||||
- /* Check if we have a keytab key for the client principal. */
|
|
||||||
- code = krb5_kt_get_entry(context, cred->client_keytab, cred->name->princ,
|
|
||||||
- 0, 0, &entry);
|
|
||||||
- if (code) {
|
|
||||||
- krb5_clear_error_message(context);
|
|
||||||
- return FALSE;
|
|
||||||
- }
|
|
||||||
- krb5_free_keytab_entry_contents(context, &entry);
|
|
||||||
- return TRUE;
|
|
||||||
+ /*
|
|
||||||
+ * Check if we have a keytab key for the client principal. This is a bit
|
|
||||||
+ * more permissive than we really want because krb5_kt_have_match()
|
|
||||||
+ * supports wildcarding and obeys ignore_acceptor_hostname, but that should
|
|
||||||
+ * generally be harmless.
|
|
||||||
+ */
|
|
||||||
+ code = k5_kt_have_match(context, cred->client_keytab, cred->name->princ);
|
|
||||||
+ return code == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-/* Scan cred->ccache for name, expiry time, impersonator, refresh time. */
|
|
||||||
+/* Scan cred->ccache for name, expiry time, impersonator, refresh time. If
|
|
||||||
+ * check_name is true, verify the cache name against the credential name. */
|
|
||||||
static krb5_error_code
|
|
||||||
-scan_ccache(krb5_context context, krb5_gss_cred_id_rec *cred)
|
|
||||||
+scan_ccache(krb5_context context, krb5_gss_cred_id_rec *cred,
|
|
||||||
+ krb5_boolean check_name)
|
|
||||||
{
|
|
||||||
krb5_error_code code;
|
|
||||||
krb5_ccache ccache = cred->ccache;
|
|
||||||
@@ -365,23 +365,31 @@ scan_ccache(krb5_context context, krb5_gss_cred_id_rec *cred)
|
|
||||||
if (code)
|
|
||||||
return code;
|
|
||||||
|
|
||||||
- /* Credentials cache principal must match the initiator name. */
|
|
||||||
code = krb5_cc_get_principal(context, ccache, &ccache_princ);
|
|
||||||
if (code != 0)
|
|
||||||
goto cleanup;
|
|
||||||
- if (cred->name != NULL &&
|
|
||||||
- !krb5_principal_compare(context, ccache_princ, cred->name->princ)) {
|
|
||||||
- code = KG_CCACHE_NOMATCH;
|
|
||||||
- goto cleanup;
|
|
||||||
- }
|
|
||||||
|
|
||||||
- /* Save the ccache principal as the credential name if not already set. */
|
|
||||||
- if (!cred->name) {
|
|
||||||
+ if (cred->name == NULL) {
|
|
||||||
+ /* Save the ccache principal as the credential name. */
|
|
||||||
code = kg_init_name(context, ccache_princ, NULL, NULL, NULL,
|
|
||||||
KG_INIT_NAME_NO_COPY, &cred->name);
|
|
||||||
if (code)
|
|
||||||
goto cleanup;
|
|
||||||
ccache_princ = NULL;
|
|
||||||
+ } else {
|
|
||||||
+ /* Check against the desired name if needed. */
|
|
||||||
+ if (check_name) {
|
|
||||||
+ if (!k5_sname_compare(context, cred->name->princ, ccache_princ)) {
|
|
||||||
+ code = KG_CCACHE_NOMATCH;
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Replace the credential name principal with the canonical client
|
|
||||||
+ * principal, retaining acceptor_mprinc if set. */
|
|
||||||
+ krb5_free_principal(context, cred->name->princ);
|
|
||||||
+ cred->name->princ = ccache_princ;
|
|
||||||
+ ccache_princ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(cred->name->princ != NULL);
|
|
||||||
@@ -447,7 +455,7 @@ get_cache_for_name(krb5_context context, krb5_gss_cred_id_rec *cred)
|
|
||||||
assert(cred->name != NULL && cred->ccache == NULL);
|
|
||||||
#ifdef USE_LEASH
|
|
||||||
code = get_ccache_leash(context, cred->name->princ, &cred->ccache);
|
|
||||||
- return code ? code : scan_ccache(context, cred);
|
|
||||||
+ return code ? code : scan_ccache(context, cred, TRUE);
|
|
||||||
#else
|
|
||||||
/* Check first whether we can acquire tickets, to avoid overwriting the
|
|
||||||
* extended error message from krb5_cc_cache_match. */
|
|
||||||
@@ -456,7 +464,7 @@ get_cache_for_name(krb5_context context, krb5_gss_cred_id_rec *cred)
|
|
||||||
/* Look for an existing cache for the client principal. */
|
|
||||||
code = krb5_cc_cache_match(context, cred->name->princ, &cred->ccache);
|
|
||||||
if (code == 0)
|
|
||||||
- return scan_ccache(context, cred);
|
|
||||||
+ return scan_ccache(context, cred, FALSE);
|
|
||||||
if (code != KRB5_CC_NOTFOUND || !can_get)
|
|
||||||
return code;
|
|
||||||
krb5_clear_error_message(context);
|
|
||||||
@@ -633,6 +641,13 @@ get_initial_cred(krb5_context context, const struct verify_params *verify,
|
|
||||||
kg_cred_set_initial_refresh(context, cred, &creds.times);
|
|
||||||
cred->have_tgt = TRUE;
|
|
||||||
cred->expire = creds.times.endtime;
|
|
||||||
+
|
|
||||||
+ /* Steal the canonical client principal name from creds and save it in the
|
|
||||||
+ * credential name, retaining acceptor_mprinc if set. */
|
|
||||||
+ krb5_free_principal(context, cred->name->princ);
|
|
||||||
+ cred->name->princ = creds.client;
|
|
||||||
+ creds.client = NULL;
|
|
||||||
+
|
|
||||||
krb5_free_cred_contents(context, &creds);
|
|
||||||
cleanup:
|
|
||||||
krb5_get_init_creds_opt_free(context, opt);
|
|
||||||
@@ -721,7 +736,7 @@ acquire_init_cred(krb5_context context, OM_uint32 *minor_status,
|
|
||||||
|
|
||||||
if (cred->ccache != NULL) {
|
|
||||||
/* The caller specified a ccache; check what's in it. */
|
|
||||||
- code = scan_ccache(context, cred);
|
|
||||||
+ code = scan_ccache(context, cred, TRUE);
|
|
||||||
if (code == KRB5_FCC_NOFILE) {
|
|
||||||
/* See if we can get initial creds. If the caller didn't specify
|
|
||||||
* a name, pick one from the client keytab. */
|
|
||||||
@@ -984,7 +999,7 @@ kg_cred_resolve(OM_uint32 *minor_status, krb5_context context,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cred->ccache != NULL) {
|
|
||||||
- code = scan_ccache(context, cred);
|
|
||||||
+ code = scan_ccache(context, cred, FALSE);
|
|
||||||
if (code)
|
|
||||||
goto kerr;
|
|
||||||
}
|
|
||||||
@@ -996,7 +1011,7 @@ kg_cred_resolve(OM_uint32 *minor_status, krb5_context context,
|
|
||||||
code = krb5int_cc_default(context, &cred->ccache);
|
|
||||||
if (code)
|
|
||||||
goto kerr;
|
|
||||||
- code = scan_ccache(context, cred);
|
|
||||||
+ code = scan_ccache(context, cred, FALSE);
|
|
||||||
if (code == KRB5_FCC_NOFILE) {
|
|
||||||
/* Default ccache doesn't exist; fall through to client keytab. */
|
|
||||||
krb5_cc_close(context, cred->ccache);
|
|
||||||
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
|
|
||||||
index 3bacdcd35..fd7abbd77 100644
|
|
||||||
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
|
|
||||||
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
|
|
||||||
@@ -175,6 +175,7 @@ typedef struct _krb5_gss_cred_id_rec {
|
|
||||||
/* name/type of credential */
|
|
||||||
gss_cred_usage_t usage;
|
|
||||||
krb5_gss_name_t name;
|
|
||||||
+ krb5_principal acceptor_mprinc;
|
|
||||||
krb5_principal impersonator;
|
|
||||||
unsigned int default_identity : 1;
|
|
||||||
unsigned int iakerb_mech : 1;
|
|
||||||
diff --git a/src/lib/gssapi/krb5/rel_cred.c b/src/lib/gssapi/krb5/rel_cred.c
|
|
||||||
index a9515daf7..0da6c1b95 100644
|
|
||||||
--- a/src/lib/gssapi/krb5/rel_cred.c
|
|
||||||
+++ b/src/lib/gssapi/krb5/rel_cred.c
|
|
||||||
@@ -72,6 +72,7 @@ krb5_gss_release_cred(minor_status, cred_handle)
|
|
||||||
if (cred->name)
|
|
||||||
kg_release_name(context, &cred->name);
|
|
||||||
|
|
||||||
+ krb5_free_principal(context, cred->acceptor_mprinc);
|
|
||||||
krb5_free_principal(context, cred->impersonator);
|
|
||||||
|
|
||||||
if (cred->req_enctypes)
|
|
||||||
diff --git a/src/lib/krb5/ccache/cccursor.c b/src/lib/krb5/ccache/cccursor.c
|
|
||||||
index 8f5872116..760216d05 100644
|
|
||||||
--- a/src/lib/krb5/ccache/cccursor.c
|
|
||||||
+++ b/src/lib/krb5/ccache/cccursor.c
|
|
||||||
@@ -30,6 +30,7 @@
|
|
||||||
|
|
||||||
#include "cc-int.h"
|
|
||||||
#include "../krb/int-proto.h"
|
|
||||||
+#include "../os/os-proto.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
@@ -141,18 +142,18 @@ krb5_cccol_cursor_free(krb5_context context,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-krb5_error_code KRB5_CALLCONV
|
|
||||||
-krb5_cc_cache_match(krb5_context context, krb5_principal client,
|
|
||||||
- krb5_ccache *cache_out)
|
|
||||||
+static krb5_error_code
|
|
||||||
+match_caches(krb5_context context, krb5_const_principal client,
|
|
||||||
+ krb5_ccache *cache_out)
|
|
||||||
{
|
|
||||||
krb5_error_code ret;
|
|
||||||
krb5_cccol_cursor cursor;
|
|
||||||
krb5_ccache cache = NULL;
|
|
||||||
krb5_principal princ;
|
|
||||||
- char *name;
|
|
||||||
krb5_boolean eq;
|
|
||||||
|
|
||||||
*cache_out = NULL;
|
|
||||||
+
|
|
||||||
ret = krb5_cccol_cursor_new(context, &cursor);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
@@ -169,20 +170,52 @@ krb5_cc_cache_match(krb5_context context, krb5_principal client,
|
|
||||||
krb5_cc_close(context, cache);
|
|
||||||
}
|
|
||||||
krb5_cccol_cursor_free(context, &cursor);
|
|
||||||
+
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
- if (cache == NULL) {
|
|
||||||
- ret = krb5_unparse_name(context, client, &name);
|
|
||||||
- if (ret == 0) {
|
|
||||||
- k5_setmsg(context, KRB5_CC_NOTFOUND,
|
|
||||||
+ if (cache == NULL)
|
|
||||||
+ return KRB5_CC_NOTFOUND;
|
|
||||||
+
|
|
||||||
+ *cache_out = cache;
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+krb5_error_code KRB5_CALLCONV
|
|
||||||
+krb5_cc_cache_match(krb5_context context, krb5_principal client,
|
|
||||||
+ krb5_ccache *cache_out)
|
|
||||||
+{
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+ struct canonprinc iter = { client, .subst_defrealm = TRUE };
|
|
||||||
+ krb5_const_principal canonprinc = NULL;
|
|
||||||
+ krb5_ccache cache = NULL;
|
|
||||||
+ char *name;
|
|
||||||
+
|
|
||||||
+ *cache_out = NULL;
|
|
||||||
+
|
|
||||||
+ while ((ret = k5_canonprinc(context, &iter, &canonprinc)) == 0 &&
|
|
||||||
+ canonprinc != NULL) {
|
|
||||||
+ ret = match_caches(context, canonprinc, &cache);
|
|
||||||
+ if (ret != KRB5_CC_NOTFOUND)
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ free_canonprinc(&iter);
|
|
||||||
+
|
|
||||||
+ if (ret == 0 && canonprinc == NULL) {
|
|
||||||
+ ret = KRB5_CC_NOTFOUND;
|
|
||||||
+ if (krb5_unparse_name(context, client, &name) == 0) {
|
|
||||||
+ k5_setmsg(context, ret,
|
|
||||||
_("Can't find client principal %s in cache collection"),
|
|
||||||
name);
|
|
||||||
krb5_free_unparsed_name(context, name);
|
|
||||||
}
|
|
||||||
- ret = KRB5_CC_NOTFOUND;
|
|
||||||
- } else
|
|
||||||
- *cache_out = cache;
|
|
||||||
- return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ TRACE_CC_CACHE_MATCH(context, client, ret);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ *cache_out = cache;
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store the error state for code from context into errsave, but only if code
|
|
||||||
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
|
|
||||||
index adbfa332b..df6e2ffbe 100644
|
|
||||||
--- a/src/lib/krb5/libkrb5.exports
|
|
||||||
+++ b/src/lib/krb5/libkrb5.exports
|
|
||||||
@@ -181,6 +181,7 @@ k5_size_authdata_context
|
|
||||||
k5_size_context
|
|
||||||
k5_size_keyblock
|
|
||||||
k5_size_principal
|
|
||||||
+k5_sname_compare
|
|
||||||
k5_unmarshal_cred
|
|
||||||
k5_unmarshal_princ
|
|
||||||
k5_unwrap_cammac_svc
|
|
||||||
diff --git a/src/lib/krb5/os/sn2princ.c b/src/lib/krb5/os/sn2princ.c
|
|
||||||
index 8b7214189..c99b7da17 100644
|
|
||||||
--- a/src/lib/krb5/os/sn2princ.c
|
|
||||||
+++ b/src/lib/krb5/os/sn2princ.c
|
|
||||||
@@ -277,7 +277,8 @@ k5_canonprinc(krb5_context context, struct canonprinc *iter,
|
|
||||||
|
|
||||||
/* If we're not doing fallback, the input principal is canonical. */
|
|
||||||
if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK ||
|
|
||||||
- iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2) {
|
|
||||||
+ iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2 ||
|
|
||||||
+ iter->princ->data[1].length == 0) {
|
|
||||||
*princ_out = (step == 1) ? iter->princ : NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -288,6 +289,26 @@ k5_canonprinc(krb5_context context, struct canonprinc *iter,
|
|
||||||
return canonicalize_princ(context, iter, step == 2, princ_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
+krb5_boolean
|
|
||||||
+k5_sname_compare(krb5_context context, krb5_const_principal sname,
|
|
||||||
+ krb5_const_principal princ)
|
|
||||||
+{
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+ struct canonprinc iter = { sname, .subst_defrealm = TRUE };
|
|
||||||
+ krb5_const_principal canonprinc = NULL;
|
|
||||||
+ krb5_boolean match = FALSE;
|
|
||||||
+
|
|
||||||
+ while ((ret = k5_canonprinc(context, &iter, &canonprinc)) == 0 &&
|
|
||||||
+ canonprinc != NULL) {
|
|
||||||
+ if (krb5_principal_compare(context, canonprinc, princ)) {
|
|
||||||
+ match = TRUE;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ free_canonprinc(&iter);
|
|
||||||
+ return match;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
krb5_error_code KRB5_CALLCONV
|
|
||||||
krb5_sname_to_principal(krb5_context context, const char *hostname,
|
|
||||||
const char *sname, krb5_int32 type,
|
|
||||||
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
|
|
||||||
index 60b8dd311..cf690dbe4 100644
|
|
||||||
--- a/src/lib/krb5_32.def
|
|
||||||
+++ b/src/lib/krb5_32.def
|
|
||||||
@@ -507,3 +507,4 @@ EXPORTS
|
|
||||||
; new in 1.20
|
|
||||||
krb5_marshal_credentials @472
|
|
||||||
krb5_unmarshal_credentials @473
|
|
||||||
+ k5_sname_compare @474 ; PRIVATE GSSAPI
|
|
||||||
diff --git a/src/tests/gssapi/t_client_keytab.py b/src/tests/gssapi/t_client_keytab.py
|
|
||||||
index 7847b3ecd..9a61d53b8 100755
|
|
||||||
--- a/src/tests/gssapi/t_client_keytab.py
|
|
||||||
+++ b/src/tests/gssapi/t_client_keytab.py
|
|
||||||
@@ -141,5 +141,49 @@ msgs = ('Getting initial credentials for user/admin@KRBTEST.COM',
|
|
||||||
'/Matching credential not found')
|
|
||||||
realm.run(['./t_ccselect', phost], expected_code=1,
|
|
||||||
expected_msg='Ticket expired', expected_trace=msgs)
|
|
||||||
+realm.run([kdestroy, '-A'])
|
|
||||||
+
|
|
||||||
+# Test 19: host-based initiator name
|
|
||||||
+mark('host-based initiator name')
|
|
||||||
+hsvc = 'h:svc@' + hostname
|
|
||||||
+svcprinc = 'svc/%s@%s' % (hostname, realm.realm)
|
|
||||||
+realm.addprinc(svcprinc)
|
|
||||||
+realm.extract_keytab(svcprinc, realm.client_keytab)
|
|
||||||
+# On the first run we match against the keytab while getting tickets,
|
|
||||||
+# substituting the default realm.
|
|
||||||
+msgs = ('/Can\'t find client principal svc/%s@ in' % hostname,
|
|
||||||
+ 'Getting initial credentials for svc/%s@' % hostname,
|
|
||||||
+ 'Found entries for %s in keytab' % svcprinc,
|
|
||||||
+ 'Retrieving %s from FILE:%s' % (svcprinc, realm.client_keytab),
|
|
||||||
+ 'Storing %s -> %s in' % (svcprinc, realm.krbtgt_princ),
|
|
||||||
+ 'Retrieving %s -> %s from' % (svcprinc, realm.krbtgt_princ),
|
|
||||||
+ 'authenticator for %s -> %s' % (svcprinc, realm.host_princ))
|
|
||||||
+realm.run(['./t_ccselect', phost, hsvc], expected_trace=msgs)
|
|
||||||
+# On the second run we match against the collection.
|
|
||||||
+msgs = ('Matching svc/%s@ in collection with result: 0' % hostname,
|
|
||||||
+ 'Getting credentials %s -> %s' % (svcprinc, realm.host_princ),
|
|
||||||
+ 'authenticator for %s -> %s' % (svcprinc, realm.host_princ))
|
|
||||||
+realm.run(['./t_ccselect', phost, hsvc], expected_trace=msgs)
|
|
||||||
+realm.run([kdestroy, '-A'])
|
|
||||||
+
|
|
||||||
+# Test 20: host-based initiator name with fallback
|
|
||||||
+mark('host-based fallback initiator name')
|
|
||||||
+canonname = canonicalize_hostname(hostname)
|
|
||||||
+if canonname != hostname:
|
|
||||||
+ hfsvc = 'h:fsvc@' + hostname
|
|
||||||
+ canonprinc = 'fsvc/%s@%s' % (canonname, realm.realm)
|
|
||||||
+ realm.addprinc(canonprinc)
|
|
||||||
+ realm.extract_keytab(canonprinc, realm.client_keytab)
|
|
||||||
+ msgs = ('/Can\'t find client principal fsvc/%s@ in' % hostname,
|
|
||||||
+ 'Found entries for %s in keytab' % canonprinc,
|
|
||||||
+ 'authenticator for %s -> %s' % (canonprinc, realm.host_princ))
|
|
||||||
+ realm.run(['./t_ccselect', phost, hfsvc], expected_trace=msgs)
|
|
||||||
+ msgs = ('Matching fsvc/%s@ in collection with result: 0' % hostname,
|
|
||||||
+ 'Getting credentials %s -> %s' % (canonprinc, realm.host_princ))
|
|
||||||
+ realm.run(['./t_ccselect', phost, hfsvc], expected_trace=msgs)
|
|
||||||
+ realm.run([kdestroy, '-A'])
|
|
||||||
+else:
|
|
||||||
+ skipped('GSS initiator name fallback test',
|
|
||||||
+ '%s does not canonicalize to a different name' % hostname)
|
|
||||||
|
|
||||||
success('Client keytab tests')
|
|
||||||
diff --git a/src/tests/gssapi/t_credstore.py b/src/tests/gssapi/t_credstore.py
|
|
||||||
index c11975bf5..9be57bb82 100644
|
|
||||||
--- a/src/tests/gssapi/t_credstore.py
|
|
||||||
+++ b/src/tests/gssapi/t_credstore.py
|
|
||||||
@@ -15,6 +15,38 @@ msgs = ('Storing %s -> %s in %s' % (service_cs, realm.krbtgt_princ,
|
|
||||||
realm.run(['./t_credstore', '-s', 'p:' + service_cs, 'ccache', storagecache,
|
|
||||||
'keytab', servicekeytab], expected_trace=msgs)
|
|
||||||
|
|
||||||
+mark('matching')
|
|
||||||
+scc = 'FILE:' + os.path.join(realm.testdir, 'service_cache')
|
|
||||||
+realm.kinit(realm.host_princ, flags=['-k', '-c', scc])
|
|
||||||
+realm.run(['./t_credstore', '-i', 'p:' + realm.host_princ, 'ccache', scc])
|
|
||||||
+realm.run(['./t_credstore', '-i', 'h:host', 'ccache', scc])
|
|
||||||
+realm.run(['./t_credstore', '-i', 'h:host@' + hostname, 'ccache', scc])
|
|
||||||
+realm.run(['./t_credstore', '-i', 'p:wrong', 'ccache', scc],
|
|
||||||
+ expected_code=1, expected_msg='does not match desired name')
|
|
||||||
+realm.run(['./t_credstore', '-i', 'h:host@-nomatch-', 'ccache', scc],
|
|
||||||
+ expected_code=1, expected_msg='does not match desired name')
|
|
||||||
+realm.run(['./t_credstore', '-i', 'h:svc', 'ccache', scc],
|
|
||||||
+ expected_code=1, expected_msg='does not match desired name')
|
|
||||||
+
|
|
||||||
+mark('matching (fallback)')
|
|
||||||
+canonname = canonicalize_hostname(hostname)
|
|
||||||
+if canonname != hostname:
|
|
||||||
+ canonprinc = 'host/%s@%s' % (canonname, realm.realm)
|
|
||||||
+ realm.addprinc(canonprinc)
|
|
||||||
+ realm.extract_keytab(canonprinc, realm.keytab)
|
|
||||||
+ realm.kinit(canonprinc, flags=['-k', '-c', scc])
|
|
||||||
+ realm.run(['./t_credstore', '-i', 'h:host', 'ccache', scc])
|
|
||||||
+ realm.run(['./t_credstore', '-i', 'h:host@' + hostname, 'ccache', scc])
|
|
||||||
+ realm.run(['./t_credstore', '-i', 'h:host@' + canonname, 'ccache', scc])
|
|
||||||
+ realm.run(['./t_credstore', '-i', 'p:' + canonprinc, 'ccache', scc])
|
|
||||||
+ realm.run(['./t_credstore', '-i', 'p:' + realm.host_princ, 'ccache', scc],
|
|
||||||
+ expected_code=1, expected_msg='does not match desired name')
|
|
||||||
+ realm.run(['./t_credstore', '-i', 'h:host@-nomatch-', 'ccache', scc],
|
|
||||||
+ expected_code=1, expected_msg='does not match desired name')
|
|
||||||
+else:
|
|
||||||
+ skipped('fallback matching test',
|
|
||||||
+ '%s does not canonicalize to a different name' % hostname)
|
|
||||||
+
|
|
||||||
mark('rcache')
|
|
||||||
# t_credstore -r should produce a replay error normally, but not with
|
|
||||||
# rcache set to "none:".
|
|
@ -1,91 +0,0 @@
|
|||||||
From ad8e02485791023dcf66ef4612616f03895ceeb3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Greg Hudson <ghudson@mit.edu>
|
|
||||||
Date: Fri, 4 Mar 2022 00:45:00 -0500
|
|
||||||
Subject: [PATCH] Try harder to avoid password change replay errors
|
|
||||||
|
|
||||||
Commit d7b3018d338fc9c989c3fa17505870f23c3759a8 (ticket 7905) changed
|
|
||||||
change_set_password() to prefer TCP. However, because UDP_LAST falls
|
|
||||||
back to UDP after one second, we can still get a replay error due to a
|
|
||||||
dropped packet, before the TCP layer has a chance to retry.
|
|
||||||
|
|
||||||
Instead, try k5_sendto() with NO_UDP, and only fall back to UDP after
|
|
||||||
TCP fails completely without reaching a server. In sendto_kdc.c,
|
|
||||||
implement an ONLY_UDP transport strategy to allow the UDP fallback.
|
|
||||||
|
|
||||||
ticket: 9037
|
|
||||||
---
|
|
||||||
src/lib/krb5/os/changepw.c | 9 ++++++++-
|
|
||||||
src/lib/krb5/os/os-proto.h | 1 +
|
|
||||||
src/lib/krb5/os/sendto_kdc.c | 12 ++++++++----
|
|
||||||
3 files changed, 17 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c
|
|
||||||
index 9f968da7f..c59232586 100644
|
|
||||||
--- a/src/lib/krb5/os/changepw.c
|
|
||||||
+++ b/src/lib/krb5/os/changepw.c
|
|
||||||
@@ -255,9 +255,16 @@ change_set_password(krb5_context context,
|
|
||||||
callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup;
|
|
||||||
krb5_free_data_contents(callback_ctx.context, &chpw_rep);
|
|
||||||
|
|
||||||
+ /* UDP retransmits may be seen as replays. Only try UDP after other
|
|
||||||
+ * transports fail completely. */
|
|
||||||
code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm,
|
|
||||||
- &sl, UDP_LAST, &callback_info, &chpw_rep,
|
|
||||||
+ &sl, NO_UDP, &callback_info, &chpw_rep,
|
|
||||||
ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL);
|
|
||||||
+ if (code == KRB5_KDC_UNREACH) {
|
|
||||||
+ code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm,
|
|
||||||
+ &sl, ONLY_UDP, &callback_info, &chpw_rep,
|
|
||||||
+ ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL);
|
|
||||||
+ }
|
|
||||||
if (code)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
|
|
||||||
index a985f2aec..91d2791ce 100644
|
|
||||||
--- a/src/lib/krb5/os/os-proto.h
|
|
||||||
+++ b/src/lib/krb5/os/os-proto.h
|
|
||||||
@@ -49,6 +49,7 @@ typedef enum {
|
|
||||||
UDP_FIRST = 0,
|
|
||||||
UDP_LAST,
|
|
||||||
NO_UDP,
|
|
||||||
+ ONLY_UDP
|
|
||||||
} k5_transport_strategy;
|
|
||||||
|
|
||||||
/* A single server hostname or address. */
|
|
||||||
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
|
|
||||||
index 0eedec175..c7f5d861a 100644
|
|
||||||
--- a/src/lib/krb5/os/sendto_kdc.c
|
|
||||||
+++ b/src/lib/krb5/os/sendto_kdc.c
|
|
||||||
@@ -802,11 +802,14 @@ resolve_server(krb5_context context, const krb5_data *realm,
|
|
||||||
int err, result;
|
|
||||||
char portbuf[PORT_LENGTH];
|
|
||||||
|
|
||||||
- /* Skip UDP entries if we don't want UDP. */
|
|
||||||
+ /* Skip entries excluded by the strategy. */
|
|
||||||
if (strategy == NO_UDP && entry->transport == UDP)
|
|
||||||
return 0;
|
|
||||||
+ if (strategy == ONLY_UDP && entry->transport != UDP &&
|
|
||||||
+ entry->transport != TCP_OR_UDP)
|
|
||||||
+ return 0;
|
|
||||||
|
|
||||||
- transport = (strategy == UDP_FIRST) ? UDP : TCP;
|
|
||||||
+ transport = (strategy == UDP_FIRST || strategy == ONLY_UDP) ? UDP : TCP;
|
|
||||||
if (entry->hostname == NULL) {
|
|
||||||
/* Added by a module, so transport is either TCP or UDP. */
|
|
||||||
ai.ai_socktype = socktype_for_transport(entry->transport);
|
|
||||||
@@ -850,8 +853,9 @@ resolve_server(krb5_context context, const krb5_data *realm,
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For TCP_OR_UDP entries, add each address again with the non-preferred
|
|
||||||
- * transport, unless we are avoiding UDP. Flag these as deferred. */
|
|
||||||
- if (retval == 0 && entry->transport == TCP_OR_UDP && strategy != NO_UDP) {
|
|
||||||
+ * transport, if there is one. Flag these as deferred. */
|
|
||||||
+ if (retval == 0 && entry->transport == TCP_OR_UDP &&
|
|
||||||
+ (strategy == UDP_FIRST || strategy == UDP_LAST)) {
|
|
||||||
transport = (strategy == UDP_FIRST) ? TCP : UDP;
|
|
||||||
for (a = addrs; a != 0 && retval == 0; a = a->ai_next) {
|
|
||||||
a->ai_socktype = socktype_for_transport(transport);
|
|
||||||
--
|
|
||||||
2.35.1
|
|
||||||
|
|
@ -1,236 +0,0 @@
|
|||||||
From 43e3bca2a711de257091454bc5e25a985340d847 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Greg Hudson <ghudson@mit.edu>
|
|
||||||
Date: Fri, 26 Mar 2021 23:38:54 -0400
|
|
||||||
Subject: [PATCH] Use KCM_OP_RETRIEVE in KCM client
|
|
||||||
|
|
||||||
In kcm_retrieve(), try KCM_OP_RETRIEVE. Fall back to iteration if the
|
|
||||||
server doesn't implement it, or if we can an answer incompatible with
|
|
||||||
KRB5_TC_SUPPORTED_KTYPES.
|
|
||||||
|
|
||||||
In kcmserver.py, implement partial decoding for creds and cred tags so
|
|
||||||
that we can do a basic principal name match.
|
|
||||||
|
|
||||||
ticket: 8997 (new)
|
|
||||||
(cherry picked from commit 795ebba8c039be172ab93cd41105c73ffdba0fdb)
|
|
||||||
(cherry picked from commit c56d4b87de0f30a38dc61d374ad225d02d581eb3)
|
|
||||||
---
|
|
||||||
src/include/kcm.h | 2 +-
|
|
||||||
src/lib/krb5/ccache/cc_kcm.c | 52 +++++++++++++++++++++++++++++++++---
|
|
||||||
src/tests/kcmserver.py | 44 +++++++++++++++++++++++++++---
|
|
||||||
src/tests/t_ccache.py | 11 +++++---
|
|
||||||
4 files changed, 99 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/include/kcm.h b/src/include/kcm.h
|
|
||||||
index 9b66f1cbd..85c20d345 100644
|
|
||||||
--- a/src/include/kcm.h
|
|
||||||
+++ b/src/include/kcm.h
|
|
||||||
@@ -87,7 +87,7 @@ typedef enum kcm_opcode {
|
|
||||||
KCM_OP_INITIALIZE, /* (name, princ) -> () */
|
|
||||||
KCM_OP_DESTROY, /* (name) -> () */
|
|
||||||
KCM_OP_STORE, /* (name, cred) -> () */
|
|
||||||
- KCM_OP_RETRIEVE,
|
|
||||||
+ KCM_OP_RETRIEVE, /* (name, flags, credtag) -> (cred) */
|
|
||||||
KCM_OP_GET_PRINCIPAL, /* (name) -> (princ) */
|
|
||||||
KCM_OP_GET_CRED_UUID_LIST, /* (name) -> (uuid, ...) */
|
|
||||||
KCM_OP_GET_CRED_BY_UUID, /* (name, uuid) -> (cred) */
|
|
||||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
index 46705f1da..23fcf13ea 100644
|
|
||||||
--- a/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
+++ b/src/lib/krb5/ccache/cc_kcm.c
|
|
||||||
@@ -826,9 +826,55 @@ static krb5_error_code KRB5_CALLCONV
|
|
||||||
kcm_retrieve(krb5_context context, krb5_ccache cache, krb5_flags flags,
|
|
||||||
krb5_creds *mcred, krb5_creds *cred_out)
|
|
||||||
{
|
|
||||||
- /* There is a KCM opcode for retrieving creds, but Heimdal's client doesn't
|
|
||||||
- * use it. It causes the KCM daemon to actually make a TGS request. */
|
|
||||||
- return k5_cc_retrieve_cred_default(context, cache, flags, mcred, cred_out);
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+ struct kcmreq req = EMPTY_KCMREQ;
|
|
||||||
+ krb5_creds cred;
|
|
||||||
+ krb5_enctype *enctypes = NULL;
|
|
||||||
+
|
|
||||||
+ memset(&cred, 0, sizeof(cred));
|
|
||||||
+
|
|
||||||
+ /* Include KCM_GC_CACHED in flags to prevent Heimdal's sssd from making a
|
|
||||||
+ * TGS request itself. */
|
|
||||||
+ kcmreq_init(&req, KCM_OP_RETRIEVE, cache);
|
|
||||||
+ k5_buf_add_uint32_be(&req.reqbuf, map_tcflags(flags) | KCM_GC_CACHED);
|
|
||||||
+ k5_marshal_mcred(&req.reqbuf, mcred);
|
|
||||||
+ ret = cache_call(context, cache, &req);
|
|
||||||
+
|
|
||||||
+ /* Fall back to iteration if the server does not support retrieval. */
|
|
||||||
+ if (ret == KRB5_FCC_INTERNAL || ret == KRB5_CC_IO) {
|
|
||||||
+ ret = k5_cc_retrieve_cred_default(context, cache, flags, mcred,
|
|
||||||
+ cred_out);
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+
|
|
||||||
+ ret = k5_unmarshal_cred(req.reply.ptr, req.reply.len, 4, &cred);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+
|
|
||||||
+ /* In rare cases we might retrieve a credential with a session key this
|
|
||||||
+ * context can't support, in which case we must retry using iteration. */
|
|
||||||
+ if (flags & KRB5_TC_SUPPORTED_KTYPES) {
|
|
||||||
+ ret = krb5_get_tgs_ktypes(context, cred.server, &enctypes);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+ if (!k5_etypes_contains(enctypes, cred.keyblock.enctype)) {
|
|
||||||
+ ret = k5_cc_retrieve_cred_default(context, cache, flags, mcred,
|
|
||||||
+ cred_out);
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ *cred_out = cred;
|
|
||||||
+ memset(&cred, 0, sizeof(cred));
|
|
||||||
+
|
|
||||||
+cleanup:
|
|
||||||
+ kcmreq_free(&req);
|
|
||||||
+ krb5_free_cred_contents(context, &cred);
|
|
||||||
+ free(enctypes);
|
|
||||||
+ /* Heimdal's KCM returns KRB5_CC_END if no cred is found. */
|
|
||||||
+ return (ret == KRB5_CC_END) ? KRB5_CC_NOTFOUND : map_invalid(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static krb5_error_code KRB5_CALLCONV
|
|
||||||
diff --git a/src/tests/kcmserver.py b/src/tests/kcmserver.py
|
|
||||||
index 8c5e66ff1..25e6f2bbe 100644
|
|
||||||
--- a/src/tests/kcmserver.py
|
|
||||||
+++ b/src/tests/kcmserver.py
|
|
||||||
@@ -40,6 +40,7 @@ class KCMOpcodes(object):
|
|
||||||
INITIALIZE = 4
|
|
||||||
DESTROY = 5
|
|
||||||
STORE = 6
|
|
||||||
+ RETRIEVE = 7
|
|
||||||
GET_PRINCIPAL = 8
|
|
||||||
GET_CRED_UUID_LIST = 9
|
|
||||||
GET_CRED_BY_UUID = 10
|
|
||||||
@@ -54,6 +55,7 @@ class KCMOpcodes(object):
|
|
||||||
|
|
||||||
|
|
||||||
class KRB5Errors(object):
|
|
||||||
+ KRB5_CC_NOTFOUND = -1765328243
|
|
||||||
KRB5_CC_END = -1765328242
|
|
||||||
KRB5_CC_NOSUPP = -1765328137
|
|
||||||
KRB5_FCC_NOFILE = -1765328189
|
|
||||||
@@ -86,11 +88,29 @@ def get_cache(name):
|
|
||||||
return cache
|
|
||||||
|
|
||||||
|
|
||||||
+def unpack_data(argbytes):
|
|
||||||
+ dlen, = struct.unpack('>L', argbytes[:4])
|
|
||||||
+ return argbytes[4:dlen+4], argbytes[dlen+4:]
|
|
||||||
+
|
|
||||||
+
|
|
||||||
def unmarshal_name(argbytes):
|
|
||||||
offset = argbytes.find(b'\0')
|
|
||||||
return argbytes[0:offset], argbytes[offset+1:]
|
|
||||||
|
|
||||||
|
|
||||||
+def unmarshal_princ(argbytes):
|
|
||||||
+ # Ignore the type at argbytes[0:4].
|
|
||||||
+ ncomps, = struct.unpack('>L', argbytes[4:8])
|
|
||||||
+ realm, rest = unpack_data(argbytes[8:])
|
|
||||||
+ comps = []
|
|
||||||
+ for i in range(ncomps):
|
|
||||||
+ comp, rest = unpack_data(rest)
|
|
||||||
+ comps.append(comp)
|
|
||||||
+ # Asssume no quoting is needed.
|
|
||||||
+ princ = b'/'.join(comps) + b'@' + realm
|
|
||||||
+ return princ, rest
|
|
||||||
+
|
|
||||||
+
|
|
||||||
def op_gen_new(argbytes):
|
|
||||||
# Does not actually check for uniqueness.
|
|
||||||
global next_unique
|
|
||||||
@@ -126,6 +146,22 @@ def op_store(argbytes):
|
|
||||||
return 0, b''
|
|
||||||
|
|
||||||
|
|
||||||
+def op_retrieve(argbytes):
|
|
||||||
+ name, rest = unmarshal_name(argbytes)
|
|
||||||
+ # Ignore the flags at rest[0:4] and the header at rest[4:8].
|
|
||||||
+ # Assume there are client and server creds in the tag and match
|
|
||||||
+ # only against them.
|
|
||||||
+ cprinc, rest = unmarshal_princ(rest[8:])
|
|
||||||
+ sprinc, rest = unmarshal_princ(rest)
|
|
||||||
+ cache = get_cache(name)
|
|
||||||
+ for cred in (cache.creds[u] for u in cache.cred_uuids):
|
|
||||||
+ cred_cprinc, rest = unmarshal_princ(cred)
|
|
||||||
+ cred_sprinc, rest = unmarshal_princ(rest)
|
|
||||||
+ if cred_cprinc == cprinc and cred_sprinc == sprinc:
|
|
||||||
+ return 0, cred
|
|
||||||
+ return KRB5Errors.KRB5_CC_NOTFOUND, b''
|
|
||||||
+
|
|
||||||
+
|
|
||||||
def op_get_principal(argbytes):
|
|
||||||
name, rest = unmarshal_name(argbytes)
|
|
||||||
cache = get_cache(name)
|
|
||||||
@@ -199,6 +235,7 @@ ophandlers = {
|
|
||||||
KCMOpcodes.INITIALIZE : op_initialize,
|
|
||||||
KCMOpcodes.DESTROY : op_destroy,
|
|
||||||
KCMOpcodes.STORE : op_store,
|
|
||||||
+ KCMOpcodes.RETRIEVE : op_retrieve,
|
|
||||||
KCMOpcodes.GET_PRINCIPAL : op_get_principal,
|
|
||||||
KCMOpcodes.GET_CRED_UUID_LIST : op_get_cred_uuid_list,
|
|
||||||
KCMOpcodes.GET_CRED_BY_UUID : op_get_cred_by_uuid,
|
|
||||||
@@ -243,10 +280,11 @@ def service_request(s):
|
|
||||||
return True
|
|
||||||
|
|
||||||
parser = optparse.OptionParser()
|
|
||||||
-parser.add_option('-c', '--credlist', action='store_true', dest='credlist',
|
|
||||||
- default=False, help='Support KCM_OP_GET_CRED_LIST')
|
|
||||||
+parser.add_option('-f', '--fallback', action='store_true', dest='fallback',
|
|
||||||
+ default=False, help='Do not support RETRIEVE/GET_CRED_LIST')
|
|
||||||
(options, args) = parser.parse_args()
|
|
||||||
-if not options.credlist:
|
|
||||||
+if options.fallback:
|
|
||||||
+ del ophandlers[KCMOpcodes.RETRIEVE]
|
|
||||||
del ophandlers[KCMOpcodes.GET_CRED_LIST]
|
|
||||||
|
|
||||||
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
||||||
diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py
|
|
||||||
index 90040fb7b..6ea9fb969 100755
|
|
||||||
--- a/src/tests/t_ccache.py
|
|
||||||
+++ b/src/tests/t_ccache.py
|
|
||||||
@@ -25,7 +25,7 @@ from k5test import *
|
|
||||||
kcm_socket_path = os.path.join(os.getcwd(), 'testdir', 'kcm')
|
|
||||||
conf = {'libdefaults': {'kcm_socket': kcm_socket_path,
|
|
||||||
'kcm_mach_service': '-'}}
|
|
||||||
-realm = K5Realm(create_host=False, krb5_conf=conf)
|
|
||||||
+realm = K5Realm(krb5_conf=conf)
|
|
||||||
|
|
||||||
keyctl = which('keyctl')
|
|
||||||
out = realm.run([klist, '-c', 'KEYRING:process:abcd'], expected_code=1)
|
|
||||||
@@ -71,6 +71,11 @@ def collection_test(realm, ccname):
|
|
||||||
realm.kinit('alice', password('alice'))
|
|
||||||
realm.run([klist], expected_msg='Default principal: alice@')
|
|
||||||
realm.run([klist, '-A', '-s'])
|
|
||||||
+ realm.run([kvno, realm.host_princ], expected_msg = 'kvno = 1')
|
|
||||||
+ realm.run([kvno, realm.host_princ], expected_msg = 'kvno = 1')
|
|
||||||
+ out = realm.run([klist])
|
|
||||||
+ if out.count(realm.host_princ) != 1:
|
|
||||||
+ fail('Wrong number of service tickets in cache')
|
|
||||||
realm.run([kdestroy])
|
|
||||||
output = realm.run([klist], expected_code=1)
|
|
||||||
if 'No credentials cache' not in output and 'not found' not in output:
|
|
||||||
@@ -126,14 +131,14 @@ def collection_test(realm, ccname):
|
|
||||||
|
|
||||||
collection_test(realm, 'DIR:' + os.path.join(realm.testdir, 'cc'))
|
|
||||||
|
|
||||||
-# Test KCM without and with GET_CRED_LIST support.
|
|
||||||
+# Test KCM with and without RETRIEVE and GET_CRED_LIST support.
|
|
||||||
kcmserver_path = os.path.join(srctop, 'tests', 'kcmserver.py')
|
|
||||||
kcmd = realm.start_server([sys.executable, kcmserver_path, kcm_socket_path],
|
|
||||||
'starting...')
|
|
||||||
collection_test(realm, 'KCM:')
|
|
||||||
stop_daemon(kcmd)
|
|
||||||
os.remove(kcm_socket_path)
|
|
||||||
-realm.start_server([sys.executable, kcmserver_path, '-c', kcm_socket_path],
|
|
||||||
+realm.start_server([sys.executable, kcmserver_path, '-f', kcm_socket_path],
|
|
||||||
'starting...')
|
|
||||||
collection_test(realm, 'KCM:')
|
|
||||||
|
|
@ -1,485 +0,0 @@
|
|||||||
From 21e3b9a4463f1d1aeb71de8a27c298f1307d186b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
Date: Fri, 4 Oct 2019 14:49:29 -0400
|
|
||||||
Subject: [PATCH] Use OpenSSL's KBKDF and KRB5KDF for deriving long-term keys
|
|
||||||
|
|
||||||
If supported, use OpenSSL-provided KBKDF (aes-sha2 and camellia) and
|
|
||||||
KRB5KDF (3des and aes-sha1). We already use OpenSSL's PBKDF2 where
|
|
||||||
appropriate. OpenSSL added support for these KDFs in 3.0.
|
|
||||||
|
|
||||||
OpenSSL's restrictions to use KRB5KDF in FIPS mode are bypassed in case
|
|
||||||
AES SHA-1 HMAC encryption types are allowed by the crypto policy.
|
|
||||||
|
|
||||||
(cherry picked from commit ef8d11f6fb1232201c9efd2ae2ed567023fb85d2)
|
|
||||||
[rharwood@redhat.com: 3des removal]
|
|
||||||
---
|
|
||||||
src/lib/crypto/krb/derive.c | 409 ++++++++++++++++++++++++++++--------
|
|
||||||
1 file changed, 324 insertions(+), 85 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/lib/crypto/krb/derive.c b/src/lib/crypto/krb/derive.c
|
|
||||||
index 6707a7308..8e474b38e 100644
|
|
||||||
--- a/src/lib/crypto/krb/derive.c
|
|
||||||
+++ b/src/lib/crypto/krb/derive.c
|
|
||||||
@@ -27,6 +27,12 @@
|
|
||||||
|
|
||||||
#include "crypto_int.h"
|
|
||||||
|
|
||||||
+#ifdef HAVE_EVP_KDF_FETCH
|
|
||||||
+#include <openssl/core_names.h>
|
|
||||||
+#include <openssl/evp.h>
|
|
||||||
+#include <openssl/kdf.h>
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
static krb5_key
|
|
||||||
find_cached_dkey(struct derived_key *list, const krb5_data *constant)
|
|
||||||
{
|
|
||||||
@@ -77,55 +83,251 @@ cleanup:
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
+#ifdef HAVE_EVP_KDF_FETCH
|
|
||||||
static krb5_error_code
|
|
||||||
-derive_random_rfc3961(const struct krb5_enc_provider *enc,
|
|
||||||
- krb5_key inkey, krb5_data *outrnd,
|
|
||||||
- const krb5_data *in_constant)
|
|
||||||
+openssl_kbdkf_counter_hmac(const struct krb5_hash_provider *hash,
|
|
||||||
+ krb5_key inkey, krb5_data *outrnd,
|
|
||||||
+ const krb5_data *label, const krb5_data *context)
|
|
||||||
{
|
|
||||||
- size_t blocksize, keybytes, n;
|
|
||||||
krb5_error_code ret;
|
|
||||||
- krb5_data block = empty_data();
|
|
||||||
+ EVP_KDF *kdf = NULL;
|
|
||||||
+ EVP_KDF_CTX *kctx = NULL;
|
|
||||||
+ OSSL_PARAM params[6];
|
|
||||||
+ size_t i = 0;
|
|
||||||
+ char *digest;
|
|
||||||
|
|
||||||
- blocksize = enc->block_size;
|
|
||||||
- keybytes = enc->keybytes;
|
|
||||||
+ /* On NULL hash, preserve default behavior for pbkdf2_string_to_key(). */
|
|
||||||
+ if (hash == NULL || !strcmp(hash->hash_name, "SHA1")) {
|
|
||||||
+ digest = "SHA1";
|
|
||||||
+ } else if (!strcmp(hash->hash_name, "SHA-256")) {
|
|
||||||
+ digest = "SHA256";
|
|
||||||
+ } else if (!strcmp(hash->hash_name, "SHA-384")) {
|
|
||||||
+ digest = "SHA384";
|
|
||||||
+ } else {
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- if (blocksize == 1)
|
|
||||||
- return KRB5_BAD_ENCTYPE;
|
|
||||||
- if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
|
|
||||||
+ kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL);
|
|
||||||
+ if (!kdf) {
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ kctx = EVP_KDF_CTX_new(kdf);
|
|
||||||
+ if (!kctx) {
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
|
|
||||||
+ digest, 0);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC,
|
|
||||||
+ "HMAC", 0);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
|
|
||||||
+ inkey->keyblock.contents,
|
|
||||||
+ inkey->keyblock.length);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
|
|
||||||
+ context->data,
|
|
||||||
+ context->length);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
|
|
||||||
+ label->data,
|
|
||||||
+ label->length);
|
|
||||||
+ params[i] = OSSL_PARAM_construct_end();
|
|
||||||
+ if (EVP_KDF_derive(kctx, (unsigned char *)outrnd->data, outrnd->length,
|
|
||||||
+ params) <= 0) {
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = 0;
|
|
||||||
+done:
|
|
||||||
+ if (ret)
|
|
||||||
+ zap(outrnd->data, outrnd->length);
|
|
||||||
+ EVP_KDF_free(kdf);
|
|
||||||
+ EVP_KDF_CTX_free(kctx);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static krb5_error_code
|
|
||||||
+openssl_kbkdf_feedback_cmac(const struct krb5_enc_provider *enc,
|
|
||||||
+ krb5_key inkey, krb5_data *outrnd,
|
|
||||||
+ const krb5_data *in_constant)
|
|
||||||
+{
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+ EVP_KDF *kdf = NULL;
|
|
||||||
+ EVP_KDF_CTX *kctx = NULL;
|
|
||||||
+ OSSL_PARAM params[7];
|
|
||||||
+ size_t i = 0;
|
|
||||||
+ char *cipher;
|
|
||||||
+ static unsigned char zeroes[16];
|
|
||||||
+
|
|
||||||
+ memset(zeroes, 0, sizeof(zeroes));
|
|
||||||
+
|
|
||||||
+ if (!memcmp(enc, &krb5int_enc_camellia128, sizeof(*enc))) {
|
|
||||||
+ cipher = "CAMELLIA-128-CBC";
|
|
||||||
+ } else if (!memcmp(enc, &krb5int_enc_camellia256, sizeof(*enc))) {
|
|
||||||
+ cipher = "CAMELLIA-256-CBC";
|
|
||||||
+ } else {
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL);
|
|
||||||
+ if (!kdf) {
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ kctx = EVP_KDF_CTX_new(kdf);
|
|
||||||
+ if (!kctx) {
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE,
|
|
||||||
+ "FEEDBACK", 0);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC,
|
|
||||||
+ "CMAC", 0);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CIPHER,
|
|
||||||
+ cipher, 0);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
|
|
||||||
+ inkey->keyblock.contents,
|
|
||||||
+ inkey->keyblock.length);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
|
|
||||||
+ in_constant->data,
|
|
||||||
+ in_constant->length);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED,
|
|
||||||
+ zeroes, sizeof(zeroes));
|
|
||||||
+ params[i] = OSSL_PARAM_construct_end();
|
|
||||||
+ if (EVP_KDF_derive(kctx, (unsigned char *)outrnd->data, outrnd->length,
|
|
||||||
+ params) <= 0) {
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = 0;
|
|
||||||
+done:
|
|
||||||
+ if (ret)
|
|
||||||
+ zap(outrnd->data, outrnd->length);
|
|
||||||
+ EVP_KDF_free(kdf);
|
|
||||||
+ EVP_KDF_CTX_free(kctx);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static krb5_error_code
|
|
||||||
+openssl_krb5kdf(const struct krb5_enc_provider *enc, krb5_key inkey,
|
|
||||||
+ krb5_data *outrnd, const krb5_data *in_constant)
|
|
||||||
+{
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+ EVP_KDF *kdf = NULL;
|
|
||||||
+ EVP_KDF_CTX *kctx = NULL;
|
|
||||||
+ OSSL_PARAM params[4];
|
|
||||||
+ size_t i = 0;
|
|
||||||
+ char *cipher;
|
|
||||||
+
|
|
||||||
+ if (inkey->keyblock.length != enc->keylength ||
|
|
||||||
+ outrnd->length != enc->keybytes) {
|
|
||||||
+ return KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!memcmp(enc, &krb5int_enc_aes128, sizeof(*enc))) {
|
|
||||||
+ cipher = "AES-128-CBC";
|
|
||||||
+ } else if (!memcmp(enc, &krb5int_enc_aes256, sizeof(*enc))) {
|
|
||||||
+ cipher = "AES-256-CBC";
|
|
||||||
+ } else {
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ kdf = EVP_KDF_fetch(NULL, "KRB5KDF", "-fips");
|
|
||||||
+ if (kdf == NULL) {
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ kctx = EVP_KDF_CTX_new(kdf);
|
|
||||||
+ if (kctx == NULL) {
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CIPHER,
|
|
||||||
+ cipher, 0);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
|
|
||||||
+ inkey->keyblock.contents,
|
|
||||||
+ inkey->keyblock.length);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_CONSTANT,
|
|
||||||
+ in_constant->data,
|
|
||||||
+ in_constant->length);
|
|
||||||
+ params[i] = OSSL_PARAM_construct_end();
|
|
||||||
+ if (EVP_KDF_derive(kctx, (unsigned char *)outrnd->data, outrnd->length,
|
|
||||||
+ params) <= 0) {
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = 0;
|
|
||||||
+done:
|
|
||||||
+ if (ret)
|
|
||||||
+ zap(outrnd->data, outrnd->length);
|
|
||||||
+ EVP_KDF_free(kdf);
|
|
||||||
+ EVP_KDF_CTX_free(kctx);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#else /* HAVE_EVP_KDF_FETCH */
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * NIST SP800-108 KDF in counter mode (section 5.1).
|
|
||||||
+ * Parameters:
|
|
||||||
+ * - HMAC (with hash as the hash provider) is the PRF.
|
|
||||||
+ * - A block counter of four bytes is used.
|
|
||||||
+ * - Four bytes are used to encode the output length in the PRF input.
|
|
||||||
+ *
|
|
||||||
+ * There are no uses requiring more than a single PRF invocation.
|
|
||||||
+ */
|
|
||||||
+static krb5_error_code
|
|
||||||
+builtin_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
|
|
||||||
+ krb5_key inkey, krb5_data *outrnd,
|
|
||||||
+ const krb5_data *label,
|
|
||||||
+ const krb5_data *context)
|
|
||||||
+{
|
|
||||||
+ krb5_crypto_iov iov[5];
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+ krb5_data prf;
|
|
||||||
+ unsigned char ibuf[4], lbuf[4];
|
|
||||||
+
|
|
||||||
+ if (hash == NULL || outrnd->length > hash->hashsize)
|
|
||||||
return KRB5_CRYPTO_INTERNAL;
|
|
||||||
|
|
||||||
/* Allocate encryption data buffer. */
|
|
||||||
- ret = alloc_data(&block, blocksize);
|
|
||||||
+ ret = alloc_data(&prf, hash->hashsize);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- /* Initialize the input block. */
|
|
||||||
- if (in_constant->length == blocksize) {
|
|
||||||
- memcpy(block.data, in_constant->data, blocksize);
|
|
||||||
- } else {
|
|
||||||
- krb5int_nfold(in_constant->length * 8,
|
|
||||||
- (unsigned char *) in_constant->data,
|
|
||||||
- blocksize * 8, (unsigned char *) block.data);
|
|
||||||
- }
|
|
||||||
+ /* [i]2: four-byte big-endian binary string giving the block counter (1) */
|
|
||||||
+ iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
|
||||||
+ iov[0].data = make_data(ibuf, sizeof(ibuf));
|
|
||||||
+ store_32_be(1, ibuf);
|
|
||||||
+ /* Label */
|
|
||||||
+ iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
|
|
||||||
+ iov[1].data = *label;
|
|
||||||
+ /* 0x00: separator byte */
|
|
||||||
+ iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
|
|
||||||
+ iov[2].data = make_data("", 1);
|
|
||||||
+ /* Context */
|
|
||||||
+ iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
|
|
||||||
+ iov[3].data = *context;
|
|
||||||
+ /* [L]2: four-byte big-endian binary string giving the output length */
|
|
||||||
+ iov[4].flags = KRB5_CRYPTO_TYPE_DATA;
|
|
||||||
+ iov[4].data = make_data(lbuf, sizeof(lbuf));
|
|
||||||
+ store_32_be(outrnd->length * 8, lbuf);
|
|
||||||
|
|
||||||
- /* Loop encrypting the blocks until enough key bytes are generated. */
|
|
||||||
- n = 0;
|
|
||||||
- while (n < keybytes) {
|
|
||||||
- ret = encrypt_block(enc, inkey, &block);
|
|
||||||
- if (ret)
|
|
||||||
- goto cleanup;
|
|
||||||
-
|
|
||||||
- if ((keybytes - n) <= blocksize) {
|
|
||||||
- memcpy(outrnd->data + n, block.data, (keybytes - n));
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- memcpy(outrnd->data + n, block.data, blocksize);
|
|
||||||
- n += blocksize;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
-cleanup:
|
|
||||||
- zapfree(block.data, blocksize);
|
|
||||||
+ ret = krb5int_hmac(hash, inkey, iov, 5, &prf);
|
|
||||||
+ if (!ret)
|
|
||||||
+ memcpy(outrnd->data, prf.data, outrnd->length);
|
|
||||||
+ zapfree(prf.data, prf.length);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -139,9 +341,9 @@ cleanup:
|
|
||||||
* - Four bytes are used to encode the output length in the PRF input.
|
|
||||||
*/
|
|
||||||
static krb5_error_code
|
|
||||||
-derive_random_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
|
|
||||||
- krb5_key inkey, krb5_data *outrnd,
|
|
||||||
- const krb5_data *in_constant)
|
|
||||||
+builtin_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
|
|
||||||
+ krb5_key inkey, krb5_data *outrnd,
|
|
||||||
+ const krb5_data *in_constant)
|
|
||||||
{
|
|
||||||
size_t blocksize, keybytes, n;
|
|
||||||
krb5_crypto_iov iov[6];
|
|
||||||
@@ -204,56 +406,94 @@ cleanup:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
-/*
|
|
||||||
- * NIST SP800-108 KDF in counter mode (section 5.1).
|
|
||||||
- * Parameters:
|
|
||||||
- * - HMAC (with hash as the hash provider) is the PRF.
|
|
||||||
- * - A block counter of four bytes is used.
|
|
||||||
- * - Four bytes are used to encode the output length in the PRF input.
|
|
||||||
- *
|
|
||||||
- * There are no uses requiring more than a single PRF invocation.
|
|
||||||
- */
|
|
||||||
+static krb5_error_code
|
|
||||||
+builtin_derive_random_rfc3961(const struct krb5_enc_provider *enc,
|
|
||||||
+ krb5_key inkey, krb5_data *outrnd,
|
|
||||||
+ const krb5_data *in_constant)
|
|
||||||
+{
|
|
||||||
+ size_t blocksize, keybytes, n;
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+ krb5_data block = empty_data();
|
|
||||||
+
|
|
||||||
+ blocksize = enc->block_size;
|
|
||||||
+ keybytes = enc->keybytes;
|
|
||||||
+
|
|
||||||
+ if (blocksize == 1)
|
|
||||||
+ return KRB5_BAD_ENCTYPE;
|
|
||||||
+ if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
|
|
||||||
+ return KRB5_CRYPTO_INTERNAL;
|
|
||||||
+
|
|
||||||
+ /* Allocate encryption data buffer. */
|
|
||||||
+ ret = alloc_data(&block, blocksize);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ /* Initialize the input block. */
|
|
||||||
+ if (in_constant->length == blocksize) {
|
|
||||||
+ memcpy(block.data, in_constant->data, blocksize);
|
|
||||||
+ } else {
|
|
||||||
+ krb5int_nfold(in_constant->length * 8,
|
|
||||||
+ (unsigned char *) in_constant->data,
|
|
||||||
+ blocksize * 8, (unsigned char *) block.data);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Loop encrypting the blocks until enough key bytes are generated. */
|
|
||||||
+ n = 0;
|
|
||||||
+ while (n < keybytes) {
|
|
||||||
+ ret = encrypt_block(enc, inkey, &block);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+
|
|
||||||
+ if ((keybytes - n) <= blocksize) {
|
|
||||||
+ memcpy(outrnd->data + n, block.data, (keybytes - n));
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ memcpy(outrnd->data + n, block.data, blocksize);
|
|
||||||
+ n += blocksize;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+cleanup:
|
|
||||||
+ zapfree(block.data, blocksize);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+#endif /* HAVE_EVP_KDF_FETCH */
|
|
||||||
+
|
|
||||||
krb5_error_code
|
|
||||||
k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
|
|
||||||
krb5_key inkey, krb5_data *outrnd,
|
|
||||||
const krb5_data *label, const krb5_data *context)
|
|
||||||
{
|
|
||||||
- krb5_crypto_iov iov[5];
|
|
||||||
- krb5_error_code ret;
|
|
||||||
- krb5_data prf;
|
|
||||||
- unsigned char ibuf[4], lbuf[4];
|
|
||||||
+#ifdef HAVE_EVP_KDF_FETCH
|
|
||||||
+ return openssl_kbdkf_counter_hmac(hash, inkey, outrnd, label, context);
|
|
||||||
+#else
|
|
||||||
+ return builtin_sp800_108_counter_hmac(hash, inkey, outrnd, label,
|
|
||||||
+ context);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
|
|
||||||
- if (hash == NULL || outrnd->length > hash->hashsize)
|
|
||||||
- return KRB5_CRYPTO_INTERNAL;
|
|
||||||
+static krb5_error_code
|
|
||||||
+sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
|
|
||||||
+ krb5_key inkey, krb5_data *outrnd,
|
|
||||||
+ const krb5_data *in_constant)
|
|
||||||
+{
|
|
||||||
+#ifdef HAVE_EVP_KDF_FETCH
|
|
||||||
+ return openssl_kbkdf_feedback_cmac(enc, inkey, outrnd, in_constant);
|
|
||||||
+#else
|
|
||||||
+ return builtin_sp800_108_feedback_cmac(enc, inkey, outrnd, in_constant);
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
|
|
||||||
- /* Allocate encryption data buffer. */
|
|
||||||
- ret = alloc_data(&prf, hash->hashsize);
|
|
||||||
- if (ret)
|
|
||||||
- return ret;
|
|
||||||
-
|
|
||||||
- /* [i]2: four-byte big-endian binary string giving the block counter (1) */
|
|
||||||
- iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
|
||||||
- iov[0].data = make_data(ibuf, sizeof(ibuf));
|
|
||||||
- store_32_be(1, ibuf);
|
|
||||||
- /* Label */
|
|
||||||
- iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
|
|
||||||
- iov[1].data = *label;
|
|
||||||
- /* 0x00: separator byte */
|
|
||||||
- iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
|
|
||||||
- iov[2].data = make_data("", 1);
|
|
||||||
- /* Context */
|
|
||||||
- iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
|
|
||||||
- iov[3].data = *context;
|
|
||||||
- /* [L]2: four-byte big-endian binary string giving the output length */
|
|
||||||
- iov[4].flags = KRB5_CRYPTO_TYPE_DATA;
|
|
||||||
- iov[4].data = make_data(lbuf, sizeof(lbuf));
|
|
||||||
- store_32_be(outrnd->length * 8, lbuf);
|
|
||||||
-
|
|
||||||
- ret = krb5int_hmac(hash, inkey, iov, 5, &prf);
|
|
||||||
- if (!ret)
|
|
||||||
- memcpy(outrnd->data, prf.data, outrnd->length);
|
|
||||||
- zapfree(prf.data, prf.length);
|
|
||||||
- return ret;
|
|
||||||
+static krb5_error_code
|
|
||||||
+derive_random_rfc3961(const struct krb5_enc_provider *enc,
|
|
||||||
+ krb5_key inkey, krb5_data *outrnd,
|
|
||||||
+ const krb5_data *in_constant)
|
|
||||||
+{
|
|
||||||
+#ifdef HAVE_EVP_KDF_FETCH
|
|
||||||
+ return openssl_krb5kdf(enc, inkey, outrnd, in_constant);
|
|
||||||
+#else
|
|
||||||
+ return builtin_derive_random_rfc3961(enc, inkey, outrnd, in_constant);
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
krb5_error_code
|
|
||||||
@@ -268,8 +508,7 @@ krb5int_derive_random(const struct krb5_enc_provider *enc,
|
|
||||||
case DERIVE_RFC3961:
|
|
||||||
return derive_random_rfc3961(enc, inkey, outrnd, in_constant);
|
|
||||||
case DERIVE_SP800_108_CMAC:
|
|
||||||
- return derive_random_sp800_108_feedback_cmac(enc, inkey, outrnd,
|
|
||||||
- in_constant);
|
|
||||||
+ return sp800_108_feedback_cmac(enc, inkey, outrnd, in_constant);
|
|
||||||
case DERIVE_SP800_108_HMAC:
|
|
||||||
return k5_sp800_108_counter_hmac(hash, inkey, outrnd, in_constant,
|
|
||||||
&empty);
|
|
@ -1,408 +0,0 @@
|
|||||||
From 8bbb492f2be1418e1e4bb2cf197414810dac9589 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
Date: Fri, 20 Sep 2019 17:20:59 -0400
|
|
||||||
Subject: [PATCH] Use OpenSSL's SSKDF in PKINIT when available
|
|
||||||
|
|
||||||
Starting in 3.0, OpenSSL implements SSKDF, which is the basis of our
|
|
||||||
id-pkinit-kdf (RFC 8636). Factor out common setup code around
|
|
||||||
other_info. Adjust code to comply to existing style.
|
|
||||||
|
|
||||||
(cherry picked from commit 4376a22e41fb639be31daf81275a332d3f930996)
|
|
||||||
---
|
|
||||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 294 +++++++++++-------
|
|
||||||
1 file changed, 181 insertions(+), 113 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
||||||
index e1153344e..350c2118a 100644
|
|
||||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
||||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
||||||
@@ -38,6 +38,12 @@
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
+#ifdef HAVE_EVP_KDF_FETCH
|
|
||||||
+#include <openssl/core_names.h>
|
|
||||||
+#include <openssl/kdf.h>
|
|
||||||
+#include <openssl/params.h>
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
|
|
||||||
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
|
|
||||||
|
|
||||||
@@ -2294,15 +2300,16 @@ cleanup:
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
-/**
|
|
||||||
+/*
|
|
||||||
* Given an algorithm_identifier, this function returns the hash length
|
|
||||||
* and EVP function associated with that algorithm.
|
|
||||||
+ *
|
|
||||||
+ * RFC 8636 defines a SHA384 variant, but we don't use it.
|
|
||||||
*/
|
|
||||||
static krb5_error_code
|
|
||||||
-pkinit_alg_values(krb5_context context,
|
|
||||||
- const krb5_data *alg_id,
|
|
||||||
- size_t *hash_bytes,
|
|
||||||
- const EVP_MD *(**func)(void))
|
|
||||||
+pkinit_alg_values(krb5_context context, const krb5_data *alg_id,
|
|
||||||
+ size_t *hash_bytes, const EVP_MD *(**func)(void),
|
|
||||||
+ char **hash_name)
|
|
||||||
{
|
|
||||||
*hash_bytes = 0;
|
|
||||||
*func = NULL;
|
|
||||||
@@ -2311,18 +2318,21 @@ pkinit_alg_values(krb5_context context,
|
|
||||||
krb5_pkinit_sha1_oid_len))) {
|
|
||||||
*hash_bytes = 20;
|
|
||||||
*func = &EVP_sha1;
|
|
||||||
+ *hash_name = strdup("SHA1");
|
|
||||||
return 0;
|
|
||||||
} else if ((alg_id->length == krb5_pkinit_sha256_oid_len) &&
|
|
||||||
(0 == memcmp(alg_id->data, krb5_pkinit_sha256_oid,
|
|
||||||
krb5_pkinit_sha256_oid_len))) {
|
|
||||||
*hash_bytes = 32;
|
|
||||||
*func = &EVP_sha256;
|
|
||||||
+ *hash_name = strdup("SHA256");
|
|
||||||
return 0;
|
|
||||||
} else if ((alg_id->length == krb5_pkinit_sha512_oid_len) &&
|
|
||||||
(0 == memcmp(alg_id->data, krb5_pkinit_sha512_oid,
|
|
||||||
krb5_pkinit_sha512_oid_len))) {
|
|
||||||
*hash_bytes = 64;
|
|
||||||
*func = &EVP_sha512;
|
|
||||||
+ *hash_name = strdup("SHA512");
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
krb5_set_error_message(context, KRB5_ERR_BAD_S2K_PARAMS,
|
|
||||||
@@ -2331,11 +2341,60 @@ pkinit_alg_values(krb5_context context,
|
|
||||||
}
|
|
||||||
} /* pkinit_alg_values() */
|
|
||||||
|
|
||||||
+#ifdef HAVE_EVP_KDF_FETCH
|
|
||||||
+static krb5_error_code
|
|
||||||
+openssl_sskdf(krb5_context context, size_t hash_bytes, krb5_data *key,
|
|
||||||
+ krb5_data *info, char *out, size_t out_len, char *digest)
|
|
||||||
+{
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+ EVP_KDF *kdf = NULL;
|
|
||||||
+ EVP_KDF_CTX *kctx = NULL;
|
|
||||||
+ OSSL_PARAM params[4];
|
|
||||||
+ size_t i = 0;
|
|
||||||
|
|
||||||
-/* pkinit_alg_agility_kdf() --
|
|
||||||
- * This function generates a key using the KDF described in
|
|
||||||
- * draft_ietf_krb_wg_pkinit_alg_agility-04.txt. The algorithm is
|
|
||||||
- * described as follows:
|
|
||||||
+ if (digest == NULL) {
|
|
||||||
+ ret = oerr(context, ENOMEM,
|
|
||||||
+ _("Failed to allocate space for digest algorithm name"));
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL);
|
|
||||||
+ if (kdf == NULL) {
|
|
||||||
+ ret = oerr(context, KRB5_CRYPTO_INTERNAL, _("Failed to fetch SSKDF"));
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ kctx = EVP_KDF_CTX_new(kdf);
|
|
||||||
+ if (!kctx) {
|
|
||||||
+ ret = oerr(context, KRB5_CRYPTO_INTERNAL,
|
|
||||||
+ _("Failed to instantiate SSKDF"));
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
|
|
||||||
+ digest, 0);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
|
|
||||||
+ key->data, key->length);
|
|
||||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
|
|
||||||
+ info->data, info->length);
|
|
||||||
+ params[i] = OSSL_PARAM_construct_end();
|
|
||||||
+ if (EVP_KDF_derive(kctx, (unsigned char *)out, out_len, params) <= 0) {
|
|
||||||
+ ret = oerr(context, KRB5_CRYPTO_INTERNAL,
|
|
||||||
+ _("Failed to derive key using SSKDF"));
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = 0;
|
|
||||||
+done:
|
|
||||||
+ EVP_KDF_free(kdf);
|
|
||||||
+ EVP_KDF_CTX_free(kctx);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+#else
|
|
||||||
+/*
|
|
||||||
+ * Generate a key using the KDF described in RFC 8636, also known as SSKDF
|
|
||||||
+ * (single-step kdf). Our caller precomputes `reps`, but otherwise the
|
|
||||||
+ * algorithm is as follows:
|
|
||||||
*
|
|
||||||
* 1. reps = keydatalen (K) / hash length (H)
|
|
||||||
*
|
|
||||||
@@ -2349,95 +2408,16 @@ pkinit_alg_values(krb5_context context,
|
|
||||||
*
|
|
||||||
* 4. Set key = Hash1 || Hash2 || ... so that length of key is K bytes.
|
|
||||||
*/
|
|
||||||
-krb5_error_code
|
|
||||||
-pkinit_alg_agility_kdf(krb5_context context,
|
|
||||||
- krb5_data *secret,
|
|
||||||
- krb5_data *alg_oid,
|
|
||||||
- krb5_const_principal party_u_info,
|
|
||||||
- krb5_const_principal party_v_info,
|
|
||||||
- krb5_enctype enctype,
|
|
||||||
- krb5_data *as_req,
|
|
||||||
- krb5_data *pk_as_rep,
|
|
||||||
- krb5_keyblock *key_block)
|
|
||||||
+static krb5_error_code
|
|
||||||
+builtin_sskdf(krb5_context context, unsigned int reps, size_t hash_len,
|
|
||||||
+ const EVP_MD *(*EVP_func)(void), krb5_data *secret,
|
|
||||||
+ krb5_data *other_info, char *out, size_t out_len)
|
|
||||||
{
|
|
||||||
- krb5_error_code retval = 0;
|
|
||||||
+ krb5_error_code ret = 0;
|
|
||||||
|
|
||||||
- unsigned int reps = 0;
|
|
||||||
- uint32_t counter = 1; /* Does this type work on Windows? */
|
|
||||||
+ uint32_t counter = 1;
|
|
||||||
size_t offset = 0;
|
|
||||||
- size_t hash_len = 0;
|
|
||||||
- size_t rand_len = 0;
|
|
||||||
- size_t key_len = 0;
|
|
||||||
- krb5_data random_data;
|
|
||||||
- krb5_sp80056a_other_info other_info_fields;
|
|
||||||
- krb5_pkinit_supp_pub_info supp_pub_info_fields;
|
|
||||||
- krb5_data *other_info = NULL;
|
|
||||||
- krb5_data *supp_pub_info = NULL;
|
|
||||||
- krb5_algorithm_identifier alg_id;
|
|
||||||
EVP_MD_CTX *ctx = NULL;
|
|
||||||
- const EVP_MD *(*EVP_func)(void);
|
|
||||||
-
|
|
||||||
- /* initialize random_data here to make clean-up safe */
|
|
||||||
- random_data.length = 0;
|
|
||||||
- random_data.data = NULL;
|
|
||||||
-
|
|
||||||
- /* allocate and initialize the key block */
|
|
||||||
- key_block->magic = 0;
|
|
||||||
- key_block->enctype = enctype;
|
|
||||||
- if (0 != (retval = krb5_c_keylengths(context, enctype, &rand_len,
|
|
||||||
- &key_len)))
|
|
||||||
- goto cleanup;
|
|
||||||
-
|
|
||||||
- random_data.length = rand_len;
|
|
||||||
- key_block->length = key_len;
|
|
||||||
-
|
|
||||||
- if (NULL == (key_block->contents = malloc(key_block->length))) {
|
|
||||||
- retval = ENOMEM;
|
|
||||||
- goto cleanup;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- memset (key_block->contents, 0, key_block->length);
|
|
||||||
-
|
|
||||||
- /* If this is anonymous pkinit, use the anonymous principle for party_u_info */
|
|
||||||
- if (party_u_info && krb5_principal_compare_any_realm(context, party_u_info,
|
|
||||||
- krb5_anonymous_principal()))
|
|
||||||
- party_u_info = (krb5_principal)krb5_anonymous_principal();
|
|
||||||
-
|
|
||||||
- if (0 != (retval = pkinit_alg_values(context, alg_oid, &hash_len, &EVP_func)))
|
|
||||||
- goto cleanup;
|
|
||||||
-
|
|
||||||
- /* 1. reps = keydatalen (K) / hash length (H) */
|
|
||||||
- reps = key_block->length/hash_len;
|
|
||||||
-
|
|
||||||
- /* ... and round up, if necessary */
|
|
||||||
- if (key_block->length > (reps * hash_len))
|
|
||||||
- reps++;
|
|
||||||
-
|
|
||||||
- /* Allocate enough space in the random data buffer to hash directly into
|
|
||||||
- * it, even if the last hash will make it bigger than the key length. */
|
|
||||||
- if (NULL == (random_data.data = malloc(reps * hash_len))) {
|
|
||||||
- retval = ENOMEM;
|
|
||||||
- goto cleanup;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* Encode the ASN.1 octet string for "SuppPubInfo" */
|
|
||||||
- supp_pub_info_fields.enctype = enctype;
|
|
||||||
- supp_pub_info_fields.as_req = *as_req;
|
|
||||||
- supp_pub_info_fields.pk_as_rep = *pk_as_rep;
|
|
||||||
- if (0 != ((retval = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields,
|
|
||||||
- &supp_pub_info))))
|
|
||||||
- goto cleanup;
|
|
||||||
-
|
|
||||||
- /* Now encode the ASN.1 octet string for "OtherInfo" */
|
|
||||||
- memset(&alg_id, 0, sizeof alg_id);
|
|
||||||
- alg_id.algorithm = *alg_oid; /*alias*/
|
|
||||||
-
|
|
||||||
- other_info_fields.algorithm_identifier = alg_id;
|
|
||||||
- other_info_fields.party_u_info = (krb5_principal) party_u_info;
|
|
||||||
- other_info_fields.party_v_info = (krb5_principal) party_v_info;
|
|
||||||
- other_info_fields.supp_pub_info = *supp_pub_info;
|
|
||||||
- if (0 != (retval = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info)))
|
|
||||||
- goto cleanup;
|
|
||||||
|
|
||||||
/* 2. Initialize a 32-bit, big-endian bit string counter as 1.
|
|
||||||
* 3. For i = 1 to reps by 1, do the following:
|
|
||||||
@@ -2450,7 +2430,7 @@ pkinit_alg_agility_kdf(krb5_context context,
|
|
||||||
|
|
||||||
ctx = EVP_MD_CTX_new();
|
|
||||||
if (ctx == NULL) {
|
|
||||||
- retval = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2458,7 +2438,7 @@ pkinit_alg_agility_kdf(krb5_context context,
|
|
||||||
if (!EVP_DigestInit(ctx, EVP_func())) {
|
|
||||||
krb5_set_error_message(context, KRB5_CRYPTO_INTERNAL,
|
|
||||||
"Call to OpenSSL EVP_DigestInit() returned an error.");
|
|
||||||
- retval = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2467,15 +2447,16 @@ pkinit_alg_agility_kdf(krb5_context context,
|
|
||||||
!EVP_DigestUpdate(ctx, other_info->data, other_info->length)) {
|
|
||||||
krb5_set_error_message(context, KRB5_CRYPTO_INTERNAL,
|
|
||||||
"Call to OpenSSL EVP_DigestUpdate() returned an error.");
|
|
||||||
- retval = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* 4. Set key = Hash1 || Hash2 || ... so that length of key is K bytes. */
|
|
||||||
- if (!EVP_DigestFinal(ctx, (uint8_t *)random_data.data + offset, &s)) {
|
|
||||||
+ /* 4. Set key = Hash1 || Hash2 || ... so that length of key is K
|
|
||||||
+ * bytes. */
|
|
||||||
+ if (!EVP_DigestFinal(ctx, (unsigned char *)out + offset, &s)) {
|
|
||||||
krb5_set_error_message(context, KRB5_CRYPTO_INTERNAL,
|
|
||||||
"Call to OpenSSL EVP_DigestUpdate() returned an error.");
|
|
||||||
- retval = KRB5_CRYPTO_INTERNAL;
|
|
||||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
offset += s;
|
|
||||||
@@ -2484,26 +2465,113 @@ pkinit_alg_agility_kdf(krb5_context context,
|
|
||||||
EVP_MD_CTX_free(ctx);
|
|
||||||
ctx = NULL;
|
|
||||||
}
|
|
||||||
-
|
|
||||||
- retval = krb5_c_random_to_key(context, enctype, &random_data,
|
|
||||||
- key_block);
|
|
||||||
-
|
|
||||||
cleanup:
|
|
||||||
EVP_MD_CTX_free(ctx);
|
|
||||||
+ return ret;
|
|
||||||
+} /* builtin_sskdf() */
|
|
||||||
+#endif /* HAVE_EVP_KDF_FETCH */
|
|
||||||
|
|
||||||
- /* If this has been an error, free the allocated key_block, if any */
|
|
||||||
- if (retval) {
|
|
||||||
- krb5_free_keyblock_contents(context, key_block);
|
|
||||||
+/* id-pkinit-kdf family, as specified by RFC 8636. */
|
|
||||||
+krb5_error_code
|
|
||||||
+pkinit_alg_agility_kdf(krb5_context context, krb5_data *secret,
|
|
||||||
+ krb5_data *alg_oid, krb5_const_principal party_u_info,
|
|
||||||
+ krb5_const_principal party_v_info,
|
|
||||||
+ krb5_enctype enctype, krb5_data *as_req,
|
|
||||||
+ krb5_data *pk_as_rep, krb5_keyblock *key_block)
|
|
||||||
+{
|
|
||||||
+ krb5_error_code ret;
|
|
||||||
+ size_t hash_len = 0, rand_len = 0, key_len = 0;
|
|
||||||
+ const EVP_MD *(*EVP_func)(void);
|
|
||||||
+ krb5_sp80056a_other_info other_info_fields;
|
|
||||||
+ krb5_pkinit_supp_pub_info supp_pub_info_fields;
|
|
||||||
+ krb5_data *other_info = NULL, *supp_pub_info = NULL;
|
|
||||||
+ krb5_data random_data = empty_data();
|
|
||||||
+ krb5_algorithm_identifier alg_id;
|
|
||||||
+ unsigned int reps;
|
|
||||||
+ char *hash_name = NULL;
|
|
||||||
+
|
|
||||||
+ /* Allocate and initialize the key block. */
|
|
||||||
+ key_block->magic = 0;
|
|
||||||
+ key_block->enctype = enctype;
|
|
||||||
+
|
|
||||||
+ /* Use separate variables to avoid alignment restriction problems. */
|
|
||||||
+ ret = krb5_c_keylengths(context, enctype, &rand_len, &key_len);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+ random_data.length = rand_len;
|
|
||||||
+ key_block->length = key_len;
|
|
||||||
+
|
|
||||||
+ key_block->contents = k5calloc(key_block->length, 1, &ret);
|
|
||||||
+ if (key_block->contents == NULL)
|
|
||||||
+ goto cleanup;
|
|
||||||
+
|
|
||||||
+ /* If this is anonymous pkinit, use the anonymous principle for
|
|
||||||
+ * party_u_info. */
|
|
||||||
+ if (party_u_info &&
|
|
||||||
+ krb5_principal_compare_any_realm(context, party_u_info,
|
|
||||||
+ krb5_anonymous_principal())) {
|
|
||||||
+ party_u_info = (krb5_principal)krb5_anonymous_principal();
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* free other allocated resources, either way */
|
|
||||||
- if (random_data.data)
|
|
||||||
- free(random_data.data);
|
|
||||||
+ ret = pkinit_alg_values(context, alg_oid, &hash_len, &EVP_func,
|
|
||||||
+ &hash_name);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+
|
|
||||||
+ /* 1. reps = keydatalen (K) / hash length (H) */
|
|
||||||
+ reps = key_block->length / hash_len;
|
|
||||||
+
|
|
||||||
+ /* ... and round up, if necessary. */
|
|
||||||
+ if (key_block->length > (reps * hash_len))
|
|
||||||
+ reps++;
|
|
||||||
+
|
|
||||||
+ /* Allocate enough space in the random data buffer to hash directly into
|
|
||||||
+ * it, even if the last hash will make it bigger than the key length. */
|
|
||||||
+ random_data.data = k5alloc(reps * hash_len, &ret);
|
|
||||||
+ if (random_data.data == NULL)
|
|
||||||
+ goto cleanup;
|
|
||||||
+
|
|
||||||
+ /* Encode the ASN.1 octet string for "SuppPubInfo". */
|
|
||||||
+ supp_pub_info_fields.enctype = enctype;
|
|
||||||
+ supp_pub_info_fields.as_req = *as_req;
|
|
||||||
+ supp_pub_info_fields.pk_as_rep = *pk_as_rep;
|
|
||||||
+ ret = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields,
|
|
||||||
+ &supp_pub_info);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+
|
|
||||||
+ /* Now encode the ASN.1 octet string for "OtherInfo". */
|
|
||||||
+ memset(&alg_id, 0, sizeof(alg_id));
|
|
||||||
+ alg_id.algorithm = *alg_oid;
|
|
||||||
+ other_info_fields.algorithm_identifier = alg_id;
|
|
||||||
+ other_info_fields.party_u_info = (krb5_principal)party_u_info;
|
|
||||||
+ other_info_fields.party_v_info = (krb5_principal)party_v_info;
|
|
||||||
+ other_info_fields.supp_pub_info = *supp_pub_info;
|
|
||||||
+ ret = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+
|
|
||||||
+#ifdef HAVE_EVP_KDF_FETCH
|
|
||||||
+ ret = openssl_sskdf(context, hash_len, secret, other_info,
|
|
||||||
+ random_data.data, key_block->length, hash_name);
|
|
||||||
+#else
|
|
||||||
+ ret = builtin_sskdf(context, reps, hash_len, EVP_func, secret,
|
|
||||||
+ other_info, random_data.data, key_block->length);
|
|
||||||
+#endif
|
|
||||||
+ if (ret)
|
|
||||||
+ goto cleanup;
|
|
||||||
+
|
|
||||||
+ ret = krb5_c_random_to_key(context, enctype, &random_data, key_block);
|
|
||||||
+cleanup:
|
|
||||||
+ if (ret)
|
|
||||||
+ krb5_free_keyblock_contents(context, key_block);
|
|
||||||
+
|
|
||||||
+ free(hash_name);
|
|
||||||
+ zapfree(random_data.data, random_data.length);
|
|
||||||
krb5_free_data(context, other_info);
|
|
||||||
krb5_free_data(context, supp_pub_info);
|
|
||||||
-
|
|
||||||
- return retval;
|
|
||||||
-} /*pkinit_alg_agility_kdf() */
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
|
|
||||||
/* Call DH_compute_key() and ensure that we left-pad short results instead of
|
|
||||||
* leaving junk bytes at the end of the buffer. */
|
|
@ -1,113 +0,0 @@
|
|||||||
From f0740c131b69f3346f07e7b7b03ebf27c50c0ccd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Julien Rische <jrische@redhat.com>
|
|
||||||
Date: Fri, 11 Mar 2022 11:33:56 +0100
|
|
||||||
Subject: [PATCH] Use SHA-256 instead of SHA-1 for PKINIT CMS digest
|
|
||||||
|
|
||||||
Various organizations including NIST have been strongly recommending to
|
|
||||||
stop using SHA-1 for digital signatures for some years already. CMS
|
|
||||||
digest is used to generate such signatures, hence it should be upgraded
|
|
||||||
to use SHA-256.
|
|
||||||
---
|
|
||||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 27 ++++++++++---------
|
|
||||||
1 file changed, 14 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
||||||
index 42e5c581d..2a6ef4aaa 100644
|
|
||||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
||||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
||||||
@@ -1240,7 +1240,7 @@ cms_signeddata_create(krb5_context context,
|
|
||||||
/* will not fill-out EVP_PKEY because it's on the smartcard */
|
|
||||||
|
|
||||||
/* Set digest algs */
|
|
||||||
- p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
|
|
||||||
+ p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha256);
|
|
||||||
|
|
||||||
if (p7si->digest_alg->parameter != NULL)
|
|
||||||
ASN1_TYPE_free(p7si->digest_alg->parameter);
|
|
||||||
@@ -1251,17 +1251,17 @@ cms_signeddata_create(krb5_context context,
|
|
||||||
/* Set sig algs */
|
|
||||||
if (p7si->digest_enc_alg->parameter != NULL)
|
|
||||||
ASN1_TYPE_free(p7si->digest_enc_alg->parameter);
|
|
||||||
- p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption);
|
|
||||||
+ p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha256WithRSAEncryption);
|
|
||||||
if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new()))
|
|
||||||
goto cleanup;
|
|
||||||
p7si->digest_enc_alg->parameter->type = V_ASN1_NULL;
|
|
||||||
|
|
||||||
/* add signed attributes */
|
|
||||||
- /* compute sha1 digest over the EncapsulatedContentInfo */
|
|
||||||
+ /* compute sha256 digest over the EncapsulatedContentInfo */
|
|
||||||
ctx = EVP_MD_CTX_new();
|
|
||||||
if (ctx == NULL)
|
|
||||||
goto cleanup;
|
|
||||||
- EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
|
|
||||||
+ EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
|
|
||||||
EVP_DigestUpdate(ctx, data, data_len);
|
|
||||||
md_tmp = EVP_MD_CTX_md(ctx);
|
|
||||||
EVP_DigestFinal_ex(ctx, md_data, &md_len);
|
|
||||||
@@ -1289,9 +1289,10 @@ cms_signeddata_create(krb5_context context,
|
|
||||||
goto cleanup2;
|
|
||||||
|
|
||||||
#ifndef WITHOUT_PKCS11
|
|
||||||
- /* Some tokens can only do RSAEncryption without sha1 hash */
|
|
||||||
- /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
|
|
||||||
- * function and the hash value into an ASN.1 value of type DigestInfo
|
|
||||||
+ /* Some tokens can only do RSAEncryption without sha256 hash */
|
|
||||||
+ /* to compute sha256WithRSAEncryption, encode the algorithm ID for the
|
|
||||||
+ * hash function and the hash value into an ASN.1 value of type
|
|
||||||
+ * DigestInfo
|
|
||||||
* DigestInfo::=SEQUENCE {
|
|
||||||
* digestAlgorithm AlgorithmIdentifier,
|
|
||||||
* digest OCTET STRING }
|
|
||||||
@@ -1310,7 +1311,7 @@ cms_signeddata_create(krb5_context context,
|
|
||||||
alg = X509_ALGOR_new();
|
|
||||||
if (alg == NULL)
|
|
||||||
goto cleanup2;
|
|
||||||
- X509_ALGOR_set0(alg, OBJ_nid2obj(NID_sha1), V_ASN1_NULL, NULL);
|
|
||||||
+ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_sha256), V_ASN1_NULL, NULL);
|
|
||||||
alg_len = i2d_X509_ALGOR(alg, NULL);
|
|
||||||
|
|
||||||
digest = ASN1_OCTET_STRING_new();
|
|
||||||
@@ -1339,7 +1340,7 @@ cms_signeddata_create(krb5_context context,
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
pkiDebug("mech = %s\n",
|
|
||||||
- id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA1_RSA_PKCS" : "FS");
|
|
||||||
+ id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA256_RSA_PKCS" : "FS");
|
|
||||||
retval = pkinit_sign_data(context, id_cryptoctx, abuf, alen,
|
|
||||||
&sig, &sig_len);
|
|
||||||
}
|
|
||||||
@@ -4189,7 +4190,7 @@ create_signature(unsigned char **sig, unsigned int *sig_len,
|
|
||||||
ctx = EVP_MD_CTX_new();
|
|
||||||
if (ctx == NULL)
|
|
||||||
return ENOMEM;
|
|
||||||
- EVP_SignInit(ctx, EVP_sha1());
|
|
||||||
+ EVP_SignInit(ctx, EVP_sha256());
|
|
||||||
EVP_SignUpdate(ctx, data, data_len);
|
|
||||||
*sig_len = EVP_PKEY_size(pkey);
|
|
||||||
if ((*sig = malloc(*sig_len)) == NULL)
|
|
||||||
@@ -4663,10 +4664,10 @@ pkinit_get_certs_pkcs11(krb5_context context,
|
|
||||||
|
|
||||||
#ifndef PKINIT_USE_MECH_LIST
|
|
||||||
/*
|
|
||||||
- * We'd like to use CKM_SHA1_RSA_PKCS for signing if it's available, but
|
|
||||||
+ * We'd like to use CKM_SHA256_RSA_PKCS for signing if it's available, but
|
|
||||||
* many cards seems to be confused about whether they are capable of
|
|
||||||
* this or not. The safe thing seems to be to ignore the mechanism list,
|
|
||||||
- * always use CKM_RSA_PKCS and calculate the sha1 digest ourselves.
|
|
||||||
+ * always use CKM_RSA_PKCS and calculate the sha256 digest ourselves.
|
|
||||||
*/
|
|
||||||
|
|
||||||
id_cryptoctx->mech = CKM_RSA_PKCS;
|
|
||||||
@@ -4694,7 +4695,7 @@ pkinit_get_certs_pkcs11(krb5_context context,
|
|
||||||
if (mechp[i] == CKM_RSA_PKCS) {
|
|
||||||
/* This seems backwards... */
|
|
||||||
id_cryptoctx->mech =
|
|
||||||
- (info.flags & CKF_SIGN) ? CKM_SHA1_RSA_PKCS : CKM_RSA_PKCS;
|
|
||||||
+ (info.flags & CKF_SIGN) ? CKM_SHA256_RSA_PKCS : CKM_RSA_PKCS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(mechp);
|
|
||||||
--
|
|
||||||
2.35.1
|
|
||||||
|
|
@ -1,727 +0,0 @@
|
|||||||
From 20cbbd0b273af56c6d527c8e6b9d96eef49926f2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Julien Rische <jrische@redhat.com>
|
|
||||||
Date: Thu, 31 Mar 2022 18:24:39 +0200
|
|
||||||
Subject: [PATCH] Use newly enforced dejagnu path naming convention
|
|
||||||
|
|
||||||
Since version 1.6.3, dejagnu started to enforce a naming convention that
|
|
||||||
was already in place, but not mandatory: dejagnu test directories have
|
|
||||||
to be named "testsuite". If they don't implicit relative sub-paths
|
|
||||||
resolution (e.g. "lib", "config") is not forking.
|
|
||||||
|
|
||||||
This commit renames kadm5 library's unit tests and global tests
|
|
||||||
directories to match this requirement.
|
|
||||||
|
|
||||||
Resolves: rhbz#2053133
|
|
||||||
|
|
||||||
Signed-off-by: Julien Rische <jrische@redhat.com>
|
|
||||||
---
|
|
||||||
src/configure.ac | 4 +--
|
|
||||||
src/lib/kadm5/Makefile.in | 2 +-
|
|
||||||
.../{unit-test => testsuite}/Makefile.in | 28 +++++++++---------
|
|
||||||
.../api.2/crte-policy.exp | 0
|
|
||||||
.../api.2/get-policy.exp | 0
|
|
||||||
.../api.2/mod-policy.exp | 0
|
|
||||||
.../api.current/chpass-principal-v2.exp | 0
|
|
||||||
.../api.current/chpass-principal.exp | 0
|
|
||||||
.../api.current/crte-policy.exp | 0
|
|
||||||
.../api.current/crte-principal.exp | 0
|
|
||||||
.../api.current/destroy.exp | 0
|
|
||||||
.../api.current/dlte-policy.exp | 0
|
|
||||||
.../api.current/dlte-principal.exp | 0
|
|
||||||
.../api.current/get-policy.exp | 0
|
|
||||||
.../api.current/get-principal-v2.exp | 0
|
|
||||||
.../api.current/get-principal.exp | 0
|
|
||||||
.../api.current/init-v2.exp | 0
|
|
||||||
.../api.current/init.exp | 0
|
|
||||||
.../api.current/mod-policy.exp | 0
|
|
||||||
.../api.current/mod-principal-v2.exp | 0
|
|
||||||
.../api.current/mod-principal.exp | 0
|
|
||||||
.../api.current/randkey-principal-v2.exp | 0
|
|
||||||
.../api.current/randkey-principal.exp | 0
|
|
||||||
.../{unit-test => testsuite}/config/unix.exp | 0
|
|
||||||
src/lib/kadm5/{unit-test => testsuite}/deps | 0
|
|
||||||
.../{unit-test => testsuite}/destroy-test.c | 0
|
|
||||||
.../diff-files/destroy-1 | 0
|
|
||||||
.../diff-files/no-diffs | 0
|
|
||||||
.../{unit-test => testsuite}/handle-test.c | 0
|
|
||||||
.../{unit-test => testsuite}/init-test.c | 0
|
|
||||||
.../{unit-test => testsuite}/iter-test.c | 0
|
|
||||||
.../kadm5/{unit-test => testsuite}/lib/lib.t | 2 +-
|
|
||||||
.../{unit-test => testsuite}/lock-test.c | 0
|
|
||||||
.../{unit-test => testsuite}/randkey-test.c | 0
|
|
||||||
.../{unit-test => testsuite}/setkey-test.c | 0
|
|
||||||
.../kadm5/{unit-test => testsuite}/site.exp | 0
|
|
||||||
src/tests/Makefile.in | 2 +-
|
|
||||||
src/tests/t_authdata.py | 2 +-
|
|
||||||
src/tests/t_certauth.py | 2 +-
|
|
||||||
src/tests/t_pkinit.py | 2 +-
|
|
||||||
src/tests/t_proxy.py | 12 ++++----
|
|
||||||
src/tests/{dejagnu => testsuite}/Makefile.in | 4 +--
|
|
||||||
.../{dejagnu => testsuite}/config/default.exp | 2 +-
|
|
||||||
src/tests/{dejagnu => testsuite}/deps | 0
|
|
||||||
.../krb-standalone/gssapi.exp | 2 +-
|
|
||||||
.../krb-standalone/kprop.exp | 0
|
|
||||||
.../krb-standalone/princexpire.exp | 0
|
|
||||||
.../krb-standalone/sample.exp | 2 +-
|
|
||||||
.../krb-standalone/simple.exp | 2 +-
|
|
||||||
.../krb-standalone/standalone.exp | 0
|
|
||||||
.../krb-standalone/tcp.exp | 0
|
|
||||||
.../pkinit-certs/ca.pem | 0
|
|
||||||
.../pkinit-certs/generic.p12 | Bin
|
|
||||||
.../pkinit-certs/generic.pem | 0
|
|
||||||
.../pkinit-certs/kdc.pem | 0
|
|
||||||
.../pkinit-certs/make-certs.sh | 0
|
|
||||||
.../pkinit-certs/privkey-enc.pem | 0
|
|
||||||
.../pkinit-certs/privkey.pem | 0
|
|
||||||
.../pkinit-certs/user-enc.p12 | Bin
|
|
||||||
.../pkinit-certs/user-upn.p12 | Bin
|
|
||||||
.../pkinit-certs/user-upn.pem | 0
|
|
||||||
.../pkinit-certs/user-upn2.p12 | Bin
|
|
||||||
.../pkinit-certs/user-upn2.pem | 0
|
|
||||||
.../pkinit-certs/user-upn3.p12 | Bin
|
|
||||||
.../pkinit-certs/user-upn3.pem | 0
|
|
||||||
.../pkinit-certs/user.p12 | Bin
|
|
||||||
.../pkinit-certs/user.pem | 0
|
|
||||||
.../{dejagnu => testsuite}/proxy-certs/ca.pem | 0
|
|
||||||
.../proxy-certs/make-certs.sh | 0
|
|
||||||
.../proxy-certs/proxy-badsig.pem | 0
|
|
||||||
.../proxy-certs/proxy-ideal.pem | 0
|
|
||||||
.../proxy-certs/proxy-no-match.pem | 0
|
|
||||||
.../proxy-certs/proxy-san.pem | 0
|
|
||||||
.../proxy-certs/proxy-subject.pem | 0
|
|
||||||
src/tests/{dejagnu => testsuite}/t_inetd.c | 2 +-
|
|
||||||
src/util/k5test.py | 2 +-
|
|
||||||
76 files changed, 36 insertions(+), 36 deletions(-)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/Makefile.in (86%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.2/crte-policy.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.2/get-policy.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.2/mod-policy.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/chpass-principal-v2.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/chpass-principal.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/crte-policy.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/crte-principal.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/destroy.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/dlte-policy.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/dlte-principal.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/get-policy.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/get-principal-v2.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/get-principal.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/init-v2.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/init.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/mod-policy.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/mod-principal-v2.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/mod-principal.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/randkey-principal-v2.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/randkey-principal.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/config/unix.exp (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/deps (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/destroy-test.c (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/diff-files/destroy-1 (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/diff-files/no-diffs (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/handle-test.c (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/init-test.c (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/iter-test.c (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/lib/lib.t (99%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/lock-test.c (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/randkey-test.c (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/setkey-test.c (100%)
|
|
||||||
rename src/lib/kadm5/{unit-test => testsuite}/site.exp (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/Makefile.in (92%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/config/default.exp (99%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/deps (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/gssapi.exp (98%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/kprop.exp (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/princexpire.exp (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/sample.exp (98%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/simple.exp (98%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/standalone.exp (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/tcp.exp (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/ca.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/generic.p12 (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/generic.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/kdc.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/make-certs.sh (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/privkey-enc.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/privkey.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-enc.p12 (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-upn.p12 (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-upn.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-upn2.p12 (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-upn2.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-upn3.p12 (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-upn3.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user.p12 (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/ca.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/make-certs.sh (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/proxy-badsig.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/proxy-ideal.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/proxy-no-match.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/proxy-san.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/proxy-subject.pem (100%)
|
|
||||||
rename src/tests/{dejagnu => testsuite}/t_inetd.c (99%)
|
|
||||||
|
|
||||||
diff --git a/src/configure.ac b/src/configure.ac
|
|
||||||
index 20066918b..363d5d62d 100644
|
|
||||||
--- a/src/configure.ac
|
|
||||||
+++ b/src/configure.ac
|
|
||||||
@@ -1500,7 +1500,7 @@ V5_AC_OUTPUT_MAKEFILE(.
|
|
||||||
|
|
||||||
lib/rpc lib/rpc/unit-test
|
|
||||||
|
|
||||||
- lib/kadm5 lib/kadm5/clnt lib/kadm5/srv lib/kadm5/unit-test
|
|
||||||
+ lib/kadm5 lib/kadm5/clnt lib/kadm5/srv lib/kadm5/testsuite
|
|
||||||
lib/krad
|
|
||||||
lib/apputils
|
|
||||||
|
|
||||||
@@ -1544,5 +1544,5 @@ V5_AC_OUTPUT_MAKEFILE(.
|
|
||||||
appl/gss-sample appl/user_user
|
|
||||||
|
|
||||||
tests tests/asn.1 tests/create tests/hammer tests/verify tests/gssapi
|
|
||||||
- tests/dejagnu tests/threads tests/shlib tests/gss-threads tests/misc
|
|
||||||
+ tests/testsuite tests/threads tests/shlib tests/gss-threads tests/misc
|
|
||||||
)
|
|
||||||
diff --git a/src/lib/kadm5/Makefile.in b/src/lib/kadm5/Makefile.in
|
|
||||||
index c4eaad38d..76fc4b548 100644
|
|
||||||
--- a/src/lib/kadm5/Makefile.in
|
|
||||||
+++ b/src/lib/kadm5/Makefile.in
|
|
||||||
@@ -1,6 +1,6 @@
|
|
||||||
mydir=lib$(S)kadm5
|
|
||||||
BUILDTOP=$(REL)..$(S)..
|
|
||||||
-SUBDIRS = clnt srv unit-test
|
|
||||||
+SUBDIRS = clnt srv testsuite
|
|
||||||
|
|
||||||
##DOSBUILDTOP = ..\..
|
|
||||||
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/Makefile.in b/src/lib/kadm5/testsuite/Makefile.in
|
|
||||||
similarity index 86%
|
|
||||||
rename from src/lib/kadm5/unit-test/Makefile.in
|
|
||||||
rename to src/lib/kadm5/testsuite/Makefile.in
|
|
||||||
index 68fa097ff..5a55b786b 100644
|
|
||||||
--- a/src/lib/kadm5/unit-test/Makefile.in
|
|
||||||
+++ b/src/lib/kadm5/testsuite/Makefile.in
|
|
||||||
@@ -1,4 +1,4 @@
|
|
||||||
-mydir=lib$(S)kadm5$(S)unit-test
|
|
||||||
+mydir=lib$(S)kadm5$(S)testsuite
|
|
||||||
BUILDTOP=$(REL)..$(S)..$(S)..
|
|
||||||
KDB_DEP_LIB=$(DL_LIB) $(THREAD_LINKOPTS)
|
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ runenv.exp: Makefile
|
|
||||||
eval echo "set env\($$i\) \$$$$i"; done > runenv.exp
|
|
||||||
|
|
||||||
#
|
|
||||||
-# The unit-test targets
|
|
||||||
+# The testsuite targets
|
|
||||||
#
|
|
||||||
|
|
||||||
check: check-@DO_TEST@
|
|
||||||
@@ -72,13 +72,13 @@ check-:
|
|
||||||
@echo "+++ Either tcl, runtest, or Perl is unavailable."
|
|
||||||
@echo "+++"
|
|
||||||
|
|
||||||
-check-ok unit-test: unit-test-client unit-test-server
|
|
||||||
+check-ok testsuite: testsuite-client testsuite-server
|
|
||||||
|
|
||||||
-unit-test-client: unit-test-client-setup unit-test-client-body \
|
|
||||||
- unit-test-client-cleanup
|
|
||||||
+testsuite-client: testsuite-client-setup testsuite-client-body \
|
|
||||||
+ testsuite-client-cleanup
|
|
||||||
|
|
||||||
-unit-test-server: unit-test-server-setup unit-test-server-body \
|
|
||||||
- unit-test-server-cleanup
|
|
||||||
+testsuite-server: testsuite-server-setup testsuite-server-body \
|
|
||||||
+ testsuite-server-cleanup
|
|
||||||
|
|
||||||
test-randkey: randkey-test
|
|
||||||
$(ENV_SETUP) $(VALGRIND) ./randkey-test
|
|
||||||
@@ -98,19 +98,19 @@ test-destroy: destroy-test
|
|
||||||
test-setkey-client: client-setkey-test
|
|
||||||
$(ENV_SETUP) $(VALGRIND) ./client-setkey-test testkeys admin admin
|
|
||||||
|
|
||||||
-unit-test-client-setup: runenv.sh
|
|
||||||
+testsuite-client-setup: runenv.sh
|
|
||||||
$(ENV_SETUP) $(VALGRIND) $(START_SERVERS)
|
|
||||||
|
|
||||||
-unit-test-client-cleanup:
|
|
||||||
+testsuite-client-cleanup:
|
|
||||||
$(ENV_SETUP) $(STOP_SERVERS)
|
|
||||||
|
|
||||||
-unit-test-server-setup: runenv.sh
|
|
||||||
+testsuite-server-setup: runenv.sh
|
|
||||||
$(ENV_SETUP) $(VALGRIND) $(START_SERVERS_LOCAL)
|
|
||||||
|
|
||||||
-unit-test-server-cleanup:
|
|
||||||
+testsuite-server-cleanup:
|
|
||||||
$(ENV_SETUP) $(STOP_SERVERS_LOCAL)
|
|
||||||
|
|
||||||
-unit-test-client-body: site.exp test-noauth test-destroy test-handle-client \
|
|
||||||
+testsuite-client-body: site.exp test-noauth test-destroy test-handle-client \
|
|
||||||
test-setkey-client runenv.exp
|
|
||||||
$(ENV_SETUP) $(RUNTEST) --tool api RPC=1 API=$(CLNTTCL) \
|
|
||||||
KINIT=$(BUILDTOP)/clients/kinit/kinit \
|
|
||||||
@@ -121,7 +121,7 @@ unit-test-client-body: site.exp test-noauth test-destroy test-handle-client \
|
|
||||||
-mv api.log capi.log
|
|
||||||
-mv api.sum capi.sum
|
|
||||||
|
|
||||||
-unit-test-server-body: site.exp test-handle-server lock-test
|
|
||||||
+testsuite-server-body: site.exp test-handle-server lock-test
|
|
||||||
$(ENV_SETUP) $(RUNTEST) --tool api RPC=0 API=$(SRVTCL) \
|
|
||||||
LOCKTEST=./lock-test \
|
|
||||||
KADMIN_LOCAL=$(BUILDTOP)/kadmin/cli/kadmin.local \
|
|
||||||
@@ -140,4 +140,4 @@ clean:
|
|
||||||
$(RM) lock-test lock-test.o
|
|
||||||
$(RM) server-iter-test iter-test.o
|
|
||||||
$(RM) server-setkey-test client-setkey-test setkey-test.o
|
|
||||||
- $(RM) *.log *.plog *.sum *.psum unit-test-log.* runenv.exp
|
|
||||||
+ $(RM) *.log *.plog *.sum *.psum testsuite-log.* runenv.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.2/crte-policy.exp b/src/lib/kadm5/testsuite/api.2/crte-policy.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.2/crte-policy.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.2/crte-policy.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.2/get-policy.exp b/src/lib/kadm5/testsuite/api.2/get-policy.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.2/get-policy.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.2/get-policy.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.2/mod-policy.exp b/src/lib/kadm5/testsuite/api.2/mod-policy.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.2/mod-policy.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.2/mod-policy.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/chpass-principal-v2.exp b/src/lib/kadm5/testsuite/api.current/chpass-principal-v2.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/chpass-principal-v2.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/chpass-principal-v2.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/chpass-principal.exp b/src/lib/kadm5/testsuite/api.current/chpass-principal.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/chpass-principal.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/chpass-principal.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/crte-policy.exp b/src/lib/kadm5/testsuite/api.current/crte-policy.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/crte-policy.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/crte-policy.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/crte-principal.exp b/src/lib/kadm5/testsuite/api.current/crte-principal.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/crte-principal.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/crte-principal.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/destroy.exp b/src/lib/kadm5/testsuite/api.current/destroy.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/destroy.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/destroy.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/dlte-policy.exp b/src/lib/kadm5/testsuite/api.current/dlte-policy.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/dlte-policy.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/dlte-policy.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/dlte-principal.exp b/src/lib/kadm5/testsuite/api.current/dlte-principal.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/dlte-principal.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/dlte-principal.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/get-policy.exp b/src/lib/kadm5/testsuite/api.current/get-policy.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/get-policy.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/get-policy.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/get-principal-v2.exp b/src/lib/kadm5/testsuite/api.current/get-principal-v2.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/get-principal-v2.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/get-principal-v2.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/get-principal.exp b/src/lib/kadm5/testsuite/api.current/get-principal.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/get-principal.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/get-principal.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/init-v2.exp b/src/lib/kadm5/testsuite/api.current/init-v2.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/init-v2.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/init-v2.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/init.exp b/src/lib/kadm5/testsuite/api.current/init.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/init.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/init.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/mod-policy.exp b/src/lib/kadm5/testsuite/api.current/mod-policy.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/mod-policy.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/mod-policy.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/mod-principal-v2.exp b/src/lib/kadm5/testsuite/api.current/mod-principal-v2.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/mod-principal-v2.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/mod-principal-v2.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/mod-principal.exp b/src/lib/kadm5/testsuite/api.current/mod-principal.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/mod-principal.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/mod-principal.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/randkey-principal-v2.exp b/src/lib/kadm5/testsuite/api.current/randkey-principal-v2.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/randkey-principal-v2.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/randkey-principal-v2.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/api.current/randkey-principal.exp b/src/lib/kadm5/testsuite/api.current/randkey-principal.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/api.current/randkey-principal.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/api.current/randkey-principal.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/config/unix.exp b/src/lib/kadm5/testsuite/config/unix.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/config/unix.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/config/unix.exp
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/deps b/src/lib/kadm5/testsuite/deps
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/deps
|
|
||||||
rename to src/lib/kadm5/testsuite/deps
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/destroy-test.c b/src/lib/kadm5/testsuite/destroy-test.c
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/destroy-test.c
|
|
||||||
rename to src/lib/kadm5/testsuite/destroy-test.c
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/diff-files/destroy-1 b/src/lib/kadm5/testsuite/diff-files/destroy-1
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/diff-files/destroy-1
|
|
||||||
rename to src/lib/kadm5/testsuite/diff-files/destroy-1
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/diff-files/no-diffs b/src/lib/kadm5/testsuite/diff-files/no-diffs
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/diff-files/no-diffs
|
|
||||||
rename to src/lib/kadm5/testsuite/diff-files/no-diffs
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/handle-test.c b/src/lib/kadm5/testsuite/handle-test.c
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/handle-test.c
|
|
||||||
rename to src/lib/kadm5/testsuite/handle-test.c
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/init-test.c b/src/lib/kadm5/testsuite/init-test.c
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/init-test.c
|
|
||||||
rename to src/lib/kadm5/testsuite/init-test.c
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/iter-test.c b/src/lib/kadm5/testsuite/iter-test.c
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/iter-test.c
|
|
||||||
rename to src/lib/kadm5/testsuite/iter-test.c
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/lib/lib.t b/src/lib/kadm5/testsuite/lib/lib.t
|
|
||||||
similarity index 99%
|
|
||||||
rename from src/lib/kadm5/unit-test/lib/lib.t
|
|
||||||
rename to src/lib/kadm5/testsuite/lib/lib.t
|
|
||||||
index 3444775cf..327946849 100644
|
|
||||||
--- a/src/lib/kadm5/unit-test/lib/lib.t
|
|
||||||
+++ b/src/lib/kadm5/testsuite/lib/lib.t
|
|
||||||
@@ -226,7 +226,7 @@ proc end_dump_compare {name} {
|
|
||||||
global RPC
|
|
||||||
|
|
||||||
if { ! $RPC } {
|
|
||||||
-# set file $TOP/admin/lib/unit-test/diff-files/$name
|
|
||||||
+# set file $TOP/admin/lib/testsuite/diff-files/$name
|
|
||||||
# exec $env(SIMPLE_DUMP) > /tmp/dump.after
|
|
||||||
# exec $env(COMPARE_DUMP) /tmp/dump.before /tmp/dump.after $file
|
|
||||||
}
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/lock-test.c b/src/lib/kadm5/testsuite/lock-test.c
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/lock-test.c
|
|
||||||
rename to src/lib/kadm5/testsuite/lock-test.c
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/randkey-test.c b/src/lib/kadm5/testsuite/randkey-test.c
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/randkey-test.c
|
|
||||||
rename to src/lib/kadm5/testsuite/randkey-test.c
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/setkey-test.c b/src/lib/kadm5/testsuite/setkey-test.c
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/setkey-test.c
|
|
||||||
rename to src/lib/kadm5/testsuite/setkey-test.c
|
|
||||||
diff --git a/src/lib/kadm5/unit-test/site.exp b/src/lib/kadm5/testsuite/site.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/lib/kadm5/unit-test/site.exp
|
|
||||||
rename to src/lib/kadm5/testsuite/site.exp
|
|
||||||
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
|
|
||||||
index 20f27d748..1198dca0c 100644
|
|
||||||
--- a/src/tests/Makefile.in
|
|
||||||
+++ b/src/tests/Makefile.in
|
|
||||||
@@ -1,6 +1,6 @@
|
|
||||||
mydir=tests
|
|
||||||
BUILDTOP=$(REL)..
|
|
||||||
-SUBDIRS = asn.1 create hammer verify gssapi dejagnu shlib gss-threads misc \
|
|
||||||
+SUBDIRS = asn.1 create hammer verify gssapi testsuite shlib gss-threads misc \
|
|
||||||
threads softpkcs11
|
|
||||||
|
|
||||||
RUN_DB_TEST = $(RUN_SETUP) KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf \
|
|
||||||
diff --git a/src/tests/t_authdata.py b/src/tests/t_authdata.py
|
|
||||||
index 2e01f46bc..e5135f435 100644
|
|
||||||
--- a/src/tests/t_authdata.py
|
|
||||||
+++ b/src/tests/t_authdata.py
|
|
||||||
@@ -57,7 +57,7 @@ if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')):
|
|
||||||
skipped('anonymous ticket authdata tests', 'PKINIT not built')
|
|
||||||
else:
|
|
||||||
# Set up a realm with PKINIT support and get anonymous tickets.
|
|
||||||
- certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs')
|
|
||||||
+ certs = os.path.join(srctop, 'tests', 'testsuite', 'pkinit-certs')
|
|
||||||
ca_pem = os.path.join(certs, 'ca.pem')
|
|
||||||
kdc_pem = os.path.join(certs, 'kdc.pem')
|
|
||||||
privkey_pem = os.path.join(certs, 'privkey.pem')
|
|
||||||
diff --git a/src/tests/t_certauth.py b/src/tests/t_certauth.py
|
|
||||||
index 0fe0fdb4a..bfa5bfc96 100644
|
|
||||||
--- a/src/tests/t_certauth.py
|
|
||||||
+++ b/src/tests/t_certauth.py
|
|
||||||
@@ -4,7 +4,7 @@ from k5test import *
|
|
||||||
if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')):
|
|
||||||
skip_rest('certauth tests', 'PKINIT module not built')
|
|
||||||
|
|
||||||
-certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs')
|
|
||||||
+certs = os.path.join(srctop, 'tests', 'testsuite', 'pkinit-certs')
|
|
||||||
ca_pem = os.path.join(certs, 'ca.pem')
|
|
||||||
kdc_pem = os.path.join(certs, 'kdc.pem')
|
|
||||||
privkey_pem = os.path.join(certs, 'privkey.pem')
|
|
||||||
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
|
|
||||||
index aee4da2b1..8763ce484 100755
|
|
||||||
--- a/src/tests/t_pkinit.py
|
|
||||||
+++ b/src/tests/t_pkinit.py
|
|
||||||
@@ -7,7 +7,7 @@ if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')):
|
|
||||||
soft_pkcs11 = os.path.join(buildtop, 'tests', 'softpkcs11', 'softpkcs11.so')
|
|
||||||
|
|
||||||
# Construct a krb5.conf fragment configuring pkinit.
|
|
||||||
-certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs')
|
|
||||||
+certs = os.path.join(srctop, 'tests', 'testsuite', 'pkinit-certs')
|
|
||||||
ca_pem = os.path.join(certs, 'ca.pem')
|
|
||||||
kdc_pem = os.path.join(certs, 'kdc.pem')
|
|
||||||
user_pem = os.path.join(certs, 'user.pem')
|
|
||||||
diff --git a/src/tests/t_proxy.py b/src/tests/t_proxy.py
|
|
||||||
index 3069eaa8f..6ae5c8c8e 100755
|
|
||||||
--- a/src/tests/t_proxy.py
|
|
||||||
+++ b/src/tests/t_proxy.py
|
|
||||||
@@ -10,17 +10,17 @@ except:
|
|
||||||
|
|
||||||
# Construct a krb5.conf fragment configuring the client to use a local proxy
|
|
||||||
# server.
|
|
||||||
-proxysubjectpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs',
|
|
||||||
+proxysubjectpem = os.path.join(srctop, 'tests', 'testsuite', 'proxy-certs',
|
|
||||||
'proxy-subject.pem')
|
|
||||||
-proxysanpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs',
|
|
||||||
+proxysanpem = os.path.join(srctop, 'tests', 'testsuite', 'proxy-certs',
|
|
||||||
'proxy-san.pem')
|
|
||||||
-proxyidealpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs',
|
|
||||||
+proxyidealpem = os.path.join(srctop, 'tests', 'testsuite', 'proxy-certs',
|
|
||||||
'proxy-ideal.pem')
|
|
||||||
-proxywrongpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs',
|
|
||||||
+proxywrongpem = os.path.join(srctop, 'tests', 'testsuite', 'proxy-certs',
|
|
||||||
'proxy-no-match.pem')
|
|
||||||
-proxybadpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs',
|
|
||||||
+proxybadpem = os.path.join(srctop, 'tests', 'testsuite', 'proxy-certs',
|
|
||||||
'proxy-badsig.pem')
|
|
||||||
-proxyca = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', 'ca.pem')
|
|
||||||
+proxyca = os.path.join(srctop, 'tests', 'testsuite', 'proxy-certs', 'ca.pem')
|
|
||||||
proxyurl = 'https://localhost:$port5/KdcProxy'
|
|
||||||
proxyurlupcase = 'https://LocalHost:$port5/KdcProxy'
|
|
||||||
proxyurl4 = 'https://127.0.0.1:$port5/KdcProxy'
|
|
||||||
diff --git a/src/tests/dejagnu/Makefile.in b/src/tests/testsuite/Makefile.in
|
|
||||||
similarity index 92%
|
|
||||||
rename from src/tests/dejagnu/Makefile.in
|
|
||||||
rename to src/tests/testsuite/Makefile.in
|
|
||||||
index e78e270ed..d3efe3606 100644
|
|
||||||
--- a/src/tests/dejagnu/Makefile.in
|
|
||||||
+++ b/src/tests/testsuite/Makefile.in
|
|
||||||
@@ -1,4 +1,4 @@
|
|
||||||
-mydir=tests$(S)dejagnu
|
|
||||||
+mydir=tests$(S)testsuite
|
|
||||||
BUILDTOP=$(REL)..$(S)..
|
|
||||||
RUNTEST = @RUNTEST@ $(DEJAFLAGS)
|
|
||||||
RUNTESTFLAGS =
|
|
||||||
@@ -13,7 +13,7 @@ check: check-runtest-@HAVE_RUNTEST@
|
|
||||||
|
|
||||||
check-runtest-no:
|
|
||||||
@echo "+++"
|
|
||||||
- @echo "+++ WARNING: tests/dejagnu tests not run."
|
|
||||||
+ @echo "+++ WARNING: tests/testsuite tests not run."
|
|
||||||
@echo "+++ runtest is unavailable."
|
|
||||||
@echo "+++"
|
|
||||||
@echo 'Skipped dejagnu tests: runtest not found' >> $(SKIPTESTS)
|
|
||||||
diff --git a/src/tests/dejagnu/config/default.exp b/src/tests/testsuite/config/default.exp
|
|
||||||
similarity index 99%
|
|
||||||
rename from src/tests/dejagnu/config/default.exp
|
|
||||||
rename to src/tests/testsuite/config/default.exp
|
|
||||||
index 302dee74c..1492fac32 100644
|
|
||||||
--- a/src/tests/dejagnu/config/default.exp
|
|
||||||
+++ b/src/tests/testsuite/config/default.exp
|
|
||||||
@@ -256,7 +256,7 @@ verbose "Test realm is $REALMNAME"
|
|
||||||
|
|
||||||
# Find some programs we need. We use the binaries from the build tree
|
|
||||||
# if they exist. If they do not, then they must be in PATH. We
|
|
||||||
-# expect $objdir to be ...tests/dejagnu.
|
|
||||||
+# expect $objdir to be ...tests/testsuite.
|
|
||||||
|
|
||||||
foreach i {
|
|
||||||
{KDB5_UTIL $objdir/../../kadmin/dbutil/kdb5_util}
|
|
||||||
diff --git a/src/tests/dejagnu/deps b/src/tests/testsuite/deps
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/deps
|
|
||||||
rename to src/tests/testsuite/deps
|
|
||||||
diff --git a/src/tests/dejagnu/krb-standalone/gssapi.exp b/src/tests/testsuite/krb-standalone/gssapi.exp
|
|
||||||
similarity index 98%
|
|
||||||
rename from src/tests/dejagnu/krb-standalone/gssapi.exp
|
|
||||||
rename to src/tests/testsuite/krb-standalone/gssapi.exp
|
|
||||||
index e3357e769..d176e210c 100644
|
|
||||||
--- a/src/tests/dejagnu/krb-standalone/gssapi.exp
|
|
||||||
+++ b/src/tests/testsuite/krb-standalone/gssapi.exp
|
|
||||||
@@ -2,7 +2,7 @@
|
|
||||||
# This is a DejaGnu test script.
|
|
||||||
# This script tests that the GSS-API tester functions correctly.
|
|
||||||
|
|
||||||
-# This mostly just calls procedures in test/dejagnu/config/default.exp.
|
|
||||||
+# This mostly just calls procedures in test/testsuite/config/default.exp.
|
|
||||||
|
|
||||||
if ![info exists KDESTROY] {
|
|
||||||
set KDESTROY [findfile $objdir/../../clients/kdestroy/kdestroy]
|
|
||||||
diff --git a/src/tests/dejagnu/krb-standalone/kprop.exp b/src/tests/testsuite/krb-standalone/kprop.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/krb-standalone/kprop.exp
|
|
||||||
rename to src/tests/testsuite/krb-standalone/kprop.exp
|
|
||||||
diff --git a/src/tests/dejagnu/krb-standalone/princexpire.exp b/src/tests/testsuite/krb-standalone/princexpire.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/krb-standalone/princexpire.exp
|
|
||||||
rename to src/tests/testsuite/krb-standalone/princexpire.exp
|
|
||||||
diff --git a/src/tests/dejagnu/krb-standalone/sample.exp b/src/tests/testsuite/krb-standalone/sample.exp
|
|
||||||
similarity index 98%
|
|
||||||
rename from src/tests/dejagnu/krb-standalone/sample.exp
|
|
||||||
rename to src/tests/testsuite/krb-standalone/sample.exp
|
|
||||||
index 93a75f1d0..009de5ddb 100644
|
|
||||||
--- a/src/tests/dejagnu/krb-standalone/sample.exp
|
|
||||||
+++ b/src/tests/testsuite/krb-standalone/sample.exp
|
|
||||||
@@ -2,7 +2,7 @@
|
|
||||||
# This is a DejaGnu test script.
|
|
||||||
# This script tests that sample user-user communication works.
|
|
||||||
|
|
||||||
-# This mostly just calls procedures in test/dejagnu/config/default.exp.
|
|
||||||
+# This mostly just calls procedures in test/testsuite/config/default.exp.
|
|
||||||
|
|
||||||
if ![info exists KLIST] {
|
|
||||||
set KLIST [findfile $objdir/../../clients/klist/klist]
|
|
||||||
diff --git a/src/tests/dejagnu/krb-standalone/simple.exp b/src/tests/testsuite/krb-standalone/simple.exp
|
|
||||||
similarity index 98%
|
|
||||||
rename from src/tests/dejagnu/krb-standalone/simple.exp
|
|
||||||
rename to src/tests/testsuite/krb-standalone/simple.exp
|
|
||||||
index d8b218248..92b33066e 100644
|
|
||||||
--- a/src/tests/dejagnu/krb-standalone/simple.exp
|
|
||||||
+++ b/src/tests/testsuite/krb-standalone/simple.exp
|
|
||||||
@@ -2,7 +2,7 @@
|
|
||||||
# This is a DejaGnu test script.
|
|
||||||
# This script tests that krb-safe and krb-priv messages work.
|
|
||||||
|
|
||||||
-# This mostly just calls procedures in test/dejagnu/config/default.exp.
|
|
||||||
+# This mostly just calls procedures in test/testsuite/config/default.exp.
|
|
||||||
|
|
||||||
if ![info exists KLIST] {
|
|
||||||
set KLIST [findfile $objdir/../../clients/klist/klist]
|
|
||||||
diff --git a/src/tests/dejagnu/krb-standalone/standalone.exp b/src/tests/testsuite/krb-standalone/standalone.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/krb-standalone/standalone.exp
|
|
||||||
rename to src/tests/testsuite/krb-standalone/standalone.exp
|
|
||||||
diff --git a/src/tests/dejagnu/krb-standalone/tcp.exp b/src/tests/testsuite/krb-standalone/tcp.exp
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/krb-standalone/tcp.exp
|
|
||||||
rename to src/tests/testsuite/krb-standalone/tcp.exp
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/ca.pem b/src/tests/testsuite/pkinit-certs/ca.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/ca.pem
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/ca.pem
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/generic.p12 b/src/tests/testsuite/pkinit-certs/generic.p12
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/generic.p12
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/generic.p12
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/generic.pem b/src/tests/testsuite/pkinit-certs/generic.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/generic.pem
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/generic.pem
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/kdc.pem b/src/tests/testsuite/pkinit-certs/kdc.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/kdc.pem
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/kdc.pem
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/testsuite/pkinit-certs/make-certs.sh
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/make-certs.sh
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/make-certs.sh
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/privkey-enc.pem b/src/tests/testsuite/pkinit-certs/privkey-enc.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/privkey-enc.pem
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/privkey-enc.pem
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/privkey.pem b/src/tests/testsuite/pkinit-certs/privkey.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/privkey.pem
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/privkey.pem
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-enc.p12 b/src/tests/testsuite/pkinit-certs/user-enc.p12
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/user-enc.p12
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/user-enc.p12
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn.p12 b/src/tests/testsuite/pkinit-certs/user-upn.p12
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/user-upn.p12
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/user-upn.p12
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn.pem b/src/tests/testsuite/pkinit-certs/user-upn.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/user-upn.pem
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/user-upn.pem
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn2.p12 b/src/tests/testsuite/pkinit-certs/user-upn2.p12
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/user-upn2.p12
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/user-upn2.p12
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn2.pem b/src/tests/testsuite/pkinit-certs/user-upn2.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/user-upn2.pem
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/user-upn2.pem
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn3.p12 b/src/tests/testsuite/pkinit-certs/user-upn3.p12
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/user-upn3.p12
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/user-upn3.p12
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn3.pem b/src/tests/testsuite/pkinit-certs/user-upn3.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/user-upn3.pem
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/user-upn3.pem
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/user.p12 b/src/tests/testsuite/pkinit-certs/user.p12
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/user.p12
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/user.p12
|
|
||||||
diff --git a/src/tests/dejagnu/pkinit-certs/user.pem b/src/tests/testsuite/pkinit-certs/user.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/pkinit-certs/user.pem
|
|
||||||
rename to src/tests/testsuite/pkinit-certs/user.pem
|
|
||||||
diff --git a/src/tests/dejagnu/proxy-certs/ca.pem b/src/tests/testsuite/proxy-certs/ca.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/proxy-certs/ca.pem
|
|
||||||
rename to src/tests/testsuite/proxy-certs/ca.pem
|
|
||||||
diff --git a/src/tests/dejagnu/proxy-certs/make-certs.sh b/src/tests/testsuite/proxy-certs/make-certs.sh
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/proxy-certs/make-certs.sh
|
|
||||||
rename to src/tests/testsuite/proxy-certs/make-certs.sh
|
|
||||||
diff --git a/src/tests/dejagnu/proxy-certs/proxy-badsig.pem b/src/tests/testsuite/proxy-certs/proxy-badsig.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/proxy-certs/proxy-badsig.pem
|
|
||||||
rename to src/tests/testsuite/proxy-certs/proxy-badsig.pem
|
|
||||||
diff --git a/src/tests/dejagnu/proxy-certs/proxy-ideal.pem b/src/tests/testsuite/proxy-certs/proxy-ideal.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/proxy-certs/proxy-ideal.pem
|
|
||||||
rename to src/tests/testsuite/proxy-certs/proxy-ideal.pem
|
|
||||||
diff --git a/src/tests/dejagnu/proxy-certs/proxy-no-match.pem b/src/tests/testsuite/proxy-certs/proxy-no-match.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/proxy-certs/proxy-no-match.pem
|
|
||||||
rename to src/tests/testsuite/proxy-certs/proxy-no-match.pem
|
|
||||||
diff --git a/src/tests/dejagnu/proxy-certs/proxy-san.pem b/src/tests/testsuite/proxy-certs/proxy-san.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/proxy-certs/proxy-san.pem
|
|
||||||
rename to src/tests/testsuite/proxy-certs/proxy-san.pem
|
|
||||||
diff --git a/src/tests/dejagnu/proxy-certs/proxy-subject.pem b/src/tests/testsuite/proxy-certs/proxy-subject.pem
|
|
||||||
similarity index 100%
|
|
||||||
rename from src/tests/dejagnu/proxy-certs/proxy-subject.pem
|
|
||||||
rename to src/tests/testsuite/proxy-certs/proxy-subject.pem
|
|
||||||
diff --git a/src/tests/dejagnu/t_inetd.c b/src/tests/testsuite/t_inetd.c
|
|
||||||
similarity index 99%
|
|
||||||
rename from src/tests/dejagnu/t_inetd.c
|
|
||||||
rename to src/tests/testsuite/t_inetd.c
|
|
||||||
index abcde50fa..2bad2cf65 100644
|
|
||||||
--- a/src/tests/dejagnu/t_inetd.c
|
|
||||||
+++ b/src/tests/testsuite/t_inetd.c
|
|
||||||
@@ -1,5 +1,5 @@
|
|
||||||
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
||||||
-/* tests/dejagnu/t_inetd.c */
|
|
||||||
+/* tests/testsuite/t_inetd.c */
|
|
||||||
/*
|
|
||||||
* Copyright 1991 by the Massachusetts Institute of Technology.
|
|
||||||
* All Rights Reserved.
|
|
||||||
diff --git a/src/util/k5test.py b/src/util/k5test.py
|
|
||||||
index 251d11a9d..908a1495c 100644
|
|
||||||
--- a/src/util/k5test.py
|
|
||||||
+++ b/src/util/k5test.py
|
|
||||||
@@ -1383,7 +1383,7 @@ kswitch = os.path.join(buildtop, 'clients', 'kswitch', 'kswitch')
|
|
||||||
kvno = os.path.join(buildtop, 'clients', 'kvno', 'kvno')
|
|
||||||
kdestroy = os.path.join(buildtop, 'clients', 'kdestroy', 'kdestroy')
|
|
||||||
kpasswd = os.path.join(buildtop, 'clients', 'kpasswd', 'kpasswd')
|
|
||||||
-t_inetd = os.path.join(buildtop, 'tests', 'dejagnu', 't_inetd')
|
|
||||||
+t_inetd = os.path.join(buildtop, 'tests', 'testsuite', 't_inetd')
|
|
||||||
kproplog = os.path.join(buildtop, 'kprop', 'kproplog')
|
|
||||||
kpropd = os.path.join(buildtop, 'kprop', 'kpropd')
|
|
||||||
kprop = os.path.join(buildtop, 'kprop', 'kprop')
|
|
||||||
--
|
|
||||||
2.35.1
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
|||||||
From ad123366e5fb2694cf6d9f4f292a001a761b78fa Mon Sep 17 00:00:00 2001
|
|
||||||
From: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
Date: Tue, 23 Aug 2016 16:46:21 -0400
|
|
||||||
Subject: [PATCH] [downstream] netlib and dns
|
|
||||||
|
|
||||||
We want to be able to use --with-netlib and --enable-dns at the same time.
|
|
||||||
|
|
||||||
Last-updated: krb5-1.3.1
|
|
||||||
---
|
|
||||||
src/aclocal.m4 | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
diff --git a/src/aclocal.m4 b/src/aclocal.m4
|
|
||||||
index 5afb96e58..4a4d460e3 100644
|
|
||||||
--- a/src/aclocal.m4
|
|
||||||
+++ b/src/aclocal.m4
|
|
||||||
@@ -718,6 +718,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library),
|
|
||||||
LIBS="$LIBS $withval"
|
|
||||||
AC_MSG_RESULT("netlib will use \'$withval\'")
|
|
||||||
fi
|
|
||||||
+ KRB5_AC_ENABLE_DNS
|
|
||||||
],dnl
|
|
||||||
[AC_LIBRARY_NET]
|
|
||||||
)])dnl
|
|
@ -1,16 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQIzBAABCgAdFiEExEk8tzn0qJ+YUsvCDLoIV1+Dct8FAmAuntAACgkQDLoIV1+D
|
|
||||||
ct8TIhAArFittFBcz4ZfMxqhHVGdK6kOeQXrrV27d3FW6y28BvS7yHJ8CkyK+I3g
|
|
||||||
4rsaaf7srkH8jaiCjmjHC2rWJIuceOwkD4GRqXtb2CiqKxXI9eZ+g9ipB7DGKixg
|
|
||||||
+1nki7mOhd3oaeUkCRFXgyiOqSE/ird7/itLYzEoAroLpTazNp6Kk4gXmhJIENlq
|
|
||||||
dj1God+JxhuwzzWZRdsy2SyvMQPQMOTIilsXRboObZFvPrhZKkJmgNm+RzU/YRSg
|
|
||||||
/1Po7takBXq8qhgnwPHTnTPb+BYRdrqQc/a2WcmEdgbzeMpijNmkFsgAFeKDijSz
|
|
||||||
1nmFO4SQd/rAfgUovkDd+GMAYZ6DCLFqoI/WeKOgCrRMxJMMRbLlr48bTvMwjuIl
|
|
||||||
xE5gy8h2Iju/UP1lxz8KheCm/FyNzNw4pe74zbGgK5fdiEQ8xNlKZOs9LRrtvyfL
|
|
||||||
j1G+IX6cK+5yTo/NceYjnHVAatbuW6C6xJmsIQ1GYdMPvto7Wctq/4/BmwxqgFAJ
|
|
||||||
HCPuQgAGi875JpPYvi/c3tioRiIPwOz54CXCrcFyKELvgHi6lGN6MRNSzAP4QdA0
|
|
||||||
HlXZQ4/4NFOJxjLGu9ZXKUbYPaGizhI+ayzg5/RJLHPIgW7yLvwFqkBIa1xs26bA
|
|
||||||
xiP5JKuDC4mqDPwVjwpufkUBH6SoBFnbiIWEYSKVPLJFw+Dbhv0=
|
|
||||||
=PP6r
|
|
||||||
-----END PGP SIGNATURE-----
|
|
@ -0,0 +1,16 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQIzBAABCgAdFiEExEk8tzn0qJ+YUsvCDLoIV1+Dct8FAmNvED8ACgkQDLoIV1+D
|
||||||
|
ct9uKw/8C5GS8mdh335lB+bkfjYYCZLD+oQToDAAbdCddrIcuLftvnTfXJ8cMtMc
|
||||||
|
UT2hsp8u7ZupjJRevdhaH7fFwomc0V8iSES5J2cQHTNd9aK93j/W6NaMoqWLrQWg
|
||||||
|
jx99oqLn7orvp8N5RufEQcNMNWhFIX4XSfrA3vPfHbbffA2vkjJzOGno4UHi8zUn
|
||||||
|
6nye7jbrBpiQIeFIJSS3VPsvGrKdRgb9BqGTUsqPIuFvr3Qvo42lKr5X8CWYSXjK
|
||||||
|
0aKlOpfbWdkteEe2o84/wyMpuGvmYkmOgaMB5xQ3jfEuvPNAWX2CWHNDamiqwBT/
|
||||||
|
YxwhZimNa1B9r3P1yDHvpUu8cJaRzw2UDRi2f3Kztrmn2jlqzmoZ31WBALJA7lmL
|
||||||
|
SrVFdXi7AcWwppMp1kbe9SvurCXID8/Q4n+qAdzSvqrXbeWerVUkdYFvtxQ1bMJR
|
||||||
|
jnqN11iZFYaoCaaR2lFEhjoMdR80jUa2m6vdF7a7xhH1UvuPHDnzLT9X/TiPvx0R
|
||||||
|
Itrp5MMIrUQHcZUL9hM5hrg3nxEsGsSCnjB0zWDmgXdLGwd4CvcOF4HPQR3BBlEH
|
||||||
|
CLtAa27bBXMJTYVvmmKt06hw+U3ALDfUlFrV6ZNLr9ug69l29n7JoChAbZ97Hx1m
|
||||||
|
twPwJpKd8AiUz+j3KCfgGU21qMbHNP3jEn3q9tkq0qcs/z7RCmU=
|
||||||
|
=1WIq
|
||||||
|
-----END PGP SIGNATURE-----
|
@ -1,69 +0,0 @@
|
|||||||
From 0ac0fd2d349e4d5ef7379182f4d7ce480edd8d2b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Sumit Bose <sbose@redhat.com>
|
|
||||||
Date: Mon, 8 Nov 2021 17:48:50 +0100
|
|
||||||
Subject: [PATCH 2/2] Support larger RADIUS attributes in libkrad
|
|
||||||
|
|
||||||
In kr_attrset_decode(), explicitly treat the length byte as unsigned.
|
|
||||||
Otherwise attributes longer than 125 characters will be rejected with
|
|
||||||
EBADMSG.
|
|
||||||
|
|
||||||
Add a 253-character-long NAS-Identifier attribute to the tests to make
|
|
||||||
sure that attributes with the maximal number of characters are working
|
|
||||||
as expected.
|
|
||||||
|
|
||||||
[ghudson@mit.edu: used uint8_t cast per current practices; edited
|
|
||||||
commit message]
|
|
||||||
|
|
||||||
ticket: 9036 (new)
|
|
||||||
---
|
|
||||||
src/lib/krad/attrset.c | 2 +-
|
|
||||||
src/lib/krad/t_packet.c | 13 +++++++++++++
|
|
||||||
2 files changed, 14 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
|
|
||||||
index d89982a13..6ec031e32 100644
|
|
||||||
--- a/src/lib/krad/attrset.c
|
|
||||||
+++ b/src/lib/krad/attrset.c
|
|
||||||
@@ -218,7 +218,7 @@ kr_attrset_decode(krb5_context ctx, const krb5_data *in, const char *secret,
|
|
||||||
|
|
||||||
for (i = 0; i + 2 < in->length; ) {
|
|
||||||
type = in->data[i++];
|
|
||||||
- tmp = make_data(&in->data[i + 1], in->data[i] - 2);
|
|
||||||
+ tmp = make_data(&in->data[i + 1], (uint8_t)in->data[i] - 2);
|
|
||||||
i += tmp.length + 1;
|
|
||||||
|
|
||||||
retval = (in->length < i) ? EBADMSG : 0;
|
|
||||||
diff --git a/src/lib/krad/t_packet.c b/src/lib/krad/t_packet.c
|
|
||||||
index 0a92e9cc2..c22489144 100644
|
|
||||||
--- a/src/lib/krad/t_packet.c
|
|
||||||
+++ b/src/lib/krad/t_packet.c
|
|
||||||
@@ -57,6 +57,14 @@ make_packet(krb5_context ctx, const krb5_data *username,
|
|
||||||
krb5_error_code retval;
|
|
||||||
const krb5_data *data;
|
|
||||||
int i = 0;
|
|
||||||
+ krb5_data nas_id;
|
|
||||||
+
|
|
||||||
+ nas_id = string2data("12345678901234567890123456789012345678901234567890"
|
|
||||||
+ "12345678901234567890123456789012345678901234567890"
|
|
||||||
+ "12345678901234567890123456789012345678901234567890"
|
|
||||||
+ "12345678901234567890123456789012345678901234567890"
|
|
||||||
+ "12345678901234567890123456789012345678901234567890"
|
|
||||||
+ "123");
|
|
||||||
|
|
||||||
retval = krad_attrset_new(ctx, &set);
|
|
||||||
if (retval != 0)
|
|
||||||
@@ -71,6 +79,11 @@ make_packet(krb5_context ctx, const krb5_data *username,
|
|
||||||
if (retval != 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
+ retval = krad_attrset_add(set, krad_attr_name2num("NAS-Identifier"),
|
|
||||||
+ &nas_id);
|
|
||||||
+ if (retval != 0)
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
retval = krad_packet_new_request(ctx, "foo",
|
|
||||||
krad_code_name2num("Access-Request"),
|
|
||||||
set, iterator, &i, &tmp);
|
|
||||||
--
|
|
||||||
2.35.3
|
|
||||||
|
|
@ -1,171 +0,0 @@
|
|||||||
From a8551b609fd50458ca3c06a9dd345b6cdf18689b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Greg Hudson <ghudson@mit.edu>
|
|
||||||
Date: Tue, 9 Nov 2021 13:00:43 -0500
|
|
||||||
Subject: [PATCH 1/2] Avoid use after free during libkrad cleanup
|
|
||||||
|
|
||||||
libkrad client requests contain a list of references to remotes, with
|
|
||||||
no back-references or reference counts. To prevent accesses to
|
|
||||||
dangling references during cleanup, cancel all requests on all remotes
|
|
||||||
before freeing any remotes.
|
|
||||||
|
|
||||||
Remove the code for aging out unused servers. This code was fairly
|
|
||||||
safe as all requests referencing a remote should have completed or
|
|
||||||
timed out during an hour of disuse, but in the current design we have
|
|
||||||
no way to guarantee or check that. The set of addresses we send
|
|
||||||
RADIUS requests to will generally be small, so aging out servers is
|
|
||||||
unnecessary.
|
|
||||||
|
|
||||||
ticket: 9035 (new)
|
|
||||||
---
|
|
||||||
src/lib/krad/client.c | 42 ++++++++++++++---------------------------
|
|
||||||
src/lib/krad/internal.h | 4 ++++
|
|
||||||
src/lib/krad/remote.c | 11 ++++++++---
|
|
||||||
3 files changed, 26 insertions(+), 31 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/lib/krad/client.c b/src/lib/krad/client.c
|
|
||||||
index 6365dd1c6..810940afc 100644
|
|
||||||
--- a/src/lib/krad/client.c
|
|
||||||
+++ b/src/lib/krad/client.c
|
|
||||||
@@ -64,7 +64,6 @@ struct request_st {
|
|
||||||
|
|
||||||
struct server_st {
|
|
||||||
krad_remote *serv;
|
|
||||||
- time_t last;
|
|
||||||
K5_LIST_ENTRY(server_st) list;
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -81,15 +80,10 @@ get_server(krad_client *rc, const struct addrinfo *ai, const char *secret,
|
|
||||||
krad_remote **out)
|
|
||||||
{
|
|
||||||
krb5_error_code retval;
|
|
||||||
- time_t currtime;
|
|
||||||
server *srv;
|
|
||||||
|
|
||||||
- if (time(&currtime) == (time_t)-1)
|
|
||||||
- return errno;
|
|
||||||
-
|
|
||||||
K5_LIST_FOREACH(srv, &rc->servers, list) {
|
|
||||||
if (kr_remote_equals(srv->serv, ai, secret)) {
|
|
||||||
- srv->last = currtime;
|
|
||||||
*out = srv->serv;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -98,7 +92,6 @@ get_server(krad_client *rc, const struct addrinfo *ai, const char *secret,
|
|
||||||
srv = calloc(1, sizeof(server));
|
|
||||||
if (srv == NULL)
|
|
||||||
return ENOMEM;
|
|
||||||
- srv->last = currtime;
|
|
||||||
|
|
||||||
retval = kr_remote_new(rc->kctx, rc->vctx, ai, secret, &srv->serv);
|
|
||||||
if (retval != 0) {
|
|
||||||
@@ -173,28 +166,12 @@ request_new(krad_client *rc, krad_code code, const krad_attrset *attrs,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-/* Close remotes that haven't been used in a while. */
|
|
||||||
-static void
|
|
||||||
-age(struct server_head *head, time_t currtime)
|
|
||||||
-{
|
|
||||||
- server *srv, *tmp;
|
|
||||||
-
|
|
||||||
- K5_LIST_FOREACH_SAFE(srv, head, list, tmp) {
|
|
||||||
- if (currtime == (time_t)-1 || currtime - srv->last > 60 * 60) {
|
|
||||||
- K5_LIST_REMOVE(srv, list);
|
|
||||||
- kr_remote_free(srv->serv);
|
|
||||||
- free(srv);
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
/* Handle a response from a server (or related errors). */
|
|
||||||
static void
|
|
||||||
on_response(krb5_error_code retval, const krad_packet *reqp,
|
|
||||||
const krad_packet *rspp, void *data)
|
|
||||||
{
|
|
||||||
request *req = data;
|
|
||||||
- time_t currtime;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
/* Do nothing if we are already completed. */
|
|
||||||
@@ -221,10 +198,6 @@ on_response(krb5_error_code retval, const krad_packet *reqp,
|
|
||||||
for (i = 0; req->remotes[i].remote != NULL; i++)
|
|
||||||
kr_remote_cancel(req->remotes[i].remote, req->remotes[i].packet);
|
|
||||||
|
|
||||||
- /* Age out servers that haven't been used in a while. */
|
|
||||||
- if (time(&currtime) != (time_t)-1)
|
|
||||||
- age(&req->rc->servers, currtime);
|
|
||||||
-
|
|
||||||
request_free(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -247,10 +220,23 @@ krad_client_new(krb5_context kctx, verto_ctx *vctx, krad_client **out)
|
|
||||||
void
|
|
||||||
krad_client_free(krad_client *rc)
|
|
||||||
{
|
|
||||||
+ server *srv;
|
|
||||||
+
|
|
||||||
if (rc == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
- age(&rc->servers, -1);
|
|
||||||
+ /* Cancel all requests before freeing any remotes, since each request's
|
|
||||||
+ * callback data may contain references to multiple remotes. */
|
|
||||||
+ K5_LIST_FOREACH(srv, &rc->servers, list)
|
|
||||||
+ kr_remote_cancel_all(srv->serv);
|
|
||||||
+
|
|
||||||
+ while (!K5_LIST_EMPTY(&rc->servers)) {
|
|
||||||
+ srv = K5_LIST_FIRST(&rc->servers);
|
|
||||||
+ K5_LIST_REMOVE(srv, list);
|
|
||||||
+ kr_remote_free(srv->serv);
|
|
||||||
+ free(srv);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
free(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
|
|
||||||
index 223ffd730..fa012db78 100644
|
|
||||||
--- a/src/lib/krad/internal.h
|
|
||||||
+++ b/src/lib/krad/internal.h
|
|
||||||
@@ -120,6 +120,10 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
|
|
||||||
void
|
|
||||||
kr_remote_cancel(krad_remote *rr, const krad_packet *pkt);
|
|
||||||
|
|
||||||
+/* Cancel all requests awaiting responses. */
|
|
||||||
+void
|
|
||||||
+kr_remote_cancel_all(krad_remote *rr);
|
|
||||||
+
|
|
||||||
/* Determine if this remote object refers to the remote resource identified
|
|
||||||
* by the addrinfo struct and the secret. */
|
|
||||||
krb5_boolean
|
|
||||||
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
|
|
||||||
index c8912892c..01a5fd2a4 100644
|
|
||||||
--- a/src/lib/krad/remote.c
|
|
||||||
+++ b/src/lib/krad/remote.c
|
|
||||||
@@ -452,15 +452,20 @@ error:
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
+void
|
|
||||||
+kr_remote_cancel_all(krad_remote *rr)
|
|
||||||
+{
|
|
||||||
+ while (!K5_TAILQ_EMPTY(&rr->list))
|
|
||||||
+ request_finish(K5_TAILQ_FIRST(&rr->list), ECANCELED, NULL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void
|
|
||||||
kr_remote_free(krad_remote *rr)
|
|
||||||
{
|
|
||||||
if (rr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
- while (!K5_TAILQ_EMPTY(&rr->list))
|
|
||||||
- request_finish(K5_TAILQ_FIRST(&rr->list), ECANCELED, NULL);
|
|
||||||
-
|
|
||||||
+ kr_remote_cancel_all(rr);
|
|
||||||
free(rr->secret);
|
|
||||||
if (rr->info != NULL)
|
|
||||||
free(rr->info->ai_addr);
|
|
||||||
--
|
|
||||||
2.35.3
|
|
||||||
|
|
Loading…
Reference in new issue