import krb5-1.17-18.el8

This commit is contained in:
CentOS Sources 2020-04-28 05:39:01 -04:00 committed by Andrew Lukoshko
parent 8fbeb381dc
commit 3ec284c784
24 changed files with 4227 additions and 365 deletions

View File

@ -1,4 +1,4 @@
From 656fb920da2d6be3c55976320e3e13a69af30c8a Mon Sep 17 00:00:00 2001
From ba1fd0a44c74089d42af244ff2b315baf506fd2f Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 15 Jan 2019 16:16:57 -0500
Subject: [PATCH] Add function and enctype flag for deprecations

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
From dd863eb4311310c23ee12961fa8e91703f29a6f5 Mon Sep 17 00:00:00 2001
From 7ab0bbac058d2b82aa3432759c600b22012f8afe Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 22 Nov 2018 00:27:35 -0500
Subject: [PATCH] Add tests for KCM ccache type

View File

@ -1,4 +1,4 @@
From 54348bbfaec50bb72d1625c015f8e5c4cfa59e0d Mon Sep 17 00:00:00 2001
From 722247aa6201d18a7ee69c4a9a05315226fe6383 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sun, 30 Dec 2018 16:40:28 -0500
Subject: [PATCH] Address some optimized-out memset() calls

View File

@ -0,0 +1,63 @@
From e22f3e2439903aa05321ca339be6a12067b2c4db Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 6 May 2019 15:14:49 -0400
Subject: [PATCH] Avoid alignment warnings in openssl rc4.c
Add a comment to k5_arcfour_init_state() explaining how we stretch the
krb5_data cipher state contract. Use void * casts when interpreting
the data pointer to avoid alignment warnings.
[ghudson@mit.edu: moved and expanded comment; rewrote commit message]
(cherry picked from commit 1cd41d76c12fc1cea0a8bf0d6a40f34623c60d6d)
---
src/lib/crypto/openssl/enc_provider/rc4.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
index 7f3c086ed..a65d57b7a 100644
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
@@ -57,7 +57,7 @@ struct arcfour_state {
/* In-place IOV crypto */
static krb5_error_code
-k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data,
+k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
size_t num_data)
{
size_t i;
@@ -66,7 +66,7 @@ k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx = NULL;
struct arcfour_state *arcstate;
- arcstate = (state != NULL) ? (struct arcfour_state *) state->data : NULL;
+ arcstate = (state != NULL) ? (void *)state->data : NULL;
if (arcstate != NULL) {
ctx = arcstate->ctx;
if (arcstate->loopback != arcstate)
@@ -113,7 +113,7 @@ k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data,
static void
k5_arcfour_free_state(krb5_data *state)
{
- struct arcfour_state *arcstate = (struct arcfour_state *) state->data;
+ struct arcfour_state *arcstate = (void *)state->data;
EVP_CIPHER_CTX_free(arcstate->ctx);
free(arcstate);
@@ -125,6 +125,15 @@ k5_arcfour_init_state(const krb5_keyblock *key,
{
struct arcfour_state *arcstate;
+ /*
+ * The cipher state here is a saved pointer to a struct arcfour_state
+ * object, rather than a flat byte array as in most enc providers. The
+ * object includes a loopback pointer to detect if if the caller made a
+ * copy of the krb5_data value or otherwise assumed it was a simple byte
+ * array. When we cast the data pointer back, we need to go through void *
+ * to avoid increased alignment warnings.
+ */
+
/* Create a state structure with an uninitialized context. */
arcstate = calloc(1, sizeof(*arcstate));
if (arcstate == NULL)

View File

@ -1,183 +0,0 @@
From 0c361343839b2ff6f89f1ee9c1e01d4f05ab6ffe Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 9 Nov 2018 15:12:21 -0500
Subject: [PATCH] Become FIPS-aware (with 3DES)
A lot of the FIPS error conditions from OpenSSL are incredibly
mysterious (at best, things return NULL unexpectedly; at worst,
internal assertions are tripped; most of the time, you just get
ENOMEM). In order to cope with this, we need to have some level of
awareness of what we can and can't safely call.
This will slow down some calls slightly (FIPS_mode() takes multiple
locks), but not for any crypto we care about - which is to say that
AES is fine.
(cherry picked from commit 9f5fbf191d74cae9b28d318fff4c80d3d3e49c86)
---
src/lib/crypto/openssl/enc_provider/camellia.c | 6 ++++++
src/lib/crypto/openssl/enc_provider/des.c | 9 +++++++++
src/lib/crypto/openssl/enc_provider/des3.c | 6 ++++++
src/lib/crypto/openssl/enc_provider/rc4.c | 13 ++++++++++++-
src/lib/crypto/openssl/hash_provider/hash_evp.c | 4 ++++
src/lib/crypto/openssl/hmac.c | 6 +++++-
6 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
index 2da691329..f79679a0b 100644
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
@@ -304,6 +304,9 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE];
struct iov_cursor cursor;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
if (output->length < CAMELLIA_BLOCK_SIZE)
return KRB5_BAD_MSIZE;
@@ -331,6 +334,9 @@ static krb5_error_code
krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage,
krb5_data *state)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
state->length = 16;
state->data = (void *) malloc(16);
if (state->data == NULL)
diff --git a/src/lib/crypto/openssl/enc_provider/des.c b/src/lib/crypto/openssl/enc_provider/des.c
index a662db512..7d17d287e 100644
--- a/src/lib/crypto/openssl/enc_provider/des.c
+++ b/src/lib/crypto/openssl/enc_provider/des.c
@@ -85,6 +85,9 @@ k5_des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -133,6 +136,9 @@ k5_des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -182,6 +188,9 @@ k5_des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data,
DES_key_schedule sched;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0)
return ret;
diff --git a/src/lib/crypto/openssl/enc_provider/des3.c b/src/lib/crypto/openssl/enc_provider/des3.c
index 1c439c2cd..8be555a8d 100644
--- a/src/lib/crypto/openssl/enc_provider/des3.c
+++ b/src/lib/crypto/openssl/enc_provider/des3.c
@@ -84,6 +84,9 @@ k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -133,6 +136,9 @@ k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
index 7f3c086ed..a3f2a7442 100644
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
@@ -66,6 +66,9 @@ k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx = NULL;
struct arcfour_state *arcstate;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
arcstate = (state != NULL) ? (struct arcfour_state *) state->data : NULL;
if (arcstate != NULL) {
ctx = arcstate->ctx;
@@ -113,7 +116,12 @@ k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data,
static void
k5_arcfour_free_state(krb5_data *state)
{
- struct arcfour_state *arcstate = (struct arcfour_state *) state->data;
+ struct arcfour_state *arcstate;
+
+ if (FIPS_mode())
+ return;
+
+ arcstate = (struct arcfour_state *) state->data;
EVP_CIPHER_CTX_free(arcstate->ctx);
free(arcstate);
@@ -125,6 +133,9 @@ k5_arcfour_init_state(const krb5_keyblock *key,
{
struct arcfour_state *arcstate;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
/* Create a state structure with an uninitialized context. */
arcstate = calloc(1, sizeof(*arcstate));
if (arcstate == NULL)
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
index 957ed8d9c..8c1fd7f59 100644
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
@@ -64,12 +64,16 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
static krb5_error_code
hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
return hash_evp(EVP_md4(), data, num_data, output);
}
static krb5_error_code
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
return hash_evp(EVP_md5(), data, num_data, output);
}
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
index b2db6ec02..d94d9ac94 100644
--- a/src/lib/crypto/openssl/hmac.c
+++ b/src/lib/crypto/openssl/hmac.c
@@ -103,7 +103,11 @@ map_digest(const struct krb5_hash_provider *hash)
return EVP_sha256();
else if (!strncmp(hash->hash_name, "SHA-384",7))
return EVP_sha384();
- else if (!strncmp(hash->hash_name, "MD5", 3))
+
+ if (FIPS_mode())
+ return NULL;
+
+ if (!strncmp(hash->hash_name, "MD5", 3))
return EVP_md5();
else if (!strncmp(hash->hash_name, "MD4", 3))
return EVP_md4();

View File

@ -1,43 +0,0 @@
From 5b4467a2c47e6de814e69ec3eb4c3e7a4632119c Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 1 Apr 2019 13:13:09 -0400
Subject: [PATCH] FIPS-aware SPAKE group negotiation
(cherry picked from commit 59269fca96168aa89dc32834d188a54eea8953ac)
---
src/plugins/preauth/spake/groups.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/plugins/preauth/spake/groups.c b/src/plugins/preauth/spake/groups.c
index a195cc195..8a913cb5a 100644
--- a/src/plugins/preauth/spake/groups.c
+++ b/src/plugins/preauth/spake/groups.c
@@ -56,6 +56,8 @@
#include "trace.h"
#include "groups.h"
+#include <openssl/crypto.h>
+
#define DEFAULT_GROUPS_CLIENT "edwards25519"
#define DEFAULT_GROUPS_KDC ""
@@ -102,6 +104,9 @@ find_gdef(int32_t group)
{
size_t i;
+ if (group == builtin_edwards25519.reg->id && FIPS_mode())
+ return NULL;
+
for (i = 0; groupdefs[i] != NULL; i++) {
if (groupdefs[i]->reg->id == group)
return groupdefs[i];
@@ -116,6 +121,9 @@ find_gnum(const char *name)
{
size_t i;
+ if (strcasecmp(name, builtin_edwards25519.reg->name) == 0 && FIPS_mode())
+ return 0;
+
for (i = 0; groupdefs[i] != NULL; i++) {
if (strcasecmp(name, groupdefs[i]->reg->name) == 0)
return groupdefs[i]->reg->id;

View File

@ -0,0 +1,207 @@
From 44b429df9ac4bb8ad84a090fee1bd70d83adcf23 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sat, 20 Jul 2019 00:51:52 -0400
Subject: [PATCH] Fix Coverity defects in soft-pkcs11 test code
Nothing in the code removes objects from soft_token.object.obs, so
simplify add_st_object() not to search for an empty slot. Avoid using
random() by using a counter for session handles and just the array
slot number for object handles. Add a helper get_rcfilename() to
facilitate checking the result of asprintf(). Properly initialize ap
in sprintf_fill(). Close the file handle in read_conf_file().
(cherry picked from commit b4831515b2f3b6fd7d7fd4bff4558c10c710891d)
(cherry picked from commit 28db01445d2807d51b5045c0a04d5e49905de504)
---
src/tests/softpkcs11/main.c | 102 +++++++++++++++++++-----------------
1 file changed, 53 insertions(+), 49 deletions(-)
diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c
index 5255323d3..2d1448ca2 100644
--- a/src/tests/softpkcs11/main.c
+++ b/src/tests/softpkcs11/main.c
@@ -78,6 +78,7 @@ compat_rsa_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e,
(BL) = i2d_##T((S), &p); \
if ((BL) <= 0) { \
free((B)); \
+ (B) = NULL; \
(R) = EINVAL; \
} \
} \
@@ -149,6 +150,7 @@ static struct soft_token {
} state[10];
#define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0]))
FILE *logfile;
+ CK_SESSION_HANDLE next_session_handle;
} soft_token;
static void
@@ -179,6 +181,7 @@ snprintf_fill(char *str, int size, char fillchar, const char *fmt, ...)
{
int len;
va_list ap;
+ va_start(ap, fmt);
len = vsnprintf(str, size, fmt, ap);
va_end(ap);
if (len < 0 || len > size)
@@ -344,7 +347,13 @@ static struct st_object *
add_st_object(void)
{
struct st_object *o, **objs;
- int i;
+
+ objs = realloc(soft_token.object.objs,
+ (soft_token.object.num_objs + 1) *
+ sizeof(soft_token.object.objs[0]));
+ if (objs == NULL)
+ return NULL;
+ soft_token.object.objs = objs;
o = malloc(sizeof(*o));
if (o == NULL)
@@ -352,26 +361,9 @@ add_st_object(void)
memset(o, 0, sizeof(*o));
o->attrs = NULL;
o->num_attributes = 0;
+ o->object_handle = soft_token.object.num_objs;
- for (i = 0; i < soft_token.object.num_objs; i++) {
- if (soft_token.object.objs == NULL) {
- soft_token.object.objs[i] = o;
- break;
- }
- }
- if (i == soft_token.object.num_objs) {
- objs = realloc(soft_token.object.objs,
- (soft_token.object.num_objs + 1) * sizeof(soft_token.object.objs[0]));
- if (objs == NULL) {
- free(o);
- return NULL;
- }
- soft_token.object.objs = objs;
- soft_token.object.objs[soft_token.object.num_objs++] = o;
- }
- soft_token.object.objs[i]->object_handle =
- (random() & (~OBJECT_ID_MASK)) | i;
-
+ soft_token.object.objs[soft_token.object.num_objs++] = o;
return o;
}
@@ -797,6 +789,8 @@ read_conf_file(const char *fn)
add_certificate(label, cert, key, id, anchor);
}
+
+ fclose(f);
}
static CK_RV
@@ -806,19 +800,47 @@ func_not_supported(void)
return CKR_FUNCTION_NOT_SUPPORTED;
}
+static char *
+get_rcfilename()
+{
+ struct passwd *pw;
+ const char *home = NULL;
+ char *fn;
+
+ if (getuid() == geteuid()) {
+ fn = getenv("SOFTPKCS11RC");
+ if (fn != NULL)
+ return strdup(fn);
+
+ home = getenv("HOME");
+ }
+
+ if (home == NULL) {
+ pw = getpwuid(getuid());
+ if (pw != NULL)
+ home = pw->pw_dir;
+ }
+
+ if (home == NULL)
+ return strdup("/etc/soft-token.rc");
+
+ if (asprintf(&fn, "%s/.soft-token.rc", home) < 0)
+ return NULL;
+ return fn;
+}
+
CK_RV
C_Initialize(CK_VOID_PTR a)
{
CK_C_INITIALIZE_ARGS_PTR args = a;
size_t i;
+ char *fn;
st_logf("Initialize\n");
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
- srandom(getpid() ^ time(NULL));
-
for (i = 0; i < MAX_NUM_SESSION; i++) {
soft_token.state[i].session_handle = CK_INVALID_HANDLE;
soft_token.state[i].find.attributes = NULL;
@@ -850,31 +872,13 @@ C_Initialize(CK_VOID_PTR a)
st_logf("\tFlags\t%04x\n", (unsigned int)args->flags);
}
- {
- char *fn = NULL, *home = NULL;
-
- if (getuid() == geteuid()) {
- fn = getenv("SOFTPKCS11RC");
- if (fn)
- fn = strdup(fn);
- home = getenv("HOME");
- }
- if (fn == NULL && home == NULL) {
- struct passwd *pw = getpwuid(getuid());
- if(pw != NULL)
- home = pw->pw_dir;
- }
- if (fn == NULL) {
- if (home)
- asprintf(&fn, "%s/.soft-token.rc", home);
- else
- fn = strdup("/etc/soft-token.rc");
- }
-
- read_conf_file(fn);
- free(fn);
- }
+ soft_token.next_session_handle = 0;
+ fn = get_rcfilename();
+ if (fn == NULL)
+ return CKR_DEVICE_MEMORY;
+ read_conf_file(fn);
+ free(fn);
return CKR_OK;
}
@@ -1082,8 +1086,7 @@ C_OpenSession(CK_SLOT_ID slotID,
soft_token.open_sessions++;
- soft_token.state[i].session_handle =
- (CK_SESSION_HANDLE)(random() & 0xfffff);
+ soft_token.state[i].session_handle = soft_token.next_session_handle++;
*phSession = soft_token.state[i].session_handle;
return CKR_OK;
@@ -1152,7 +1155,8 @@ C_Login(CK_SESSION_HANDLE hSession,
VERIFY_SESSION_HANDLE(hSession, NULL);
if (pPin != NULL_PTR) {
- asprintf(&pin, "%.*s", (int)ulPinLen, pPin);
+ if (asprintf(&pin, "%.*s", (int)ulPinLen, pPin) < 0)
+ return CKR_DEVICE_MEMORY;
st_logf("type: %d password: %s\n", (int)userType, pin);
}

View File

@ -0,0 +1,33 @@
From 7e4576cc62a16fa77030c42dcc43c61cdfa5b4e6 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Wed, 14 Aug 2019 13:52:27 -0400
Subject: [PATCH] Fix KCM client time offset propagation
An inverted status check in get_kdc_offset() would cause querying the
offset time from the ccache to always fail (silently) on KCM. Fix the
status check so that KCM can properly handle desync.
ticket: 8826 (new)
tags: pullup
target_version: 1.17-next
target_verison: 1.16-next
(cherry picked from commit 323abb6d1ebe5469d6c2167c29aa5d696d099b90)
(cherry picked from commit 7e81b8077cf2cf186dadb96b064573f7c221fbf3)
---
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 092ab7daf..fe93ca3dc 100644
--- a/src/lib/krb5/ccache/cc_kcm.c
+++ b/src/lib/krb5/ccache/cc_kcm.c
@@ -583,7 +583,7 @@ get_kdc_offset(krb5_context context, krb5_ccache cache)
if (cache_call(context, cache, &req, FALSE) != 0)
goto cleanup;
time_offset = k5_input_get_uint32_be(&req.reply);
- if (!req.reply.status)
+ if (req.reply.status)
goto cleanup;
context->os_context.time_offset = time_offset;
context->os_context.usec_offset = 0;

View File

@ -1,4 +1,4 @@
From 3a64eb3477e0e60d447c99f86b7bf4fd1259cb58 Mon Sep 17 00:00:00 2001
From 9a38af6aa136fdc92d5e0f1591c1647aec498f5a Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 17 Sep 2019 18:29:15 -0400
Subject: [PATCH] Fix argument order on strlcpy() in enctype_name()

View File

@ -1,4 +1,4 @@
From a904a5b85e8425823016b821153b37396edc2306 Mon Sep 17 00:00:00 2001
From 74a3b8448949130d91417b261c3e1c316ffa8796 Mon Sep 17 00:00:00 2001
From: Corene Casper <C.Casper@Dell.com>
Date: Sat, 16 Feb 2019 00:49:26 -0500
Subject: [PATCH] Fix memory leak in 'none' replay cache type

View File

@ -0,0 +1,123 @@
From 604f5dcbb018fca8ea27e00314ed615133b861e1 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 5 Aug 2019 01:53:51 -0400
Subject: [PATCH] Fix memory leaks in soft-pkcs11 code
Fix leaks detected by asan in t_pkinit.py. Add a helper to free a
struct st_object and free objects in C_Finalize(). Duplicate the X509
cert in add_certificate() instead of creating aliases so it can be
properly freed. Start the session handle counter at 1 so that
C_Finalize() won't confuse the first session handle with
CK_INVALID_HANDLE (defined to 0 in pkinit.h) and will properly clean
the session object.
(cherry picked from commit 15bcaf8bcb4af25ff89820ad3bf23ad5a324e863)
(cherry picked from commit 5cc80472e7a8b0fb3002f229ffb104dccf8bd120)
---
src/tests/softpkcs11/main.c | 44 +++++++++++++++++++++++++++++++++----
1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c
index 2d1448ca2..a4c3ae78e 100644
--- a/src/tests/softpkcs11/main.c
+++ b/src/tests/softpkcs11/main.c
@@ -109,7 +109,7 @@ struct st_object {
X509 *cert;
EVP_PKEY *public_key;
struct {
- const char *file;
+ char *file;
EVP_PKEY *key;
X509 *cert;
} private_key;
@@ -343,6 +343,26 @@ print_attributes(const CK_ATTRIBUTE *attributes,
}
}
+static void
+free_st_object(struct st_object *o)
+{
+ int i;
+
+ for (i = 0; i < o->num_attributes; i++)
+ free(o->attrs[i].attribute.pValue);
+ free(o->attrs);
+ if (o->type == STO_T_CERTIFICATE) {
+ X509_free(o->u.cert);
+ } else if (o->type == STO_T_PRIVATE_KEY) {
+ free(o->u.private_key.file);
+ EVP_PKEY_free(o->u.private_key.key);
+ X509_free(o->u.private_key.cert);
+ } else if (o->type == STO_T_PUBLIC_KEY) {
+ EVP_PKEY_free(o->u.public_key);
+ }
+ free(o);
+}
+
static struct st_object *
add_st_object(void)
{
@@ -518,7 +538,11 @@ add_certificate(char *label,
goto out;
}
o->type = STO_T_CERTIFICATE;
- o->u.cert = cert;
+ o->u.cert = X509_dup(cert);
+ if (o->u.cert == NULL) {
+ ret = CKR_DEVICE_MEMORY;
+ goto out;
+ }
public_key = X509_get_pubkey(o->u.cert);
switch (EVP_PKEY_base_id(public_key)) {
@@ -602,7 +626,11 @@ add_certificate(char *label,
o->u.private_key.file = strdup(private_key_file);
o->u.private_key.key = NULL;
- o->u.private_key.cert = cert;
+ o->u.private_key.cert = X509_dup(cert);
+ if (o->u.private_key.cert == NULL) {
+ ret = CKR_DEVICE_MEMORY;
+ goto out;
+ }
c = CKO_PRIVATE_KEY;
add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
@@ -676,6 +704,7 @@ add_certificate(char *label,
free(serial_data);
free(issuer_data);
free(subject_data);
+ X509_free(cert);
return ret;
}
@@ -872,7 +901,7 @@ C_Initialize(CK_VOID_PTR a)
st_logf("\tFlags\t%04x\n", (unsigned int)args->flags);
}
- soft_token.next_session_handle = 0;
+ soft_token.next_session_handle = 1;
fn = get_rcfilename();
if (fn == NULL)
@@ -886,6 +915,7 @@ CK_RV
C_Finalize(CK_VOID_PTR args)
{
size_t i;
+ int j;
st_logf("Finalize\n");
@@ -897,6 +927,12 @@ C_Finalize(CK_VOID_PTR args)
}
}
+ for (j = 0; j < soft_token.object.num_objs; j++)
+ free_st_object(soft_token.object.objs[j]);
+ free(soft_token.object.objs);
+ soft_token.object.objs = NULL;
+ soft_token.object.num_objs = 0;
+
return CKR_OK;
}

View File

@ -1,4 +1,4 @@
From e07ddc519254a35e54af020643685b9da9e0e973 Mon Sep 17 00:00:00 2001
From 30f112f8dc1c5241da5ba301cb45a06bb5bb4c01 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 15 Jan 2019 13:41:16 -0500
Subject: [PATCH] In kpropd, debug-log proper ticket enctype names

View File

@ -1,4 +1,4 @@
From 83c2f0bac35c2ad0872dc9b2a9ca1bdde948f216 Mon Sep 17 00:00:00 2001
From 2b4521f3ba3dad064e3f64bfd56b88d5cb5d0955 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 14 Jan 2019 17:14:42 -0500
Subject: [PATCH] In rd_req_dec, always log non-permitted enctypes

View File

@ -1,4 +1,4 @@
From c3dd133cf06d55e3fe516a2aa8b4b37e203878da Mon Sep 17 00:00:00 2001
From f815140182976e882445a38ee5a0a77f56da7c8a Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 8 Jan 2019 17:42:35 -0500
Subject: [PATCH] Make etype names in KDC logs human-readable
@ -12,9 +12,9 @@ ticket: 8772 (new)
(cherry picked from commit a649279727490687d54becad91fde8cf7429d951)
---
src/kdc/kdc_log.c | 42 +++++++--------
src/kdc/kdc_util.c | 125 +++++++++++++++++++++++----------------------
src/kdc/kdc_util.c | 131 +++++++++++++++++++++++----------------------
src/kdc/kdc_util.h | 6 +--
3 files changed, 87 insertions(+), 86 deletions(-)
3 files changed, 90 insertions(+), 89 deletions(-)
diff --git a/src/kdc/kdc_log.c b/src/kdc/kdc_log.c
index 4eec50373..b160ba21a 100644
@ -132,16 +132,57 @@ index 0155c28c6..f5c581c82 100644
- * L10_2 = log10(2**x), rounded up; log10(2) ~= 0.301.
- */
-#define L10_2(x) ((int)(((x * 301) + 999) / 1000))
-
-/*
- * Max length of sprintf("%ld") for an int of type T; includes leading
- * minus sign and terminating NUL.
- */
-#define D_LEN(t) (L10_2(sizeof(t) * CHAR_BIT) + 2)
-
-void
-ktypes2str(char *s, size_t len, int nktypes, krb5_enctype *ktype)
+/* Wrapper of krb5_enctype_to_name() to include the PKINIT types. */
+static krb5_error_code
+enctype_name(krb5_enctype ktype, char *buf, size_t buflen)
+{
{
- int i;
- char stmp[D_LEN(krb5_enctype) + 1];
- char *p;
+ char *name;
+
- if (nktypes < 0
- || len < (sizeof(" etypes {...}") + D_LEN(int))) {
- *s = '\0';
- return;
- }
+ if (buflen == 0)
+ return EINVAL;
+ *buf = '\0'; /* ensure these are always valid C-strings */
+
- snprintf(s, len, "%d etypes {", nktypes);
- for (i = 0; i < nktypes; i++) {
- snprintf(stmp, sizeof(stmp), "%s%ld", i ? " " : "", (long)ktype[i]);
- if (strlen(s) + strlen(stmp) + sizeof("}") > len)
- break;
- strlcat(s, stmp, len);
- }
- if (i < nktypes) {
- /*
- * We broke out of the loop. Try to truncate the list.
- */
- p = s + strlen(s);
- while (p - s + sizeof("...}") > len) {
- while (p > s && *p != ' ' && *p != '{')
- *p-- = '\0';
- if (p > s && *p == ' ') {
- *p-- = '\0';
- continue;
- }
- }
- strlcat(s, "...", len);
- }
- strlcat(s, "}", len);
- return;
+ /* rfc4556 recommends that clients wishing to indicate support for these
+ * pkinit algorithms include them in the etype field of the AS-REQ. */
+ if (ktype == ENCTYPE_DSA_SHA1_CMS)
@ -160,85 +201,47 @@ index 0155c28c6..f5c581c82 100644
+ name = "des-ede3-cbc-EnvOID";
+ else
+ return krb5_enctype_to_name(ktype, FALSE, buf, buflen);
-/*
- * Max length of sprintf("%ld") for an int of type T; includes leading
- * minus sign and terminating NUL.
- */
-#define D_LEN(t) (L10_2(sizeof(t) * CHAR_BIT) + 2)
+
+ if (strlcpy(name, buf, buflen) >= buflen)
+ return ENOMEM;
+ return 0;
+}
-void
-ktypes2str(char *s, size_t len, int nktypes, krb5_enctype *ktype)
+char *
+ktypes2str(krb5_enctype *ktype, int nktypes)
{
+ struct k5buf buf;
int i;
- char stmp[D_LEN(krb5_enctype) + 1];
- char *p;
+ char name[64];
- if (nktypes < 0
- || len < (sizeof(" etypes {...}") + D_LEN(int))) {
- *s = '\0';
- return;
- }
+ if (nktypes < 0)
+ return NULL;
- snprintf(s, len, "%d etypes {", nktypes);
+ k5_buf_init_dynamic(&buf);
+ k5_buf_add_fmt(&buf, "%d etypes {", nktypes);
for (i = 0; i < nktypes; i++) {
- snprintf(stmp, sizeof(stmp), "%s%ld", i ? " " : "", (long)ktype[i]);
- if (strlen(s) + strlen(stmp) + sizeof("}") > len)
- break;
- strlcat(s, stmp, len);
+ enctype_name(ktype[i], name, sizeof(name));
+ k5_buf_add_fmt(&buf, "%s%s(%ld)", i ? ", " : "", name, (long)ktype[i]);
}
- if (i < nktypes) {
- /*
- * We broke out of the loop. Try to truncate the list.
- */
- p = s + strlen(s);
- while (p - s + sizeof("...}") > len) {
- while (p > s && *p != ' ' && *p != '{')
- *p-- = '\0';
- if (p > s && *p == ' ') {
- *p-- = '\0';
- continue;
- }
- }
- strlcat(s, "...", len);
- }
- strlcat(s, "}", len);
- return;
+ k5_buf_add(&buf, "}");
+ return buf.data;
}
-void
-rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep)
+char *
+rep_etypes2str(krb5_kdc_rep *rep)
+ktypes2str(krb5_enctype *ktype, int nktypes)
{
- char stmp[sizeof("ses=") + D_LEN(krb5_enctype)];
-
+ struct k5buf buf;
+ int i;
+ char name[64];
- if (len < (3 * D_LEN(krb5_enctype)
- + sizeof("etypes {rep= tkt= ses=}"))) {
- *s = '\0';
- return;
- }
+ if (nktypes < 0)
+ return NULL;
+
+ k5_buf_init_dynamic(&buf);
+ k5_buf_add_fmt(&buf, "%d etypes {", nktypes);
+ for (i = 0; i < nktypes; i++) {
+ enctype_name(ktype[i], name, sizeof(name));
+ k5_buf_add_fmt(&buf, "%s%s(%ld)", i ? ", " : "", name, (long)ktype[i]);
}
+ k5_buf_add(&buf, "}");
+ return buf.data;
+}
- snprintf(s, len, "etypes {rep=%ld", (long)rep->enc_part.enctype);
+char *
+rep_etypes2str(krb5_kdc_rep *rep)
+{
+ struct k5buf buf;
+ char name[64];
+ krb5_enctype etype;
- snprintf(s, len, "etypes {rep=%ld", (long)rep->enc_part.enctype);
+
+ k5_buf_init_dynamic(&buf);
+ k5_buf_add(&buf, "etypes {rep=");
+ enctype_name(rep->enc_part.enctype, name, sizeof(name));

View File

@ -1,4 +1,4 @@
From 4f56267a204764ed3d00e69cd16a0e877f055455 Mon Sep 17 00:00:00 2001
From 6306a2a8697c94f968a02d66204f7d357aa0e7f6 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 10 Jan 2019 16:34:54 -0500
Subject: [PATCH] Mark deprecated enctypes when used

View File

@ -1,4 +1,4 @@
From 11ebf658c737baddcd5ce91e018213f28c279737 Mon Sep 17 00:00:00 2001
From bad6d4390e6e23099cc2295d94e2553575687561 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 14 Feb 2019 11:50:35 -0500
Subject: [PATCH] Properly size #ifdef in k5_cccol_lock()

View File

@ -0,0 +1,45 @@
From 684821fc68fd27ddcc5f809a37819edd35365a9d Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Sat, 1 Feb 2020 16:13:30 +0100
Subject: [PATCH] Put KDB authdata first
Windows services, as well as some versions of Samba, may refuse
tickets if the PAC is not in the first AD-IF-RELEVANT container. In
fetch_kdb_authdata(), change the merge order so that authdata from the
KDB module appears first.
[ghudson@mit.edu: added comment and clarified commit message]
ticket: 8872 (new)
tags: pullup
target_version: 1.18
target_version: 1.17-next
(cherry picked from commit 331fa4bdd34263ea20667a0f51338cb84357fdaa)
(cherry picked from commit 1678270de3fda699114122447b1f06b08fb4e53e)
---
src/kdc/kdc_authdata.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c
index 1b067cb0b..616c3eadc 100644
--- a/src/kdc/kdc_authdata.c
+++ b/src/kdc/kdc_authdata.c
@@ -383,11 +383,14 @@ fetch_kdb_authdata(krb5_context context, unsigned int flags,
if (ret)
return (ret == KRB5_PLUGIN_OP_NOTSUPP) ? 0 : ret;
- /* Add the KDB authdata to the ticket, without copying or filtering. */
- ret = merge_authdata(context, db_authdata,
- &enc_tkt_reply->authorization_data, FALSE, FALSE);
+ /* Put the KDB authdata first in the ticket. A successful merge places the
+ * combined list in db_authdata and releases the old ticket authdata. */
+ ret = merge_authdata(context, enc_tkt_reply->authorization_data,
+ &db_authdata, FALSE, FALSE);
if (ret)
krb5_free_authdata(context, db_authdata);
+ else
+ enc_tkt_reply->authorization_data = db_authdata;
return ret;
}

View File

@ -0,0 +1,751 @@
From 5e147f7f2924edfd278940dea8b1d8ed09d6872c Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 15 Nov 2019 20:05:16 +0000
Subject: [PATCH] Use backported version of OpenSSL-3 KDF interface
(cherry picked from commit 0e20daf7ccfe50518c89735c3dae2fde08d92325)
---
src/configure.in | 4 +
src/lib/crypto/krb/derive.c | 356 +++++++++++++-----
.../preauth/pkinit/pkinit_crypto_openssl.c | 257 ++++++++-----
3 files changed, 428 insertions(+), 189 deletions(-)
diff --git a/src/configure.in b/src/configure.in
index 9f6b67b44..cf4b1139a 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -269,6 +269,10 @@ AC_SUBST(CRYPTO_IMPL)
AC_SUBST(CRYPTO_IMPL_CFLAGS)
AC_SUBST(CRYPTO_IMPL_LIBS)
+AC_CHECK_FUNCS(EVP_KDF_CTX_new_id EVP_KDF_ctrl EVP_KDF_derive,
+ AC_DEFINE(OSSL_KDFS, 1, [Define if using OpenSSL KDFs]),
+ AC_MSG_ERROR([backported OpenSSL KDFs not found]))
+
AC_ARG_WITH([prng-alg],
AC_HELP_STRING([--with-prng-alg=ALG], [use specified PRNG algorithm. @<:@fortuna@:>@]),
[PRNG_ALG=$withval
diff --git a/src/lib/crypto/krb/derive.c b/src/lib/crypto/krb/derive.c
index 6707a7308..915a173dd 100644
--- a/src/lib/crypto/krb/derive.c
+++ b/src/lib/crypto/krb/derive.c
@@ -27,6 +27,13 @@
#include "crypto_int.h"
+#ifdef OSSL_KDFS
+#include <openssl/evp.h>
+#include <openssl/kdf.h>
+#else
+#error "Refusing to build without OpenSSL KDFs!"
+#endif
+
static krb5_key
find_cached_dkey(struct derived_key *list, const krb5_data *constant)
{
@@ -77,55 +84,193 @@ cleanup:
return ENOMEM;
}
+#ifdef OSSL_KDFS
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_CRYPTO_INTERNAL;
+ EVP_KDF_CTX *ctx = NULL;
+ const EVP_MD *digest;
+
+ if (!strcmp(hash->hash_name, "SHA1"))
+ digest = EVP_sha1();
+ else if (!strcmp(hash->hash_name, "SHA-256"))
+ digest = EVP_sha256();
+ else if (!strcmp(hash->hash_name, "SHA-384"))
+ digest = EVP_sha384();
+ else
+ goto done;
+
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_KB);
+ if (!ctx)
+ goto done;
+
+ if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest) != 1 ||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_MAC_TYPE,
+ EVP_KDF_KB_MAC_TYPE_HMAC) != 1 ||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, inkey->keyblock.contents,
+ inkey->keyblock.length) != 1 ||
+ (context->length > 0 &&
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_INFO, context->data,
+ context->length) != 1) ||
+ (label->length > 0 &&
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SALT, label->data,
+ label->length) != 1) ||
+ EVP_KDF_derive(ctx, (unsigned char *)outrnd->data,
+ outrnd->length) != 1)
+ goto done;
+
+ ret = 0;
+done:
+ if (ret)
+ zap(outrnd->data, outrnd->length);
+ EVP_KDF_CTX_free(ctx);
+ 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 = KRB5_CRYPTO_INTERNAL;
+ EVP_KDF_CTX *ctx = NULL;
+ const EVP_CIPHER *cipher;
+ static unsigned char zeroes[16];
+
+ memset(zeroes, 0, sizeof(zeroes));
+
+ if (enc->keylength == 16)
+ cipher = EVP_camellia_128_cbc();
+ else if (enc->keylength == 32)
+ cipher = EVP_camellia_256_cbc();
+ else
+ goto done;
+
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_KB);
+ if (!ctx)
+ goto done;
+
+ if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_MODE,
+ EVP_KDF_KB_MODE_FEEDBACK) != 1 ||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_MAC_TYPE,
+ EVP_KDF_KB_MAC_TYPE_CMAC) != 1 ||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_CIPHER, cipher) != 1 ||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, inkey->keyblock.contents,
+ inkey->keyblock.length) != 1 ||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SALT, in_constant->data,
+ in_constant->length) != 1 ||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_SEED, zeroes,
+ sizeof(zeroes)) != 1 ||
+ EVP_KDF_derive(ctx, (unsigned char *)outrnd->data,
+ outrnd->length) != 1)
+ goto done;
+
+ ret = 0;
+done:
+ if (ret)
+ zap(outrnd->data, outrnd->length);
+ EVP_KDF_CTX_free(ctx);
+ 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 = KRB5_CRYPTO_INTERNAL;
+ EVP_KDF_CTX *ctx = NULL;
+ const EVP_CIPHER *cipher;
+
+ if (inkey->keyblock.length != enc->keylength ||
+ outrnd->length != enc->keybytes) {
+ return KRB5_CRYPTO_INTERNAL;
+ }
+
+ if (enc->encrypt == krb5int_aes_encrypt && enc->keylength == 16)
+ cipher = EVP_aes_128_cbc();
+ else if (enc->encrypt == krb5int_aes_encrypt && enc->keylength == 32)
+ cipher = EVP_aes_256_cbc();
+ else if (enc->keylength == 24)
+ cipher = EVP_des_ede3_cbc();
+ else
+ goto done;
+
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_KRB5KDF);
+ if (ctx == NULL)
+ goto done;
+
+ if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_CIPHER, cipher) != 1 ||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, inkey->keyblock.contents,
+ inkey->keyblock.length) != 1 ||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KRB5KDF_CONSTANT,
+ in_constant->data, in_constant->length) != 1 ||
+ EVP_KDF_derive(ctx, (unsigned char *)outrnd->data,
+ outrnd->length) != 1)
+ goto done;
+
+ ret = 0;
+done:
+ if (ret)
+ zap(outrnd->data, outrnd->length);
+ EVP_KDF_CTX_free(ctx);
+ return ret;
+}
+
+#else /* OSSL_KDFS */
+
+/*
+ * 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 block = empty_data();
+ krb5_data prf;
+ unsigned char ibuf[4], lbuf[4];
- blocksize = enc->block_size;
- keybytes = enc->keybytes;
-
- if (blocksize == 1)
- return KRB5_BAD_ENCTYPE;
- if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
+ 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 +284,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 +349,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 /* OSSL_KDFS */
+
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 OSSL_KDFS
+ 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
+k5_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
+ krb5_key inkey, krb5_data *outrnd,
+ const krb5_data *in_constant)
+{
+#ifdef OSSL_KDFS
+ 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
+k5_derive_random_rfc3961(const struct krb5_enc_provider *enc,
+ krb5_key inkey, krb5_data *outrnd,
+ const krb5_data *in_constant)
+{
+#ifdef OSSL_KDFS
+ return openssl_krb5kdf(enc, inkey, outrnd, in_constant);
+#else
+ return builtin_derive_random_rfc3961(enc, inkey, outrnd, in_constant);
+#endif
}
krb5_error_code
@@ -266,10 +449,9 @@ krb5int_derive_random(const struct krb5_enc_provider *enc,
switch (alg) {
case DERIVE_RFC3961:
- return derive_random_rfc3961(enc, inkey, outrnd, in_constant);
+ return k5_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 k5_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);
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 5ff81d8cf..8d2c230c8 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -38,6 +38,13 @@
#include <dirent.h>
#include <arpa/inet.h>
+#ifdef OSSL_KDFS
+#include <openssl/evp.h>
+#include <openssl/kdf.h>
+#else
+#error "Refusing to build without OpenSSL KDFs!"
+#endif
+
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
@@ -2460,11 +2467,51 @@ pkinit_alg_values(krb5_context context,
}
} /* pkinit_alg_values() */
+#ifdef OSSL_KDFS
+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)
+{
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
+ EVP_KDF_CTX *ctx = NULL;
+ const EVP_MD *digest;
-/* 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:
+ /* RFC 8636 defines a SHA384 variant, but we don't use it. */
+ if (hash_bytes == 20) {
+ digest = EVP_sha1();
+ } else if (hash_bytes == 32) {
+ digest = EVP_sha256();
+ } else if (hash_bytes == 64) {
+ digest = EVP_sha512();
+ } else {
+ krb5_set_error_message(context, ret, "Bad hash type for SSKDF");
+ goto done;
+ }
+
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_SS);
+ if (!ctx) {
+ oerr(context, ret, _("Failed to instantiate SSKDF"));
+ goto done;
+ }
+
+ if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest) != 1 ||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, key->data,
+ key->length) != 1 ||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSKDF_INFO, info->data,
+ info->length) != 1 ||
+ EVP_KDF_derive(ctx, (unsigned char *)out, out_len) != 1)
+ goto done;
+
+ ret = 0;
+done:
+ EVP_KDF_CTX_free(ctx);
+ 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)
*
@@ -2478,95 +2525,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;
- 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:
@@ -2600,8 +2568,9 @@ pkinit_alg_agility_kdf(krb5_context context,
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;
@@ -2613,26 +2582,110 @@ 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 retval;
+} /* builtin_sskdf() */
+#endif /* OSSL_KDFS */
- /* 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 retval;
+ 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;
+
+ /* Allocate and initialize the key block. */
+ key_block->magic = 0;
+ key_block->enctype = enctype;
+
+ /* Use separate variables to avoid alignment restriction problems. */
+ retval = krb5_c_keylengths(context, enctype, &rand_len, &key_len);
+ if (retval)
+ goto cleanup;
+ random_data.length = rand_len;
+ key_block->length = key_len;
+
+ key_block->contents = k5calloc(key_block->length, 1, &retval);
+ 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);
+ retval = pkinit_alg_values(context, alg_oid, &hash_len, &EVP_func);
+ if (retval)
+ 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, &retval);
+ 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;
+ retval = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields,
+ &supp_pub_info);
+ if (retval)
+ 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;
+ retval = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info);
+ if (retval)
+ goto cleanup;
+
+#ifdef OSSL_KDFS
+ retval = openssl_sskdf(context, hash_len, secret, other_info,
+ random_data.data, key_block->length);
+#else
+ retval = builtin_sskdf(context, reps, hash_len, EVP_func, secret,
+ other_info, random_data.data, key_block->length);
+#endif
+ if (retval)
+ goto cleanup;
+
+ retval = krb5_c_random_to_key(context, enctype, &random_data, key_block);
+cleanup:
+ if (retval)
+ krb5_free_keyblock_contents(context, key_block);
+
+ 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() */
+}
/* Call DH_compute_key() and ensure that we left-pad short results instead of
* leaving junk bytes at the end of the buffer. */

View File

@ -0,0 +1,472 @@
From 43f5837eecd5022c525efcfb3605af16958dc59a Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 20 Jun 2019 13:41:57 -0400
Subject: [PATCH] Use imported soft-pkcs11 for tests
Update the soft-pkcs11 code for OpenSSL 1.1, fix some warnings,
integrate it into the build system, and use it for the PKINIT tests.
(cherry picked from commit e5ef7b69765353ea62ad8712a229ed4e90a8fe17)
(cherry picked from commit 47e66724b9d5cfef84965d99c83d29e4739932e3)
---
src/configure.in | 1 +
src/tests/Makefile.in | 2 +-
src/tests/softpkcs11/Makefile.in | 21 ++++
src/tests/softpkcs11/deps | 6 ++
src/tests/softpkcs11/main.c | 124 +++++++++++++++++-------
src/tests/softpkcs11/softpkcs11.exports | 39 ++++++++
src/tests/t_pkinit.py | 18 +---
7 files changed, 162 insertions(+), 49 deletions(-)
create mode 100644 src/tests/softpkcs11/Makefile.in
create mode 100644 src/tests/softpkcs11/deps
create mode 100644 src/tests/softpkcs11/softpkcs11.exports
diff --git a/src/configure.in b/src/configure.in
index 93aec682e..9f6b67b44 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1086,6 +1086,7 @@ int i = 1;
fi
if test "$k5_cv_openssl_version_okay" = yes && (test "$enable_pkinit" = yes || test "$enable_pkinit" = try); then
K5_GEN_MAKEFILE(plugins/preauth/pkinit)
+ K5_GEN_MAKEFILE(tests/softpkcs11)
PKINIT=yes
AC_CHECK_LIB(crypto, CMS_get0_content, [AC_DEFINE([HAVE_OPENSSL_CMS], 1, [Define if OpenSSL supports cms.])])
elif test "$k5_cv_openssl_version_okay" = no && test "$enable_pkinit" = yes; then
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index e27617ee2..ab958eb4c 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -1,7 +1,7 @@
mydir=tests
BUILDTOP=$(REL)..
SUBDIRS = resolve asn.1 create hammer verify gssapi dejagnu shlib \
- gss-threads misc threads
+ gss-threads misc threads softpkcs11
RUN_DB_TEST = $(RUN_SETUP) KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf \
LC_ALL=C $(VALGRIND)
diff --git a/src/tests/softpkcs11/Makefile.in b/src/tests/softpkcs11/Makefile.in
new file mode 100644
index 000000000..e89678154
--- /dev/null
+++ b/src/tests/softpkcs11/Makefile.in
@@ -0,0 +1,21 @@
+mydir=tests$(S)softpkcs11
+BUILDTOP=$(REL)..$(S)..
+
+LOCALINCLUDES = -I$(top_srcdir)/plugins/preauth/pkinit
+
+LIBBASE=softpkcs11
+LIBMAJOR=0
+LIBMINOR=0
+
+SHLIB_EXPLIBS=$(SUPPORT_LIB) -lcrypto
+SHLIB_EXPDEPS=$(SUPPORT_DEPLIB)
+
+STLIBOBJS=main.o
+
+SRCS=$(srcdir)/main.c
+
+all-unix: all-libs
+clean-unix:: clean-libs clean-libobjs
+
+@libnover_frag@
+@libobj_frag@
diff --git a/src/tests/softpkcs11/deps b/src/tests/softpkcs11/deps
new file mode 100644
index 000000000..1e82d9572
--- /dev/null
+++ b/src/tests/softpkcs11/deps
@@ -0,0 +1,6 @@
+#
+# Generated makefile dependencies follow.
+#
+main.so main.po $(OUTPRE)main.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/plugins/preauth/pkinit/pkcs11.h main.c
diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c
index 2acec5169..5255323d3 100644
--- a/src/tests/softpkcs11/main.c
+++ b/src/tests/softpkcs11/main.c
@@ -1,3 +1,4 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
* Copyright (c) 2004-2006, Stockholms universitet
* (Stockholm University, Stockholm Sweden)
@@ -31,7 +32,57 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include "locl.h"
+#include "k5-platform.h"
+
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+
+#include <ctype.h>
+#include <pwd.h>
+
+#include <pkcs11.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define EVP_PKEY_get0_RSA(key) ((key)->pkey.rsa)
+#define RSA_PKCS1_OpenSSL RSA_PKCS1_SSLeay
+#define RSA_get0_key compat_rsa_get0_key
+static void
+compat_rsa_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e,
+ const BIGNUM **d)
+{
+ if (n != NULL)
+ *n = rsa->n;
+ if (e != NULL)
+ *e = rsa->e;
+ if (d != NULL)
+ *d = rsa->d;
+}
+#endif
+
+#define OPENSSL_ASN1_MALLOC_ENCODE(T, B, BL, S, R) \
+ { \
+ unsigned char *p; \
+ (BL) = i2d_##T((S), NULL); \
+ if ((BL) <= 0) { \
+ (R) = EINVAL; \
+ } else { \
+ (B) = malloc((BL)); \
+ if ((B) == NULL) { \
+ (R) = ENOMEM; \
+ } else { \
+ p = (B); \
+ (R) = 0; \
+ (BL) = i2d_##T((S), &p); \
+ if ((BL) <= 0) { \
+ free((B)); \
+ (R) = EINVAL; \
+ } \
+ } \
+ } \
+ }
/* RCSID("$Id: main.c,v 1.24 2006/01/11 12:42:53 lha Exp $"); */
@@ -124,7 +175,7 @@ st_logf(const char *fmt, ...)
}
static void
-snprintf_fill(char *str, size_t size, char fillchar, const char *fmt, ...)
+snprintf_fill(char *str, int size, char fillchar, const char *fmt, ...)
{
int len;
va_list ap;
@@ -141,19 +192,19 @@ snprintf_fill(char *str, size_t size, char fillchar, const char *fmt, ...)
#endif
#define VERIFY_SESSION_HANDLE(s, state) \
-{ \
- CK_RV ret; \
- ret = verify_session_handle(s, state); \
- if (ret != CKR_OK) { \
- /* return CKR_OK */; \
- } \
-}
+ { \
+ CK_RV vshret; \
+ vshret = verify_session_handle(s, state); \
+ if (vshret != CKR_OK) { \
+ /* return CKR_OK */; \
+ } \
+ }
static CK_RV
verify_session_handle(CK_SESSION_HANDLE hSession,
struct session_state **state)
{
- int i;
+ size_t i;
for (i = 0; i < MAX_NUM_SESSION; i++){
if (soft_token.state[i].session_handle == hSession)
@@ -361,16 +412,20 @@ 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 BIGNUM *n, *e;
- modulus_bits = BN_num_bits(key->pkey.rsa->n);
+ rsa = EVP_PKEY_get0_RSA(key);
+ RSA_get0_key(rsa, &n, &e, NULL);
+ modulus_bits = BN_num_bits(n);
- modulus_len = BN_num_bytes(key->pkey.rsa->n);
+ modulus_len = BN_num_bytes(n);
modulus = malloc(modulus_len);
- BN_bn2bin(key->pkey.rsa->n, modulus);
+ BN_bn2bin(n, modulus);
- exponent_len = BN_num_bytes(key->pkey.rsa->e);
+ exponent_len = BN_num_bytes(e);
exponent = malloc(exponent_len);
- BN_bn2bin(key->pkey.rsa->e, exponent);
+ BN_bn2bin(e, exponent);
add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
add_object_attribute(o, 0, CKA_MODULUS_BITS,
@@ -378,7 +433,7 @@ 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(key->pkey.rsa, RSA_PKCS1_SSLeay());
+ RSA_set_method(rsa, RSA_PKCS1_OpenSSL());
free(modulus);
free(exponent);
@@ -474,7 +529,7 @@ add_certificate(char *label,
o->u.cert = cert;
public_key = X509_get_pubkey(o->u.cert);
- switch (EVP_PKEY_type(public_key->type)) {
+ switch (EVP_PKEY_base_id(public_key)) {
case EVP_PKEY_RSA:
key_type = CKK_RSA;
break;
@@ -604,8 +659,8 @@ add_certificate(char *label,
/* XXX verify keytype */
if (key_type == CKK_RSA)
- RSA_set_method(o->u.private_key.key->pkey.rsa,
- RSA_PKCS1_SSLeay());
+ 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);
@@ -755,8 +810,9 @@ CK_RV
C_Initialize(CK_VOID_PTR a)
{
CK_C_INITIALIZE_ARGS_PTR args = a;
+ size_t i;
+
st_logf("Initialize\n");
- int i;
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
@@ -825,7 +881,7 @@ C_Initialize(CK_VOID_PTR a)
CK_RV
C_Finalize(CK_VOID_PTR args)
{
- int i;
+ size_t i;
st_logf("Finalize\n");
@@ -1008,7 +1064,7 @@ C_OpenSession(CK_SLOT_ID slotID,
CK_NOTIFY Notify,
CK_SESSION_HANDLE_PTR phSession)
{
- int i;
+ size_t i;
st_logf("OpenSession: slot: %d\n", (int)slotID);
@@ -1050,7 +1106,7 @@ C_CloseSession(CK_SESSION_HANDLE hSession)
CK_RV
C_CloseAllSessions(CK_SLOT_ID slotID)
{
- int i;
+ size_t i;
st_logf("CloseAllSessions\n");
@@ -1127,7 +1183,8 @@ C_Login(CK_SESSION_HANDLE hSession,
}
/* XXX check keytype */
- RSA_set_method(o->u.private_key.key->pkey.rsa, RSA_PKCS1_SSLeay());
+ 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);
@@ -1226,7 +1283,6 @@ C_FindObjectsInit(CK_SESSION_HANDLE hSession,
}
if (ulCount) {
CK_ULONG i;
- size_t len;
print_attributes(pTemplate, ulCount);
@@ -1415,7 +1471,7 @@ C_Encrypt(CK_SESSION_HANDLE hSession,
return CKR_ARGUMENTS_BAD;
}
- rsa = o->u.public_key->pkey.rsa;
+ rsa = EVP_PKEY_get0_RSA(o->u.public_key);
if (rsa == NULL)
return CKR_ARGUMENTS_BAD;
@@ -1445,7 +1501,7 @@ C_Encrypt(CK_SESSION_HANDLE hSession,
goto out;
}
- if (buffer_len + padding_len < ulDataLen) {
+ if ((CK_ULONG)buffer_len + padding_len < ulDataLen) {
ret = CKR_ARGUMENTS_BAD;
goto out;
}
@@ -1566,7 +1622,7 @@ C_Decrypt(CK_SESSION_HANDLE hSession,
return CKR_ARGUMENTS_BAD;
}
- rsa = o->u.private_key.key->pkey.rsa;
+ rsa = EVP_PKEY_get0_RSA(o->u.private_key.key);
if (rsa == NULL)
return CKR_ARGUMENTS_BAD;
@@ -1596,7 +1652,7 @@ C_Decrypt(CK_SESSION_HANDLE hSession,
goto out;
}
- if (buffer_len + padding_len < ulEncryptedDataLen) {
+ if ((CK_ULONG)buffer_len + padding_len < ulEncryptedDataLen) {
ret = CKR_ARGUMENTS_BAD;
goto out;
}
@@ -1725,7 +1781,7 @@ C_Sign(CK_SESSION_HANDLE hSession,
return CKR_ARGUMENTS_BAD;
}
- rsa = o->u.private_key.key->pkey.rsa;
+ rsa = EVP_PKEY_get0_RSA(o->u.private_key.key);
if (rsa == NULL)
return CKR_ARGUMENTS_BAD;
@@ -1754,7 +1810,7 @@ C_Sign(CK_SESSION_HANDLE hSession,
goto out;
}
- if (buffer_len < ulDataLen + padding_len) {
+ if ((CK_ULONG)buffer_len < ulDataLen + padding_len) {
ret = CKR_ARGUMENTS_BAD;
goto out;
}
@@ -1872,7 +1928,7 @@ C_Verify(CK_SESSION_HANDLE hSession,
return CKR_ARGUMENTS_BAD;
}
- rsa = o->u.public_key->pkey.rsa;
+ rsa = EVP_PKEY_get0_RSA(o->u.public_key);
if (rsa == NULL)
return CKR_ARGUMENTS_BAD;
@@ -1900,7 +1956,7 @@ C_Verify(CK_SESSION_HANDLE hSession,
goto out;
}
- if (buffer_len < ulDataLen) {
+ if ((CK_ULONG)buffer_len < ulDataLen) {
ret = CKR_ARGUMENTS_BAD;
goto out;
}
@@ -1926,7 +1982,7 @@ C_Verify(CK_SESSION_HANDLE hSession,
if (len > buffer_len)
abort();
- if (len != ulSignatureLen) {
+ if ((CK_ULONG)len != ulSignatureLen) {
ret = CKR_GENERAL_ERROR;
goto out;
}
diff --git a/src/tests/softpkcs11/softpkcs11.exports b/src/tests/softpkcs11/softpkcs11.exports
new file mode 100644
index 000000000..aa7284511
--- /dev/null
+++ b/src/tests/softpkcs11/softpkcs11.exports
@@ -0,0 +1,39 @@
+C_CloseAllSessions
+C_CloseSession
+C_Decrypt
+C_DecryptFinal
+C_DecryptInit
+C_DecryptUpdate
+C_DigestInit
+C_Encrypt
+C_EncryptFinal
+C_EncryptInit
+C_EncryptUpdate
+C_Finalize
+C_FindObjects
+C_FindObjectsFinal
+C_FindObjectsInit
+C_GenerateRandom
+C_GetAttributeValue
+C_GetFunctionList
+C_GetInfo
+C_GetMechanismInfo
+C_GetMechanismList
+C_GetObjectSize
+C_GetSessionInfo
+C_GetSlotInfo
+C_GetSlotList
+C_GetTokenInfo
+C_Initialize
+C_InitToken
+C_Login
+C_Logout
+C_OpenSession
+C_Sign
+C_SignFinal
+C_SignInit
+C_SignUpdate
+C_Verify
+C_VerifyFinal
+C_VerifyInit
+C_VerifyUpdate
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index 1dadb1b96..384bf1426 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -4,14 +4,7 @@ from k5test import *
if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')):
skip_rest('PKINIT tests', 'PKINIT module not built')
-# Check if soft-pkcs11.so is available.
-try:
- import ctypes
- lib = ctypes.LibraryLoader(ctypes.CDLL).LoadLibrary('soft-pkcs11.so')
- del lib
- have_soft_pkcs11 = True
-except:
- have_soft_pkcs11 = False
+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')
@@ -69,9 +62,9 @@ p12_upn2_identity = 'PKCS12:%s' % user_upn2_p12
p12_upn3_identity = 'PKCS12:%s' % user_upn3_p12
p12_generic_identity = 'PKCS12:%s' % generic_p12
p12_enc_identity = 'PKCS12:%s' % user_enc_p12
-p11_identity = 'PKCS11:soft-pkcs11.so'
-p11_token_identity = ('PKCS11:module_name=soft-pkcs11.so:'
- 'slotid=1:token=SoftToken (token)')
+p11_identity = 'PKCS11:' + soft_pkcs11
+p11_token_identity = ('PKCS11:module_name=' + soft_pkcs11 +
+ ':slotid=1:token=SoftToken (token)')
# Start a realm with the test kdb module for the following UPN SAN tests.
realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=alias_kdc_conf,
@@ -398,9 +391,6 @@ realm.klist(realm.user_princ)
realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=,'],
expected_code=1, expected_msg='Preauthentication failed while')
-if not have_soft_pkcs11:
- skip_rest('PKINIT PKCS11 tests', 'soft-pkcs11.so not found')
-
softpkcs11rc = os.path.join(os.getcwd(), 'testdir', 'soft-pkcs11.rc')
realm.env['SOFTPKCS11RC'] = softpkcs11rc

View File

@ -1,41 +0,0 @@
From 196ee40d489e4e6a72232a3cdbb7af19a72362b3 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 4 Jan 2019 17:00:15 -0500
Subject: [PATCH] Use openssl's PRNG in FIPS mode
(cherry picked from commit 31277d79675a76612015ea00d420b41b9a232d5a)
---
src/lib/crypto/krb/prng.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
index cb9ca9b98..f0e9984ca 100644
--- a/src/lib/crypto/krb/prng.c
+++ b/src/lib/crypto/krb/prng.c
@@ -26,6 +26,8 @@
#include "crypto_int.h"
+#include <openssl/rand.h>
+
krb5_error_code KRB5_CALLCONV
krb5_c_random_seed(krb5_context context, krb5_data *data)
{
@@ -99,9 +101,16 @@ krb5_boolean
k5_get_os_entropy(unsigned char *buf, size_t len, int strong)
{
const char *device;
-#if defined(__linux__) && defined(SYS_getrandom)
int r;
+ /* A wild FIPS mode appeared! */
+ if (FIPS_mode()) {
+ /* The return codes on this API are not good */
+ r = RAND_bytes(buf, len);
+ return r == 1;
+ }
+
+#if defined(__linux__) && defined(SYS_getrandom)
while (len > 0) {
/*
* Pull from the /dev/urandom pool, but require it to have been seeded.

View File

@ -0,0 +1,103 @@
From fe66536c1b7aec67233739df97cbe0301ee6475e Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 19 Nov 2019 15:03:19 -0500
Subject: [PATCH] krb5-1.17post2 DES/3DES fixups
Kept separate from the other patch because rawhide doesn't have DES.
post2 adds krb5kdf workarounds.
---
src/lib/crypto/krb/derive.c | 6 +++++-
src/lib/crypto/openssl/enc_provider/des.c | 9 +++++++++
src/lib/crypto/openssl/enc_provider/des3.c | 6 ++++++
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/lib/crypto/krb/derive.c b/src/lib/crypto/krb/derive.c
index 915a173dd..ebdab69bc 100644
--- a/src/lib/crypto/krb/derive.c
+++ b/src/lib/crypto/krb/derive.c
@@ -348,6 +348,7 @@ cleanup:
zapfree(prf.data, blocksize);
return ret;
}
+#endif /* OSSL_KDFS */
static krb5_error_code
builtin_derive_random_rfc3961(const struct krb5_enc_provider *enc,
@@ -400,7 +401,6 @@ cleanup:
zapfree(block.data, blocksize);
return ret;
}
-#endif /* OSSL_KDFS */
krb5_error_code
k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
@@ -432,6 +432,10 @@ k5_derive_random_rfc3961(const struct krb5_enc_provider *enc,
krb5_key inkey, krb5_data *outrnd,
const krb5_data *in_constant)
{
+ /* DES (single and triple). They'll be gone very soon. */
+ if (enc->keylength == 8 || enc->keylength == 24)
+ return builtin_derive_random_rfc3961(enc, inkey, outrnd, in_constant);
+
#ifdef OSSL_KDFS
return openssl_krb5kdf(enc, inkey, outrnd, in_constant);
#else
diff --git a/src/lib/crypto/openssl/enc_provider/des.c b/src/lib/crypto/openssl/enc_provider/des.c
index a662db512..7d17d287e 100644
--- a/src/lib/crypto/openssl/enc_provider/des.c
+++ b/src/lib/crypto/openssl/enc_provider/des.c
@@ -85,6 +85,9 @@ k5_des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -133,6 +136,9 @@ k5_des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -182,6 +188,9 @@ k5_des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data,
DES_key_schedule sched;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0)
return ret;
diff --git a/src/lib/crypto/openssl/enc_provider/des3.c b/src/lib/crypto/openssl/enc_provider/des3.c
index 1c439c2cd..8be555a8d 100644
--- a/src/lib/crypto/openssl/enc_provider/des3.c
+++ b/src/lib/crypto/openssl/enc_provider/des3.c
@@ -84,6 +84,9 @@ k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -133,6 +136,9 @@ k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;

View File

@ -1,20 +1,186 @@
From 088fd5a56e030739a31a43aee7335bc661a92b1c Mon Sep 17 00:00:00 2001
From 2a4e2418875b41c3273db5f6b4e9e1b01c1fb5ff Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 31 Jul 2018 13:47:26 -0400
Subject: [PATCH] In FIPS mode, add plaintext fallback for RC4 usages and taint
Date: Fri, 9 Nov 2018 15:12:21 -0500
Subject: [PATCH] krb5-1.17post6 FIPS with PRNG and RADIUS and MD4
(cherry picked from commit a327e3bf5b992ac829c7b2d3317fb7d93b1c88ef)
(cherry picked from commit 2bd85da058d2d73eb2818a8e64656fec9b21b3c3)
NB: Use openssl's PRNG in FIPS mode and taint within krad.
A lot of the FIPS error conditions from OpenSSL are incredibly
mysterious (at best, things return NULL unexpectedly; at worst,
internal assertions are tripped; most of the time, you just get
ENOMEM). In order to cope with this, we need to have some level of
awareness of what we can and can't safely call.
This will slow down some calls slightly (FIPS_mode() takes multiple
locks), but not for any ciphers we care about - which is to say that
AES is fine. Shame about SPAKE though.
post6 restores MD4 (and therefore keygen-only RC4).
(cherry picked from commit 80b56b04d90fcacd9f78fed305c7d5528d863b38)
---
src/lib/krad/attr.c | 45 +++++++++++++++++++++++++++++-----------
src/lib/krad/attrset.c | 5 +++--
src/lib/krad/internal.h | 13 ++++++++++--
src/lib/krad/packet.c | 22 +++++++++++---------
src/lib/krad/remote.c | 10 +++++++--
src/lib/krad/t_attr.c | 3 ++-
src/lib/krad/t_attrset.c | 4 +++-
7 files changed, 72 insertions(+), 30 deletions(-)
src/lib/crypto/krb/prng.c | 11 ++++-
.../crypto/openssl/enc_provider/camellia.c | 6 +++
src/lib/crypto/openssl/enc_provider/rc4.c | 13 +++++-
.../crypto/openssl/hash_provider/hash_evp.c | 12 +++++
src/lib/crypto/openssl/hmac.c | 6 ++-
src/lib/krad/attr.c | 45 ++++++++++++++-----
src/lib/krad/attrset.c | 5 ++-
src/lib/krad/internal.h | 13 +++++-
src/lib/krad/packet.c | 22 ++++-----
src/lib/krad/remote.c | 10 ++++-
src/lib/krad/t_attr.c | 3 +-
src/lib/krad/t_attrset.c | 4 +-
src/plugins/preauth/spake/spake_client.c | 6 +++
src/plugins/preauth/spake/spake_kdc.c | 6 +++
14 files changed, 129 insertions(+), 33 deletions(-)
diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
index cb9ca9b98..f0e9984ca 100644
--- a/src/lib/crypto/krb/prng.c
+++ b/src/lib/crypto/krb/prng.c
@@ -26,6 +26,8 @@
#include "crypto_int.h"
+#include <openssl/rand.h>
+
krb5_error_code KRB5_CALLCONV
krb5_c_random_seed(krb5_context context, krb5_data *data)
{
@@ -99,9 +101,16 @@ krb5_boolean
k5_get_os_entropy(unsigned char *buf, size_t len, int strong)
{
const char *device;
-#if defined(__linux__) && defined(SYS_getrandom)
int r;
+ /* A wild FIPS mode appeared! */
+ if (FIPS_mode()) {
+ /* The return codes on this API are not good */
+ r = RAND_bytes(buf, len);
+ return r == 1;
+ }
+
+#if defined(__linux__) && defined(SYS_getrandom)
while (len > 0) {
/*
* Pull from the /dev/urandom pool, but require it to have been seeded.
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
index 2da691329..f79679a0b 100644
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
@@ -304,6 +304,9 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE];
struct iov_cursor cursor;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
if (output->length < CAMELLIA_BLOCK_SIZE)
return KRB5_BAD_MSIZE;
@@ -331,6 +334,9 @@ static krb5_error_code
krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage,
krb5_data *state)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
state->length = 16;
state->data = (void *) malloc(16);
if (state->data == NULL)
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
index a65d57b7a..6ccaca94a 100644
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
@@ -66,6 +66,9 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx = NULL;
struct arcfour_state *arcstate;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
arcstate = (state != NULL) ? (void *)state->data : NULL;
if (arcstate != NULL) {
ctx = arcstate->ctx;
@@ -113,7 +116,12 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
static void
k5_arcfour_free_state(krb5_data *state)
{
- struct arcfour_state *arcstate = (void *)state->data;
+ struct arcfour_state *arcstate;
+
+ if (FIPS_mode())
+ return;
+
+ arcstate = (void *) state->data;
EVP_CIPHER_CTX_free(arcstate->ctx);
free(arcstate);
@@ -125,6 +133,9 @@ k5_arcfour_init_state(const krb5_keyblock *key,
{
struct arcfour_state *arcstate;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
/*
* The cipher state here is a saved pointer to a struct arcfour_state
* object, rather than a flat byte array as in most enc providers. The
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
index 957ed8d9c..915da9dbe 100644
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
@@ -49,6 +49,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
if (ctx == NULL)
return ENOMEM;
+ if (type == EVP_md4()) {
+ /* See comment below in hash_md4(). */
+ 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]))
@@ -64,12 +69,19 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
static krb5_error_code
hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
+ /*
+ * MD4 is needed in FIPS mode to perform key generation for RC4 keys used
+ * 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);
}
static krb5_error_code
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
return hash_evp(EVP_md5(), data, num_data, output);
}
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
index b2db6ec02..d94d9ac94 100644
--- a/src/lib/crypto/openssl/hmac.c
+++ b/src/lib/crypto/openssl/hmac.c
@@ -103,7 +103,11 @@ map_digest(const struct krb5_hash_provider *hash)
return EVP_sha256();
else if (!strncmp(hash->hash_name, "SHA-384",7))
return EVP_sha384();
- else if (!strncmp(hash->hash_name, "MD5", 3))
+
+ if (FIPS_mode())
+ return NULL;
+
+ if (!strncmp(hash->hash_name, "MD5", 3))
return EVP_md5();
else if (!strncmp(hash->hash_name, "MD4", 3))
return EVP_md4();
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
index 9c13d9d75..275327e67 100644
--- a/src/lib/krad/attr.c
@ -352,3 +518,51 @@ index 7928335ca..0f9576253 100644
krad_attrset_free(set);
/* Manually encode User-Name. */
diff --git a/src/plugins/preauth/spake/spake_client.c b/src/plugins/preauth/spake/spake_client.c
index 00734a13b..a3ce22b70 100644
--- a/src/plugins/preauth/spake/spake_client.c
+++ b/src/plugins/preauth/spake/spake_client.c
@@ -38,6 +38,8 @@
#include "groups.h"
#include <krb5/clpreauth_plugin.h>
+#include <openssl/crypto.h>
+
typedef struct reqstate_st {
krb5_pa_spake *msg; /* set in prep_questions, used in process */
krb5_keyblock *initial_key;
@@ -375,6 +377,10 @@ clpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver,
if (maj_ver != 1)
return KRB5_PLUGIN_VER_NOTSUPP;
+
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
vt = (krb5_clpreauth_vtable)vtable;
vt->name = "spake";
vt->pa_type_list = pa_types;
diff --git a/src/plugins/preauth/spake/spake_kdc.c b/src/plugins/preauth/spake/spake_kdc.c
index 59e88409e..1b3e569e9 100644
--- a/src/plugins/preauth/spake/spake_kdc.c
+++ b/src/plugins/preauth/spake/spake_kdc.c
@@ -41,6 +41,8 @@
#include <krb5/kdcpreauth_plugin.h>
+#include <openssl/crypto.h>
+
/*
* The SPAKE kdcpreauth module uses a secure cookie containing the following
* concatenated fields (all integer fields are big-endian):
@@ -578,6 +580,10 @@ kdcpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver,
if (maj_ver != 1)
return KRB5_PLUGIN_VER_NOTSUPP;
+
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
vt = (krb5_kdcpreauth_vtable)vtable;
vt->name = "spake";
vt->pa_type_list = pa_types;

View File

@ -18,12 +18,12 @@ Summary: The Kerberos network authentication system
Name: krb5
Version: 1.17
# for prerelease, should be e.g., 0.% {prerelease}.1% { ?dist } (without spaces)
Release: 9%{?dist}
Release: 18%{?dist}
# lookaside-cached sources; two downloads and a build artifact
Source0: https://web.mit.edu/kerberos/dist/krb5/1.16/krb5-%{version}%{prerelease}.tar.gz
Source0: https://web.mit.edu/kerberos/dist/krb5/1.17/krb5-%{version}%{prerelease}.tar.gz
# rharwood has trust path to signing key and verifies on check-in
Source1: https://web.mit.edu/kerberos/dist/krb5/1.16/krb5-%{version}%{prerelease}.tar.gz.asc
Source1: https://web.mit.edu/kerberos/dist/krb5/1.17/krb5-%{version}%{prerelease}.tar.gz.asc
# This source is generated during the build because it is documentation.
# To override this behavior (e.g., new upstream version), do:
# tar cfT krb5-1.15.2-pdfs.tar /dev/null
@ -57,20 +57,26 @@ Patch33: krb5-1.13-dirsrv-accountlock.patch
Patch34: krb5-1.9-debuginfo.patch
Patch35: krb5-1.11-run_user_0.patch
Patch36: krb5-1.11-kpasswdtest.patch
Patch87: In-FIPS-mode-add-plaintext-fallback-for-RC4-usages-a.patch
Patch88: Add-tests-for-KCM-ccache-type.patch
Patch89: Properly-size-ifdef-in-k5_cccol_lock.patch
Patch90: Fix-memory-leak-in-none-replay-cache-type.patch
Patch91: Address-some-optimized-out-memset-calls.patch
Patch92: Use-openssl-s-PRNG-in-FIPS-mode.patch
Patch93: Become-FIPS-aware-with-3DES.patch
Patch94: FIPS-aware-SPAKE-group-negotiation.patch
Patch95: In-rd_req_dec-always-log-non-permitted-enctypes.patch
Patch96: In-kpropd-debug-log-proper-ticket-enctype-names.patch
Patch97: Make-etype-names-in-KDC-logs-human-readable.patch
Patch98: Mark-deprecated-enctypes-when-used.patch
Patch99: Add-function-and-enctype-flag-for-deprecations.patch
Patch100: Fix-argument-order-on-strlcpy-in-enctype_name.patch
Patch101: Fix-KCM-client-time-offset-propagation.patch
Patch102: Add-soft-pkcs11-source-code.patch
Patch103: Use-imported-soft-pkcs11-for-tests.patch
Patch104: Fix-Coverity-defects-in-soft-pkcs11-test-code.patch
Patch105: Fix-memory-leaks-in-soft-pkcs11-code.patch
Patch106: Avoid-alignment-warnings-in-openssl-rc4.c.patch
Patch107: Use-backported-version-of-OpenSSL-3-KDF-interface.patch
Patch108: krb5-1.17post6-FIPS-with-PRNG-and-RADIUS-and-MD4.patch
Patch109: krb5-1.17post2-DES-3DES-fixups.patch
Patch110: Put-KDB-authdata-first.patch
License: MIT
URL: http://web.mit.edu/kerberos/www/
@ -83,12 +89,12 @@ BuildRequires: gzip, ncurses-devel
BuildRequires: python3-sphinx, texlive-pdftex, latexmk
BuildRequires: libverto-devel
BuildRequires: openldap-devel
BuildRequires: openssl-devel >= 0.9.8
BuildRequires: python3
BuildRequires: keyutils, keyutils-libs-devel >= 1.5.8
BuildRequires: libselinux-devel
BuildRequires: pam-devel
BuildRequires: tcl-devel
BuildRequires: openssl-devel >= 1:1.1.1c-4
# For autosetup
BuildRequires: git
@ -153,6 +159,7 @@ Summary: The non-admin shared libraries used by Kerberos 5
Group: System Environment/Libraries
Requires: coreutils, gawk, grep, sed
Requires: keyutils-libs >= 1.5.8
Requires: openssl-libs >= 1:1.1.1c-4
Requires: /etc/crypto-policies/back-ends/krb5.config
%description libs
@ -683,6 +690,42 @@ exit 0
%{_libdir}/libkadm5srv_mit.so.*
%changelog
* Wed Feb 19 2020 Robbie Harwood <rharwood@redhat.com> - 1.17-18
- Put KDB authdata first
- Resolves: #1800575
* Thu Nov 21 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-17
- OpenSSL has an epoch, apparently
- Resolves: #1754690
* Wed Nov 20 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-16
- Put openssl runtime requirement in the right place this time
- Resolves: #1754690
* Wed Nov 20 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-15
- Restore accidentally dropped patch
- Resolves: #1754690
* Wed Nov 20 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-14
- Fix krb5kdf support and add proper openssl version requirements
- Resolves: #1754690
* Tue Nov 19 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-13
- Full FIPS compliance
- Resolves: #1754690
* Tue Oct 15 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-12
- Backport soft-pkcs11 testing code
- Resolves: #1734158
* Tue Oct 15 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-11
- Fix KCM client time offset propagation
- Resolves: #1738553
* Tue Oct 15 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-10
- Fix source URLs in spec file
- Resolves: #1755959
* Tue Sep 17 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-9
- Fix argument order on strlcpy() in enctype_name()
- Resolves: #1754369