import CS krb5-1.21.1-6.el9
This commit is contained in:
parent
e057897bbe
commit
4dfb127281
1295
SOURCES/0024-Remove-PKINIT-RSA-support.patch
Normal file
1295
SOURCES/0024-Remove-PKINIT-RSA-support.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,175 @@
|
||||
From 5464ad5b64f7ce7c3d78082352189af7c8feb95f Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Fri, 6 Sep 2024 17:18:11 +0200
|
||||
Subject: [PATCH] Fix various issues detected by static analysis
|
||||
|
||||
(cherry picked from commit 53d352949941ee236461658d01f03c37abafc6f6)
|
||||
---
|
||||
src/clients/klist/klist.c | 13 +++++++------
|
||||
src/kadmin/dbutil/dump.c | 5 +++++
|
||||
src/kdc/ndr.c | 2 +-
|
||||
src/lib/kdb/decrypt_key.c | 2 +-
|
||||
src/lib/rpc/svc_auth_gss.c | 5 ++++-
|
||||
src/lib/rpc/svc_udp.c | 13 +++++++------
|
||||
src/util/support/threads.c | 2 --
|
||||
7 files changed, 25 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
|
||||
index 27cf0ee11b..9db66f6072 100644
|
||||
--- a/src/clients/klist/klist.c
|
||||
+++ b/src/clients/klist/klist.c
|
||||
@@ -666,7 +666,7 @@ show_credential(krb5_creds *cred)
|
||||
krb5_error_code ret;
|
||||
krb5_ticket *tkt = NULL;
|
||||
char *name = NULL, *sname = NULL, *tktsname, *flags;
|
||||
- int extra_field = 0, ccol = 0, i;
|
||||
+ int extra_field = 0, ccol = 0, i, r;
|
||||
krb5_boolean is_config = krb5_is_config_principal(context, cred->server);
|
||||
|
||||
ret = krb5_unparse_name(context, cred->client, &name);
|
||||
@@ -696,11 +696,12 @@ show_credential(krb5_creds *cred)
|
||||
fputs("config: ", stdout);
|
||||
ccol = 8;
|
||||
for (i = 1; i < cred->server->length; i++) {
|
||||
- ccol += printf("%s%.*s%s",
|
||||
- i > 1 ? "(" : "",
|
||||
- (int)cred->server->data[i].length,
|
||||
- cred->server->data[i].data,
|
||||
- i > 1 ? ")" : "");
|
||||
+ r = printf("%s%.*s%s", i > 1 ? "(" : "",
|
||||
+ (int)cred->server->data[i].length,
|
||||
+ cred->server->data[i].data,
|
||||
+ i > 1 ? ")" : "");
|
||||
+ if (r >= 0)
|
||||
+ ccol += r;
|
||||
}
|
||||
fputs(" = ", stdout);
|
||||
ccol += 3;
|
||||
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
|
||||
index 4d6cc0bdf9..feb053d834 100644
|
||||
--- a/src/kadmin/dbutil/dump.c
|
||||
+++ b/src/kadmin/dbutil/dump.c
|
||||
@@ -704,6 +704,11 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
|
||||
|
||||
dbentry->len = u1;
|
||||
dbentry->n_key_data = u4;
|
||||
+
|
||||
+ if (u5 > UINT16_MAX) {
|
||||
+ load_err(fname, *linenop, _("invalid principal extra data size"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
dbentry->e_length = u5;
|
||||
|
||||
if (kp != NULL) {
|
||||
diff --git a/src/kdc/ndr.c b/src/kdc/ndr.c
|
||||
index d438408ee2..38be9fe42a 100644
|
||||
--- a/src/kdc/ndr.c
|
||||
+++ b/src/kdc/ndr.c
|
||||
@@ -242,7 +242,7 @@ ndr_enc_delegation_info(struct pac_s4u_delegation_info *in, krb5_data *out)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
size_t i;
|
||||
- struct k5buf b;
|
||||
+ struct k5buf b = EMPTY_K5BUF;
|
||||
struct encoded_wchars pt_encoded = { 0 }, *tss_encoded = NULL;
|
||||
uint32_t pointer = 0;
|
||||
|
||||
diff --git a/src/lib/kdb/decrypt_key.c b/src/lib/kdb/decrypt_key.c
|
||||
index 82bbed6312..c971793c9d 100644
|
||||
--- a/src/lib/kdb/decrypt_key.c
|
||||
+++ b/src/lib/kdb/decrypt_key.c
|
||||
@@ -60,7 +60,7 @@ krb5_dbe_def_decrypt_key_data(krb5_context context, const krb5_keyblock *mkey,
|
||||
krb5_keyblock *dbkey_out,
|
||||
krb5_keysalt *keysalt_out)
|
||||
{
|
||||
- krb5_error_code ret;
|
||||
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
|
||||
int16_t keylen;
|
||||
krb5_enc_data cipher;
|
||||
krb5_data plain = empty_data();
|
||||
diff --git a/src/lib/rpc/svc_auth_gss.c b/src/lib/rpc/svc_auth_gss.c
|
||||
index 98d601c8ab..461e5de542 100644
|
||||
--- a/src/lib/rpc/svc_auth_gss.c
|
||||
+++ b/src/lib/rpc/svc_auth_gss.c
|
||||
@@ -297,7 +297,7 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
|
||||
struct opaque_auth *oa;
|
||||
gss_buffer_desc rpcbuf, checksum;
|
||||
OM_uint32 maj_stat, min_stat, qop_state;
|
||||
- u_char rpchdr[128];
|
||||
+ u_char rpchdr[32 + MAX_AUTH_BYTES];
|
||||
int32_t *buf;
|
||||
|
||||
log_debug("in svcauth_gss_validate()");
|
||||
@@ -315,6 +315,8 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
|
||||
return (FALSE);
|
||||
|
||||
buf = (int32_t *)(void *)rpchdr;
|
||||
+
|
||||
+ /* Write the 32 first bytes of the header. */
|
||||
IXDR_PUT_LONG(buf, msg->rm_xid);
|
||||
IXDR_PUT_ENUM(buf, msg->rm_direction);
|
||||
IXDR_PUT_LONG(buf, msg->rm_call.cb_rpcvers);
|
||||
@@ -323,6 +325,7 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
|
||||
IXDR_PUT_LONG(buf, msg->rm_call.cb_proc);
|
||||
IXDR_PUT_ENUM(buf, oa->oa_flavor);
|
||||
IXDR_PUT_LONG(buf, oa->oa_length);
|
||||
+
|
||||
if (oa->oa_length) {
|
||||
memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
|
||||
buf += RNDUP(oa->oa_length) / sizeof(int32_t);
|
||||
diff --git a/src/lib/rpc/svc_udp.c b/src/lib/rpc/svc_udp.c
|
||||
index 8ecbdf2b33..3aff277eb7 100644
|
||||
--- a/src/lib/rpc/svc_udp.c
|
||||
+++ b/src/lib/rpc/svc_udp.c
|
||||
@@ -248,8 +248,9 @@ static bool_t svcudp_reply(
|
||||
{
|
||||
struct svcudp_data *su = su_data(xprt);
|
||||
XDR *xdrs = &su->su_xdrs;
|
||||
- int slen;
|
||||
+ u_int slen;
|
||||
bool_t stat = FALSE;
|
||||
+ ssize_t r;
|
||||
|
||||
xdrproc_t xdr_results = NULL;
|
||||
caddr_t xdr_location = 0;
|
||||
@@ -272,12 +273,12 @@ static bool_t svcudp_reply(
|
||||
if (xdr_replymsg(xdrs, msg) &&
|
||||
(!has_args ||
|
||||
(SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_results, xdr_location)))) {
|
||||
- slen = (int)XDR_GETPOS(xdrs);
|
||||
- if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
|
||||
- (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
|
||||
- == slen) {
|
||||
+ slen = XDR_GETPOS(xdrs);
|
||||
+ r = sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
|
||||
+ (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen);
|
||||
+ if (r >= 0 && (u_int)r == slen) {
|
||||
stat = TRUE;
|
||||
- if (su->su_cache && slen >= 0) {
|
||||
+ if (su->su_cache) {
|
||||
cache_set(xprt, (uint32_t) slen);
|
||||
}
|
||||
}
|
||||
diff --git a/src/util/support/threads.c b/src/util/support/threads.c
|
||||
index be7e4c2e3f..4ded805b79 100644
|
||||
--- a/src/util/support/threads.c
|
||||
+++ b/src/util/support/threads.c
|
||||
@@ -118,7 +118,6 @@ struct tsd_block {
|
||||
# pragma weak pthread_mutex_destroy
|
||||
# pragma weak pthread_mutex_init
|
||||
# pragma weak pthread_self
|
||||
-# pragma weak pthread_equal
|
||||
# pragma weak pthread_getspecific
|
||||
# pragma weak pthread_setspecific
|
||||
# pragma weak pthread_key_create
|
||||
@@ -151,7 +150,6 @@ int krb5int_pthread_loaded (void)
|
||||
|| &pthread_mutex_destroy == 0
|
||||
|| &pthread_mutex_init == 0
|
||||
|| &pthread_self == 0
|
||||
- || &pthread_equal == 0
|
||||
/* Any program that's really multithreaded will have to be
|
||||
able to create threads. */
|
||||
|| &pthread_create == 0
|
||||
--
|
||||
2.46.0
|
||||
|
629
SOURCES/0026-Generate-and-verify-message-MACs-in-libkrad.patch
Normal file
629
SOURCES/0026-Generate-and-verify-message-MACs-in-libkrad.patch
Normal file
@ -0,0 +1,629 @@
|
||||
From 023dcf87d34e29649dd76d33ce7d896c2b6f61d2 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Thu, 22 Aug 2024 17:15:50 +0200
|
||||
Subject: [PATCH] Generate and verify message MACs in libkrad
|
||||
|
||||
Implement some of the measures specified in
|
||||
draft-ietf-radext-deprecating-radius-03 for mitigating the BlastRADIUS
|
||||
attack (CVE-2024-3596):
|
||||
|
||||
* Include a Message-Authenticator MAC as the first attribute when
|
||||
generating a packet of type Access-Request, Access-Reject,
|
||||
Access-Accept, or Access-Challenge (sections 5.2.1 and 5.2.4), if
|
||||
the secret is non-empty. (An empty secret indicates the use of Unix
|
||||
domain socket transport.)
|
||||
|
||||
* Validate the Message-Authenticator MAC in received packets, if
|
||||
present.
|
||||
|
||||
FreeRADIUS enforces Message-Authenticator as of versions 3.2.5 and
|
||||
3.0.27. libkrad must generate Message-Authenticator attributes in
|
||||
order to remain compatible with these implementations.
|
||||
|
||||
[ghudson@mit.edu: adjusted style and naming; simplified some
|
||||
functions; edited commit message]
|
||||
|
||||
ticket: 9142 (new)
|
||||
tags: pullup
|
||||
target_version: 1.21-next
|
||||
|
||||
(cherry picked from commit 871125fea8ce0370a972bf65f7d1de63f619b06c)
|
||||
---
|
||||
src/include/k5-int.h | 5 +
|
||||
src/lib/crypto/krb/checksum_hmac_md5.c | 28 ++++
|
||||
src/lib/crypto/libk5crypto.exports | 1 +
|
||||
src/lib/krad/attr.c | 17 ++
|
||||
src/lib/krad/attrset.c | 59 +++++--
|
||||
src/lib/krad/internal.h | 7 +-
|
||||
src/lib/krad/packet.c | 206 +++++++++++++++++++++++--
|
||||
src/lib/krad/t_attrset.c | 2 +-
|
||||
src/lib/krad/t_daemon.py | 3 +-
|
||||
src/lib/krad/t_packet.c | 11 ++
|
||||
src/tests/t_otp.py | 3 +
|
||||
11 files changed, 311 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||||
index 69d6a6f569..b7789a2dd8 100644
|
||||
--- a/src/include/k5-int.h
|
||||
+++ b/src/include/k5-int.h
|
||||
@@ -2403,4 +2403,9 @@ krb5_boolean
|
||||
k5_sname_compare(krb5_context context, krb5_const_principal sname,
|
||||
krb5_const_principal princ);
|
||||
|
||||
+/* Generate an HMAC-MD5 keyed checksum as specified by RFC 2104. */
|
||||
+krb5_error_code
|
||||
+k5_hmac_md5(const krb5_data *key, const krb5_crypto_iov *data, size_t num_data,
|
||||
+ krb5_data *output);
|
||||
+
|
||||
#endif /* _KRB5_INT_H */
|
||||
diff --git a/src/lib/crypto/krb/checksum_hmac_md5.c b/src/lib/crypto/krb/checksum_hmac_md5.c
|
||||
index ec024f3966..a809388549 100644
|
||||
--- a/src/lib/crypto/krb/checksum_hmac_md5.c
|
||||
+++ b/src/lib/crypto/krb/checksum_hmac_md5.c
|
||||
@@ -92,3 +92,31 @@ cleanup:
|
||||
free(hash_iov);
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+krb5_error_code
|
||||
+k5_hmac_md5(const krb5_data *key, const krb5_crypto_iov *data, size_t num_data,
|
||||
+ krb5_data *output)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ const struct krb5_hash_provider *hash = &krb5int_hash_md5;
|
||||
+ krb5_keyblock keyblock = { 0 };
|
||||
+ krb5_data hashed_key;
|
||||
+ uint8_t hkeybuf[16];
|
||||
+ krb5_crypto_iov iov;
|
||||
+
|
||||
+ /* Hash the key if it is longer than the block size. */
|
||||
+ if (key->length > hash->blocksize) {
|
||||
+ hashed_key = make_data(hkeybuf, sizeof(hkeybuf));
|
||||
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov.data = *key;
|
||||
+ ret = hash->hash(&iov, 1, &hashed_key);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ key = &hashed_key;
|
||||
+ }
|
||||
+
|
||||
+ keyblock.magic = KV5M_KEYBLOCK;
|
||||
+ keyblock.length = key->length;
|
||||
+ keyblock.contents = (uint8_t *)key->data;
|
||||
+ return krb5int_hmac_keyblock(hash, &keyblock, data, num_data, output);
|
||||
+}
|
||||
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
|
||||
index d8ffa63304..00e0ce1812 100644
|
||||
--- a/src/lib/crypto/libk5crypto.exports
|
||||
+++ b/src/lib/crypto/libk5crypto.exports
|
||||
@@ -102,3 +102,4 @@ krb5_c_prfplus
|
||||
krb5_c_derive_prfplus
|
||||
k5_enctype_to_ssf
|
||||
krb5int_c_deprecated_enctype
|
||||
+k5_hmac_md5
|
||||
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
|
||||
index 42d354a3b5..65ed1d35e7 100644
|
||||
--- a/src/lib/krad/attr.c
|
||||
+++ b/src/lib/krad/attr.c
|
||||
@@ -125,6 +125,23 @@ static const attribute_record attributes[UCHAR_MAX] = {
|
||||
{"NAS-Port-Type", 4, 4, NULL, NULL},
|
||||
{"Port-Limit", 4, 4, NULL, NULL},
|
||||
{"Login-LAT-Port", 1, MAX_ATTRSIZE, NULL, NULL},
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Password-Retry */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Prompt */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Connect-Info */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Configuration-Token */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* EAP-Message */
|
||||
+ {"Message-Authenticator", MD5_DIGEST_SIZE, MD5_DIGEST_SIZE, NULL, NULL},
|
||||
};
|
||||
|
||||
/* Encode User-Password attribute. */
|
||||
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
|
||||
index 6ec031e320..e5457ebfd7 100644
|
||||
--- a/src/lib/krad/attrset.c
|
||||
+++ b/src/lib/krad/attrset.c
|
||||
@@ -164,15 +164,44 @@ krad_attrset_copy(const krad_attrset *set, krad_attrset **copy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Place an encoded attributes into outbuf at position *i. Increment *i by the
|
||||
+ * length of the encoding. */
|
||||
+static krb5_error_code
|
||||
+append_attr(krb5_context ctx, const char *secret,
|
||||
+ const uint8_t *auth, krad_attr type, const krb5_data *data,
|
||||
+ uint8_t outbuf[MAX_ATTRSETSIZE], size_t *i, krb5_boolean *is_fips)
|
||||
+{
|
||||
+ uint8_t buffer[MAX_ATTRSIZE];
|
||||
+ size_t attrlen;
|
||||
+ krb5_error_code retval;
|
||||
+
|
||||
+ retval = kr_attr_encode(ctx, secret, auth, type, data, buffer, &attrlen,
|
||||
+ is_fips);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+
|
||||
+ if (attrlen > MAX_ATTRSETSIZE - *i - 2)
|
||||
+ return EMSGSIZE;
|
||||
+
|
||||
+ outbuf[(*i)++] = type;
|
||||
+ outbuf[(*i)++] = attrlen + 2;
|
||||
+ memcpy(outbuf + *i, buffer, attrlen);
|
||||
+ *i += attrlen;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
krb5_error_code
|
||||
kr_attrset_encode(const krad_attrset *set, const char *secret,
|
||||
- const unsigned char *auth,
|
||||
+ const uint8_t *auth, krb5_boolean add_msgauth,
|
||||
unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
|
||||
krb5_boolean *is_fips)
|
||||
{
|
||||
- unsigned char buffer[MAX_ATTRSIZE];
|
||||
krb5_error_code retval;
|
||||
- size_t i = 0, attrlen;
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+ const uint8_t zeroes[MD5_DIGEST_SIZE] = { 0 };
|
||||
+ krb5_data zerodata;
|
||||
+ size_t i = 0;
|
||||
attr *a;
|
||||
|
||||
if (set == NULL) {
|
||||
@@ -180,19 +209,21 @@ kr_attrset_encode(const krad_attrset *set, const char *secret,
|
||||
return 0;
|
||||
}
|
||||
|
||||
- K5_TAILQ_FOREACH(a, &set->list, list) {
|
||||
- retval = kr_attr_encode(set->ctx, secret, auth, a->type, &a->attr,
|
||||
- buffer, &attrlen, is_fips);
|
||||
- if (retval != 0)
|
||||
+ if (add_msgauth) {
|
||||
+ /* Encode Message-Authenticator as the first attribute, per
|
||||
+ * draft-ietf-radext-deprecating-radius-03 section 5.2. */
|
||||
+ zerodata = make_data((uint8_t *)zeroes, MD5_DIGEST_SIZE);
|
||||
+ retval = append_attr(set->ctx, secret, auth, msgauth_type, &zerodata,
|
||||
+ outbuf, &i, is_fips);
|
||||
+ if (retval)
|
||||
return retval;
|
||||
+ }
|
||||
|
||||
- if (i + attrlen + 2 > MAX_ATTRSETSIZE)
|
||||
- return EMSGSIZE;
|
||||
-
|
||||
- outbuf[i++] = a->type;
|
||||
- outbuf[i++] = attrlen + 2;
|
||||
- memcpy(&outbuf[i], buffer, attrlen);
|
||||
- i += attrlen;
|
||||
+ K5_TAILQ_FOREACH(a, &set->list, list) {
|
||||
+ retval = append_attr(set->ctx, secret, auth, a->type, &a->attr,
|
||||
+ outbuf, &i, is_fips);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
}
|
||||
|
||||
*outlen = i;
|
||||
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
|
||||
index a17b6f39b1..ca66f3ec68 100644
|
||||
--- a/src/lib/krad/internal.h
|
||||
+++ b/src/lib/krad/internal.h
|
||||
@@ -49,6 +49,8 @@
|
||||
#define UCHAR_MAX 255
|
||||
#endif
|
||||
|
||||
+#define MD5_DIGEST_SIZE 16
|
||||
+
|
||||
/* RFC 2865 */
|
||||
#define MAX_ATTRSIZE (UCHAR_MAX - 2)
|
||||
#define MAX_ATTRSETSIZE (KRAD_PACKET_SIZE_MAX - 20)
|
||||
@@ -79,10 +81,11 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
|
||||
krad_attr type, const krb5_data *in,
|
||||
unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
|
||||
|
||||
-/* Encode the attributes into the buffer. */
|
||||
+/* Encode set into outbuf. If add_msgauth is true, include a zeroed
|
||||
+ * Message-Authenticator as the first attribute. */
|
||||
krb5_error_code
|
||||
kr_attrset_encode(const krad_attrset *set, const char *secret,
|
||||
- const unsigned char *auth,
|
||||
+ const uint8_t *auth, krb5_boolean add_msgauth,
|
||||
unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
|
||||
krb5_boolean *is_fips);
|
||||
|
||||
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
|
||||
index c5446b890c..3c1a4d507e 100644
|
||||
--- a/src/lib/krad/packet.c
|
||||
+++ b/src/lib/krad/packet.c
|
||||
@@ -36,6 +36,7 @@
|
||||
typedef unsigned char uchar;
|
||||
|
||||
/* RFC 2865 */
|
||||
+#define MSGAUTH_SIZE (2 + MD5_DIGEST_SIZE)
|
||||
#define OFFSET_CODE 0
|
||||
#define OFFSET_ID 1
|
||||
#define OFFSET_LENGTH 2
|
||||
@@ -222,6 +223,106 @@ packet_set_attrset(krb5_context ctx, const char *secret, krad_packet *pkt)
|
||||
return kr_attrset_decode(ctx, &tmp, secret, pkt_auth(pkt), &pkt->attrset);
|
||||
}
|
||||
|
||||
+/* Determine if a packet requires a Message-Authenticator attribute. */
|
||||
+static inline krb5_boolean
|
||||
+requires_msgauth(const char *secret, krad_code code)
|
||||
+{
|
||||
+ /* If no secret is provided, assume that the transport is a UNIX socket.
|
||||
+ * Message-Authenticator is required only on UDP and TCP connections. */
|
||||
+ if (*secret == '\0')
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /*
|
||||
+ * Per draft-ietf-radext-deprecating-radius-03 sections 5.2.1 and 5.2.4,
|
||||
+ * Message-Authenticator is required in Access-Request packets and all
|
||||
+ * potential responses when UDP or TCP transport is used.
|
||||
+ */
|
||||
+ return code == krad_code_name2num("Access-Request") ||
|
||||
+ code == krad_code_name2num("Access-Reject") ||
|
||||
+ code == krad_code_name2num("Access-Accept") ||
|
||||
+ code == krad_code_name2num("Access-Challenge");
|
||||
+}
|
||||
+
|
||||
+/* Check if the packet has a Message-Authenticator attribute. */
|
||||
+static inline krb5_boolean
|
||||
+has_pkt_msgauth(const krad_packet *pkt)
|
||||
+{
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+
|
||||
+ return krad_attrset_get(pkt->attrset, msgauth_type, 0) != NULL;
|
||||
+}
|
||||
+
|
||||
+/* Return the beginning of the Message-Authenticator attribute in pkt, or NULL
|
||||
+ * if no such attribute is present. */
|
||||
+static const uint8_t *
|
||||
+lookup_msgauth_addr(const krad_packet *pkt)
|
||||
+{
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+ size_t i;
|
||||
+ uint8_t *p;
|
||||
+
|
||||
+ i = OFFSET_ATTR;
|
||||
+ while (i + 2 < pkt->pkt.length) {
|
||||
+ p = (uint8_t *)offset(&pkt->pkt, i);
|
||||
+ if (msgauth_type == *p)
|
||||
+ return p;
|
||||
+ i += p[1];
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Calculate the message authenticator MAC for pkt as specified in RFC 2869
|
||||
+ * section 5.14, placing the result in mac_out. Use the provided authenticator
|
||||
+ * auth, which may be from pkt or from a corresponding request.
|
||||
+ */
|
||||
+static krb5_error_code
|
||||
+calculate_mac(const char *secret, const krad_packet *pkt,
|
||||
+ const uint8_t auth[AUTH_FIELD_SIZE],
|
||||
+ uint8_t mac_out[MD5_DIGEST_SIZE])
|
||||
+{
|
||||
+ uint8_t zeroed_msgauth[MSGAUTH_SIZE];
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+ const uint8_t *msgauth_attr, *msgauth_end, *pkt_end;
|
||||
+ krb5_crypto_iov input[5];
|
||||
+ krb5_data ksecr, mac;
|
||||
+
|
||||
+ msgauth_attr = lookup_msgauth_addr(pkt);
|
||||
+ if (msgauth_attr == NULL)
|
||||
+ return EINVAL;
|
||||
+ msgauth_end = msgauth_attr + MSGAUTH_SIZE;
|
||||
+ pkt_end = (const uint8_t *)pkt->pkt.data + pkt->pkt.length;
|
||||
+
|
||||
+ /* Read code, id, and length from the packet. */
|
||||
+ input[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[0].data = make_data(pkt->pkt.data, OFFSET_AUTH);
|
||||
+
|
||||
+ /* Read the provided authenticator. */
|
||||
+ input[1].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[1].data = make_data((uint8_t *)auth, AUTH_FIELD_SIZE);
|
||||
+
|
||||
+ /* Read any attributes before Message-Authenticator. */
|
||||
+ input[2].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[2].data = make_data(pkt_attr(pkt), msgauth_attr - pkt_attr(pkt));
|
||||
+
|
||||
+ /* Read Message-Authenticator with the data bytes all set to zero, per RFC
|
||||
+ * 2869 section 5.14. */
|
||||
+ zeroed_msgauth[0] = msgauth_type;
|
||||
+ zeroed_msgauth[1] = MSGAUTH_SIZE;
|
||||
+ memset(zeroed_msgauth + 2, 0, MD5_DIGEST_SIZE);
|
||||
+ input[3].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[3].data = make_data(zeroed_msgauth, MSGAUTH_SIZE);
|
||||
+
|
||||
+ /* Read any attributes after Message-Authenticator. */
|
||||
+ input[4].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[4].data = make_data((uint8_t *)msgauth_end, pkt_end - msgauth_end);
|
||||
+
|
||||
+ mac = make_data(mac_out, MD5_DIGEST_SIZE);
|
||||
+ ksecr = string2data((char *)secret);
|
||||
+ return k5_hmac_md5(&ksecr, input, 5, &mac);
|
||||
+}
|
||||
+
|
||||
ssize_t
|
||||
krad_packet_bytes_needed(const krb5_data *buffer)
|
||||
{
|
||||
@@ -255,6 +356,7 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
|
||||
krad_packet *pkt;
|
||||
uchar id;
|
||||
size_t attrset_len;
|
||||
+ krb5_boolean msgauth_required;
|
||||
|
||||
pkt = packet_new();
|
||||
if (pkt == NULL) {
|
||||
@@ -274,9 +376,13 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
||||
+ /* Determine if Message-Authenticator is required. */
|
||||
+ msgauth_required = (*secret != '\0' &&
|
||||
+ code == krad_code_name2num("Access-Request"));
|
||||
+
|
||||
/* Encode the attributes. */
|
||||
- retval = kr_attrset_encode(set, secret, pkt_auth(pkt), pkt_attr(pkt),
|
||||
- &attrset_len, &pkt->is_fips);
|
||||
+ retval = kr_attrset_encode(set, secret, pkt_auth(pkt), msgauth_required,
|
||||
+ pkt_attr(pkt), &attrset_len, &pkt->is_fips);
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
||||
@@ -285,6 +391,13 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
|
||||
pkt_code_set(pkt, code);
|
||||
pkt_len_set(pkt, pkt->pkt.length);
|
||||
|
||||
+ if (msgauth_required) {
|
||||
+ /* Calculate and set the Message-Authenticator MAC. */
|
||||
+ retval = calculate_mac(secret, pkt, pkt_auth(pkt), pkt_attr(pkt) + 2);
|
||||
+ if (retval != 0)
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
/* Copy the attrset for future use. */
|
||||
retval = packet_set_attrset(ctx, secret, pkt);
|
||||
if (retval != 0)
|
||||
@@ -307,14 +420,19 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
|
||||
krb5_error_code retval;
|
||||
krad_packet *pkt;
|
||||
size_t attrset_len;
|
||||
+ krb5_boolean msgauth_required;
|
||||
|
||||
pkt = packet_new();
|
||||
if (pkt == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
+ /* Determine if Message-Authenticator is required. */
|
||||
+ msgauth_required = requires_msgauth(secret, code);
|
||||
+
|
||||
/* Encode the attributes. */
|
||||
- retval = kr_attrset_encode(set, secret, pkt_auth(request), pkt_attr(pkt),
|
||||
- &attrset_len, &pkt->is_fips);
|
||||
+ retval = kr_attrset_encode(set, secret, pkt_auth(request),
|
||||
+ msgauth_required, pkt_attr(pkt), &attrset_len,
|
||||
+ &pkt->is_fips);
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
||||
@@ -330,6 +448,18 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
||||
+ if (msgauth_required) {
|
||||
+ /*
|
||||
+ * Calculate and replace the Message-Authenticator MAC. Per RFC 2869
|
||||
+ * section 5.14, use the authenticator from the request, not from the
|
||||
+ * response.
|
||||
+ */
|
||||
+ retval = calculate_mac(secret, pkt, pkt_auth(request),
|
||||
+ pkt_attr(pkt) + 2);
|
||||
+ if (retval != 0)
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
/* Copy the attrset for future use. */
|
||||
retval = packet_set_attrset(ctx, secret, pkt);
|
||||
if (retval != 0)
|
||||
@@ -343,6 +473,34 @@ error:
|
||||
return retval;
|
||||
}
|
||||
|
||||
+/* Verify the Message-Authenticator value in pkt, using the provided
|
||||
+ * authenticator (which may be from pkt or from a corresponding request). */
|
||||
+static krb5_error_code
|
||||
+verify_msgauth(const char *secret, const krad_packet *pkt,
|
||||
+ const uint8_t auth[AUTH_FIELD_SIZE])
|
||||
+{
|
||||
+ uint8_t mac[MD5_DIGEST_SIZE];
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+ const krb5_data *msgauth;
|
||||
+ krb5_error_code retval;
|
||||
+
|
||||
+ msgauth = krad_packet_get_attr(pkt, msgauth_type, 0);
|
||||
+ if (msgauth == NULL)
|
||||
+ return ENODATA;
|
||||
+
|
||||
+ retval = calculate_mac(secret, pkt, auth, mac);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+
|
||||
+ if (msgauth->length != MD5_DIGEST_SIZE)
|
||||
+ return EMSGSIZE;
|
||||
+
|
||||
+ if (k5_bcmp(mac, msgauth->data, MD5_DIGEST_SIZE) != 0)
|
||||
+ return EBADMSG;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Decode a packet. */
|
||||
static krb5_error_code
|
||||
decode_packet(krb5_context ctx, const char *secret, const krb5_data *buffer,
|
||||
@@ -394,21 +552,35 @@ krad_packet_decode_request(krb5_context ctx, const char *secret,
|
||||
krad_packet **reqpkt)
|
||||
{
|
||||
const krad_packet *tmp = NULL;
|
||||
+ krad_packet *req;
|
||||
krb5_error_code retval;
|
||||
|
||||
- retval = decode_packet(ctx, secret, buffer, reqpkt);
|
||||
- if (cb != NULL && retval == 0) {
|
||||
+ retval = decode_packet(ctx, secret, buffer, &req);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+
|
||||
+ /* Verify Message-Authenticator if present. */
|
||||
+ if (has_pkt_msgauth(req)) {
|
||||
+ retval = verify_msgauth(secret, req, pkt_auth(req));
|
||||
+ if (retval) {
|
||||
+ krad_packet_free(req);
|
||||
+ return retval;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (cb != NULL) {
|
||||
for (tmp = (*cb)(data, FALSE); tmp != NULL; tmp = (*cb)(data, FALSE)) {
|
||||
if (pkt_id_get(*reqpkt) == pkt_id_get(tmp))
|
||||
break;
|
||||
}
|
||||
- }
|
||||
|
||||
- if (cb != NULL && (retval != 0 || tmp != NULL))
|
||||
- (*cb)(data, TRUE);
|
||||
+ if (tmp != NULL)
|
||||
+ (*cb)(data, TRUE);
|
||||
+ }
|
||||
|
||||
+ *reqpkt = req;
|
||||
*duppkt = tmp;
|
||||
- return retval;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -435,9 +607,17 @@ krad_packet_decode_response(krb5_context ctx, const char *secret,
|
||||
break;
|
||||
}
|
||||
|
||||
- /* If the authenticator matches, then the response is valid. */
|
||||
- if (memcmp(pkt_auth(*rsppkt), auth, sizeof(auth)) == 0)
|
||||
- break;
|
||||
+ /* Verify the response authenticator. */
|
||||
+ if (k5_bcmp(pkt_auth(*rsppkt), auth, sizeof(auth)) != 0)
|
||||
+ continue;
|
||||
+
|
||||
+ /* Verify Message-Authenticator if present. */
|
||||
+ if (has_pkt_msgauth(*rsppkt)) {
|
||||
+ if (verify_msgauth(secret, *rsppkt, pkt_auth(tmp)) != 0)
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/lib/krad/t_attrset.c b/src/lib/krad/t_attrset.c
|
||||
index 4cdb8b7d8e..f9c66509bd 100644
|
||||
--- a/src/lib/krad/t_attrset.c
|
||||
+++ b/src/lib/krad/t_attrset.c
|
||||
@@ -63,7 +63,7 @@ main(void)
|
||||
noerror(krad_attrset_add(set, krad_attr_name2num("User-Password"), &tmp));
|
||||
|
||||
/* Encode attrset. */
|
||||
- noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len,
|
||||
+ noerror(kr_attrset_encode(set, "foo", auth, FALSE, buffer, &encode_len,
|
||||
&is_fips));
|
||||
krad_attrset_free(set);
|
||||
|
||||
diff --git a/src/lib/krad/t_daemon.py b/src/lib/krad/t_daemon.py
|
||||
index 4a3de079c7..647d4894eb 100755
|
||||
--- a/src/lib/krad/t_daemon.py
|
||||
+++ b/src/lib/krad/t_daemon.py
|
||||
@@ -40,6 +40,7 @@ DICTIONARY = """
|
||||
ATTRIBUTE\tUser-Name\t1\tstring
|
||||
ATTRIBUTE\tUser-Password\t2\toctets
|
||||
ATTRIBUTE\tNAS-Identifier\t32\tstring
|
||||
+ATTRIBUTE\tMessage-Authenticator\t80\toctets
|
||||
"""
|
||||
|
||||
class TestServer(server.Server):
|
||||
@@ -52,7 +53,7 @@ class TestServer(server.Server):
|
||||
if key == "User-Password":
|
||||
passwd = [pkt.PwDecrypt(x) for x in pkt[key]]
|
||||
|
||||
- reply = self.CreateReplyPacket(pkt)
|
||||
+ reply = self.CreateReplyPacket(pkt, message_authenticator=True)
|
||||
if passwd == ['accept']:
|
||||
reply.code = packet.AccessAccept
|
||||
else:
|
||||
diff --git a/src/lib/krad/t_packet.c b/src/lib/krad/t_packet.c
|
||||
index c22489144f..104b6507a2 100644
|
||||
--- a/src/lib/krad/t_packet.c
|
||||
+++ b/src/lib/krad/t_packet.c
|
||||
@@ -172,6 +172,9 @@ main(int argc, const char **argv)
|
||||
krb5_data username, password;
|
||||
krb5_boolean auth = FALSE;
|
||||
krb5_context ctx;
|
||||
+ const krad_packet *dupreq;
|
||||
+ const krb5_data *encpkt;
|
||||
+ krad_packet *decreq;
|
||||
|
||||
username = string2data("testUser");
|
||||
|
||||
@@ -184,9 +187,17 @@ main(int argc, const char **argv)
|
||||
|
||||
password = string2data("accept");
|
||||
noerror(make_packet(ctx, &username, &password, &packets[ACCEPT_PACKET]));
|
||||
+ encpkt = krad_packet_encode(packets[ACCEPT_PACKET]);
|
||||
+ noerror(krad_packet_decode_request(ctx, "foo", encpkt, NULL, NULL,
|
||||
+ &dupreq, &decreq));
|
||||
+ krad_packet_free(decreq);
|
||||
|
||||
password = string2data("reject");
|
||||
noerror(make_packet(ctx, &username, &password, &packets[REJECT_PACKET]));
|
||||
+ encpkt = krad_packet_encode(packets[REJECT_PACKET]);
|
||||
+ noerror(krad_packet_decode_request(ctx, "foo", encpkt, NULL, NULL,
|
||||
+ &dupreq, &decreq));
|
||||
+ krad_packet_free(decreq);
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
diff --git a/src/tests/t_otp.py b/src/tests/t_otp.py
|
||||
index c3b820a411..dd5cdc5c26 100755
|
||||
--- a/src/tests/t_otp.py
|
||||
+++ b/src/tests/t_otp.py
|
||||
@@ -49,6 +49,7 @@ ATTRIBUTE User-Name 1 string
|
||||
ATTRIBUTE User-Password 2 octets
|
||||
ATTRIBUTE Service-Type 6 integer
|
||||
ATTRIBUTE NAS-Identifier 32 string
|
||||
+ATTRIBUTE Message-Authenticator 80 octets
|
||||
'''
|
||||
|
||||
class RadiusDaemon(Process):
|
||||
@@ -97,6 +98,8 @@ class RadiusDaemon(Process):
|
||||
reply.code = packet.AccessReject
|
||||
replyq['reply'] = False
|
||||
|
||||
+ reply.add_message_authenticator()
|
||||
+
|
||||
outq.put(replyq)
|
||||
if addr is None:
|
||||
sock.send(reply.ReplyPacket())
|
||||
--
|
||||
2.46.0
|
||||
|
1027
SOURCES/0027-PKINIT-ECDH-support.patch
Normal file
1027
SOURCES/0027-PKINIT-ECDH-support.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,78 @@
|
||||
From b61ba0bb29d80811d2e0efc893c2932c57b2c807 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Wed, 21 Jun 2023 18:27:11 +0200
|
||||
Subject: [PATCH] Add ecdsa-with-sha512/256 to supportedCMSTypes
|
||||
|
||||
Elliptic curve certificates are already supported for PKINIT
|
||||
pre-authentication, but their associated signature types aren't
|
||||
advertized. Add ecdsa-with-sha512 and ecdsa-with-sha256 OIDs to the
|
||||
supportedCMSTypes list sent by the client.
|
||||
|
||||
[ghudson@mit.edu: edited commit message]
|
||||
|
||||
ticket: 9100 (new)
|
||||
(cherry picked from commit 9913e5c92c4e5cb76d6ae58386f744766d2e6454)
|
||||
---
|
||||
src/plugins/preauth/pkinit/pkinit_constants.c | 38 +++++++++++++++++++
|
||||
1 file changed, 38 insertions(+)
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_constants.c b/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||
index 10f8688ec2..905e90d29c 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||
@@ -64,14 +64,52 @@ static char sha512WithRSAEncr_oid[9] = {
|
||||
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d
|
||||
};
|
||||
|
||||
+/* RFC 3279 ecdsa-with-SHA1: iso(1) member-body(2) us(840) ansi-X9-62(10045)
|
||||
+ * signatures(4) 1 */
|
||||
+static char ecdsaWithSha1_oid[] = {
|
||||
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01
|
||||
+};
|
||||
+
|
||||
+/* RFC 5758 ecdsa-with-SHA256: iso(1) member-body(2) us(840) ansi-X9-62(10045)
|
||||
+ * signatures(4) ecdsa-with-SHA2(3) 2 */
|
||||
+static char ecdsaWithSha256_oid[] = {
|
||||
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02
|
||||
+};
|
||||
+
|
||||
+/* RFC 5758 ecdsa-with-SHA384: iso(1) member-body(2) us(840) ansi-X9-62(10045)
|
||||
+ * signatures(4) ecdsa-with-SHA2(3) 3 */
|
||||
+static char ecdsaWithSha384_oid[] = {
|
||||
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03
|
||||
+};
|
||||
+
|
||||
+/* RFC 5758 ecdsa-with-SHA512: iso(1) member-body(2) us(840) ansi-X9-62(10045)
|
||||
+ * signatures(4) ecdsa-with-SHA2(3) 4 */
|
||||
+static char ecdsaWithSha512_oid[] = {
|
||||
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04
|
||||
+};
|
||||
+
|
||||
const krb5_data sha256WithRSAEncr_id = {
|
||||
KV5M_DATA, sizeof(sha256WithRSAEncr_oid), sha256WithRSAEncr_oid
|
||||
};
|
||||
const krb5_data sha512WithRSAEncr_id = {
|
||||
KV5M_DATA, sizeof(sha512WithRSAEncr_oid), sha512WithRSAEncr_oid
|
||||
};
|
||||
+const krb5_data ecdsaWithSha1_id = {
|
||||
+ KV5M_DATA, sizeof(ecdsaWithSha1_oid), ecdsaWithSha1_oid
|
||||
+};
|
||||
+const krb5_data ecdsaWithSha256_id = {
|
||||
+ KV5M_DATA, sizeof(ecdsaWithSha256_oid), ecdsaWithSha256_oid
|
||||
+};
|
||||
+const krb5_data ecdsaWithSha384_id = {
|
||||
+ KV5M_DATA, sizeof(ecdsaWithSha384_oid), ecdsaWithSha384_oid
|
||||
+};
|
||||
+const krb5_data ecdsaWithSha512_id = {
|
||||
+ KV5M_DATA, sizeof(ecdsaWithSha512_oid), ecdsaWithSha512_oid
|
||||
+};
|
||||
|
||||
krb5_data const * const supported_cms_algs[] = {
|
||||
+ &ecdsaWithSha512_id,
|
||||
+ &ecdsaWithSha256_id,
|
||||
&sha512WithRSAEncr_id,
|
||||
&sha256WithRSAEncr_id,
|
||||
NULL
|
||||
--
|
||||
2.47.1
|
||||
|
264
SOURCES/0029-Get-rid-of-pkinit_crypto_openssl.h.patch
Normal file
264
SOURCES/0029-Get-rid-of-pkinit_crypto_openssl.h.patch
Normal file
@ -0,0 +1,264 @@
|
||||
From 47075e6033f6d000a588f7b35850f685f6fbfca5 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Sun, 30 Jul 2023 01:07:38 -0400
|
||||
Subject: [PATCH] Get rid of pkinit_crypto_openssl.h
|
||||
|
||||
Fold pkinit_crypto_openssl.h into the one source file where it was
|
||||
used. Also clean up the include of <arpa/inet.h>, as htonl() is no
|
||||
longer used after commit 1c87ce6c44a9de0824580a2d72a8a202237e01f4.
|
||||
|
||||
(cherry picked from commit b3352945fb8836f8b4095e0b8aad04b54aca3152)
|
||||
---
|
||||
src/plugins/preauth/pkinit/deps | 2 +-
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 85 +++++++++++-
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.h | 121 ------------------
|
||||
3 files changed, 83 insertions(+), 125 deletions(-)
|
||||
delete mode 100644 src/plugins/preauth/pkinit/pkinit_crypto_openssl.h
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/deps b/src/plugins/preauth/pkinit/deps
|
||||
index 58320aa801..b6f4476fe8 100644
|
||||
--- a/src/plugins/preauth/pkinit/deps
|
||||
+++ b/src/plugins/preauth/pkinit/deps
|
||||
@@ -112,4 +112,4 @@ pkinit_crypto_openssl.so pkinit_crypto_openssl.po $(OUTPRE)pkinit_crypto_openssl
|
||||
$(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
|
||||
$(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
|
||||
pkcs11.h pkinit.h pkinit_accessor.h pkinit_crypto.h \
|
||||
- pkinit_crypto_openssl.c pkinit_crypto_openssl.h pkinit_trace.h
|
||||
+ pkinit_crypto_openssl.c pkinit_trace.h
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index 75036f8655..8d1216724c 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -30,20 +30,99 @@
|
||||
*/
|
||||
|
||||
#include "k5-int.h"
|
||||
-#include "pkinit_crypto_openssl.h"
|
||||
#include "k5-buf.h"
|
||||
#include "k5-err.h"
|
||||
#include "k5-hex.h"
|
||||
-#include <unistd.h>
|
||||
+#include "pkinit.h"
|
||||
#include <dirent.h>
|
||||
-#include <arpa/inet.h>
|
||||
|
||||
+#include <openssl/bn.h>
|
||||
+#include <openssl/dh.h>
|
||||
+#include <openssl/x509.h>
|
||||
+#include <openssl/pkcs7.h>
|
||||
+#include <openssl/pkcs12.h>
|
||||
+#include <openssl/obj_mac.h>
|
||||
+#include <openssl/x509v3.h>
|
||||
+#include <openssl/err.h>
|
||||
+#include <openssl/evp.h>
|
||||
+#include <openssl/sha.h>
|
||||
+#include <openssl/asn1.h>
|
||||
+#include <openssl/pem.h>
|
||||
+#include <openssl/asn1t.h>
|
||||
+#include <openssl/cms.h>
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/kdf.h>
|
||||
+#include <openssl/decoder.h>
|
||||
#include <openssl/params.h>
|
||||
#endif
|
||||
|
||||
+#define DN_BUF_LEN 256
|
||||
+#define MAX_CREDS_ALLOWED 20
|
||||
+
|
||||
+struct _pkinit_cred_info {
|
||||
+ char *name;
|
||||
+ X509 *cert;
|
||||
+ EVP_PKEY *key;
|
||||
+#ifndef WITHOUT_PKCS11
|
||||
+ CK_BYTE_PTR cert_id;
|
||||
+ int cert_id_len;
|
||||
+#endif
|
||||
+};
|
||||
+typedef struct _pkinit_cred_info *pkinit_cred_info;
|
||||
+
|
||||
+struct _pkinit_identity_crypto_context {
|
||||
+ pkinit_cred_info creds[MAX_CREDS_ALLOWED+1];
|
||||
+ STACK_OF(X509) *my_certs; /* available user certs */
|
||||
+ char *identity; /* identity name for user cert */
|
||||
+ int cert_index; /* cert to use out of available certs*/
|
||||
+ EVP_PKEY *my_key; /* available user keys if in filesystem */
|
||||
+ STACK_OF(X509) *trustedCAs; /* available trusted ca certs */
|
||||
+ STACK_OF(X509) *intermediateCAs; /* available intermediate ca certs */
|
||||
+ STACK_OF(X509_CRL) *revoked; /* available crls */
|
||||
+ int pkcs11_method;
|
||||
+ krb5_prompter_fct prompter;
|
||||
+ void *prompter_data;
|
||||
+#ifndef WITHOUT_PKCS11
|
||||
+ char *p11_module_name;
|
||||
+ CK_SLOT_ID slotid;
|
||||
+ char *token_label;
|
||||
+ char *cert_label;
|
||||
+ /* These are crypto-specific. */
|
||||
+ struct plugin_file_handle *p11_module;
|
||||
+ CK_SESSION_HANDLE session;
|
||||
+ CK_FUNCTION_LIST_PTR p11;
|
||||
+ uint8_t *cert_id;
|
||||
+ size_t cert_id_len;
|
||||
+ CK_MECHANISM_TYPE mech;
|
||||
+#endif
|
||||
+ krb5_boolean defer_id_prompt;
|
||||
+ pkinit_deferred_id *deferred_ids;
|
||||
+};
|
||||
+
|
||||
+struct _pkinit_plg_crypto_context {
|
||||
+ EVP_PKEY *dh_1024;
|
||||
+ EVP_PKEY *dh_2048;
|
||||
+ EVP_PKEY *dh_4096;
|
||||
+ EVP_PKEY *ec_p256;
|
||||
+ EVP_PKEY *ec_p384;
|
||||
+ EVP_PKEY *ec_p521;
|
||||
+ ASN1_OBJECT *id_pkinit_authData;
|
||||
+ ASN1_OBJECT *id_pkinit_DHKeyData;
|
||||
+ ASN1_OBJECT *id_pkinit_rkeyData;
|
||||
+ ASN1_OBJECT *id_pkinit_san;
|
||||
+ ASN1_OBJECT *id_ms_san_upn;
|
||||
+ ASN1_OBJECT *id_pkinit_KPClientAuth;
|
||||
+ ASN1_OBJECT *id_pkinit_KPKdc;
|
||||
+ ASN1_OBJECT *id_ms_kp_sc_logon;
|
||||
+ ASN1_OBJECT *id_kp_serverAuth;
|
||||
+};
|
||||
+
|
||||
+struct _pkinit_req_crypto_context {
|
||||
+ X509 *received_cert;
|
||||
+ EVP_PKEY *client_pkey;
|
||||
+};
|
||||
+
|
||||
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
|
||||
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h
|
||||
deleted file mode 100644
|
||||
index b7a3358800..0000000000
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h
|
||||
+++ /dev/null
|
||||
@@ -1,121 +0,0 @@
|
||||
-/*
|
||||
- * COPYRIGHT (C) 2006,2007
|
||||
- * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
|
||||
- * ALL RIGHTS RESERVED
|
||||
- *
|
||||
- * Permission is granted to use, copy, create derivative works
|
||||
- * and redistribute this software and such derivative works
|
||||
- * for any purpose, so long as the name of The University of
|
||||
- * Michigan is not used in any advertising or publicity
|
||||
- * pertaining to the use of distribution of this software
|
||||
- * without specific, written prior authorization. If the
|
||||
- * above copyright notice or any other identification of the
|
||||
- * University of Michigan is included in any copy of any
|
||||
- * portion of this software, then the disclaimer below must
|
||||
- * also be included.
|
||||
- *
|
||||
- * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
|
||||
- * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
|
||||
- * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
|
||||
- * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
- * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
|
||||
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||
- * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
|
||||
- * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
|
||||
- * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
|
||||
- * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
|
||||
- * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
|
||||
- * SUCH DAMAGES.
|
||||
- */
|
||||
-
|
||||
-#ifndef _PKINIT_CRYPTO_OPENSSL_H
|
||||
-#define _PKINIT_CRYPTO_OPENSSL_H
|
||||
-
|
||||
-#include "pkinit.h"
|
||||
-
|
||||
-#include <openssl/bn.h>
|
||||
-#include <openssl/dh.h>
|
||||
-#include <openssl/x509.h>
|
||||
-#include <openssl/pkcs7.h>
|
||||
-#include <openssl/pkcs12.h>
|
||||
-#include <openssl/obj_mac.h>
|
||||
-#include <openssl/x509v3.h>
|
||||
-#include <openssl/err.h>
|
||||
-#include <openssl/evp.h>
|
||||
-#include <openssl/sha.h>
|
||||
-#include <openssl/asn1.h>
|
||||
-#include <openssl/pem.h>
|
||||
-#include <openssl/asn1t.h>
|
||||
-#include <openssl/cms.h>
|
||||
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
-#include <openssl/core_names.h>
|
||||
-#include <openssl/decoder.h>
|
||||
-#endif
|
||||
-
|
||||
-#define DN_BUF_LEN 256
|
||||
-#define MAX_CREDS_ALLOWED 20
|
||||
-
|
||||
-struct _pkinit_cred_info {
|
||||
- char *name;
|
||||
- X509 *cert;
|
||||
- EVP_PKEY *key;
|
||||
-#ifndef WITHOUT_PKCS11
|
||||
- CK_BYTE_PTR cert_id;
|
||||
- int cert_id_len;
|
||||
-#endif
|
||||
-};
|
||||
-typedef struct _pkinit_cred_info * pkinit_cred_info;
|
||||
-
|
||||
-struct _pkinit_identity_crypto_context {
|
||||
- pkinit_cred_info creds[MAX_CREDS_ALLOWED+1];
|
||||
- STACK_OF(X509) *my_certs; /* available user certs */
|
||||
- char *identity; /* identity name for user cert */
|
||||
- int cert_index; /* cert to use out of available certs*/
|
||||
- EVP_PKEY *my_key; /* available user keys if in filesystem */
|
||||
- STACK_OF(X509) *trustedCAs; /* available trusted ca certs */
|
||||
- STACK_OF(X509) *intermediateCAs; /* available intermediate ca certs */
|
||||
- STACK_OF(X509_CRL) *revoked; /* available crls */
|
||||
- int pkcs11_method;
|
||||
- krb5_prompter_fct prompter;
|
||||
- void *prompter_data;
|
||||
-#ifndef WITHOUT_PKCS11
|
||||
- char *p11_module_name;
|
||||
- CK_SLOT_ID slotid;
|
||||
- char *token_label;
|
||||
- char *cert_label;
|
||||
- /* These are crypto-specific */
|
||||
- struct plugin_file_handle *p11_module;
|
||||
- CK_SESSION_HANDLE session;
|
||||
- CK_FUNCTION_LIST_PTR p11;
|
||||
- uint8_t *cert_id;
|
||||
- size_t cert_id_len;
|
||||
- CK_MECHANISM_TYPE mech;
|
||||
-#endif
|
||||
- krb5_boolean defer_id_prompt;
|
||||
- pkinit_deferred_id *deferred_ids;
|
||||
-};
|
||||
-
|
||||
-struct _pkinit_plg_crypto_context {
|
||||
- EVP_PKEY *dh_1024;
|
||||
- EVP_PKEY *dh_2048;
|
||||
- EVP_PKEY *dh_4096;
|
||||
- EVP_PKEY *ec_p256;
|
||||
- EVP_PKEY *ec_p384;
|
||||
- EVP_PKEY *ec_p521;
|
||||
- ASN1_OBJECT *id_pkinit_authData;
|
||||
- ASN1_OBJECT *id_pkinit_DHKeyData;
|
||||
- ASN1_OBJECT *id_pkinit_rkeyData;
|
||||
- ASN1_OBJECT *id_pkinit_san;
|
||||
- ASN1_OBJECT *id_ms_san_upn;
|
||||
- ASN1_OBJECT *id_pkinit_KPClientAuth;
|
||||
- ASN1_OBJECT *id_pkinit_KPKdc;
|
||||
- ASN1_OBJECT *id_ms_kp_sc_logon;
|
||||
- ASN1_OBJECT *id_kp_serverAuth;
|
||||
-};
|
||||
-
|
||||
-struct _pkinit_req_crypto_context {
|
||||
- X509 *received_cert;
|
||||
- EVP_PKEY *client_pkey;
|
||||
-};
|
||||
-
|
||||
-#endif /* _PKINIT_CRYPTO_OPENSSL_H */
|
||||
--
|
||||
2.47.1
|
||||
|
157
SOURCES/0030-Use-SoftHSMv2-for-PKCS11-PKINIT-tests.patch
Normal file
157
SOURCES/0030-Use-SoftHSMv2-for-PKCS11-PKINIT-tests.patch
Normal file
@ -0,0 +1,157 @@
|
||||
From 7ffb7ce9de02121622d79227105f0028e5c6ad11 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Mon, 26 Feb 2024 19:03:38 -0500
|
||||
Subject: [PATCH] Use SoftHSMv2 for PKCS11 PKINIT tests
|
||||
|
||||
Instead of softpkcs11, use SoftHSMv2 to mock the PKCS11 token for
|
||||
PKINIT tests. Use pkcs11-tool from OpenSC to initialize the token and
|
||||
import a certificate and key. SoftHSM does not support PIN-less
|
||||
tokens (see https://github.com/opendnssec/SoftHSMv2/issues/480) so
|
||||
remove that test for now.
|
||||
|
||||
(cherry picked from commit 8ab61608236883fdc5c2d43f4bd1ff2094401d19)
|
||||
---
|
||||
.github/workflows/build.yml | 2 +-
|
||||
src/tests/t_pkinit.py | 82 ++++++++++++++++++++-----------------
|
||||
2 files changed, 45 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
|
||||
index 68a4788adb..d7ae86b150 100644
|
||||
--- a/.github/workflows/build.yml
|
||||
+++ b/.github/workflows/build.yml
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
if: startsWith(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
- sudo apt-get install -y bison gettext keyutils ldap-utils libcmocka-dev libldap2-dev libkeyutils-dev libsasl2-dev libssl-dev python3-kdcproxy python3-pip slapd tcsh
|
||||
+ sudo apt-get install -y bison gettext keyutils ldap-utils libcmocka-dev libldap2-dev libkeyutils-dev libsasl2-dev libssl-dev python3-kdcproxy python3-pip slapd tcsh softhsm2 opensc
|
||||
pip3 install pyrad
|
||||
- name: Build
|
||||
env:
|
||||
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
|
||||
index f8f2debc1b..4435746429 100755
|
||||
--- a/src/tests/t_pkinit.py
|
||||
+++ b/src/tests/t_pkinit.py
|
||||
@@ -1,11 +1,10 @@
|
||||
from k5test import *
|
||||
+import re
|
||||
|
||||
# Skip this test if pkinit wasn't built.
|
||||
if not pkinit_enabled:
|
||||
skip_rest('PKINIT tests', 'PKINIT module not built')
|
||||
|
||||
-soft_pkcs11 = os.path.join(buildtop, 'tests', 'softpkcs11', 'softpkcs11.so')
|
||||
-
|
||||
# Construct a krb5.conf fragment configuring pkinit.
|
||||
user_pem = os.path.join(pkinit_certs, 'user.pem')
|
||||
privkey_pem = os.path.join(pkinit_certs, 'privkey.pem')
|
||||
@@ -55,9 +54,6 @@ 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
|
||||
-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(kdc_conf=alias_kdc_conf, create_kdb=False, pkinit=True)
|
||||
@@ -389,53 +385,63 @@ realm.klist(realm.user_princ)
|
||||
realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=,'],
|
||||
expected_code=1, expected_msg='Preauthentication failed while')
|
||||
|
||||
-softpkcs11rc = os.path.join(os.getcwd(), 'testdir', 'soft-pkcs11.rc')
|
||||
-realm.env['SOFTPKCS11RC'] = softpkcs11rc
|
||||
+softhsm2 = '/usr/lib/softhsm/libsofthsm2.so'
|
||||
+if not os.path.exists(softhsm2):
|
||||
+ skip_rest('PKCS11 tests', 'SoftHSMv2 required')
|
||||
+pkcs11_tool = which('pkcs11-tool')
|
||||
+if not pkcs11_tool:
|
||||
+ skip_rest('PKCS11 tests', 'pkcs11-tool from OpenSC required')
|
||||
+tool_cmd = [pkcs11_tool, '--module', softhsm2]
|
||||
+
|
||||
+# Prepare a SoftHSM token.
|
||||
+softhsm2_conf = os.path.join(realm.testdir, 'softhsm2.conf')
|
||||
+softhsm2_tokens = os.path.join(realm.testdir, 'tokens')
|
||||
+os.mkdir(softhsm2_tokens)
|
||||
+realm.env['SOFTHSM2_CONF'] = softhsm2_conf
|
||||
+with open(softhsm2_conf, 'w') as f:
|
||||
+ f.write('directories.tokendir = %s\n' % softhsm2_tokens)
|
||||
+realm.run(tool_cmd + ['--init-token', '--label', 'user',
|
||||
+ '--so-pin', 'sopin', '--init-pin', '--pin', 'userpin'])
|
||||
+realm.run(tool_cmd + ['-w', user_pem, '-y', 'cert'])
|
||||
+realm.run(tool_cmd + ['-w', privkey_pem, '-y', 'privkey',
|
||||
+ '-l', '--pin', 'userpin'])
|
||||
+
|
||||
+# Extract the slot ID generated by SoftHSM.
|
||||
+out = realm.run(tool_cmd + ['-L'])
|
||||
+m = re.search(r'slot ID 0x([0-9a-f]+)\n', out)
|
||||
+if not m:
|
||||
+ fail('could not extract slot ID from SoftHSM token')
|
||||
+slot_id = int(m.group(1), 16)
|
||||
+
|
||||
+p11_attr = 'X509_user_identity=PKCS11:' + softhsm2
|
||||
+p11_token_identity = ('PKCS11:module_name=%s:slotid=%d:token=user' %
|
||||
+ (softhsm2, slot_id))
|
||||
|
||||
-# PKINIT with PKCS11: identity, with no need for a PIN.
|
||||
-mark('PKCS11 identity, no PIN')
|
||||
-conf = open(softpkcs11rc, 'w')
|
||||
-conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem, privkey_pem))
|
||||
-conf.close()
|
||||
-# Expect to succeed without having to supply any more information.
|
||||
-realm.kinit(realm.user_princ,
|
||||
- flags=['-X', 'X509_user_identity=%s' % p11_identity])
|
||||
+mark('PKCS11 identity, with PIN (prompter)')
|
||||
+realm.kinit(realm.user_princ, flags=['-X', p11_attr], password='userpin')
|
||||
realm.klist(realm.user_princ)
|
||||
realm.run([kvno, realm.host_princ])
|
||||
|
||||
-# PKINIT with PKCS11: identity, with a PIN supplied by the prompter.
|
||||
-mark('PKCS11 identity, with PIN (prompter)')
|
||||
-os.remove(softpkcs11rc)
|
||||
-conf = open(softpkcs11rc, 'w')
|
||||
-conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem,
|
||||
- privkey_enc_pem))
|
||||
-conf.close()
|
||||
-# Expect failure if the responder does nothing, and there's no prompter
|
||||
+mark('PKCS11 identity, unavailable PIN')
|
||||
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity,
|
||||
- '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ],
|
||||
- expected_code=2)
|
||||
-realm.kinit(realm.user_princ,
|
||||
- flags=['-X', 'X509_user_identity=%s' % p11_identity],
|
||||
- password='encrypted')
|
||||
-realm.klist(realm.user_princ)
|
||||
-realm.run([kvno, realm.host_princ])
|
||||
+ '-X', p11_attr, realm.user_princ], expected_code=2)
|
||||
|
||||
-# Supply the wrong PIN.
|
||||
mark('PKCS11 identity, wrong PIN')
|
||||
expected_trace = ('PKINIT client has no configured identity; giving up',)
|
||||
realm.kinit(realm.user_princ,
|
||||
- flags=['-X', 'X509_user_identity=%s' % p11_identity],
|
||||
+ flags=['-X', p11_attr],
|
||||
password='wrong', expected_code=1, expected_trace=expected_trace)
|
||||
|
||||
# PKINIT with PKCS11: identity, with a PIN supplied by the responder.
|
||||
-# Supply the response in raw form.
|
||||
+# Supply the response in raw form. Expect the PIN_COUNT_LOW flag (1)
|
||||
+# to be set due to the previous test.
|
||||
mark('PKCS11 identity, with PIN (responder)')
|
||||
-realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity,
|
||||
- '-r', 'pkinit={"%s": "encrypted"}' % p11_token_identity,
|
||||
- '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ])
|
||||
+realm.run(['./responder', '-x', 'pkinit={"%s": 1}' % p11_token_identity,
|
||||
+ '-r', 'pkinit={"%s": "userpin"}' % p11_token_identity,
|
||||
+ '-X', p11_attr, realm.user_princ])
|
||||
# Supply the response through the convenience API.
|
||||
-realm.run(['./responder', '-X', 'X509_user_identity=%s' % p11_identity,
|
||||
- '-p', '%s=%s' % (p11_token_identity, 'encrypted'),
|
||||
+realm.run(['./responder', '-X', p11_attr,
|
||||
+ '-p', '%s=%s' % (p11_token_identity, 'userpin'),
|
||||
realm.user_princ])
|
||||
realm.klist(realm.user_princ)
|
||||
realm.run([kvno, realm.host_princ])
|
||||
--
|
||||
2.47.1
|
||||
|
202
SOURCES/0031-Simplify-PKINIT-cert-representation.patch
Normal file
202
SOURCES/0031-Simplify-PKINIT-cert-representation.patch
Normal file
@ -0,0 +1,202 @@
|
||||
From 35d11a545757efe9c57a6a8b26fc6396e7d0eb5f Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 9 Feb 2024 17:32:40 -0500
|
||||
Subject: [PATCH] Simplify PKINIT cert representation
|
||||
|
||||
In the _pkinit_identity_crypto_context structure, the my_certs field
|
||||
is a stack which only ever contains one cert and is only ever used to
|
||||
retrieve that one cert. The cert_index field is always 0. Replace
|
||||
these fields with a my_cert field pointing directly to the X509
|
||||
certificate.
|
||||
|
||||
Simplify crypto_cert_select_default() by making it call
|
||||
crypto_cert_select() with index 0 after verifying the certificate
|
||||
count.
|
||||
|
||||
(cherry picked from commit f95dfb7908456f9563cee66706216a21df8d791f)
|
||||
---
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 74 +++++--------------
|
||||
1 file changed, 20 insertions(+), 54 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index 8d1216724c..875ac4206b 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -73,10 +73,9 @@ typedef struct _pkinit_cred_info *pkinit_cred_info;
|
||||
|
||||
struct _pkinit_identity_crypto_context {
|
||||
pkinit_cred_info creds[MAX_CREDS_ALLOWED+1];
|
||||
- STACK_OF(X509) *my_certs; /* available user certs */
|
||||
+ X509 *my_cert; /* selected user or KDC cert */
|
||||
char *identity; /* identity name for user cert */
|
||||
- int cert_index; /* cert to use out of available certs*/
|
||||
- EVP_PKEY *my_key; /* available user keys if in filesystem */
|
||||
+ EVP_PKEY *my_key; /* selected cert key if in filesystem */
|
||||
STACK_OF(X509) *trustedCAs; /* available trusted ca certs */
|
||||
STACK_OF(X509) *intermediateCAs; /* available intermediate ca certs */
|
||||
STACK_OF(X509_CRL) *revoked; /* available crls */
|
||||
@@ -1489,8 +1488,7 @@ pkinit_init_certs(pkinit_identity_crypto_context ctx)
|
||||
|
||||
for (i = 0; i < MAX_CREDS_ALLOWED; i++)
|
||||
ctx->creds[i] = NULL;
|
||||
- ctx->my_certs = NULL;
|
||||
- ctx->cert_index = 0;
|
||||
+ ctx->my_cert = NULL;
|
||||
ctx->my_key = NULL;
|
||||
ctx->trustedCAs = NULL;
|
||||
ctx->intermediateCAs = NULL;
|
||||
@@ -1506,8 +1504,8 @@ pkinit_fini_certs(pkinit_identity_crypto_context ctx)
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
- if (ctx->my_certs != NULL)
|
||||
- sk_X509_pop_free(ctx->my_certs, X509_free);
|
||||
+ if (ctx->my_cert != NULL)
|
||||
+ X509_free(ctx->my_cert);
|
||||
|
||||
if (ctx->my_key != NULL)
|
||||
EVP_PKEY_free(ctx->my_key);
|
||||
@@ -1696,7 +1694,6 @@ cms_signeddata_create(krb5_context context,
|
||||
ASN1_OCTET_STRING *digest = NULL;
|
||||
unsigned int alg_len = 0, digest_len = 0;
|
||||
unsigned char *y = NULL;
|
||||
- X509 *cert = NULL;
|
||||
ASN1_OBJECT *oid = NULL, *oid_copy;
|
||||
|
||||
/* Start creating PKCS7 data. */
|
||||
@@ -1715,7 +1712,7 @@ cms_signeddata_create(krb5_context context,
|
||||
if (oid == NULL)
|
||||
goto cleanup;
|
||||
|
||||
- if (id_cryptoctx->my_certs != NULL) {
|
||||
+ if (id_cryptoctx->my_cert != NULL) {
|
||||
X509_STORE *certstore = NULL;
|
||||
X509_STORE_CTX *certctx;
|
||||
STACK_OF(X509) *certstack = NULL;
|
||||
@@ -1726,8 +1723,6 @@ cms_signeddata_create(krb5_context context,
|
||||
if ((cert_stack = sk_X509_new_null()) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
- cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
|
||||
-
|
||||
certstore = X509_STORE_new();
|
||||
if (certstore == NULL)
|
||||
goto cleanup;
|
||||
@@ -1736,7 +1731,7 @@ cms_signeddata_create(krb5_context context,
|
||||
certctx = X509_STORE_CTX_new();
|
||||
if (certctx == NULL)
|
||||
goto cleanup;
|
||||
- X509_STORE_CTX_init(certctx, certstore, cert,
|
||||
+ X509_STORE_CTX_init(certctx, certstore, id_cryptoctx->my_cert,
|
||||
id_cryptoctx->intermediateCAs);
|
||||
X509_STORE_CTX_trusted_stack(certctx, id_cryptoctx->trustedCAs);
|
||||
if (!X509_verify_cert(certctx)) {
|
||||
@@ -1764,13 +1759,13 @@ cms_signeddata_create(krb5_context context,
|
||||
if (!ASN1_INTEGER_set(p7si->version, 1))
|
||||
goto cleanup;
|
||||
if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
|
||||
- X509_get_issuer_name(cert)))
|
||||
+ X509_get_issuer_name(id_cryptoctx->my_cert)))
|
||||
goto cleanup;
|
||||
/* because ASN1_INTEGER_set is used to set a 'long' we will do
|
||||
* things the ugly way. */
|
||||
ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
|
||||
if (!(p7si->issuer_and_serial->serial =
|
||||
- ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
|
||||
+ ASN1_INTEGER_dup(X509_get_serialNumber(id_cryptoctx->my_cert))))
|
||||
goto cleanup;
|
||||
|
||||
/* will not fill-out EVP_PKEY because it's on the smartcard */
|
||||
@@ -3311,7 +3306,7 @@ pkinit_check_kdc_pkid(krb5_context context,
|
||||
PKCS7_ISSUER_AND_SERIAL *is = NULL;
|
||||
const unsigned char *p = pdid_buf;
|
||||
int status = 1;
|
||||
- X509 *kdc_cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
|
||||
+ X509 *kdc_cert = id_cryptoctx->my_cert;
|
||||
|
||||
*valid_kdcPkId = 0;
|
||||
pkiDebug("found kdcPkId in AS REQ\n");
|
||||
@@ -4783,7 +4778,8 @@ cleanup:
|
||||
}
|
||||
|
||||
/*
|
||||
- * Set the certificate in idctx->creds[cred_index] as the selected certificate.
|
||||
+ * Set the certificate in idctx->creds[cred_index] as the selected certificate,
|
||||
+ * stealing pointers from it.
|
||||
*/
|
||||
krb5_error_code
|
||||
crypto_cert_select(krb5_context context, pkinit_identity_crypto_context idctx,
|
||||
@@ -4795,20 +4791,17 @@ crypto_cert_select(krb5_context context, pkinit_identity_crypto_context idctx,
|
||||
return ENOENT;
|
||||
|
||||
ci = idctx->creds[cred_index];
|
||||
- /* copy the selected cert into our id_cryptoctx */
|
||||
- if (idctx->my_certs != NULL)
|
||||
- sk_X509_pop_free(idctx->my_certs, X509_free);
|
||||
- idctx->my_certs = sk_X509_new_null();
|
||||
- sk_X509_push(idctx->my_certs, ci->cert);
|
||||
- free(idctx->identity);
|
||||
+
|
||||
+ idctx->my_cert = ci->cert;
|
||||
+ ci->cert = NULL;
|
||||
+
|
||||
/* hang on to the selected credential name */
|
||||
+ free(idctx->identity);
|
||||
if (ci->name != NULL)
|
||||
idctx->identity = strdup(ci->name);
|
||||
else
|
||||
idctx->identity = NULL;
|
||||
|
||||
- ci->cert = NULL; /* Don't free it twice */
|
||||
- idctx->cert_index = 0;
|
||||
if (idctx->pkcs11_method != 1) {
|
||||
idctx->my_key = ci->key;
|
||||
ci->key = NULL; /* Don't free it twice */
|
||||
@@ -4837,41 +4830,14 @@ crypto_cert_select_default(krb5_context context,
|
||||
|
||||
retval = crypto_cert_get_count(id_cryptoctx, &cert_count);
|
||||
if (retval)
|
||||
- goto errout;
|
||||
+ return retval;
|
||||
|
||||
if (cert_count != 1) {
|
||||
TRACE_PKINIT_NO_DEFAULT_CERT(context, cert_count);
|
||||
- retval = EINVAL;
|
||||
- goto errout;
|
||||
- }
|
||||
- /* copy the selected cert into our id_cryptoctx */
|
||||
- if (id_cryptoctx->my_certs != NULL) {
|
||||
- sk_X509_pop_free(id_cryptoctx->my_certs, X509_free);
|
||||
+ return EINVAL;
|
||||
}
|
||||
- id_cryptoctx->my_certs = sk_X509_new_null();
|
||||
- sk_X509_push(id_cryptoctx->my_certs, id_cryptoctx->creds[0]->cert);
|
||||
- id_cryptoctx->creds[0]->cert = NULL; /* Don't free it twice */
|
||||
- id_cryptoctx->cert_index = 0;
|
||||
- /* hang on to the selected credential name */
|
||||
- if (id_cryptoctx->creds[0]->name != NULL)
|
||||
- id_cryptoctx->identity = strdup(id_cryptoctx->creds[0]->name);
|
||||
- else
|
||||
- id_cryptoctx->identity = NULL;
|
||||
|
||||
- if (id_cryptoctx->pkcs11_method != 1) {
|
||||
- id_cryptoctx->my_key = id_cryptoctx->creds[0]->key;
|
||||
- id_cryptoctx->creds[0]->key = NULL; /* Don't free it twice */
|
||||
- }
|
||||
-#ifndef WITHOUT_PKCS11
|
||||
- else {
|
||||
- id_cryptoctx->cert_id = id_cryptoctx->creds[0]->cert_id;
|
||||
- id_cryptoctx->creds[0]->cert_id = NULL; /* Don't free it twice */
|
||||
- id_cryptoctx->cert_id_len = id_cryptoctx->creds[0]->cert_id_len;
|
||||
- }
|
||||
-#endif
|
||||
- retval = 0;
|
||||
-errout:
|
||||
- return retval;
|
||||
+ return crypto_cert_select(context, id_cryptoctx, 0);
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
2.47.1
|
||||
|
1768
SOURCES/0032-Support-PKCS11-EC-client-certs-in-PKINIT.patch
Normal file
1768
SOURCES/0032-Support-PKCS11-EC-client-certs-in-PKINIT.patch
Normal file
File diff suppressed because it is too large
Load Diff
599
SOURCES/0033-Improve-PKCS11-error-reporting-in-PKINIT.patch
Normal file
599
SOURCES/0033-Improve-PKCS11-error-reporting-in-PKINIT.patch
Normal file
@ -0,0 +1,599 @@
|
||||
From 6c4c659859bb6fde1b0631dea2ac03070fbe1a26 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 23 Feb 2024 13:51:26 -0500
|
||||
Subject: [PATCH] Improve PKCS11 error reporting in PKINIT
|
||||
|
||||
Create a helper p11err() to set extended error message for failed
|
||||
PKCS11 operations, and use it instead of pkiDebug() and pkcs11error().
|
||||
|
||||
ticket: 9113 (new)
|
||||
(cherry picked from commit 98afb314d13939cbee19c69885dcb655db8460da)
|
||||
---
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 262 ++++++++++--------
|
||||
src/plugins/preauth/pkinit/pkinit_trace.h | 9 -
|
||||
2 files changed, 142 insertions(+), 129 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index b33b696954..87eb677c49 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -161,9 +161,11 @@ static krb5_error_code pkinit_create_sequence_of_principal_identifiers
|
||||
int type, krb5_pa_data ***e_data_out);
|
||||
|
||||
#ifndef WITHOUT_PKCS11
|
||||
-static krb5_error_code pkinit_find_private_key
|
||||
-(pkinit_identity_crypto_context, CK_ATTRIBUTE_TYPE usage,
|
||||
- CK_OBJECT_HANDLE *objp);
|
||||
+static krb5_error_code
|
||||
+pkinit_find_private_key(krb5_context context,
|
||||
+ pkinit_identity_crypto_context id_cryptoctx,
|
||||
+ CK_ATTRIBUTE_TYPE usage,
|
||||
+ CK_OBJECT_HANDLE *objp);
|
||||
static krb5_error_code pkinit_login
|
||||
(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
|
||||
CK_TOKEN_INFO *tip, const char *password);
|
||||
@@ -180,6 +182,8 @@ static krb5_error_code pkinit_sign_data_pkcs11
|
||||
(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
|
||||
unsigned char *data, unsigned int data_len,
|
||||
unsigned char **sig, unsigned int *sig_len);
|
||||
+
|
||||
+static krb5_error_code p11err(krb5_context context, CK_RV rv, const char *op);
|
||||
#endif /* WITHOUT_PKCS11 */
|
||||
|
||||
static krb5_error_code pkinit_sign_data_fs
|
||||
@@ -197,9 +201,6 @@ create_krb5_invalidCertificates(krb5_context context,
|
||||
static krb5_error_code
|
||||
create_identifiers_from_stack(STACK_OF(X509) *sk,
|
||||
krb5_external_principal_identifier *** ids);
|
||||
-static const char *
|
||||
-pkcs11err(int err);
|
||||
-
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
|
||||
@@ -944,8 +945,9 @@ cleanup:
|
||||
|
||||
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
|
||||
|
||||
+#ifndef WITHOUT_PKC11
|
||||
static struct pkcs11_errstrings {
|
||||
- short code;
|
||||
+ CK_RV code;
|
||||
char *text;
|
||||
} pkcs11_errstrings[] = {
|
||||
{ 0x0, "ok" },
|
||||
@@ -1035,6 +1037,7 @@ static struct pkcs11_errstrings {
|
||||
{ 0x200, "function rejected" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
+#endif
|
||||
|
||||
MAKE_INIT_FUNCTION(pkinit_openssl_init);
|
||||
|
||||
@@ -1563,6 +1566,8 @@ pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx)
|
||||
free(ctx->token_label);
|
||||
free(ctx->cert_id);
|
||||
free(ctx->cert_label);
|
||||
+ ctx->p11_module_name = ctx->token_label = ctx->cert_label = NULL;
|
||||
+ ctx->cert_id = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3344,48 +3349,53 @@ pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
|
||||
}
|
||||
|
||||
#ifndef WITHOUT_PKCS11
|
||||
-static struct plugin_file_handle *
|
||||
+static krb5_error_code
|
||||
load_pkcs11_module(krb5_context context, const char *modname,
|
||||
- CK_FUNCTION_LIST_PTR_PTR p11p)
|
||||
+ struct plugin_file_handle **handle_out,
|
||||
+ CK_FUNCTION_LIST_PTR_PTR p11_out)
|
||||
{
|
||||
struct plugin_file_handle *handle = NULL;
|
||||
- CK_RV (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
|
||||
+ CK_RV rv, (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
|
||||
struct errinfo einfo = EMPTY_ERRINFO;
|
||||
- const char *errmsg = NULL;
|
||||
+ const char *errmsg = NULL, *failure;
|
||||
void (*sym)(void);
|
||||
long err;
|
||||
- CK_RV rv;
|
||||
|
||||
TRACE_PKINIT_PKCS11_OPEN(context, modname);
|
||||
err = krb5int_open_plugin(modname, &handle, &einfo);
|
||||
if (err) {
|
||||
- errmsg = k5_get_error(&einfo, err);
|
||||
- TRACE_PKINIT_PKCS11_OPEN_FAILED(context, errmsg);
|
||||
+ failure = _("Cannot load PKCS11 module");
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = krb5int_get_plugin_func(handle, "C_GetFunctionList", &sym, &einfo);
|
||||
if (err) {
|
||||
- errmsg = k5_get_error(&einfo, err);
|
||||
- TRACE_PKINIT_PKCS11_GETSYM_FAILED(context, errmsg);
|
||||
+ failure = _("Cannot find C_GetFunctionList in PKCS11 module");
|
||||
goto error;
|
||||
}
|
||||
|
||||
getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))sym;
|
||||
- rv = (*getflist)(p11p);
|
||||
+ rv = (*getflist)(p11_out);
|
||||
if (rv != CKR_OK) {
|
||||
- TRACE_PKINIT_PKCS11_GETFLIST_FAILED(context, pkcs11err(rv));
|
||||
+ failure = _("Cannot retrieve function list in PKCS11 module");
|
||||
goto error;
|
||||
}
|
||||
|
||||
- return handle;
|
||||
+ *handle_out = handle;
|
||||
+ return 0;
|
||||
|
||||
error:
|
||||
- k5_free_error(&einfo, errmsg);
|
||||
+ if (err) {
|
||||
+ errmsg = k5_get_error(&einfo, err);
|
||||
+ k5_setmsg(context, err, _("%s: %s"), failure, errmsg);
|
||||
+ } else {
|
||||
+ err = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ k5_setmsg(context, err, "%s", failure);
|
||||
+ }
|
||||
k5_clear_error(&einfo);
|
||||
if (handle != NULL)
|
||||
krb5int_close_plugin(handle);
|
||||
- return NULL;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
@@ -3393,12 +3403,13 @@ pkinit_login(krb5_context context,
|
||||
pkinit_identity_crypto_context id_cryptoctx,
|
||||
CK_TOKEN_INFO *tip, const char *password)
|
||||
{
|
||||
+ krb5_error_code ret = 0;
|
||||
+ CK_RV rv;
|
||||
krb5_data rdat;
|
||||
char *prompt;
|
||||
const char *warning;
|
||||
krb5_prompt kprompt;
|
||||
krb5_prompt_type prompt_type;
|
||||
- int r = 0;
|
||||
|
||||
if (tip->flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
|
||||
rdat.data = NULL;
|
||||
@@ -3407,7 +3418,7 @@ pkinit_login(krb5_context context,
|
||||
rdat.data = strdup(password);
|
||||
rdat.length = strlen(password);
|
||||
} else if (id_cryptoctx->prompter == NULL) {
|
||||
- r = KRB5_LIBOS_CANTREADPWD;
|
||||
+ ret = KRB5_LIBOS_CANTREADPWD;
|
||||
rdat.data = NULL;
|
||||
} else {
|
||||
if (tip->flags & CKF_USER_PIN_LOCKED)
|
||||
@@ -3431,31 +3442,28 @@ pkinit_login(krb5_context context,
|
||||
|
||||
/* PROMPTER_INVOCATION */
|
||||
k5int_set_prompt_types(context, &prompt_type);
|
||||
- r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
|
||||
- NULL, NULL, 1, &kprompt);
|
||||
+ ret = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
|
||||
+ NULL, NULL, 1, &kprompt);
|
||||
k5int_set_prompt_types(context, 0);
|
||||
free(prompt);
|
||||
}
|
||||
|
||||
- if (r == 0) {
|
||||
- r = id_cryptoctx->p11->C_Login(id_cryptoctx->session, CKU_USER,
|
||||
- (u_char *) rdat.data, rdat.length);
|
||||
-
|
||||
- if (r != CKR_OK) {
|
||||
- TRACE_PKINIT_PKCS11_LOGIN_FAILED(context, pkcs11err(r));
|
||||
- r = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
- }
|
||||
+ if (!ret) {
|
||||
+ rv = id_cryptoctx->p11->C_Login(id_cryptoctx->session, CKU_USER,
|
||||
+ (uint8_t *)rdat.data, rdat.length);
|
||||
+ if (rv != CKR_OK)
|
||||
+ ret = p11err(context, rv, "C_Login");
|
||||
}
|
||||
free(rdat.data);
|
||||
|
||||
- return r;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
pkinit_open_session(krb5_context context,
|
||||
pkinit_identity_crypto_context cctx)
|
||||
{
|
||||
- CK_ULONG i, pret;
|
||||
+ CK_ULONG i, rv;
|
||||
unsigned char *cp;
|
||||
size_t label_len;
|
||||
CK_ULONG count = 0;
|
||||
@@ -3469,30 +3477,35 @@ pkinit_open_session(krb5_context context,
|
||||
return 0; /* session already open */
|
||||
|
||||
/* Load module */
|
||||
- cctx->p11_module = load_pkcs11_module(context, cctx->p11_module_name,
|
||||
- &cctx->p11);
|
||||
- if (cctx->p11_module == NULL)
|
||||
- return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ ret = load_pkcs11_module(context, cctx->p11_module_name, &cctx->p11_module,
|
||||
+ &cctx->p11);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
|
||||
/* Init */
|
||||
- pret = cctx->p11->C_Initialize(NULL);
|
||||
- if (pret != CKR_OK) {
|
||||
- pkiDebug("C_Initialize: %s\n", pkcs11err(pret));
|
||||
- return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = cctx->p11->C_Initialize(NULL);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_Initialize");
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
/* Get the list of available slots */
|
||||
- if (cctx->p11->C_GetSlotList(TRUE, NULL, &count) != CKR_OK)
|
||||
- return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = cctx->p11->C_GetSlotList(TRUE, NULL, &count);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_GetSlotList");
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (count == 0) {
|
||||
TRACE_PKINIT_PKCS11_NO_TOKEN(context);
|
||||
- return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ goto cleanup;
|
||||
}
|
||||
- slotlist = calloc(count, sizeof(CK_SLOT_ID));
|
||||
+ slotlist = k5calloc(count, sizeof(CK_SLOT_ID), &ret);
|
||||
if (slotlist == NULL)
|
||||
- return ENOMEM;
|
||||
- if (cctx->p11->C_GetSlotList(TRUE, slotlist, &count) != CKR_OK) {
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ goto cleanup;
|
||||
+ rv = cctx->p11->C_GetSlotList(TRUE, slotlist, &count);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_GetSlotList");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -3503,19 +3516,17 @@ pkinit_open_session(krb5_context context,
|
||||
continue;
|
||||
|
||||
/* Open session */
|
||||
- pret = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION,
|
||||
- NULL, NULL, &cctx->session);
|
||||
- if (pret != CKR_OK) {
|
||||
- pkiDebug("C_OpenSession: %s\n", pkcs11err(pret));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION,
|
||||
+ NULL, NULL, &cctx->session);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_OpenSession");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get token info */
|
||||
- pret = cctx->p11->C_GetTokenInfo(slotlist[i], &tinfo);
|
||||
- if (pret != CKR_OK) {
|
||||
- pkiDebug("C_GetTokenInfo: %s\n", pkcs11err(pret));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = cctx->p11->C_GetTokenInfo(slotlist[i], &tinfo);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_GetTokenInfo");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -3577,6 +3588,10 @@ pkinit_open_session(krb5_context context,
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
+ /* On error, finalize the PKCS11 fields to ensure that we don't mistakenly
|
||||
+ * short-circuit with success on the next call. */
|
||||
+ if (ret)
|
||||
+ pkinit_fini_pkcs11(cctx);
|
||||
free(slotlist);
|
||||
free(p11name);
|
||||
return ret;
|
||||
@@ -3598,16 +3613,17 @@ cleanup:
|
||||
* If there are more than one, we just take the first one.
|
||||
*/
|
||||
|
||||
-krb5_error_code
|
||||
-pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
|
||||
+static krb5_error_code
|
||||
+pkinit_find_private_key(krb5_context context,
|
||||
+ pkinit_identity_crypto_context id_cryptoctx,
|
||||
CK_ATTRIBUTE_TYPE usage,
|
||||
CK_OBJECT_HANDLE *objp)
|
||||
{
|
||||
CK_OBJECT_CLASS cls;
|
||||
CK_ATTRIBUTE attrs[4];
|
||||
CK_ULONG count;
|
||||
+ CK_RV rv;
|
||||
unsigned int nattrs = 0;
|
||||
- int r;
|
||||
#ifdef PKINIT_USE_KEY_USAGE
|
||||
CK_BBOOL true_false;
|
||||
#endif
|
||||
@@ -3637,18 +3653,21 @@ pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
|
||||
attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len;
|
||||
nattrs++;
|
||||
|
||||
- r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
|
||||
- if (r != CKR_OK) {
|
||||
- pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
|
||||
- pkcs11err(r));
|
||||
- return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
- }
|
||||
+ rv = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs,
|
||||
+ nattrs);
|
||||
+ if (rv != CKR_OK)
|
||||
+ return p11err(context, rv, _("C_FindObjectsInit"));
|
||||
|
||||
- r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
|
||||
+ rv = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1,
|
||||
+ &count);
|
||||
id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
|
||||
- pkiDebug("found %d private keys (%s)\n", (int)count, pkcs11err(r));
|
||||
- if (r != CKR_OK || count < 1)
|
||||
+ if (rv != CKR_OK)
|
||||
+ return p11err(context, rv, _("C_FindObjects"));
|
||||
+ if (count < 1) {
|
||||
+ k5_setmsg(context, KRB5KDC_ERR_PREAUTH_FAILED,
|
||||
+ _("Found no private keys in PKCS11 token"));
|
||||
return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -3796,34 +3815,32 @@ pkinit_sign_data_pkcs11(krb5_context context,
|
||||
CK_FUNCTION_LIST_PTR p11;
|
||||
CK_ATTRIBUTE attr;
|
||||
CK_KEY_TYPE keytype;
|
||||
+ CK_RV rv;
|
||||
EVP_MD_CTX *ctx;
|
||||
const EVP_MD *md = EVP_sha256();
|
||||
unsigned int mdlen;
|
||||
uint8_t mdbuf[EVP_MAX_MD_SIZE], *dinfo = NULL, *sigbuf = NULL, *input;
|
||||
size_t dinfo_len, input_len;
|
||||
- int r;
|
||||
|
||||
*sig = NULL;
|
||||
*sig_len = 0;
|
||||
|
||||
- if (pkinit_open_session(context, id_cryptoctx)) {
|
||||
- pkiDebug("can't open pkcs11 session\n");
|
||||
- return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
- }
|
||||
+ ret = pkinit_open_session(context, id_cryptoctx);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
p11 = id_cryptoctx->p11;
|
||||
session = id_cryptoctx->session;
|
||||
|
||||
- ret = pkinit_find_private_key(id_cryptoctx, CKA_SIGN, &obj);
|
||||
+ ret = pkinit_find_private_key(context, id_cryptoctx, CKA_SIGN, &obj);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
attr.type = CKA_KEY_TYPE;
|
||||
attr.pValue = &keytype;
|
||||
attr.ulValueLen = sizeof(keytype);
|
||||
- r = p11->C_GetAttributeValue(session, obj, &attr, 1);
|
||||
- if (r) {
|
||||
- pkiDebug("C_GetAttributeValue: %s\n", pkcs11err(r));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = p11->C_GetAttributeValue(session, obj, &attr, 1);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_GetAttributeValue");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -3865,10 +3882,9 @@ pkinit_sign_data_pkcs11(krb5_context context,
|
||||
mech.pParameter = NULL;
|
||||
mech.ulParameterLen = 0;
|
||||
|
||||
- r = p11->C_SignInit(session, &mech, obj);
|
||||
- if (r != CKR_OK) {
|
||||
- pkiDebug("C_SignInit: %s\n", pkcs11err(r));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = p11->C_SignInit(session, &mech, obj);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_SignInit");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -3881,18 +3897,17 @@ pkinit_sign_data_pkcs11(krb5_context context,
|
||||
if (sigbuf == NULL)
|
||||
goto cleanup;
|
||||
|
||||
- r = p11->C_Sign(session, input, input_len, sigbuf, &len);
|
||||
- if (r == CKR_BUFFER_TOO_SMALL || (r == CKR_OK && len >= PK_SIGLEN_GUESS)) {
|
||||
+ rv = p11->C_Sign(session, input, input_len, sigbuf, &len);
|
||||
+ if (rv == CKR_BUFFER_TOO_SMALL ||
|
||||
+ (rv == CKR_OK && len >= PK_SIGLEN_GUESS)) {
|
||||
free(sigbuf);
|
||||
- pkiDebug("C_Sign realloc %d\n", (int) len);
|
||||
sigbuf = k5alloc(len, &ret);
|
||||
if (sigbuf == NULL)
|
||||
goto cleanup;
|
||||
- r = p11->C_Sign(session, input, input_len, sigbuf, &len);
|
||||
+ rv = p11->C_Sign(session, input, input_len, sigbuf, &len);
|
||||
}
|
||||
- if (r != CKR_OK) {
|
||||
- pkiDebug("C_Sign: %s\n", pkcs11err(r));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_Sign");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -4348,13 +4363,14 @@ reassemble_pkcs11_name(pkinit_identity_opts *idopts)
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
-load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
|
||||
- pkinit_identity_opts *idopts, pkinit_cred_info *cred_out)
|
||||
+load_one_cert(krb5_context context, CK_FUNCTION_LIST_PTR p11,
|
||||
+ CK_SESSION_HANDLE session, pkinit_identity_opts *idopts,
|
||||
+ pkinit_cred_info *cred_out)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
CK_ATTRIBUTE attrs[2];
|
||||
CK_BYTE_PTR cert = NULL, cert_id = NULL;
|
||||
- CK_RV pret;
|
||||
+ CK_RV rv;
|
||||
const unsigned char *cp;
|
||||
CK_OBJECT_HANDLE obj;
|
||||
CK_ULONG count;
|
||||
@@ -4364,8 +4380,8 @@ load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
|
||||
*cred_out = NULL;
|
||||
|
||||
/* Look for X.509 cert. */
|
||||
- pret = p11->C_FindObjects(session, &obj, 1, &count);
|
||||
- if (pret != CKR_OK || count <= 0)
|
||||
+ rv = p11->C_FindObjects(session, &obj, 1, &count);
|
||||
+ if (rv != CKR_OK || count <= 0)
|
||||
return 0;
|
||||
|
||||
/* Get cert and id len. */
|
||||
@@ -4375,10 +4391,9 @@ load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
|
||||
attrs[1].type = CKA_ID;
|
||||
attrs[1].pValue = NULL;
|
||||
attrs[1].ulValueLen = 0;
|
||||
- pret = p11->C_GetAttributeValue(session, obj, attrs, 2);
|
||||
- if (pret != CKR_OK && pret != CKR_BUFFER_TOO_SMALL) {
|
||||
- pkiDebug("C_GetAttributeValue: %s\n", pkcs11err(pret));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = p11->C_GetAttributeValue(session, obj, attrs, 2);
|
||||
+ if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL) {
|
||||
+ ret = p11err(context, rv, "C_GetAttributeValue");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -4393,10 +4408,9 @@ load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
|
||||
attrs[0].pValue = cert;
|
||||
attrs[1].type = CKA_ID;
|
||||
attrs[1].pValue = cert_id;
|
||||
- pret = p11->C_GetAttributeValue(session, obj, attrs, 2);
|
||||
- if (pret != CKR_OK) {
|
||||
- pkiDebug("C_GetAttributeValue: %s\n", pkcs11err(pret));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = p11->C_GetAttributeValue(session, obj, attrs, 2);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_GetAttributeValue");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -4406,7 +4420,8 @@ load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
|
||||
cp = (unsigned char *)cert;
|
||||
x = d2i_X509(NULL, &cp, (int)attrs[0].ulValueLen);
|
||||
if (x == NULL) {
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ ret = oerr(context, 0,
|
||||
+ _("Failed to decode X509 certificate from PKCS11 token"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -4444,7 +4459,7 @@ pkinit_get_certs_pkcs11(krb5_context context,
|
||||
int i;
|
||||
unsigned int nattrs;
|
||||
krb5_error_code ret;
|
||||
- CK_RV pret;
|
||||
+ CK_RV rv;
|
||||
|
||||
/* Copy stuff from idopts -> id_cryptoctx */
|
||||
if (idopts->p11_module_name != NULL) {
|
||||
@@ -4516,16 +4531,16 @@ pkinit_get_certs_pkcs11(krb5_context context,
|
||||
nattrs++;
|
||||
}
|
||||
|
||||
- pret = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs,
|
||||
- nattrs);
|
||||
- if (pret != CKR_OK) {
|
||||
- pkiDebug("C_FindObjectsInit: %s\n", pkcs11err(pret));
|
||||
+ rv = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs,
|
||||
+ nattrs);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_FindObjectsInit");
|
||||
return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_CREDS_ALLOWED; i++) {
|
||||
- ret = load_one_cert(id_cryptoctx->p11, id_cryptoctx->session, idopts,
|
||||
- &id_cryptoctx->creds[i]);
|
||||
+ ret = load_one_cert(context, id_cryptoctx->p11, id_cryptoctx->session,
|
||||
+ idopts, &id_cryptoctx->creds[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (id_cryptoctx->creds[i] == NULL)
|
||||
@@ -5510,19 +5525,26 @@ print_pubkey(BIGNUM * key, char *msg)
|
||||
}
|
||||
#endif
|
||||
|
||||
-static const char *
|
||||
-pkcs11err(int err)
|
||||
+#ifndef WITHOUT_PKCS11
|
||||
+static krb5_error_code
|
||||
+p11err(krb5_context context, CK_RV rv, const char *op)
|
||||
{
|
||||
+ krb5_error_code code = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
int i;
|
||||
+ const char *msg;
|
||||
|
||||
- for (i = 0; pkcs11_errstrings[i].text != NULL; i++)
|
||||
- if (pkcs11_errstrings[i].code == err)
|
||||
+ for (i = 0; pkcs11_errstrings[i].text != NULL; i++) {
|
||||
+ if (pkcs11_errstrings[i].code == rv)
|
||||
break;
|
||||
- if (pkcs11_errstrings[i].text != NULL)
|
||||
- return (pkcs11_errstrings[i].text);
|
||||
+ }
|
||||
+ msg = pkcs11_errstrings[i].text;
|
||||
+ if (msg == NULL)
|
||||
+ msg = "unknown PKCS11 error";
|
||||
|
||||
- return "unknown PKCS11 error";
|
||||
+ krb5_set_error_message(context, code, _("PKCS11 error (%s): %s"), op, msg);
|
||||
+ return code;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Add an item to the pkinit_identity_crypto_context's list of deferred
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h
|
||||
index 1c1ceb5a41..1faa6816d7 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_trace.h
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h
|
||||
@@ -98,21 +98,12 @@
|
||||
#define TRACE_PKINIT_OPENSSL_ERROR(c, msg) \
|
||||
TRACE(c, "PKINIT OpenSSL error: {str}", msg)
|
||||
|
||||
-#define TRACE_PKINIT_PKCS11_GETFLIST_FAILED(c, errstr) \
|
||||
- TRACE(c, "PKINIT PKCS11 C_GetFunctionList failed: {str}", errstr)
|
||||
-#define TRACE_PKINIT_PKCS11_GETSYM_FAILED(c, errstr) \
|
||||
- TRACE(c, "PKINIT unable to find PKCS11 plugin symbol " \
|
||||
- "C_GetFunctionList: {str}", errstr)
|
||||
-#define TRACE_PKINIT_PKCS11_LOGIN_FAILED(c, errstr) \
|
||||
- TRACE(c, "PKINIT PKCS11 C_Login failed: {str}", errstr)
|
||||
#define TRACE_PKINIT_PKCS11_NO_MATCH_TOKEN(c) \
|
||||
TRACE(c, "PKINIT PKCS#11 module has no matching tokens")
|
||||
#define TRACE_PKINIT_PKCS11_NO_TOKEN(c) \
|
||||
TRACE(c, "PKINIT PKCS#11 module shows no slots with tokens")
|
||||
#define TRACE_PKINIT_PKCS11_OPEN(c, name) \
|
||||
TRACE(c, "PKINIT opening PKCS#11 module \"{str}\"", name)
|
||||
-#define TRACE_PKINIT_PKCS11_OPEN_FAILED(c, errstr) \
|
||||
- TRACE(c, "PKINIT PKCS#11 module open failed: {str}", errstr)
|
||||
#define TRACE_PKINIT_PKCS11_SLOT(c, slot, len, label) \
|
||||
TRACE(c, "PKINIT PKCS#11 slotid {int} token {lenstr}", \
|
||||
slot, len, label)
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,61 @@
|
||||
From e076f3c851b04bdee33798555c47220afbc5fe08 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Thu, 1 Aug 2024 10:56:07 +0200
|
||||
Subject: [PATCH] Set missing mask flags for kdb5_util operations
|
||||
|
||||
Set KADM5_TL_DATA for the use_mkey and update_princ_encryption
|
||||
commands. (Commit c877f13c8985d820583b0d7ac1bb4c5dc36e677e did this
|
||||
for the add_new_mkey and purge_mkeys commands.) Set appropriate flags
|
||||
for the add_random_key command.
|
||||
|
||||
[ghudson@mit.edu: combined two commits; pruned out proposed mask flag
|
||||
additions for values represented within key data or tl-data (like
|
||||
KADM5_MKVNO), as those flags are currently only used in the kadm5
|
||||
protocol, not to communicate with the KDB module]
|
||||
|
||||
ticket: 9158 (new)
|
||||
(cherry picked from commit 4ed7da378940198cf4415f86d4eb013de6ac6455)
|
||||
---
|
||||
src/kadmin/dbutil/kdb5_mkey.c | 4 +++-
|
||||
src/kadmin/dbutil/kdb5_util.c | 3 +++
|
||||
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/kadmin/dbutil/kdb5_mkey.c b/src/kadmin/dbutil/kdb5_mkey.c
|
||||
index aceb0a9b80..ac5c51d05e 100644
|
||||
--- a/src/kadmin/dbutil/kdb5_mkey.c
|
||||
+++ b/src/kadmin/dbutil/kdb5_mkey.c
|
||||
@@ -525,6 +525,8 @@ kdb5_use_mkey(int argc, char *argv[])
|
||||
goto cleanup_return;
|
||||
}
|
||||
|
||||
+ master_entry->mask |= KADM5_TL_DATA;
|
||||
+
|
||||
if ((retval = krb5_db_put_principal(util_context, master_entry))) {
|
||||
com_err(progname, retval,
|
||||
_("while adding master key entry to the database"));
|
||||
@@ -814,7 +816,7 @@ update_princ_encryption_1(void *cb, krb5_db_entry *ent)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- ent->mask |= KADM5_KEY_DATA;
|
||||
+ ent->mask |= KADM5_KEY_DATA | KADM5_TL_DATA;
|
||||
|
||||
if ((retval = krb5_db_put_principal(util_context, ent))) {
|
||||
com_err(progname, retval, _("while updating principal '%s' key data "
|
||||
diff --git a/src/kadmin/dbutil/kdb5_util.c b/src/kadmin/dbutil/kdb5_util.c
|
||||
index b9b61e3f91..073010674e 100644
|
||||
--- a/src/kadmin/dbutil/kdb5_util.c
|
||||
+++ b/src/kadmin/dbutil/kdb5_util.c
|
||||
@@ -600,6 +600,9 @@ add_random_key(int argc, char **argv)
|
||||
exit_status++;
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ dbent->mask |= KADM5_ATTRIBUTES | KADM5_KEY_DATA | KADM5_TL_DATA;
|
||||
+
|
||||
ret = krb5_db_put_principal(util_context, dbent);
|
||||
krb5_db_free_principal(util_context, dbent);
|
||||
if (ret) {
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,64 @@
|
||||
From 81e50cfb3b83a62d2a1e604a0854a9f346bdd6f9 Mon Sep 17 00:00:00 2001
|
||||
From: Zoltan Borbely <Zoltan.Borbely@morganstanley.com>
|
||||
Date: Tue, 28 Jan 2025 16:39:25 -0500
|
||||
Subject: [PATCH] Prevent overflow when calculating ulog block size
|
||||
|
||||
In kdb_log.c:resize(), log an error and fail if the update size is
|
||||
larger than the largest possible block size (2^16-1).
|
||||
|
||||
CVE-2025-24528:
|
||||
|
||||
In MIT krb5 release 1.7 and later with incremental propagation
|
||||
enabled, an authenticated attacker can cause kadmind to write beyond
|
||||
the end of the mapped region for the iprop log file, likely causing a
|
||||
process crash.
|
||||
|
||||
[ghudson@mit.edu: edited commit message and added CVE description]
|
||||
|
||||
ticket: 9159 (new)
|
||||
tags: pullup
|
||||
target_version: 1.21-next
|
||||
|
||||
(cherry picked from commit 78ceba024b64d49612375be4a12d1c066b0bfbd0)
|
||||
---
|
||||
src/lib/kdb/kdb_log.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
|
||||
index e9b95fce59..c805ebd988 100644
|
||||
--- a/src/lib/kdb/kdb_log.c
|
||||
+++ b/src/lib/kdb/kdb_log.c
|
||||
@@ -183,7 +183,7 @@ extend_file_to(int fd, unsigned int new_size)
|
||||
*/
|
||||
static krb5_error_code
|
||||
resize(kdb_hlog_t *ulog, uint32_t ulogentries, int ulogfd,
|
||||
- unsigned int recsize)
|
||||
+ unsigned int recsize, const kdb_incr_update_t *upd)
|
||||
{
|
||||
unsigned int new_block, new_size;
|
||||
|
||||
@@ -195,6 +195,12 @@ resize(kdb_hlog_t *ulog, uint32_t ulogentries, int ulogfd,
|
||||
new_block *= ULOG_BLOCK;
|
||||
new_size += ulogentries * new_block;
|
||||
|
||||
+ if (new_block > UINT16_MAX) {
|
||||
+ syslog(LOG_ERR, _("ulog overflow caused by principal %.*s"),
|
||||
+ upd->kdb_princ_name.utf8str_t_len,
|
||||
+ upd->kdb_princ_name.utf8str_t_val);
|
||||
+ return KRB5_LOG_ERROR;
|
||||
+ }
|
||||
if (new_size > MAXLOGLEN)
|
||||
return KRB5_LOG_ERROR;
|
||||
|
||||
@@ -291,7 +297,7 @@ store_update(kdb_log_context *log_ctx, kdb_incr_update_t *upd)
|
||||
recsize = sizeof(kdb_ent_header_t) + upd_size;
|
||||
|
||||
if (recsize > ulog->kdb_block) {
|
||||
- retval = resize(ulog, ulogentries, log_ctx->ulogfd, recsize);
|
||||
+ retval = resize(ulog, ulogentries, log_ctx->ulogfd, recsize, upd);
|
||||
if (retval)
|
||||
return retval;
|
||||
}
|
||||
--
|
||||
2.48.1
|
||||
|
@ -34,7 +34,7 @@
|
||||
#
|
||||
# baserelease is what we have standardized across Fedora and what
|
||||
# rpmdev-bumpspec knows how to handle.
|
||||
%global baserelease 3
|
||||
%global baserelease 6
|
||||
|
||||
# This should be e.g. beta1 or %%nil
|
||||
%global pre_release %nil
|
||||
@ -106,6 +106,18 @@ Patch0020: 0020-Avoid-strict-prototype-compiler-errors.patch
|
||||
Patch0021: 0021-Fix-leak-in-KDC-NDR-encoding.patch
|
||||
Patch0022: 0022-Fix-two-unlikely-memory-leaks.patch
|
||||
Patch0023: 0023-Fix-vulnerabilities-in-GSS-message-token-handling.patch
|
||||
Patch0024: 0024-Remove-PKINIT-RSA-support.patch
|
||||
Patch0025: 0025-Fix-various-issues-detected-by-static-analysis.patch
|
||||
Patch0026: 0026-Generate-and-verify-message-MACs-in-libkrad.patch
|
||||
Patch0027: 0027-PKINIT-ECDH-support.patch
|
||||
Patch0028: 0028-Add-ecdsa-with-sha512-256-to-supportedCMSTypes.patch
|
||||
Patch0029: 0029-Get-rid-of-pkinit_crypto_openssl.h.patch
|
||||
Patch0030: 0030-Use-SoftHSMv2-for-PKCS11-PKINIT-tests.patch
|
||||
Patch0031: 0031-Simplify-PKINIT-cert-representation.patch
|
||||
Patch0032: 0032-Support-PKCS11-EC-client-certs-in-PKINIT.patch
|
||||
Patch0033: 0033-Improve-PKCS11-error-reporting-in-PKINIT.patch
|
||||
Patch0034: 0034-Set-missing-mask-flags-for-kdb5_util-operations.patch
|
||||
Patch0035: 0035-Prevent-overflow-when-calculating-ulog-block-size.patch
|
||||
|
||||
License: MIT
|
||||
URL: https://web.mit.edu/kerberos/www/
|
||||
@ -134,6 +146,8 @@ BuildRequires: net-tools, rpcbind
|
||||
BuildRequires: hostname
|
||||
BuildRequires: iproute
|
||||
BuildRequires: python3-pyrad
|
||||
BuildRequires: opensc
|
||||
BuildRequires: softhsm
|
||||
%endif
|
||||
|
||||
# Need KDFs. This is the "real" version
|
||||
@ -670,6 +684,26 @@ exit 0
|
||||
%{_libdir}/libkadm5srv_mit.so.*
|
||||
|
||||
%changelog
|
||||
* Wed Jan 29 2025 Julien Rische <jrische@redhat.com> - 1.21.1-6
|
||||
- Prevent overflow when calculating ulog block size (CVE-2025-24528)
|
||||
Resolves: RHEL-76759
|
||||
|
||||
* Fri Jan 17 2025 Julien Rische <jrische@redhat.com> - 1.21.1-5
|
||||
- Support PKCS11 EC client certs in PKINIT
|
||||
Resolves: RHEL-74374
|
||||
- kdb5_util: fix DB entry flags on modification
|
||||
Resolves: RHEL-56059
|
||||
- Add ECDH support for PKINIT (RFC5349)
|
||||
Resolves: RHEL-4902
|
||||
|
||||
* Thu Oct 17 2024 Julien Rische <jrische@redhat.com> - 1.21.1-4
|
||||
- libkrad: implement support for Message-Authenticator (CVE-2024-3596)
|
||||
Resolves: RHEL-55423
|
||||
- Fix various issues detected by static analysis
|
||||
Resolves: RHEL-58216
|
||||
- Remove RSA protocol for PKINIT
|
||||
Resolves: RHEL-15323
|
||||
|
||||
* Fri Jul 05 2024 Julien Rische <jrische@redhat.com> - 1.21.1-3
|
||||
- CVE-2024-37370 CVE-2024-37371
|
||||
Fix vulnerabilities in GSS message token handling
|
||||
|
Loading…
Reference in New Issue
Block a user