diff options
Diffstat (limited to 'recipes-security/sssd/files/CVE-2022-4254-1.patch')
-rw-r--r-- | recipes-security/sssd/files/CVE-2022-4254-1.patch | 515 |
1 files changed, 515 insertions, 0 deletions
diff --git a/recipes-security/sssd/files/CVE-2022-4254-1.patch b/recipes-security/sssd/files/CVE-2022-4254-1.patch new file mode 100644 index 0000000..a52ce1a --- /dev/null +++ b/recipes-security/sssd/files/CVE-2022-4254-1.patch @@ -0,0 +1,515 @@ +From 1c40208aa1e0f9a17cc4f336c99bcaa6977592d3 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Tue, 27 Nov 2018 16:40:01 +0100 +Subject: [PATCH] certmap: add sss_certmap_display_cert_content() + +To make debugging and writing certificate mapping and matching rules +more easy a new function is added to libsss_certmap to display the +certificate content as seen by libsss_certmap. Please note that the +actual output might change in future. + +Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> + +CVE: CVE-2022-4254 +Upstream-Status: Backport [https://github.com/SSSD/sssd/commit/1c40208aa1e0f9a17cc4f336c99bcaa6977592d3] +Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> +--- + Makefile.am | 2 +- + src/lib/certmap/sss_certmap.c | 142 ++++++++++++++++++++++ + src/lib/certmap/sss_certmap.exports | 5 + + src/lib/certmap/sss_certmap.h | 18 +++ + src/lib/certmap/sss_certmap_int.h | 31 ++++- + src/lib/certmap/sss_certmap_krb5_match.c | 145 +++++++++++------------ + 6 files changed, 261 insertions(+), 82 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 4475b3d..29cd93c 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1835,7 +1835,7 @@ libsss_certmap_la_LIBADD = \ + $(NULL) + libsss_certmap_la_LDFLAGS = \ + -Wl,--version-script,$(srcdir)/src/lib/certmap/sss_certmap.exports \ +- -version-info 0:0:0 ++ -version-info 1:0:1 + + if HAVE_NSS + libsss_certmap_la_SOURCES += \ +diff --git a/src/lib/certmap/sss_certmap.c b/src/lib/certmap/sss_certmap.c +index f6f6f98..c60ac24 100644 +--- a/src/lib/certmap/sss_certmap.c ++++ b/src/lib/certmap/sss_certmap.c +@@ -914,3 +914,145 @@ void sss_certmap_free_filter_and_domains(char *filter, char **domains) + talloc_free(filter); + talloc_free(domains); + } ++ ++static const char *sss_eku_oid2name(const char *oid) ++{ ++ size_t c; ++ ++ for (c = 0; sss_ext_key_usage[c].name != NULL; c++) { ++ if (strcmp(sss_ext_key_usage[c].oid, oid) == 0) { ++ return sss_ext_key_usage[c].name; ++ } ++ } ++ ++ return NULL; ++} ++ ++struct parsed_template san_parsed_template[] = { ++ { NULL, NULL, NULL }, /* SAN_OTHER_NAME handled separately */ ++ { "subject_rfc822_name", NULL, NULL}, ++ { "subject_dns_name", NULL, NULL}, ++ { "subject_x400_address", NULL, NULL}, ++ { "subject_directory_name", NULL, NULL}, ++ { "subject_ediparty_name", NULL, NULL}, ++ { "subject_uri", NULL, NULL}, ++ { "subject_ip_address", NULL, NULL}, ++ { "subject_registered_id", NULL, NULL}, ++ { "subject_pkinit_principal", NULL, NULL}, ++ { "subject_nt_principal", NULL, NULL}, ++ { "subject_principal", NULL, NULL}, ++ { NULL, NULL, NULL }, /* SAN_STRING_OTHER_NAME handled separately */ ++ { NULL, NULL, NULL } /* SAN_END */ ++}; ++ ++int sss_cert_dump_content(TALLOC_CTX *mem_ctx, struct sss_cert_content *c, ++ char **content_str) ++{ ++ char *out = NULL; ++ size_t o; ++ struct san_list *s; ++ struct sss_certmap_ctx *ctx = NULL; ++ char *expanded = NULL; ++ int ret; ++ char *b64 = NULL; ++ const char *eku_str = NULL; ++ ++ ret = sss_certmap_init(mem_ctx, NULL, NULL, &ctx); ++ if (ret != EOK) { ++ return ret; ++ } ++ ++ out = talloc_strdup(mem_ctx, "sss cert content (format might change):\n"); ++ if (out == NULL) return ENOMEM; ++ ++ out = talloc_asprintf_append(out, "Issuer: %s\n", c->issuer_str != NULL ++ ? c->issuer_str ++ : "- not available -"); ++ if (out == NULL) return ENOMEM; ++ out = talloc_asprintf_append(out, "Subject: %s\n", c->subject_str != NULL ++ ? c->subject_str ++ : "- not available -"); ++ if (out == NULL) return ENOMEM; ++ ++ out = talloc_asprintf_append(out, "Key Usage: %u(0x%04x)", c->key_usage, ++ c->key_usage); ++ if (out == NULL) return ENOMEM; ++ ++ if (c->key_usage != 0) { ++ out = talloc_asprintf_append(out, " ("); ++ if (out == NULL) return ENOMEM; ++ for (o = 0; sss_key_usage[o].name != NULL; o++) { ++ if ((c->key_usage & sss_key_usage[o].flag) != 0) { ++ out = talloc_asprintf_append(out, "%s%s", ++ o == 0 ? "" : ",", ++ sss_key_usage[o].name); ++ if (out == NULL) return ENOMEM; ++ } ++ } ++ out = talloc_asprintf_append(out, ")"); ++ if (out == NULL) return ENOMEM; ++ } ++ out = talloc_asprintf_append(out, "\n"); ++ if (out == NULL) return ENOMEM; ++ ++ for (o = 0; c->extended_key_usage_oids[o] != NULL; o++) { ++ eku_str = sss_eku_oid2name(c->extended_key_usage_oids[o]); ++ out = talloc_asprintf_append(out, "Extended Key Usage #%zu: %s%s%s%s\n", ++ o, c->extended_key_usage_oids[o], ++ eku_str == NULL ? "" : " (", ++ eku_str == NULL ? "" : eku_str, ++ eku_str == NULL ? "" : ")"); ++ if (out == NULL) return ENOMEM; ++ } ++ ++ DLIST_FOR_EACH(s, c->san_list) { ++ out = talloc_asprintf_append(out, "SAN type: %s\n", ++ s->san_opt < SAN_END ++ ? sss_san_names[s->san_opt].name ++ : "- unsupported -"); ++ if (out == NULL) return ENOMEM; ++ ++ if (san_parsed_template[s->san_opt].name != NULL) { ++ ret = expand_san(ctx, &san_parsed_template[s->san_opt], c->san_list, ++ &expanded); ++ if (ret != EOK) { ++ return ret; ++ } ++ out = talloc_asprintf_append(out, " %s=%s\n\n", ++ san_parsed_template[s->san_opt].name, ++ expanded); ++ talloc_free(expanded); ++ if (out == NULL) return ENOMEM; ++ } else if (s->san_opt == SAN_STRING_OTHER_NAME) { ++ b64 = sss_base64_encode(mem_ctx, s->bin_val, s->bin_val_len); ++ out = talloc_asprintf_append(out, " %s=%s\n\n", s->other_name_oid, ++ b64 != NULL ? b64 ++ : "- cannot encode -"); ++ talloc_free(b64); ++ } ++ } ++ ++ *content_str = out; ++ ++ return EOK; ++} ++ ++int sss_certmap_display_cert_content(TALLOC_CTX *mem_cxt, ++ const uint8_t *der_cert, size_t der_size, ++ char **desc) ++{ ++ int ret; ++ struct sss_cert_content *content; ++ ++ ret = sss_cert_get_content(mem_cxt, der_cert, der_size, &content); ++ if (ret != EOK) { ++ return ret; ++ } ++ ++ ret = sss_cert_dump_content(mem_cxt, content, desc); ++ if (ret != EOK) { ++ return ret; ++ } ++ ++ return 0; ++} +diff --git a/src/lib/certmap/sss_certmap.exports b/src/lib/certmap/sss_certmap.exports +index 8b5d536..a9e48d6 100644 +--- a/src/lib/certmap/sss_certmap.exports ++++ b/src/lib/certmap/sss_certmap.exports +@@ -11,3 +11,8 @@ SSS_CERTMAP_0.0 { + local: + *; + }; ++ ++SSS_CERTMAP_0.1 { ++ global: ++ sss_certmap_display_cert_content; ++} SSS_CERTMAP_0.0; +diff --git a/src/lib/certmap/sss_certmap.h b/src/lib/certmap/sss_certmap.h +index 646e0f3..7da2d1c 100644 +--- a/src/lib/certmap/sss_certmap.h ++++ b/src/lib/certmap/sss_certmap.h +@@ -146,6 +146,24 @@ int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx, + */ + void sss_certmap_free_filter_and_domains(char *filter, char **domains); + ++/** ++ * @brief Get a string with the content of the certificate used by the library ++ * ++ * @param[in] mem_ctx Talloc memory context, may be NULL ++ * @param[in] der_cert binary blog with the DER encoded certificate ++ * @param[in] der_size size of the certificate blob ++ * @param[out] desc Multiline string showing the certificate content ++ * which is used by libsss_certmap ++ * ++ * @return ++ * - 0: success ++ * - EINVAL: certificate cannot be parsed ++ * - ENOMEM: memory allocation failure ++ */ ++int sss_certmap_display_cert_content(TALLOC_CTX *mem_cxt, ++ const uint8_t *der_cert, size_t der_size, ++ char **desc); ++ + /** + * @} + */ +diff --git a/src/lib/certmap/sss_certmap_int.h b/src/lib/certmap/sss_certmap_int.h +index 479cc16..b1155e2 100644 +--- a/src/lib/certmap/sss_certmap_int.h ++++ b/src/lib/certmap/sss_certmap_int.h +@@ -101,9 +101,9 @@ enum comp_type { + }; + + struct parsed_template { +- char *name; +- char *attr_name; +- char *conversion; ++ const char *name; ++ const char *attr_name; ++ const char *conversion; + }; + + struct ldap_mapping_rule_comp { +@@ -166,6 +166,28 @@ struct san_list { + #define SSS_KU_ENCIPHER_ONLY 0x0001 + #define SSS_KU_DECIPHER_ONLY 0x8000 + ++struct sss_key_usage { ++ const char *name; ++ uint32_t flag; ++}; ++ ++extern const struct sss_key_usage sss_key_usage[]; ++ ++struct sss_ext_key_usage { ++ const char *name; ++ const char *oid; ++}; ++ ++extern const struct sss_ext_key_usage sss_ext_key_usage[]; ++ ++struct sss_san_name { ++ const char *name; ++ enum san_opt san_opt; ++ bool is_string; ++}; ++ ++extern const struct sss_san_name sss_san_names[]; ++ + struct sss_cert_content { + char *issuer_str; + const char **issuer_rdn_list; +@@ -183,6 +205,9 @@ int sss_cert_get_content(TALLOC_CTX *mem_ctx, + const uint8_t *der_blob, size_t der_size, + struct sss_cert_content **content); + ++int sss_cert_dump_content(TALLOC_CTX *mem_ctx, struct sss_cert_content *c, ++ char **content_str); ++ + char *check_ad_attr_name(TALLOC_CTX *mem_ctx, const char *rdn); + + char *openssl_2_nss_attr_name(const char *attr); +diff --git a/src/lib/certmap/sss_certmap_krb5_match.c b/src/lib/certmap/sss_certmap_krb5_match.c +index 125e925..398d3d2 100644 +--- a/src/lib/certmap/sss_certmap_krb5_match.c ++++ b/src/lib/certmap/sss_certmap_krb5_match.c +@@ -29,6 +29,59 @@ + #include "lib/certmap/sss_certmap.h" + #include "lib/certmap/sss_certmap_int.h" + ++const struct sss_key_usage sss_key_usage[] = { ++ {"digitalSignature" , SSS_KU_DIGITAL_SIGNATURE}, ++ {"nonRepudiation" , SSS_KU_NON_REPUDIATION}, ++ {"keyEncipherment" , SSS_KU_KEY_ENCIPHERMENT}, ++ {"dataEncipherment" , SSS_KU_DATA_ENCIPHERMENT}, ++ {"keyAgreement" , SSS_KU_KEY_AGREEMENT}, ++ {"keyCertSign" , SSS_KU_KEY_CERT_SIGN}, ++ {"cRLSign" , SSS_KU_CRL_SIGN}, ++ {"encipherOnly" , SSS_KU_ENCIPHER_ONLY}, ++ {"decipherOnly" , SSS_KU_DECIPHER_ONLY}, ++ {NULL ,0} ++}; ++ ++const struct sss_ext_key_usage sss_ext_key_usage[] = { ++ /* RFC 3280 section 4.2.1.13 */ ++ {"serverAuth", "1.3.6.1.5.5.7.3.1"}, ++ {"clientAuth", "1.3.6.1.5.5.7.3.2"}, ++ {"codeSigning", "1.3.6.1.5.5.7.3.3"}, ++ {"emailProtection", "1.3.6.1.5.5.7.3.4"}, ++ {"timeStamping", "1.3.6.1.5.5.7.3.8"}, ++ {"OCSPSigning", "1.3.6.1.5.5.7.3.9"}, ++ ++ /* RFC 4556 section 3.2.2 */ ++ {"KPClientAuth", "1.3.6.1.5.2.3.4"}, ++ {"pkinit", "1.3.6.1.5.2.3.4"}, ++ ++ /* https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography*/ ++ {"msScLogin", "1.3.6.1.4.1.311.20.2.2"}, ++ ++ {NULL ,0} ++}; ++ ++const struct sss_san_name sss_san_names[] = { ++ /* https://www.ietf.org/rfc/rfc3280.txt section 4.2.1.7 */ ++ {"otherName", SAN_OTHER_NAME, false}, ++ {"rfc822Name", SAN_RFC822_NAME, true}, ++ {"dNSName", SAN_DNS_NAME, true}, ++ {"x400Address", SAN_X400_ADDRESS, false}, ++ {"directoryName", SAN_DIRECTORY_NAME, true}, ++ {"ediPartyName", SAN_EDIPART_NAME, false}, ++ {"uniformResourceIdentifier", SAN_URI, true}, ++ {"iPAddress", SAN_IP_ADDRESS, true}, ++ {"registeredID", SAN_REGISTERED_ID, true}, ++ /* https://www.ietf.org/rfc/rfc4556.txt section 3.2.2 */ ++ {"pkinitSAN", SAN_PKINIT, true}, ++ /* https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography */ ++ {"ntPrincipalName", SAN_NT, true}, ++ /* both previous principal types */ ++ {"Principal", SAN_PRINCIPAL, true}, ++ {"stringOtherName", SAN_STRING_OTHER_NAME, true}, ++ {NULL, SAN_END, false} ++}; ++ + static bool is_dotted_decimal(const char *s, size_t len) + { + size_t c = 0; +@@ -145,28 +198,6 @@ static int parse_krb5_get_eku_value(TALLOC_CTX *mem_ctx, + size_t e = 0; + int eku_list_size; + +- struct ext_key_usage { +- const char *name; +- const char *oid; +- } ext_key_usage[] = { +- /* RFC 3280 section 4.2.1.13 */ +- {"serverAuth", "1.3.6.1.5.5.7.3.1"}, +- {"clientAuth", "1.3.6.1.5.5.7.3.2"}, +- {"codeSigning", "1.3.6.1.5.5.7.3.3"}, +- {"emailProtection", "1.3.6.1.5.5.7.3.4"}, +- {"timeStamping", "1.3.6.1.5.5.7.3.8"}, +- {"OCSPSigning", "1.3.6.1.5.5.7.3.9"}, +- +- /* RFC 4556 section 3.2.2 */ +- {"KPClientAuth", "1.3.6.1.5.2.3.4"}, +- {"pkinit", "1.3.6.1.5.2.3.4"}, +- +- /* https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography*/ +- {"msScLogin", "1.3.6.1.4.1.311.20.2.2"}, +- +- {NULL ,0} +- }; +- + ret = get_comp_value(mem_ctx, ctx, cur, &comp); + if (ret != 0) { + CM_DEBUG(ctx, "Failed to parse regexp."); +@@ -188,11 +219,11 @@ static int parse_krb5_get_eku_value(TALLOC_CTX *mem_ctx, + } + + for (c = 0; eku_list[c] != NULL; c++) { +- for (k = 0; ext_key_usage[k].name != NULL; k++) { +-CM_DEBUG(ctx, "[%s][%s].", eku_list[c], ext_key_usage[k].name); +- if (strcasecmp(eku_list[c], ext_key_usage[k].name) == 0) { ++ for (k = 0; sss_ext_key_usage[k].name != NULL; k++) { ++CM_DEBUG(ctx, "[%s][%s].", eku_list[c], sss_ext_key_usage[k].name); ++ if (strcasecmp(eku_list[c], sss_ext_key_usage[k].name) == 0) { + comp->eku_oid_list[e] = talloc_strdup(comp->eku_oid_list, +- ext_key_usage[k].oid); ++ sss_ext_key_usage[k].oid); + if (comp->eku_oid_list[e] == NULL) { + ret = ENOMEM; + goto done; +@@ -202,7 +233,7 @@ CM_DEBUG(ctx, "[%s][%s].", eku_list[c], ext_key_usage[k].name); + } + } + +- if (ext_key_usage[k].name == NULL) { ++ if (sss_ext_key_usage[k].name == NULL) { + /* check for an dotted-decimal OID */ + if (*(eku_list[c]) != '.') { + o = eku_list[c]; +@@ -252,23 +283,6 @@ static int parse_krb5_get_ku_value(TALLOC_CTX *mem_ctx, + size_t c; + size_t k; + +- struct key_usage { +- const char *name; +- uint32_t flag; +- } key_usage[] = { +- {"digitalSignature" , SSS_KU_DIGITAL_SIGNATURE}, +- {"nonRepudiation" , SSS_KU_NON_REPUDIATION}, +- {"keyEncipherment" , SSS_KU_KEY_ENCIPHERMENT}, +- {"dataEncipherment" , SSS_KU_DATA_ENCIPHERMENT}, +- {"keyAgreement" , SSS_KU_KEY_AGREEMENT}, +- {"keyCertSign" , SSS_KU_KEY_CERT_SIGN}, +- {"cRLSign" , SSS_KU_CRL_SIGN}, +- {"encipherOnly" , SSS_KU_ENCIPHER_ONLY}, +- {"decipherOnly" , SSS_KU_DECIPHER_ONLY}, +- {NULL ,0} +- }; +- +- + ret = get_comp_value(mem_ctx, ctx, cur, &comp); + if (ret != 0) { + CM_DEBUG(ctx, "Failed to get value."); +@@ -283,14 +297,14 @@ static int parse_krb5_get_ku_value(TALLOC_CTX *mem_ctx, + } + + for (c = 0; ku_list[c] != NULL; c++) { +- for (k = 0; key_usage[k].name != NULL; k++) { +- if (strcasecmp(ku_list[c], key_usage[k].name) == 0) { +- comp->ku |= key_usage[k].flag; ++ for (k = 0; sss_key_usage[k].name != NULL; k++) { ++ if (strcasecmp(ku_list[c], sss_key_usage[k].name) == 0) { ++ comp->ku |= sss_key_usage[k].flag; + break; + } + } + +- if (key_usage[k].name == NULL) { ++ if (sss_key_usage[k].name == NULL) { + /* FIXME: add check for numerical ku */ + CM_DEBUG(ctx, "No matching key usage found."); + ret = EINVAL; +@@ -342,31 +356,6 @@ done: + return ret; + } + +-struct san_name { +- const char *name; +- enum san_opt san_opt; +- bool is_string; +-} san_names[] = { +- /* https://www.ietf.org/rfc/rfc3280.txt section 4.2.1.7 */ +- {"otherName", SAN_OTHER_NAME, false}, +- {"rfc822Name", SAN_RFC822_NAME,true}, +- {"dNSName", SAN_DNS_NAME, true}, +- {"x400Address", SAN_X400_ADDRESS, false}, +- {"directoryName", SAN_DIRECTORY_NAME, true}, +- {"ediPartyName", SAN_EDIPART_NAME, false}, +- {"uniformResourceIdentifier", SAN_URI, true}, +- {"iPAddress", SAN_IP_ADDRESS, true}, +- {"registeredID", SAN_REGISTERED_ID, true}, +- /* https://www.ietf.org/rfc/rfc4556.txt section 3.2.2 */ +- {"pkinitSAN", SAN_PKINIT, true}, +- /* https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography */ +- {"ntPrincipalName", SAN_NT, true}, +- /* both previous principal types */ +- {"Principal", SAN_PRINCIPAL, true}, +- {"stringOtherName", SAN_STRING_OTHER_NAME, true}, +- {NULL, SAN_END, false} +-}; +- + static int parse_krb5_get_san_option(TALLOC_CTX *mem_ctx, + struct sss_certmap_ctx *ctx, + const char **cur, +@@ -388,12 +377,12 @@ static int parse_krb5_get_san_option(TALLOC_CTX *mem_ctx, + if (len == 0) { + c= SAN_PRINCIPAL; + } else { +- for (c = 0; san_names[c].name != NULL; c++) { +- if (strncasecmp(*cur, san_names[c].name, len) == 0) { ++ for (c = 0; sss_san_names[c].name != NULL; c++) { ++ if (strncasecmp(*cur, sss_san_names[c].name, len) == 0) { + break; + } + } +- if (san_names[c].name == NULL) { ++ if (sss_san_names[c].name == NULL) { + if (is_dotted_decimal(*cur, len)) { + c = SAN_STRING_OTHER_NAME; + *str_other_name_oid = talloc_strndup(mem_ctx, *cur, len); +@@ -408,7 +397,7 @@ static int parse_krb5_get_san_option(TALLOC_CTX *mem_ctx, + } + } + +- *option = san_names[c].san_opt; ++ *option = sss_san_names[c].san_opt; + *cur = end + 1; + + return 0; +@@ -432,7 +421,7 @@ static int parse_krb5_get_san_value(TALLOC_CTX *mem_ctx, + } + } + +- if (san_names[san_opt].is_string) { ++ if (sss_san_names[san_opt].is_string) { + ret = parse_krb5_get_component_value(mem_ctx, ctx, cur, &comp); + if (ret != 0) { + goto done; +-- +2.25.1 + |