Skip to content

Commit

Permalink
certmap: add sss_certmap_display_cert_content()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
sumit-bose authored and jhrozek committed May 28, 2019
1 parent e1734ba commit 1c40208
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 82 deletions.
2 changes: 1 addition & 1 deletion Makefile.am
Expand Up @@ -2125,7 +2125,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 += \
Expand Down
142 changes: 142 additions & 0 deletions src/lib/certmap/sss_certmap.c
Expand Up @@ -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;
}
5 changes: 5 additions & 0 deletions src/lib/certmap/sss_certmap.exports
Expand Up @@ -11,3 +11,8 @@ SSS_CERTMAP_0.0 {
local:
*;
};

SSS_CERTMAP_0.1 {
global:
sss_certmap_display_cert_content;
} SSS_CERTMAP_0.0;
18 changes: 18 additions & 0 deletions src/lib/certmap/sss_certmap.h
Expand Up @@ -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);

/**
* @}
*/
Expand Down
31 changes: 28 additions & 3 deletions src/lib/certmap/sss_certmap_int.h
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down

0 comments on commit 1c40208

Please sign in to comment.