8eda442b2e
Resolves: rhbz#1488327 - SELinux is preventing selinux_child from write access on the sock_file system_bus_socket Resolves: rhbz#1490402 - SSSD does not create /var/lib/sss/deskprofile and fails to download desktop profile data Resolves: upstream#3485 - getsidbyid does not work with 1.15.3 Resolves: upstream#3488 - SUDO doesn't work for IPA users on IPA clients after applying ID Views for them in IPA server Resolves: upstream#3501 - Accessing IdM kerberos ticket fails while id mapping is applied
1683 lines
57 KiB
Diff
1683 lines
57 KiB
Diff
From a20fb9cbd5f42a6ca895aea1b84347fdfea34b89 Mon Sep 17 00:00:00 2001
|
||
From: Sumit Bose <sbose@redhat.com>
|
||
Date: Tue, 14 Feb 2017 22:47:08 +0100
|
||
Subject: [PATCH 104/115] certmap: add OpenSSL implementation
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
The OpenSSL 1.1 API is used but there is a short macro block which
|
||
should added the needed compatibility if and older OpenSSL version is
|
||
used.
|
||
|
||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||
|
||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||
---
|
||
Makefile.am | 7 +-
|
||
src/lib/certmap/sss_cert_content_common.c | 199 ++++++++
|
||
src/lib/certmap/sss_cert_content_crypto.c | 778 +++++++++++++++++++++++++++++-
|
||
src/lib/certmap/sss_cert_content_nss.c | 105 +---
|
||
src/lib/certmap/sss_certmap.c | 93 +---
|
||
src/lib/certmap/sss_certmap_attr_names.c | 81 ++--
|
||
src/lib/certmap/sss_certmap_int.h | 25 +-
|
||
src/tests/cmocka/test_certmap.c | 103 +++-
|
||
8 files changed, 1167 insertions(+), 224 deletions(-)
|
||
create mode 100644 src/lib/certmap/sss_cert_content_common.c
|
||
|
||
diff --git a/Makefile.am b/Makefile.am
|
||
index 273ecc72fba6793b4f46dbb11f6541e2e1bcc930..cb5c405a453cacbe5c2464ea09c0e6353253a789 100644
|
||
--- a/Makefile.am
|
||
+++ b/Makefile.am
|
||
@@ -288,11 +288,9 @@ if HAVE_CMOCKA
|
||
simple-access-tests \
|
||
krb5_common_test \
|
||
test_iobuf \
|
||
+ sss_certmap_test \
|
||
$(NULL)
|
||
|
||
-if HAVE_NSS
|
||
-non_interactive_cmocka_based_tests += sss_certmap_test
|
||
-endif #HAVE_NSS
|
||
|
||
if HAVE_LIBRESOLV
|
||
non_interactive_cmocka_based_tests += test_resolv_fake
|
||
@@ -1804,6 +1802,7 @@ libsss_certmap_la_SOURCES = \
|
||
src/lib/certmap/sss_certmap_attr_names.c \
|
||
src/lib/certmap/sss_certmap_krb5_match.c \
|
||
src/lib/certmap/sss_certmap_ldap_mapping.c \
|
||
+ src/lib/certmap/sss_cert_content_common.c \
|
||
src/util/util_ext.c \
|
||
src/util/cert/cert_common.c \
|
||
$(NULL)
|
||
@@ -3427,7 +3426,6 @@ test_inotify_LDADD = \
|
||
libsss_test_common.la \
|
||
$(NULL)
|
||
|
||
-if HAVE_NSS
|
||
sss_certmap_test_SOURCES = \
|
||
src/tests/cmocka/test_certmap.c \
|
||
src/lib/certmap/sss_certmap_attr_names.c \
|
||
@@ -3445,7 +3443,6 @@ sss_certmap_test_LDADD = \
|
||
libsss_test_common.la \
|
||
libsss_certmap.la \
|
||
$(NULL)
|
||
-endif
|
||
|
||
if BUILD_KCM
|
||
test_kcm_json_SOURCES = \
|
||
diff --git a/src/lib/certmap/sss_cert_content_common.c b/src/lib/certmap/sss_cert_content_common.c
|
||
new file mode 100644
|
||
index 0000000000000000000000000000000000000000..42919335221b6d1a188eebe24543668bb927f18a
|
||
--- /dev/null
|
||
+++ b/src/lib/certmap/sss_cert_content_common.c
|
||
@@ -0,0 +1,199 @@
|
||
+/*
|
||
+ SSSD - certificate handling utils
|
||
+ The calls defined here should be useable outside of SSSD as well, e.g. in
|
||
+ libsss_certmap.
|
||
+
|
||
+ Copyright (C) Sumit Bose <sbose@redhat.com> 2017
|
||
+
|
||
+ This program is free software; you can redistribute it and/or modify
|
||
+ it under the terms of the GNU General Public License as published by
|
||
+ the Free Software Foundation; either version 3 of the License, or
|
||
+ (at your option) any later version.
|
||
+
|
||
+ This program is distributed in the hope that it will be useful,
|
||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
+ GNU General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU General Public License
|
||
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
+*/
|
||
+
|
||
+#include <stdbool.h>
|
||
+#include <errno.h>
|
||
+#include <string.h>
|
||
+
|
||
+#include "lib/certmap/sss_certmap_int.h"
|
||
+
|
||
+int get_short_name(TALLOC_CTX *mem_ctx, const char *full_name,
|
||
+ char delim, char **short_name)
|
||
+{
|
||
+ char *at;
|
||
+ char *s;
|
||
+
|
||
+ if (full_name == NULL || delim == '\0' || short_name == NULL) {
|
||
+ return EINVAL;
|
||
+ }
|
||
+
|
||
+ at = strchr(full_name, delim);
|
||
+ if (at != NULL) {
|
||
+ s = talloc_strndup(mem_ctx, full_name, (at - full_name));
|
||
+ } else {
|
||
+ s = talloc_strdup(mem_ctx, full_name);
|
||
+ }
|
||
+ if (s == NULL) {
|
||
+ return ENOMEM;
|
||
+ }
|
||
+
|
||
+ *short_name = s;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+int add_to_san_list(TALLOC_CTX *mem_ctx, bool is_bin,
|
||
+ enum san_opt san_opt, const uint8_t *data, size_t len,
|
||
+ struct san_list **item)
|
||
+{
|
||
+ struct san_list *i;
|
||
+
|
||
+ if (data == NULL || len == 0 || san_opt == SAN_INVALID) {
|
||
+ return EINVAL;
|
||
+ }
|
||
+
|
||
+ i = talloc_zero(mem_ctx, struct san_list);
|
||
+ if (i == NULL) {
|
||
+ return ENOMEM;
|
||
+ }
|
||
+
|
||
+ i->san_opt = san_opt;
|
||
+ if (is_bin) {
|
||
+ i->bin_val = talloc_memdup(i, data, len);
|
||
+ i->bin_val_len = len;
|
||
+ } else {
|
||
+ i->val = talloc_strndup(i, (const char *) data, len);
|
||
+ }
|
||
+ if (i->val == NULL) {
|
||
+ talloc_free(i);
|
||
+ return ENOMEM;
|
||
+ }
|
||
+
|
||
+ *item = i;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+int add_principal_to_san_list(TALLOC_CTX *mem_ctx, enum san_opt san_opt,
|
||
+ const char *princ, struct san_list **item)
|
||
+{
|
||
+ struct san_list *i = NULL;
|
||
+ int ret;
|
||
+
|
||
+ i = talloc_zero(mem_ctx, struct san_list);
|
||
+ if (i == NULL) {
|
||
+ return ENOMEM;
|
||
+ }
|
||
+ i->san_opt = san_opt;
|
||
+
|
||
+ i->val = talloc_strdup(i, princ);
|
||
+ if (i->val == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = get_short_name(i, i->val, '@', &(i->short_name));
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = 0;
|
||
+
|
||
+done:
|
||
+ if (ret == 0) {
|
||
+ *item = i;
|
||
+ } else {
|
||
+ talloc_free(i);
|
||
+ }
|
||
+
|
||
+ return ret;
|
||
+}
|
||
+
|
||
+int rdn_list_2_dn_str(TALLOC_CTX *mem_ctx, const char *conversion,
|
||
+ const char **rdn_list, char **result)
|
||
+{
|
||
+ char *str = NULL;
|
||
+ size_t c;
|
||
+ int ret;
|
||
+ char *conv = NULL;
|
||
+
|
||
+ str = talloc_strdup(mem_ctx, "");
|
||
+ if (str == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+ if (conversion == NULL || strcmp(conversion, "nss_ldap") == 0
|
||
+ || strcmp(conversion, "nss") == 0) {
|
||
+ for (c = 0; rdn_list[c] != NULL; c++);
|
||
+ while (c != 0) {
|
||
+ c--;
|
||
+ str = talloc_asprintf_append(str, "%s%s",
|
||
+ (rdn_list[c + 1] == NULL) ? "" : ",",
|
||
+ rdn_list[c]);
|
||
+ if (str == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+ };
|
||
+ } else if (strcmp(conversion, "ad_ldap") == 0) {
|
||
+ for (c = 0; rdn_list[c] != NULL; c++);
|
||
+ while (c != 0) {
|
||
+ c--;
|
||
+ conv = check_ad_attr_name(str, rdn_list[c]);
|
||
+ str = talloc_asprintf_append(str, "%s%s",
|
||
+ (rdn_list[c + 1] == NULL) ? "" : ",",
|
||
+ conv == NULL ? rdn_list[c] : conv);
|
||
+ talloc_free(conv);
|
||
+ conv = NULL;
|
||
+ if (str == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+ };
|
||
+ } else if (strcmp(conversion, "nss_x500") == 0) {
|
||
+ for (c = 0; rdn_list[c] != NULL; c++) {
|
||
+ str = talloc_asprintf_append(str, "%s%s", (c == 0) ? "" : ",",
|
||
+ rdn_list[c]);
|
||
+ if (str == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+ }
|
||
+ } else if (strcmp(conversion, "ad_x500") == 0
|
||
+ || strcmp(conversion, "ad") == 0) {
|
||
+ for (c = 0; rdn_list[c] != NULL; c++) {
|
||
+ conv = check_ad_attr_name(str, rdn_list[c]);
|
||
+ str = talloc_asprintf_append(str, "%s%s",
|
||
+ (c == 0) ? "" : ",",
|
||
+ conv == NULL ? rdn_list[c] : conv);
|
||
+ talloc_free(conv);
|
||
+ conv = NULL;
|
||
+ if (str == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+ }
|
||
+ } else {
|
||
+ ret = EINVAL;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = 0;
|
||
+
|
||
+done:
|
||
+ if (ret == 0) {
|
||
+ *result = str;
|
||
+ } else {
|
||
+ talloc_free(str);
|
||
+ }
|
||
+
|
||
+ return ret;
|
||
+}
|
||
diff --git a/src/lib/certmap/sss_cert_content_crypto.c b/src/lib/certmap/sss_cert_content_crypto.c
|
||
index bddcf9bce986bd986aa0aa5f16a0744a97ab36d6..23e065a3cfedd103dabc0ba6379472da23d422b1 100644
|
||
--- a/src/lib/certmap/sss_cert_content_crypto.c
|
||
+++ b/src/lib/certmap/sss_cert_content_crypto.c
|
||
@@ -19,14 +19,788 @@
|
||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
-#include <errno.h>
|
||
+#include "config.h"
|
||
|
||
+#include <talloc.h>
|
||
+#include <openssl/x509v3.h>
|
||
+#include <openssl/asn1.h>
|
||
+#include <openssl/asn1t.h>
|
||
+#include <openssl/err.h>
|
||
+#include <openssl/stack.h>
|
||
+#include <openssl/safestack.h>
|
||
+
|
||
+#include "util/crypto/sss_crypto.h"
|
||
+#include "util/cert.h"
|
||
#include "lib/certmap/sss_certmap.h"
|
||
#include "lib/certmap/sss_certmap_int.h"
|
||
|
||
+/* backward compatible macros for OpenSSL < 1.1 */
|
||
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||
+#define ASN1_STRING_get0_data(o) ASN1_STRING_data(o)
|
||
+#define X509_get_extension_flags(o) ((o)->ex_flags)
|
||
+#define X509_get_key_usage(o) ((o)->ex_kusage)
|
||
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
|
||
+
|
||
+typedef struct PrincipalName_st {
|
||
+ ASN1_INTEGER *name_type;
|
||
+ STACK_OF(ASN1_GENERALSTRING) *name_string;
|
||
+} PrincipalName;
|
||
+
|
||
+ASN1_SEQUENCE(PrincipalName) = {
|
||
+ ASN1_EXP(PrincipalName, name_type, ASN1_INTEGER, 0),
|
||
+ ASN1_EXP_SEQUENCE_OF(PrincipalName, name_string, ASN1_GENERALSTRING, 1)
|
||
+} ASN1_SEQUENCE_END(PrincipalName)
|
||
+
|
||
+IMPLEMENT_ASN1_FUNCTIONS(PrincipalName)
|
||
+
|
||
+typedef struct KRB5PrincipalName_st {
|
||
+ ASN1_STRING *realm;
|
||
+ PrincipalName *principal_name;
|
||
+} KRB5PrincipalName;
|
||
+
|
||
+ASN1_SEQUENCE(KRB5PrincipalName) = {
|
||
+ ASN1_EXP(KRB5PrincipalName, realm, ASN1_GENERALSTRING, 0),
|
||
+ ASN1_EXP(KRB5PrincipalName, principal_name, PrincipalName, 1)
|
||
+} ASN1_SEQUENCE_END(KRB5PrincipalName)
|
||
+
|
||
+IMPLEMENT_ASN1_FUNCTIONS(KRB5PrincipalName)
|
||
+
|
||
+enum san_opt openssl_name_type_to_san_opt(int type)
|
||
+{
|
||
+ switch (type) {
|
||
+ case GEN_OTHERNAME:
|
||
+ return SAN_OTHER_NAME;
|
||
+ case GEN_EMAIL:
|
||
+ return SAN_RFC822_NAME;
|
||
+ case GEN_DNS:
|
||
+ return SAN_DNS_NAME;
|
||
+ case GEN_X400:
|
||
+ return SAN_X400_ADDRESS;
|
||
+ case GEN_DIRNAME:
|
||
+ return SAN_DIRECTORY_NAME;
|
||
+ case GEN_EDIPARTY:
|
||
+ return SAN_EDIPART_NAME;
|
||
+ case GEN_URI:
|
||
+ return SAN_URI;
|
||
+ case GEN_IPADD:
|
||
+ return SAN_IP_ADDRESS;
|
||
+ case GEN_RID:
|
||
+ return SAN_REGISTERED_ID;
|
||
+ default:
|
||
+ return SAN_INVALID;
|
||
+ }
|
||
+}
|
||
+
|
||
+static int add_string_other_name_to_san_list(TALLOC_CTX *mem_ctx,
|
||
+ enum san_opt san_opt,
|
||
+ OTHERNAME *other_name,
|
||
+ struct san_list **item)
|
||
+{
|
||
+ struct san_list *i = NULL;
|
||
+ int ret;
|
||
+ char oid_buf[128]; /* FIXME: any other size ?? */
|
||
+ int len;
|
||
+ unsigned char *p;
|
||
+
|
||
+ len = OBJ_obj2txt(oid_buf, sizeof(oid_buf), other_name->type_id, 1);
|
||
+ if (len <= 0) {
|
||
+ return EINVAL;
|
||
+ }
|
||
+
|
||
+ i = talloc_zero(mem_ctx, struct san_list);
|
||
+ if (i == NULL) {
|
||
+ return ENOMEM;
|
||
+ }
|
||
+ i->san_opt = san_opt;
|
||
+
|
||
+ i->other_name_oid = talloc_strndup(i, oid_buf, len);
|
||
+ if (i->other_name_oid == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ len = i2d_ASN1_TYPE(other_name->value, NULL);
|
||
+ if (len <= 0) {
|
||
+ ret = EINVAL;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ i->bin_val = talloc_size(mem_ctx, len);
|
||
+ if (i->bin_val == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ /* i2d_TYPE increment the second argument so that it points to the end of
|
||
+ * the written data hence we cannot use i->bin_val directly. */
|
||
+ p = i->bin_val;
|
||
+ i->bin_val_len = i2d_ASN1_TYPE(other_name->value, &p);
|
||
+
|
||
+ ret = 0;
|
||
+
|
||
+done:
|
||
+ if (ret == 0) {
|
||
+ *item = i;
|
||
+ } else {
|
||
+ talloc_free(i);
|
||
+ }
|
||
+
|
||
+ return ret;
|
||
+}
|
||
+
|
||
+static int add_nt_princ_to_san_list(TALLOC_CTX *mem_ctx,
|
||
+ enum san_opt san_opt,
|
||
+ GENERAL_NAME *current,
|
||
+ struct san_list **item)
|
||
+{
|
||
+ struct san_list *i = NULL;
|
||
+ int ret;
|
||
+ OTHERNAME *other_name = current->d.otherName;
|
||
+
|
||
+ if (ASN1_TYPE_get(other_name->value) != V_ASN1_UTF8STRING) {
|
||
+ return EINVAL;
|
||
+ }
|
||
+
|
||
+ i = talloc_zero(mem_ctx, struct san_list);
|
||
+ if (i == NULL) {
|
||
+ return ENOMEM;
|
||
+ }
|
||
+ i->san_opt = san_opt;
|
||
+
|
||
+ i->val = talloc_strndup(i,
|
||
+ (const char *) ASN1_STRING_get0_data(
|
||
+ other_name->value->value.utf8string),
|
||
+ ASN1_STRING_length(other_name->value->value.utf8string));
|
||
+ if (i->val == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = get_short_name(i, i->val, '@', &(i->short_name));
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = 0;
|
||
+
|
||
+done:
|
||
+ if (ret == 0) {
|
||
+ *item = i;
|
||
+ } else {
|
||
+ talloc_free(i);
|
||
+ }
|
||
+
|
||
+ return ret;
|
||
+}
|
||
+
|
||
+void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t)
|
||
+{
|
||
+ if (t == NULL || t->type != V_ASN1_SEQUENCE || t->value.sequence == NULL)
|
||
+ return NULL;
|
||
+ return ASN1_item_unpack(t->value.sequence, it);
|
||
+}
|
||
+
|
||
+static int add_pkinit_princ_to_san_list(TALLOC_CTX *mem_ctx,
|
||
+ enum san_opt san_opt,
|
||
+ GENERAL_NAME *current,
|
||
+ struct san_list **item)
|
||
+{
|
||
+ struct san_list *i = NULL;
|
||
+ int ret;
|
||
+ KRB5PrincipalName *princ = NULL;
|
||
+ size_t c;
|
||
+ const unsigned char *p;
|
||
+ const ASN1_STRING *oct;
|
||
+ ASN1_GENERALSTRING *name_comp;
|
||
+
|
||
+ oct = current->d.otherName->value->value.sequence;
|
||
+ p = oct->data;
|
||
+ princ = d2i_KRB5PrincipalName(NULL, &p, oct->length);
|
||
+ if (princ == NULL) {
|
||
+ return EINVAL;
|
||
+ }
|
||
+
|
||
+ if (princ->realm == NULL
|
||
+ || princ->principal_name == NULL
|
||
+ || princ->principal_name->name_string == NULL
|
||
+ || sk_ASN1_GENERALSTRING_num(princ->principal_name->name_string)
|
||
+ == 0) {
|
||
+ ret = EINVAL;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ i = talloc_zero(mem_ctx, struct san_list);
|
||
+ if (i == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+ i->san_opt = san_opt;
|
||
+
|
||
+ i->val = talloc_strdup(i, "");
|
||
+ if (i->val == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ for (c = 0;
|
||
+ c < sk_ASN1_GENERALSTRING_num(princ->principal_name->name_string);
|
||
+ c++) {
|
||
+
|
||
+ if (c > 0) {
|
||
+ i->val = talloc_strdup_append(i->val, "/");
|
||
+ if (i->val == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ name_comp = sk_ASN1_GENERALSTRING_value(
|
||
+ princ->principal_name->name_string, c);
|
||
+ i->val = talloc_strndup_append(i->val,
|
||
+ (const char *) ASN1_STRING_get0_data(name_comp),
|
||
+ ASN1_STRING_length(name_comp));
|
||
+ if (i->val == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ i->val = talloc_asprintf_append(i->val, "@%.*s",
|
||
+ ASN1_STRING_length(princ->realm),
|
||
+ ASN1_STRING_get0_data(princ->realm));
|
||
+ if (i->val == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = get_short_name(i, i->val, '@', &(i->short_name));
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = 0;
|
||
+
|
||
+done:
|
||
+ KRB5PrincipalName_free(princ);
|
||
+ if (ret == 0) {
|
||
+ *item = i;
|
||
+ } else {
|
||
+ talloc_free(i);
|
||
+ }
|
||
+
|
||
+ return ret;
|
||
+}
|
||
+
|
||
+static int add_ip_to_san_list(TALLOC_CTX *mem_ctx, enum san_opt san_opt,
|
||
+ const uint8_t *data, size_t len,
|
||
+ struct san_list **item)
|
||
+{
|
||
+ struct san_list *i = NULL;
|
||
+
|
||
+ i = talloc_zero(mem_ctx, struct san_list);
|
||
+ if (i == NULL) {
|
||
+ return ENOMEM;
|
||
+ }
|
||
+ i->san_opt = san_opt;
|
||
+
|
||
+ i->val = talloc_strndup(i, (const char *) data, len);
|
||
+ if (i->val == NULL) {
|
||
+ talloc_free(i);
|
||
+ return ENOMEM;
|
||
+ }
|
||
+
|
||
+ *item = i;
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int get_rdn_list(TALLOC_CTX *mem_ctx, X509_NAME *name,
|
||
+ const char ***rdn_list)
|
||
+{
|
||
+ int ret;
|
||
+ size_t c;
|
||
+ const char **list = NULL;
|
||
+ X509_NAME_ENTRY *e;
|
||
+ ASN1_STRING *rdn_str;
|
||
+ ASN1_OBJECT *rdn_name;
|
||
+ BIO *bio_mem = NULL;
|
||
+ char *tmp_str;
|
||
+ long tmp_str_size;
|
||
+
|
||
+ int nid;
|
||
+ const char *sn;
|
||
+
|
||
+ bio_mem = BIO_new(BIO_s_mem());
|
||
+ if (bio_mem == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ list = talloc_zero_array(mem_ctx, const char *,
|
||
+ X509_NAME_entry_count(name) + 1);
|
||
+ if (list == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ for (c = 0; c < X509_NAME_entry_count(name); c++) {
|
||
+ e = X509_NAME_get_entry(name, c);
|
||
+ rdn_str = X509_NAME_ENTRY_get_data(e);
|
||
+
|
||
+ ret = ASN1_STRING_print_ex(bio_mem, rdn_str, ASN1_STRFLGS_RFC2253);
|
||
+ if (ret < 0) {
|
||
+ ret = EIO;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ tmp_str_size = BIO_get_mem_data(bio_mem, &tmp_str);
|
||
+ if (tmp_str_size == 0) {
|
||
+ ret = EINVAL;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ rdn_name = X509_NAME_ENTRY_get_object(e);
|
||
+ nid = OBJ_obj2nid(rdn_name);
|
||
+ sn = OBJ_nid2sn(nid);
|
||
+
|
||
+ list[c] = talloc_asprintf(list, "%s=%.*s", openssl_2_nss_attr_name(sn),
|
||
+ (int) tmp_str_size, tmp_str);
|
||
+ ret = BIO_reset(bio_mem);
|
||
+ if (ret != 1) {
|
||
+ /* BIO_reset() for BIO_s_mem returns 1 for sucess */
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+ if (list[c] == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ ret = 0;
|
||
+
|
||
+done:
|
||
+ BIO_free_all(bio_mem);
|
||
+ if (ret == 0) {
|
||
+ *rdn_list = list;
|
||
+ } else {
|
||
+ talloc_free(list);
|
||
+ }
|
||
+
|
||
+ return ret;
|
||
+}
|
||
+
|
||
+static int add_rdn_list_to_san_list(TALLOC_CTX *mem_ctx,
|
||
+ enum san_opt san_opt,
|
||
+ X509_NAME *name,
|
||
+ struct san_list **item)
|
||
+{
|
||
+ struct san_list *i = NULL;
|
||
+ int ret;
|
||
+
|
||
+ i = talloc_zero(mem_ctx, struct san_list);
|
||
+ if (i == NULL) {
|
||
+ return ENOMEM;
|
||
+ }
|
||
+ i->san_opt = san_opt;
|
||
+
|
||
+ ret = get_rdn_list(i, name, &(i->rdn_list));
|
||
+ if (ret != 0) {
|
||
+ talloc_free(i);
|
||
+ return ret;
|
||
+ }
|
||
+
|
||
+ *item = i;
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int add_oid_to_san_list(TALLOC_CTX *mem_ctx,
|
||
+ enum san_opt san_opt,
|
||
+ ASN1_OBJECT *oid,
|
||
+ struct san_list **item)
|
||
+{
|
||
+ struct san_list *i = NULL;
|
||
+ char oid_buf[128]; /* FIXME: any other size ?? */
|
||
+ int len;
|
||
+
|
||
+ len = OBJ_obj2txt(oid_buf, sizeof(oid_buf), oid, 1);
|
||
+ if (len <= 0) {
|
||
+ return EINVAL;
|
||
+ }
|
||
+
|
||
+ i = talloc_zero(mem_ctx, struct san_list);
|
||
+ if (i == NULL) {
|
||
+ return ENOMEM;
|
||
+ }
|
||
+ i->san_opt = san_opt;
|
||
+
|
||
+ i->val = talloc_strndup(i, oid_buf, len);
|
||
+ if (i->val == NULL) {
|
||
+ talloc_free(i);
|
||
+ return ENOMEM;
|
||
+ }
|
||
+
|
||
+ *item = i;
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int get_san(TALLOC_CTX *mem_ctx, X509 *cert, struct san_list **san_list)
|
||
+{
|
||
+ STACK_OF(GENERAL_NAME) *extsan = NULL;
|
||
+ GENERAL_NAME *current;
|
||
+ size_t c;
|
||
+ int ret;
|
||
+ int crit;
|
||
+ struct san_list *list = NULL;
|
||
+ struct san_list *item = NULL;
|
||
+ struct san_list *item_s = NULL;
|
||
+ struct san_list *item_p = NULL;
|
||
+ struct san_list *item_pb = NULL;
|
||
+ int len;
|
||
+ unsigned char *data;
|
||
+ unsigned char *p;
|
||
+
|
||
+ extsan = X509_get_ext_d2i(cert, NID_subject_alt_name, &crit, NULL);
|
||
+ if (extsan == NULL) {
|
||
+ if (crit == -1) { /* extension could not be found */
|
||
+ return EOK;
|
||
+ } else {
|
||
+ return EINVAL;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ for (c = 0; c < sk_GENERAL_NAME_num(extsan); c++) {
|
||
+ current = sk_GENERAL_NAME_value(extsan, c);
|
||
+ switch (current->type) {
|
||
+ case GEN_OTHERNAME:
|
||
+ ret = add_string_other_name_to_san_list(mem_ctx,
|
||
+ SAN_STRING_OTHER_NAME,
|
||
+ current->d.otherName,
|
||
+ &item_s);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+ DLIST_ADD(list, item_s);
|
||
+
|
||
+ item_p = NULL;
|
||
+ if (strcmp(item_s->other_name_oid, NT_PRINCIPAL_OID) == 0) {
|
||
+ ret = add_nt_princ_to_san_list(mem_ctx, SAN_NT, current,
|
||
+ &item_p);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+ DLIST_ADD(list, item_p);
|
||
+ } else if (strcmp(item_s->other_name_oid, PKINIT_OID) == 0) {
|
||
+ ret = add_pkinit_princ_to_san_list(mem_ctx, SAN_PKINIT,
|
||
+ current, &item_p);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+ DLIST_ADD(list, item_p);
|
||
+ }
|
||
+
|
||
+ if (item_p != NULL) {
|
||
+ ret = add_principal_to_san_list(mem_ctx, SAN_PRINCIPAL,
|
||
+ item_p->val, &item_pb);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+ DLIST_ADD(list, item_pb);
|
||
+ }
|
||
+
|
||
+ break;
|
||
+ break;
|
||
+ case GEN_EMAIL:
|
||
+ ret = add_to_san_list(mem_ctx, false,
|
||
+ openssl_name_type_to_san_opt(current->type),
|
||
+ ASN1_STRING_get0_data(current->d.rfc822Name),
|
||
+ ASN1_STRING_length(current->d.rfc822Name),
|
||
+ &item);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = get_short_name(item, item->val, '@', &(item->short_name));
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ DLIST_ADD(list, item);
|
||
+ break;
|
||
+ case GEN_DNS:
|
||
+ ret = add_to_san_list(mem_ctx, false,
|
||
+ openssl_name_type_to_san_opt(current->type),
|
||
+ ASN1_STRING_get0_data(current->d.dNSName),
|
||
+ ASN1_STRING_length(current->d.dNSName),
|
||
+ &item);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = get_short_name(item, item->val, '.', &(item->short_name));
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ DLIST_ADD(list, item);
|
||
+ break;
|
||
+ case GEN_URI:
|
||
+ ret = add_to_san_list(mem_ctx, false,
|
||
+ openssl_name_type_to_san_opt(current->type),
|
||
+ ASN1_STRING_get0_data(current->d.uniformResourceIdentifier),
|
||
+ ASN1_STRING_length(current->d.uniformResourceIdentifier),
|
||
+ &item);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+ break;
|
||
+ case GEN_IPADD:
|
||
+ ret = add_ip_to_san_list(mem_ctx,
|
||
+ openssl_name_type_to_san_opt(current->type),
|
||
+ ASN1_STRING_get0_data(current->d.iPAddress),
|
||
+ ASN1_STRING_length(current->d.iPAddress),
|
||
+ &item);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+ DLIST_ADD(list, item);
|
||
+ break;
|
||
+ case GEN_DIRNAME:
|
||
+ ret = add_rdn_list_to_san_list(mem_ctx,
|
||
+ openssl_name_type_to_san_opt(current->type),
|
||
+ current->d.directoryName, &item);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+ DLIST_ADD(list, item);
|
||
+ break;
|
||
+ case GEN_RID:
|
||
+ ret = add_oid_to_san_list(mem_ctx,
|
||
+ openssl_name_type_to_san_opt(current->type),
|
||
+ current->d.registeredID, &item);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+ DLIST_ADD(list, item);
|
||
+ break;
|
||
+ case GEN_X400:
|
||
+ len = i2d_ASN1_TYPE(current->d.x400Address, NULL);
|
||
+ if (len <= 0) {
|
||
+ ret = EINVAL;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ data = talloc_size(mem_ctx, len);
|
||
+ if (data == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ /* i2d_TYPE increment the second argument so that it points to the end of
|
||
+ * the written data hence we cannot use i->bin_val directly. */
|
||
+ p = data;
|
||
+ len = i2d_ASN1_TYPE(current->d.x400Address, &p);
|
||
+
|
||
+ ret = add_to_san_list(mem_ctx, true,
|
||
+ openssl_name_type_to_san_opt(current->type),
|
||
+ data, len, &item);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+ DLIST_ADD(list, item);
|
||
+ break;
|
||
+ case GEN_EDIPARTY:
|
||
+ len = i2d_EDIPARTYNAME(current->d.ediPartyName, NULL);
|
||
+ if (len <= 0) {
|
||
+ ret = EINVAL;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ data = talloc_size(mem_ctx, len);
|
||
+ if (data == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ /* i2d_TYPE increment the second argument so that it points to the end of
|
||
+ * the written data hence we cannot use i->bin_val directly. */
|
||
+ p = data;
|
||
+ len = i2d_EDIPARTYNAME(current->d.ediPartyName, &data);
|
||
+
|
||
+ ret = add_to_san_list(mem_ctx, true,
|
||
+ openssl_name_type_to_san_opt(current->type),
|
||
+ data, len, &item);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+ DLIST_ADD(list, item);
|
||
+ break;
|
||
+ default:
|
||
+ ret = EINVAL;
|
||
+ goto done;
|
||
+ }
|
||
+ }
|
||
+
|
||
+done:
|
||
+ GENERAL_NAMES_free(extsan);
|
||
+
|
||
+ if (ret == EOK) {
|
||
+ *san_list = list;
|
||
+ }
|
||
+
|
||
+ return ret;
|
||
+}
|
||
+
|
||
+static int get_extended_key_usage_oids(TALLOC_CTX *mem_ctx,
|
||
+ X509 *cert,
|
||
+ const char ***_oids)
|
||
+{
|
||
+ const char **oids_list = NULL;
|
||
+ size_t c;
|
||
+ int ret;
|
||
+ char oid_buf[128]; /* FIXME: any other size ?? */
|
||
+ int len;
|
||
+ EXTENDED_KEY_USAGE *extusage = NULL;
|
||
+
|
||
+ extusage = X509_get_ext_d2i(cert, NID_ext_key_usage, NULL, NULL);
|
||
+ if (extusage == NULL) {
|
||
+ return EIO;
|
||
+ }
|
||
+
|
||
+ oids_list = talloc_zero_array(mem_ctx, const char *,
|
||
+ sk_ASN1_OBJECT_num(extusage) + 1);
|
||
+ if (oids_list == NULL) {
|
||
+ return ENOMEM;
|
||
+ }
|
||
+
|
||
+ for (c = 0; c < sk_ASN1_OBJECT_num(extusage); c++) {
|
||
+ len = OBJ_obj2txt(oid_buf, sizeof(oid_buf),
|
||
+ sk_ASN1_OBJECT_value(extusage, c), 1);
|
||
+ if (len < 0) {
|
||
+ return EIO;
|
||
+ }
|
||
+
|
||
+ oids_list[c] = talloc_strndup(oids_list, oid_buf, len);
|
||
+ if (oids_list[c] == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ ret = 0;
|
||
+
|
||
+done:
|
||
+ sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
|
||
+ if (ret == 0) {
|
||
+ *_oids = oids_list;
|
||
+ } else {
|
||
+ talloc_free(oids_list);
|
||
+ }
|
||
+
|
||
+ return ret;
|
||
+}
|
||
+
|
||
int sss_cert_get_content(TALLOC_CTX *mem_ctx,
|
||
const uint8_t *der_blob, size_t der_size,
|
||
struct sss_cert_content **content)
|
||
{
|
||
- return EINVAL;
|
||
+ int ret;
|
||
+ struct sss_cert_content *cont = NULL;
|
||
+ X509 *cert = NULL;
|
||
+ const unsigned char *der;
|
||
+ BIO *bio_mem = NULL;
|
||
+ X509_NAME *tmp_name;
|
||
+
|
||
+ if (der_blob == NULL || der_size == 0) {
|
||
+ return EINVAL;
|
||
+ }
|
||
+
|
||
+ cont = talloc_zero(mem_ctx, struct sss_cert_content);
|
||
+ if (cont == NULL) {
|
||
+ return ENOMEM;
|
||
+ }
|
||
+
|
||
+ bio_mem = BIO_new(BIO_s_mem());
|
||
+ if (bio_mem == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ der = (const unsigned char *) der_blob;
|
||
+ cert = d2i_X509(NULL, &der, (int) der_size);
|
||
+ if (cert == NULL) {
|
||
+ ret = EINVAL;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ tmp_name = X509_get_issuer_name(cert);
|
||
+
|
||
+ ret = get_rdn_list(cont, tmp_name, &cont->issuer_rdn_list);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = rdn_list_2_dn_str(cont, NULL, cont->issuer_rdn_list,
|
||
+ &cont->issuer_str);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ tmp_name = X509_get_subject_name(cert);
|
||
+
|
||
+ ret = get_rdn_list(cont, tmp_name, &cont->subject_rdn_list);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = rdn_list_2_dn_str(cont, NULL, cont->subject_rdn_list,
|
||
+ &cont->subject_str);
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = X509_check_purpose(cert, -1, -1);
|
||
+ if (ret < 0) {
|
||
+ ret = EIO;
|
||
+ goto done;
|
||
+ }
|
||
+ if (!(X509_get_extension_flags(cert) & EXFLAG_KUSAGE)) {
|
||
+ ret = EINVAL;
|
||
+ goto done;
|
||
+ }
|
||
+ cont->key_usage = X509_get_key_usage(cert);
|
||
+
|
||
+ ret = get_extended_key_usage_oids(cont, cert,
|
||
+ &(cont->extended_key_usage_oids));
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ ret = get_san(cont, cert, &(cont->san_list));
|
||
+ if (ret != 0) {
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ cont->cert_der = talloc_memdup(cont, der_blob, der_size);
|
||
+ if (cont->cert_der == NULL) {
|
||
+ ret = ENOMEM;
|
||
+ goto done;
|
||
+ }
|
||
+
|
||
+ cont->cert_der_size = der_size;
|
||
+
|
||
+ ret = EOK;
|
||
+
|
||
+done:
|
||
+
|
||
+ X509_free(cert);
|
||
+ BIO_free_all(bio_mem);
|
||
+ CRYPTO_cleanup_all_ex_data();
|
||
+
|
||
+ if (ret == EOK) {
|
||
+ *content = cont;
|
||
+ } else {
|
||
+ talloc_free(cont);
|
||
+ }
|
||
+
|
||
+ return ret;
|
||
}
|
||
diff --git a/src/lib/certmap/sss_cert_content_nss.c b/src/lib/certmap/sss_cert_content_nss.c
|
||
index d3182895465706c87503b8abb0cea49b7677625d..9b9409797228e906ce59de2472677cb292692610 100644
|
||
--- a/src/lib/certmap/sss_cert_content_nss.c
|
||
+++ b/src/lib/certmap/sss_cert_content_nss.c
|
||
@@ -278,38 +278,6 @@ enum san_opt nss_name_type_to_san_opt(CERTGeneralNameType type)
|
||
}
|
||
}
|
||
|
||
-static int add_to_san_list(TALLOC_CTX *mem_ctx, bool is_bin,
|
||
- enum san_opt san_opt, uint8_t *data, size_t len,
|
||
- struct san_list **item)
|
||
-{
|
||
- struct san_list *i;
|
||
-
|
||
- if (data == NULL || len == 0 || san_opt == SAN_INVALID) {
|
||
- return EINVAL;
|
||
- }
|
||
-
|
||
- i = talloc_zero(mem_ctx, struct san_list);
|
||
- if (i == NULL) {
|
||
- return ENOMEM;
|
||
- }
|
||
-
|
||
- i->san_opt = san_opt;
|
||
- if (is_bin) {
|
||
- i->bin_val = talloc_memdup(i, data, len);
|
||
- i->bin_val_len = len;
|
||
- } else {
|
||
- i->val = talloc_strndup(i, (char *) data, len);
|
||
- }
|
||
- if (i->val == NULL) {
|
||
- talloc_free(i);
|
||
- return ENOMEM;
|
||
- }
|
||
-
|
||
- *item = i;
|
||
-
|
||
- return 0;
|
||
-}
|
||
-
|
||
/* taken from pkinit_crypto_nss.c of MIT Kerberos */
|
||
/* KerberosString: RFC 4120, 5.2.1. */
|
||
static const SEC_ASN1Template kerberos_string_template[] = {
|
||
@@ -397,9 +365,6 @@ static const SEC_ASN1Template kerberos_principal_name_template[] = {
|
||
{0, 0, NULL, 0}
|
||
};
|
||
|
||
-#define PKINIT_OID "1.3.6.1.5.2.2"
|
||
-#define NT_PRINCIPAL_OID "1.3.6.1.4.1.311.20.2.3"
|
||
-
|
||
static int add_string_other_name_to_san_list(TALLOC_CTX *mem_ctx,
|
||
enum san_opt san_opt,
|
||
CERTGeneralName *current,
|
||
@@ -451,31 +416,6 @@ done:
|
||
return ret;
|
||
}
|
||
|
||
-static int get_short_name(TALLOC_CTX *mem_ctx, const char *full_name,
|
||
- char delim, char **short_name)
|
||
-{
|
||
- char *at;
|
||
- char *s;
|
||
-
|
||
- if (full_name == NULL || delim == '\0' || short_name == NULL) {
|
||
- return EINVAL;
|
||
- }
|
||
-
|
||
- at = strchr(full_name, delim);
|
||
- if (at != NULL) {
|
||
- s = talloc_strndup(mem_ctx, full_name, (at - full_name));
|
||
- } else {
|
||
- s = talloc_strdup(mem_ctx, full_name);
|
||
- }
|
||
- if (s == NULL) {
|
||
- return ENOMEM;
|
||
- }
|
||
-
|
||
- *short_name = s;
|
||
-
|
||
- return 0;
|
||
-}
|
||
-
|
||
static int add_nt_princ_to_san_list(TALLOC_CTX *mem_ctx,
|
||
PLArenaPool *pool,
|
||
enum san_opt san_opt,
|
||
@@ -532,7 +472,7 @@ static int add_pkinit_princ_to_san_list(TALLOC_CTX *mem_ctx,
|
||
{
|
||
struct san_list *i = NULL;
|
||
SECStatus rv;
|
||
- struct kerberos_principal_name kname;
|
||
+ struct kerberos_principal_name kname = { 0 };
|
||
int ret;
|
||
size_t c;
|
||
|
||
@@ -571,9 +511,9 @@ static int add_pkinit_princ_to_san_list(TALLOC_CTX *mem_ctx,
|
||
goto done;
|
||
}
|
||
}
|
||
- i->val = talloc_strndup_append(i->val,
|
||
- (char *) kname.realm.data,
|
||
- kname.realm.len);
|
||
+ i->val = talloc_asprintf_append(i->val, "@%.*s",
|
||
+ kname.realm.len,
|
||
+ (char *) kname.realm.data);
|
||
if (i->val == NULL) {
|
||
ret = ENOMEM;
|
||
goto done;
|
||
@@ -706,42 +646,6 @@ static int add_ip_to_san_list(TALLOC_CTX *mem_ctx, enum san_opt san_opt,
|
||
*item = i;
|
||
return 0;
|
||
}
|
||
-static int add_principal_to_san_list(TALLOC_CTX *mem_ctx,
|
||
- enum san_opt san_opt,
|
||
- const char *princ,
|
||
- struct san_list **item)
|
||
-{
|
||
- struct san_list *i = NULL;
|
||
- int ret;
|
||
-
|
||
- i = talloc_zero(mem_ctx, struct san_list);
|
||
- if (i == NULL) {
|
||
- return ENOMEM;
|
||
- }
|
||
- i->san_opt = san_opt;
|
||
-
|
||
- i->val = talloc_strdup(i, princ);
|
||
- if (i->val == NULL) {
|
||
- ret = ENOMEM;
|
||
- goto done;
|
||
- }
|
||
-
|
||
- ret = get_short_name(i, i->val, '@', &(i->short_name));
|
||
- if (ret != 0) {
|
||
- goto done;
|
||
- }
|
||
-
|
||
- ret = 0;
|
||
-
|
||
-done:
|
||
- if (ret == 0) {
|
||
- *item = i;
|
||
- } else {
|
||
- talloc_free(i);
|
||
- }
|
||
-
|
||
- return ret;
|
||
-}
|
||
|
||
static int get_san(TALLOC_CTX *mem_ctx, CERTCertificate *cert,
|
||
struct san_list **san_list)
|
||
@@ -887,6 +791,7 @@ static int get_san(TALLOC_CTX *mem_ctx, CERTCertificate *cert,
|
||
break;
|
||
default:
|
||
ret = EINVAL;
|
||
+ goto done;
|
||
}
|
||
|
||
current = CERT_GetNextGeneralName(current);
|
||
diff --git a/src/lib/certmap/sss_certmap.c b/src/lib/certmap/sss_certmap.c
|
||
index 37bbc5e7c556f637c7e09fce21950d320790ddd1..f6f6f98041bfd55a19ae919ebb62ec6f8a6e5f8f 100644
|
||
--- a/src/lib/certmap/sss_certmap.c
|
||
+++ b/src/lib/certmap/sss_certmap.c
|
||
@@ -311,87 +311,6 @@ done:
|
||
return ret;
|
||
}
|
||
|
||
-static int get_dn_str(struct sss_certmap_ctx *ctx, const char *conversion,
|
||
- const char **rdn_list, char **result)
|
||
-{
|
||
- char *str = NULL;
|
||
- size_t c;
|
||
- int ret;
|
||
- char *conv = NULL;
|
||
-
|
||
- str = talloc_strdup(ctx, "");
|
||
- if (str == NULL) {
|
||
- ret = ENOMEM;
|
||
- goto done;
|
||
- }
|
||
- if (conversion == NULL || strcmp(conversion, "nss_ldap") == 0
|
||
- || strcmp(conversion, "nss") == 0) {
|
||
- for (c = 0; rdn_list[c] != NULL; c++);
|
||
- while (c != 0) {
|
||
- c--;
|
||
- str = talloc_asprintf_append(str, "%s%s",
|
||
- (rdn_list[c + 1] == NULL) ? "" : ",",
|
||
- rdn_list[c]);
|
||
- if (str == NULL) {
|
||
- ret = ENOMEM;
|
||
- goto done;
|
||
- }
|
||
- };
|
||
- } else if (strcmp(conversion, "ad_ldap") == 0) {
|
||
- for (c = 0; rdn_list[c] != NULL; c++);
|
||
- while (c != 0) {
|
||
- c--;
|
||
- conv = check_ad_attr_name(str, rdn_list[c]);
|
||
- str = talloc_asprintf_append(str, "%s%s",
|
||
- (rdn_list[c + 1] == NULL) ? "" : ",",
|
||
- conv == NULL ? rdn_list[c] : conv);
|
||
- talloc_free(conv);
|
||
- conv = NULL;
|
||
- if (str == NULL) {
|
||
- ret = ENOMEM;
|
||
- goto done;
|
||
- }
|
||
- };
|
||
- } else if (strcmp(conversion, "nss_x500") == 0) {
|
||
- for (c = 0; rdn_list[c] != NULL; c++) {
|
||
- str = talloc_asprintf_append(str, "%s%s", (c == 0) ? "" : ",",
|
||
- rdn_list[c]);
|
||
- if (str == NULL) {
|
||
- ret = ENOMEM;
|
||
- goto done;
|
||
- }
|
||
- }
|
||
- } else if (strcmp(conversion, "ad_x500") == 0
|
||
- || strcmp(conversion, "ad") == 0) {
|
||
- for (c = 0; rdn_list[c] != NULL; c++) {
|
||
- conv = check_ad_attr_name(str, rdn_list[c]);
|
||
- str = talloc_asprintf_append(str, "%s%s",
|
||
- (c == 0) ? "" : ",",
|
||
- conv == NULL ? rdn_list[c] : conv);
|
||
- talloc_free(conv);
|
||
- conv = NULL;
|
||
- if (str == NULL) {
|
||
- ret = ENOMEM;
|
||
- goto done;
|
||
- }
|
||
- }
|
||
- } else {
|
||
- ret = EINVAL;
|
||
- goto done;
|
||
- }
|
||
-
|
||
- ret = 0;
|
||
-
|
||
-done:
|
||
- if (ret == 0) {
|
||
- *result = str;
|
||
- } else {
|
||
- talloc_free(str);
|
||
- }
|
||
-
|
||
- return ret;
|
||
-}
|
||
-
|
||
static int expand_san_blob(struct sss_certmap_ctx *ctx, enum san_opt san_opt,
|
||
struct san_list *san_list, char **expanded)
|
||
{
|
||
@@ -458,7 +377,7 @@ static int expand_san_rdn_list(struct sss_certmap_ctx *ctx,
|
||
|
||
DLIST_FOR_EACH(item, san_list) {
|
||
if (item->san_opt == san_opt) {
|
||
- ret = get_dn_str(ctx, conversion, item->rdn_list, &exp);
|
||
+ ret = rdn_list_2_dn_str(ctx, conversion, item->rdn_list, &exp);
|
||
if (ret != 0) {
|
||
return ret;
|
||
}
|
||
@@ -528,11 +447,11 @@ static int expand_template(struct sss_certmap_ctx *ctx,
|
||
char *exp = NULL;
|
||
|
||
if (strcmp("issuer_dn", parsed_template->name) == 0) {
|
||
- ret = get_dn_str(ctx, parsed_template->conversion,
|
||
- cert_content->issuer_rdn_list, &exp);
|
||
+ ret = rdn_list_2_dn_str(ctx, parsed_template->conversion,
|
||
+ cert_content->issuer_rdn_list, &exp);
|
||
} else if (strcmp("subject_dn", parsed_template->name) == 0) {
|
||
- ret = get_dn_str(ctx, parsed_template->conversion,
|
||
- cert_content->subject_rdn_list, &exp);
|
||
+ ret = rdn_list_2_dn_str(ctx, parsed_template->conversion,
|
||
+ cert_content->subject_rdn_list, &exp);
|
||
} else if (strncmp("subject_", parsed_template->name, 8) == 0) {
|
||
ret = expand_san(ctx, parsed_template, cert_content->san_list, &exp);
|
||
} else if (strcmp("cert", parsed_template->name) == 0) {
|
||
@@ -629,7 +548,7 @@ static bool check_san_regexp(struct sss_certmap_ctx *ctx,
|
||
if (item->san_opt == san_opt) {
|
||
if (item->san_opt == SAN_DIRECTORY_NAME) {
|
||
/* use LDAP order for matching */
|
||
- ret = get_dn_str(ctx, NULL, item->rdn_list, &tmp_str);
|
||
+ ret = rdn_list_2_dn_str(ctx, NULL, item->rdn_list, &tmp_str);
|
||
if (ret != 0 || tmp_str == NULL) {
|
||
return false;
|
||
}
|
||
diff --git a/src/lib/certmap/sss_certmap_attr_names.c b/src/lib/certmap/sss_certmap_attr_names.c
|
||
index a28a464910728cdd1f316b2b979da84f440685ea..65c0f9109f6d611e8054bd1ae681d5b8eee5c4f6 100644
|
||
--- a/src/lib/certmap/sss_certmap_attr_names.c
|
||
+++ b/src/lib/certmap/sss_certmap_attr_names.c
|
||
@@ -30,44 +30,48 @@
|
||
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa376556%28v=vs.85%29.aspx
|
||
* and wine source code dlls/crypt32/oid.c and include/wincrypt.h . */
|
||
|
||
+/* OpenSSL data taken from include/openssl/obj_mac.h */
|
||
+
|
||
#include <stdbool.h>
|
||
#include <string.h>
|
||
#include <talloc.h>
|
||
|
||
struct oid_attr_name_map {
|
||
bool nss_ad_differ;
|
||
+ bool nss_openssl_differ;
|
||
const char *oid;
|
||
const char *nss;
|
||
const char *ad;
|
||
+ const char *openssl;
|
||
} oid_attr_name_map[] = {
|
||
- { false, "2.5.4.3", "CN", "CN"},
|
||
- { true, "2.5.4.8", "ST", "S"},
|
||
- { false, "2.5.4.10", "O", "O"},
|
||
- { false, "2.5.4.11", "OU", "OU"},
|
||
- { false, "2.5.4.46", "dnQualifier", "dnQualifier"},
|
||
- { false, "2.5.4.6", "C", "C"},
|
||
- { true, "2.5.4.5", "serialNumber", "SERIALNUMBER"},
|
||
- { false, "2.5.4.7", "L", "L"},
|
||
- { true, "2.5.4.12", "title", "T"},
|
||
- { false, "2.5.4.4", "SN", "SN"},
|
||
- { true, "2.5.4.42", "givenName", "G"},
|
||
- { true, "2.5.4.43", "initials", "I"},
|
||
- { true, "2.5.4.44", "generationQualifier", "OID.2.5.4.44"},
|
||
- { false, "0.9.2342.19200300.100.1.25", "DC", "DC"},
|
||
- { true, "0.9.2342.19200300.100.1.3", "MAIL", "OID,0.9.2342.19200300.100.1.3"},
|
||
- { true, "0.9.2342.19200300.100.1.1", "UID", "OID.0.9.2342.19200300.100.1.1"},
|
||
- { true, "2.5.4.13", "OID.2.5.4.13", "Description"},
|
||
- { true, "2.5.4.16", "postalAddress", "OID.2.5.4.16"},
|
||
- { true, "2.5.4.17", "postalCode", "PostalCode"},
|
||
- { true, "2.5.4.18", "postOfficeBox", "POBox"},
|
||
- { true, "2.5.4.51", "houseIdentifier", "OID.2.5.4.51"},
|
||
- { false, "1.2.840.113549.1.9.1", "E", "E"},
|
||
- { false, "2.5.4.9", "STREET", "STREET"},
|
||
- { true, "2.5.4.65", "pseudonym", "OID.2.5.4.65"},
|
||
- { true, "2.5.4.15", "businessCategory", "OID.2.5.4.15"},
|
||
- { true, "2.5.4.41", "name", "OID.2.5.4.41"},
|
||
+ { false, false, "2.5.4.3", "CN", "CN", "CN"},
|
||
+ { true, false, "2.5.4.8", "ST", "S", "ST"},
|
||
+ { false, false, "2.5.4.10", "O", "O", "O"},
|
||
+ { false, false, "2.5.4.11", "OU", "OU", "OU"},
|
||
+ { false, false, "2.5.4.46", "dnQualifier", "dnQualifier", "dnQualifier"},
|
||
+ { false, false, "2.5.4.6", "C", "C", "C"},
|
||
+ { true, false, "2.5.4.5", "serialNumber", "SERIALNUMBER", "serialNumber"},
|
||
+ { false, false, "2.5.4.7", "L", "L", "L"},
|
||
+ { true, false, "2.5.4.12", "title", "T", "title"},
|
||
+ { false, false, "2.5.4.4", "SN", "SN", "SN"},
|
||
+ { true, true, "2.5.4.42", "givenName", "G", "GN"},
|
||
+ { true, false, "2.5.4.43", "initials", "I", "initials"},
|
||
+ { true, false, "2.5.4.44", "generationQualifier", "OID.2.5.4.44", "generationQualifier"},
|
||
+ { false, false, "0.9.2342.19200300.100.1.25", "DC", "DC", "DC"},
|
||
+ { true, true, "0.9.2342.19200300.100.1.3", "MAIL", "OID,0.9.2342.19200300.100.1.3", "mail"},
|
||
+ { true, false, "0.9.2342.19200300.100.1.1", "UID", "OID.0.9.2342.19200300.100.1.1", "UID"},
|
||
+ { true, true, "2.5.4.13", "OID.2.5.4.13", "Description", "description"},
|
||
+ { true, false, "2.5.4.16", "postalAddress", "OID.2.5.4.16", "postalAddress"},
|
||
+ { true, false, "2.5.4.17", "postalCode", "PostalCode", "postalCode"},
|
||
+ { true, false, "2.5.4.18", "postOfficeBox", "POBox", "postOfficeBox"},
|
||
+ { true, false, "2.5.4.51", "houseIdentifier", "OID.2.5.4.51", "houseIdentifier"},
|
||
+ { false, true, "1.2.840.113549.1.9.1", "E", "E", "emailAddress"},
|
||
+ { false, true, "2.5.4.9", "STREET", "STREET", "street"},
|
||
+ { true, false, "2.5.4.65", "pseudonym", "OID.2.5.4.65", "pseudonym"},
|
||
+ { true, false, "2.5.4.15", "businessCategory", "OID.2.5.4.15", "businessCategory"},
|
||
+ { true, false, "2.5.4.41", "name", "OID.2.5.4.41", "name"},
|
||
|
||
- { false, NULL, NULL, NULL}
|
||
+ { false, false, NULL, NULL, NULL, NULL}
|
||
};
|
||
|
||
char *check_ad_attr_name(TALLOC_CTX *mem_ctx, const char *rdn)
|
||
@@ -105,3 +109,26 @@ char *check_ad_attr_name(TALLOC_CTX *mem_ctx, const char *rdn)
|
||
|
||
return NULL;
|
||
}
|
||
+
|
||
+const char *openssl_2_nss_attr_name(const char *attr)
|
||
+{
|
||
+ size_t c;
|
||
+
|
||
+ if (attr == NULL) {
|
||
+ return NULL;
|
||
+ }
|
||
+
|
||
+ for (c = 0; oid_attr_name_map[c].oid != NULL; c++) {
|
||
+ if (!oid_attr_name_map[c].nss_openssl_differ) {
|
||
+ continue;
|
||
+ }
|
||
+
|
||
+ if (strcmp(attr, oid_attr_name_map[c].openssl) != 0) {
|
||
+ continue;
|
||
+ }
|
||
+
|
||
+ return oid_attr_name_map[c].nss;
|
||
+ }
|
||
+
|
||
+ return attr;
|
||
+}
|
||
diff --git a/src/lib/certmap/sss_certmap_int.h b/src/lib/certmap/sss_certmap_int.h
|
||
index 0b4cda73639be9b323ac3388f97be90bc1a771f2..479cc1606d2575b1b69007eb90eac0c9d5814582 100644
|
||
--- a/src/lib/certmap/sss_certmap_int.h
|
||
+++ b/src/lib/certmap/sss_certmap_int.h
|
||
@@ -28,8 +28,11 @@
|
||
#include <sys/types.h>
|
||
#include <regex.h>
|
||
#include <stdint.h>
|
||
+#include <stdbool.h>
|
||
#include <talloc.h>
|
||
|
||
+#include "lib/certmap/sss_certmap.h"
|
||
+
|
||
#define CM_DEBUG(cm_ctx, format, ...) do { \
|
||
if (cm_ctx != NULL && cm_ctx->debug != NULL) { \
|
||
cm_ctx->debug(cm_ctx->debug_priv, __FILE__, __LINE__, __FUNCTION__, \
|
||
@@ -40,6 +43,9 @@
|
||
#define DEFAULT_MATCH_RULE "<KU>digitalSignature<EKU>clientAuth"
|
||
#define DEFAULT_MAP_RULE "LDAP:(userCertificate;binary={cert!bin})"
|
||
|
||
+#define PKINIT_OID "1.3.6.1.5.2.2"
|
||
+#define NT_PRINCIPAL_OID "1.3.6.1.4.1.311.20.2.3"
|
||
+
|
||
enum san_opt {
|
||
SAN_OTHER_NAME = 0,
|
||
SAN_RFC822_NAME,
|
||
@@ -161,9 +167,9 @@ struct san_list {
|
||
#define SSS_KU_DECIPHER_ONLY 0x8000
|
||
|
||
struct sss_cert_content {
|
||
- const char *issuer_str;
|
||
+ char *issuer_str;
|
||
const char **issuer_rdn_list;
|
||
- const char *subject_str;
|
||
+ char *subject_str;
|
||
const char **subject_rdn_list;
|
||
uint32_t key_usage;
|
||
const char **extended_key_usage_oids;
|
||
@@ -179,6 +185,8 @@ int sss_cert_get_content(TALLOC_CTX *mem_ctx,
|
||
|
||
char *check_ad_attr_name(TALLOC_CTX *mem_ctx, const char *rdn);
|
||
|
||
+char *openssl_2_nss_attr_name(const char *attr);
|
||
+
|
||
int parse_krb5_match_rule(struct sss_certmap_ctx *ctx,
|
||
const char *rule_start,
|
||
struct krb5_match_rule **match_rule);
|
||
@@ -186,4 +194,17 @@ int parse_krb5_match_rule(struct sss_certmap_ctx *ctx,
|
||
int parse_ldap_mapping_rule(struct sss_certmap_ctx *ctx,
|
||
const char *rule_start,
|
||
struct ldap_mapping_rule **mapping_rule);
|
||
+
|
||
+int get_short_name(TALLOC_CTX *mem_ctx, const char *full_name,
|
||
+ char delim, char **short_name);
|
||
+
|
||
+int add_to_san_list(TALLOC_CTX *mem_ctx, bool is_bin,
|
||
+ enum san_opt san_opt, const uint8_t *data, size_t len,
|
||
+ struct san_list **item);
|
||
+
|
||
+int add_principal_to_san_list(TALLOC_CTX *mem_ctx, enum san_opt san_opt,
|
||
+ const char *princ, struct san_list **item);
|
||
+
|
||
+int rdn_list_2_dn_str(TALLOC_CTX *mem_ctx, const char *conversion,
|
||
+ const char **rdn_list, char **result);
|
||
#endif /* __SSS_CERTMAP_INT_H__ */
|
||
diff --git a/src/tests/cmocka/test_certmap.c b/src/tests/cmocka/test_certmap.c
|
||
index c998443d086eaa72cc2a05c38ddfc5ba590a1ce7..f1e73875bf7ae85fbf2be84d47d8d82f544ac8ba 100644
|
||
--- a/src/tests/cmocka/test_certmap.c
|
||
+++ b/src/tests/cmocka/test_certmap.c
|
||
@@ -40,6 +40,10 @@
|
||
#include "util/crypto/nss/nss_util.h"
|
||
#endif
|
||
|
||
+#ifdef HAVE_LIBCRYPTO
|
||
+#include <openssl/crypto.h>
|
||
+#endif
|
||
+
|
||
struct priv_sss_debug {
|
||
int level;
|
||
};
|
||
@@ -712,6 +716,65 @@ const uint8_t test_cert2_der[] = {
|
||
0xa2, 0xd3, 0x43, 0x21, 0x5b, 0xdc, 0xa2, 0x1d, 0x55, 0xa9, 0x48, 0xc5, 0xc4, 0xaa, 0xf3, 0x8b,
|
||
0xe6, 0x3e, 0x75, 0x96, 0xe4, 0x3e, 0x64, 0xaf, 0xe8, 0xa7, 0x6a, 0xb6};
|
||
|
||
+/* used to test SAN principal encoding according to RFC4556 */
|
||
+const uint8_t test_cert3_der[] = {
|
||
+0x30, 0x82, 0x03, 0x70, 0x30, 0x82, 0x02, 0x58, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
|
||
+0xe5, 0x8f, 0x16, 0xfe, 0x23, 0x4d, 0xc5, 0xd6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
|
||
+0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1a, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55,
|
||
+0x04, 0x03, 0x0c, 0x0f, 0x6b, 0x72, 0x62, 0x35, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x5f, 0x74,
|
||
+0x65, 0x73, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x37, 0x31, 0x32, 0x30, 0x39, 0x32,
|
||
+0x34, 0x31, 0x38, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x34, 0x30, 0x37, 0x30, 0x39, 0x32, 0x34,
|
||
+0x31, 0x38, 0x5a, 0x30, 0x1a, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f,
|
||
+0x6b, 0x72, 0x62, 0x35, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x30,
|
||
+0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
|
||
+0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
|
||
+0xbf, 0x84, 0x34, 0x46, 0x37, 0x50, 0xb1, 0xca, 0x14, 0x4c, 0x6b, 0x0d, 0xe4, 0xab, 0xc1, 0xce,
|
||
+0xf4, 0xd1, 0xde, 0xca, 0xf5, 0x50, 0x46, 0x3c, 0x63, 0x0f, 0x8e, 0xb8, 0xe9, 0xf9, 0x3e, 0xc4,
|
||
+0xf3, 0x24, 0xc1, 0xe4, 0x78, 0xf6, 0xa4, 0x39, 0x6f, 0xc1, 0xd8, 0x9c, 0x1c, 0xa7, 0x47, 0xe4,
|
||
+0xc8, 0x71, 0x32, 0x9a, 0x1d, 0x1d, 0xfb, 0x30, 0x0f, 0xf9, 0x85, 0x48, 0xf8, 0x1f, 0xa7, 0xbd,
|
||
+0xda, 0x39, 0xd4, 0xc7, 0x27, 0x4f, 0xf5, 0x34, 0xee, 0x4a, 0x59, 0x0c, 0x7a, 0xec, 0x2b, 0xaf,
|
||
+0x81, 0x8e, 0x41, 0x54, 0x6f, 0xcc, 0x91, 0x61, 0x4c, 0x61, 0x80, 0xca, 0x37, 0xab, 0x2c, 0x63,
|
||
+0x8d, 0xce, 0x07, 0xcd, 0x61, 0x11, 0x10, 0xa0, 0xe4, 0x08, 0x7d, 0x1d, 0x10, 0x85, 0xb1, 0x64,
|
||
+0x33, 0x6b, 0x4d, 0x8d, 0xd2, 0x9d, 0xd7, 0x0b, 0x21, 0xbc, 0x15, 0xcd, 0xed, 0xaa, 0xc0, 0x01,
|
||
+0x67, 0xe1, 0x7c, 0xd4, 0xf7, 0xdd, 0xf8, 0x28, 0x92, 0xce, 0x8b, 0x7f, 0x08, 0x29, 0x76, 0x6e,
|
||
+0xa5, 0xe6, 0xcd, 0xeb, 0x9c, 0x13, 0x78, 0xa3, 0x08, 0xb5, 0xdc, 0x7f, 0xc2, 0x60, 0xc3, 0xac,
|
||
+0x68, 0x30, 0x37, 0xe1, 0x54, 0x6a, 0xa9, 0x34, 0x3e, 0x43, 0x8d, 0x6f, 0x9b, 0xe5, 0x8a, 0xf9,
|
||
+0xa4, 0x22, 0xab, 0x33, 0x01, 0x32, 0xaf, 0xc4, 0x9f, 0xb1, 0x27, 0xba, 0xae, 0x20, 0x60, 0xd7,
|
||
+0x16, 0x48, 0x66, 0x2b, 0x36, 0x9c, 0x54, 0xd0, 0x6e, 0x45, 0xd3, 0x23, 0x3f, 0x17, 0x2e, 0xee,
|
||
+0xd4, 0x55, 0xa7, 0x75, 0x2f, 0x28, 0xa9, 0x40, 0x3b, 0xbc, 0x79, 0x69, 0xea, 0x58, 0xc2, 0x3c,
|
||
+0x4c, 0x70, 0x4b, 0x93, 0xd8, 0xa4, 0xb6, 0x59, 0x24, 0x77, 0x10, 0xb3, 0xc7, 0x34, 0x99, 0x6b,
|
||
+0x28, 0xbd, 0x03, 0xdb, 0xda, 0xea, 0x23, 0x19, 0x10, 0x56, 0x7e, 0xa4, 0x28, 0x04, 0x5a, 0x53,
|
||
+0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xb8, 0x30, 0x81, 0xb5, 0x30, 0x09, 0x06, 0x03, 0x55,
|
||
+0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03,
|
||
+0x02, 0x03, 0xa8, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0b, 0x30, 0x09, 0x06, 0x07,
|
||
+0x2b, 0x06, 0x01, 0x05, 0x02, 0x03, 0x04, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
|
||
+0x04, 0x14, 0xea, 0xd4, 0x30, 0xd7, 0x7d, 0x3b, 0xc7, 0xb4, 0x83, 0x53, 0x2c, 0xa5, 0xb9, 0xd8,
|
||
+0x1a, 0x47, 0x6b, 0xb5, 0xe5, 0x9d, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
|
||
+0x16, 0x80, 0x14, 0xea, 0xd4, 0x30, 0xd7, 0x7d, 0x3b, 0xc7, 0xb4, 0x83, 0x53, 0x2c, 0xa5, 0xb9,
|
||
+0xd8, 0x1a, 0x47, 0x6b, 0xb5, 0xe5, 0x9d, 0x30, 0x47, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x40,
|
||
+0x30, 0x3e, 0xa0, 0x3c, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05, 0x02, 0x02, 0xa0, 0x32, 0x30, 0x30,
|
||
+0xa0, 0x0b, 0x1b, 0x09, 0x53, 0x53, 0x53, 0x44, 0x2e, 0x54, 0x45, 0x53, 0x54, 0xa1, 0x21, 0x30,
|
||
+0x1f, 0xa0, 0x03, 0x02, 0x01, 0x01, 0xa1, 0x18, 0x30, 0x16, 0x1b, 0x04, 0x74, 0x65, 0x73, 0x74,
|
||
+0x1b, 0x05, 0x63, 0x6f, 0x6d, 0x70, 0x32, 0x1b, 0x07, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72,
|
||
+0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
|
||
+0x82, 0x01, 0x01, 0x00, 0x08, 0x64, 0x63, 0x89, 0x6d, 0x3d, 0x66, 0x77, 0xe3, 0xb6, 0x40, 0x54,
|
||
+0xd7, 0xe2, 0xc5, 0x99, 0xac, 0x98, 0x6e, 0xf8, 0xcd, 0x62, 0xa4, 0xf8, 0xd9, 0xaf, 0xdb, 0xef,
|
||
+0xb7, 0x10, 0x8e, 0x45, 0x42, 0x53, 0x5c, 0x3f, 0x6a, 0x8d, 0xa8, 0x8a, 0x6d, 0x76, 0x51, 0x1a,
|
||
+0xf4, 0x71, 0x54, 0x27, 0x27, 0xe2, 0x45, 0xe8, 0xa8, 0xd2, 0xa9, 0xcd, 0x62, 0x0d, 0xfc, 0x0d,
|
||
+0x28, 0x46, 0x9e, 0x4e, 0x5a, 0x57, 0x72, 0xb4, 0xf2, 0x35, 0x91, 0x57, 0x11, 0xae, 0x2b, 0x9c,
|
||
+0x6a, 0x80, 0x21, 0x8e, 0x4c, 0x19, 0x4a, 0x2d, 0xe0, 0xd2, 0xdf, 0x83, 0x9d, 0x65, 0x49, 0xd1,
|
||
+0x34, 0x34, 0x14, 0xa0, 0xbb, 0x1c, 0xa8, 0x12, 0xb0, 0xe3, 0x5e, 0x82, 0x36, 0x41, 0x4c, 0x87,
|
||
+0xd1, 0x1e, 0x1a, 0xe9, 0xff, 0x55, 0xef, 0xb5, 0x2d, 0x20, 0xc5, 0xa7, 0xe5, 0x5a, 0xf2, 0xfc,
|
||
+0xf7, 0xd2, 0x21, 0xc5, 0x32, 0xb4, 0x07, 0x8f, 0xc4, 0x94, 0x56, 0xa6, 0x21, 0x6a, 0xb6, 0x26,
|
||
+0x05, 0x48, 0x90, 0xe0, 0x6b, 0x22, 0x35, 0x00, 0x51, 0x2e, 0xd7, 0xe8, 0x3a, 0x56, 0xa8, 0x70,
|
||
+0x7d, 0x0f, 0x9a, 0x97, 0x5a, 0xb8, 0x7f, 0x33, 0xc1, 0xe0, 0x92, 0x0f, 0xb3, 0xfe, 0x36, 0xe6,
|
||
+0x8b, 0x97, 0x58, 0x42, 0x49, 0xcb, 0x74, 0xde, 0x19, 0x59, 0x90, 0xb6, 0x36, 0x38, 0x07, 0x48,
|
||
+0x5d, 0x5b, 0xab, 0x08, 0xf0, 0x69, 0x22, 0x42, 0x08, 0x29, 0xfe, 0x43, 0xab, 0x83, 0x73, 0x74,
|
||
+0x5a, 0x3f, 0x3b, 0x5d, 0x8e, 0xca, 0x6f, 0x2d, 0xad, 0xa1, 0x6e, 0x80, 0x80, 0xd2, 0xc8, 0x16,
|
||
+0xb7, 0x67, 0x1a, 0x2d, 0x37, 0x8c, 0x20, 0x3b, 0x15, 0xef, 0xb2, 0x94, 0x86, 0x5c, 0xaf, 0xa2,
|
||
+0x61, 0x8b, 0xc7, 0xc1, 0xe4, 0xbe, 0x60, 0x5a, 0x86, 0x5c, 0x86, 0xba, 0x59, 0x97, 0x83, 0x1b,
|
||
+0x79, 0x1c, 0x7c, 0x26};
|
||
+
|
||
void test_sss_cert_get_content(void **state)
|
||
{
|
||
int ret;
|
||
@@ -802,7 +865,6 @@ FIXME:
|
||
assert_string_equal(content->subject_rdn_list[3], "CN=t u");
|
||
assert_string_equal(content->subject_rdn_list[4],
|
||
"E=test.user@email.domain");
|
||
- //"CN=t u/emailAddress=test.user@email.domain");
|
||
assert_null(content->subject_rdn_list[5]);
|
||
|
||
assert_non_null(content->san_list);
|
||
@@ -880,6 +942,21 @@ static void test_sss_certmap_match_cert(void **state)
|
||
{NULL, 0}
|
||
};
|
||
|
||
+ struct match_tests match_tests_3[] = {
|
||
+ {"KRB5:<KU>digitalSignature", 0},
|
||
+ {"KRB5:<KU>keyEncipherment", 0},
|
||
+ {"KRB5:<KU>keyAgreement", 0},
|
||
+ {"KRB5:<KU>digitalSignature,keyAgreement,keyEncipherment", 0},
|
||
+ {"KRB5:<SAN:Principal>test", 0},
|
||
+ {"KRB5:<SAN:ntPrincipal>test", ENOENT},
|
||
+ {"KRB5:<SAN:Principal>comp2", 0},
|
||
+ {"KRB5:<SAN:Principal>another", 0},
|
||
+ {"KRB5:<SAN:Principal>test/comp2/another@SSSD.TEST", 0},
|
||
+ {"KRB5:<SAN:Principal>^test/comp2/another@SSSD.TEST$", 0},
|
||
+ {"KRB5:<SAN:pkinitSAN>^test/comp2/another@SSSD.TEST$", 0},
|
||
+ {NULL, 0}
|
||
+ };
|
||
+
|
||
ret = sss_certmap_init(NULL, ext_debug, NULL, &ctx);
|
||
assert_int_equal(ret, EOK);
|
||
assert_non_null(ctx);
|
||
@@ -937,6 +1014,24 @@ static void test_sss_certmap_match_cert(void **state)
|
||
|
||
sss_certmap_free_ctx(ctx);
|
||
}
|
||
+
|
||
+ for (c = 0; match_tests_3[c].rule != NULL; c++) {
|
||
+ ret = sss_certmap_init(NULL, ext_debug, NULL, &ctx);
|
||
+ assert_int_equal(ret, EOK);
|
||
+ assert_non_null(ctx);
|
||
+ assert_null(ctx->prio_list);
|
||
+
|
||
+ print_error("Checking matching rule [%s]\n", match_tests_3[c].rule);
|
||
+
|
||
+ ret = sss_certmap_add_rule(ctx, 1, match_tests_3[c].rule, NULL, NULL);
|
||
+ assert_int_equal(ret, EOK);
|
||
+
|
||
+ ret = sss_certmap_match_cert(ctx, discard_const(test_cert3_der),
|
||
+ sizeof(test_cert3_der));
|
||
+ assert_int_equal(ret, match_tests_3[c].result);
|
||
+
|
||
+ sss_certmap_free_ctx(ctx);
|
||
+ }
|
||
}
|
||
|
||
static void test_sss_certmap_add_mapping_rule(void **state)
|
||
@@ -1385,6 +1480,8 @@ static void test_sss_certmap_get_search_filter(void **state)
|
||
assert_non_null(filter);
|
||
assert_string_equal(filter, "(userCertificate;binary=" TEST_CERT2_BIN")");
|
||
assert_null(domains);
|
||
+
|
||
+ sss_certmap_free_ctx(ctx);
|
||
}
|
||
|
||
int main(int argc, const char *argv[])
|
||
@@ -1439,5 +1536,9 @@ int main(int argc, const char *argv[])
|
||
nspr_nss_cleanup();
|
||
#endif
|
||
|
||
+#ifdef HAVE_LIBCRYPTO
|
||
+ CRYPTO_cleanup_all_ex_data(); /* to make valgrind happy */
|
||
+#endif
|
||
+
|
||
return rv;
|
||
}
|
||
--
|
||
2.14.1
|
||
|