summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2017-02-14 22:47:08 +0100
committerSumit Bose <sbose@redhat.com>2017-02-14 22:47:08 +0100
commit75d194e95637ee53be298a39aeb2fb79379e2367 (patch)
tree01608a3e1aeed30067f52b3efeb2e0548f7e6195
parent20b1e6eba52caaea74eef0131ecf628f0760ae3d (diff)
downloadsssd-75d194e95637ee53be298a39aeb2fb79379e2367.tar.gz
sssd-75d194e95637ee53be298a39aeb2fb79379e2367.tar.xz
sssd-75d194e95637ee53be298a39aeb2fb79379e2367.zip
certmap openssl
-rw-r--r--Makefile.am44
-rw-r--r--configure.ac4
-rw-r--r--contrib/sssd.spec.in2
-rw-r--r--src/lib/certmap/sss_cert_content_openssl.c278
-rw-r--r--src/tests/dlopen-tests.c1
5 files changed, 326 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am
index 37aaf80af..39d5b2b70 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -276,6 +276,7 @@ if HAVE_CMOCKA
simple-access-tests \
krb5_common_test \
sss_certmap_test \
+ sss_certmap_openssl_test \
$(NULL)
if HAVE_LIBRESOLV
@@ -1050,6 +1051,7 @@ lib_LTLIBRARIES = libipa_hbac.la \
libsss_idmap.la \
libsss_nss_idmap.la \
libsss_certmap.la \
+ libsss_certmap_openssl.la \
$(NULL)
pkgconfig_DATA += src/lib/ipa_hbac/ipa_hbac.pc
@@ -1697,6 +1699,28 @@ libsss_certmap_la_LDFLAGS = \
dist_noinst_DATA += src/lib/certmap/sss_certmap.exports
dist_noinst_HEADERS += src/lib/certmap/sss_certmap_int.h
endif
+libsss_certmap_openssl_la_DEPENDENCIES = src/lib/certmap/sss_certmap.exports
+libsss_certmap_openssl_la_SOURCES = \
+ src/lib/certmap/sss_certmap.c \
+ src/lib/certmap/sss_cert_content_openssl.c \
+ src/util/util_ext.c \
+ src/util/cert/cert_common.c \
+ src/util/crypto/libcrypto/crypto_base64.c \
+ src/util/cert/libcrypto/cert.c \
+ $(NULL)
+libsss_certmap_openssl_la_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(TALLOC_CFLAGS) \
+ $(CRYPTO_CFLAGS) \
+ $(NULL)
+libsss_certmap_openssl_la_LIBADD = \
+ $(TALLOC_LIBS) \
+ $(CRYPTO_LIBS) \
+ $(NULL)
+libsss_certmap_openssl_la_LDFLAGS = \
+ -Wl,--version-script,$(srcdir)/src/lib/certmap/sss_certmap.exports \
+ -version-info 0:0:0
+
#################
# Feature Tests #
@@ -3226,6 +3250,26 @@ sss_certmap_test_LDADD = \
libsss_certmap.la \
$(NULL)
endif
+
+sss_certmap_openssl_test_SOURCES = \
+ src/tests/cmocka/test_certmap.c \
+ src/util/util.c \
+ src/util/debug.c \
+ src/util/sss_log.c \
+ src/util/util_ext.c \
+ $(NULL)
+sss_certmap_openssl_test_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(NULL)
+sss_certmap_openssl_test_LDADD = \
+ $(CMOCKA_LIBS) \
+ $(POPT_LIBS) \
+ $(TALLOC_LIBS) \
+ $(DHASH_LIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
+ libsss_test_common.la \
+ libsss_certmap_openssl.la \
+ $(NULL)
endif # HAVE_CMOCKA
noinst_PROGRAMS = pam_test_client
diff --git a/configure.ac b/configure.ac
index e82c010b2..f40890f1f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -365,9 +365,7 @@ if test x$cryptolib = xnss; then
AM_CHECK_NSS
fi
-if test x$cryptolib = xlibcrypto; then
- AM_CHECK_LIBCRYPTO
-fi
+AM_CHECK_LIBCRYPTO
AM_CHECK_INOTIFY
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index bbb5eb5d6..920d09e76 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -1162,12 +1162,14 @@ done
%defattr(-,root,root,-)
%doc src/sss_client/COPYING src/sss_client/COPYING.LESSER
%{_libdir}/libsss_certmap.so.*
+%{_libdir}/libsss_certmap_openssl.so.*
%files -n libsss_certmap-devel
%defattr(-,root,root,-)
%doc certmap_doc/html
%{_includedir}/sss_certmap.h
%{_libdir}/libsss_certmap.so
+%{_libdir}/libsss_certmap_openssl.so
%{_libdir}/pkgconfig/sss_certmap.pc
%pre common
diff --git a/src/lib/certmap/sss_cert_content_openssl.c b/src/lib/certmap/sss_cert_content_openssl.c
new file mode 100644
index 000000000..590d79167
--- /dev/null
+++ b/src/lib/certmap/sss_cert_content_openssl.c
@@ -0,0 +1,278 @@
+/*
+ SSSD - certificate handling utils - OpenSSL version
+ 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 "config.h"
+
+#include <talloc.h>
+#include <openssl/x509v3.h>
+
+#include "util/crypto/sss_crypto.h"
+#include "util/cert.h"
+#include "lib/certmap/sss_certmap.h"
+#include "lib/certmap/sss_certmap_int.h"
+
+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;
+
+}
+
+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", sn, (int) tmp_str_size,
+ tmp_str);
+ BIO_reset(bio_mem);
+ 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;
+}
+
+int sss_cert_get_content(TALLOC_CTX *mem_ctx,
+ const uint8_t *der_blob, size_t der_size,
+ struct sss_cert_content **content)
+{
+ int ret;
+ struct sss_cert_content *cont = NULL;
+ X509 *cert = NULL;
+ const unsigned char *der;
+ BIO *bio_mem = NULL;
+ char *tmp_str;
+ long tmp_str_size;
+ 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 = X509_NAME_print_ex(bio_mem, tmp_name, 0, XN_FLAG_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;
+ }
+
+ cont->issuer_str = talloc_strndup(cont, tmp_str, tmp_str_size);
+ BIO_reset(bio_mem);
+ if (cont->issuer_str == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = get_rdn_list(cont, tmp_name, &cont->issuer_rdn_list);
+ if (ret != 0) {
+ goto done;
+ }
+
+ tmp_name = X509_get_subject_name(cert);
+ ret = X509_NAME_print_ex(bio_mem, tmp_name, 0, XN_FLAG_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;
+ }
+
+ cont->subject_str = talloc_strndup(cont, tmp_str, tmp_str_size);
+ BIO_reset(bio_mem);
+ if (cont->subject_str == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = get_rdn_list(cont, tmp_name, &cont->subject_rdn_list);
+ if (ret != 0) {
+ goto done;
+ }
+
+ ret = X509_check_purpose(cert, -1, -1);
+ if (ret < 0) {
+ ret = EIO;
+ goto done;
+ }
+ if (!(cert->ex_flags & EXFLAG_KUSAGE)) {
+ ret = EINVAL;
+ goto done;
+ }
+ cont->key_usage = cert->ex_kusage;
+
+ ret = get_extended_key_usage_oids(cont, cert,
+ &(cont->extended_key_usage_oids));
+ 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);
+
+ if (ret == EOK) {
+ *content = cont;
+ } else {
+ talloc_free(cont);
+ }
+
+ return ret;
+}
diff --git a/src/tests/dlopen-tests.c b/src/tests/dlopen-tests.c
index 89b4dae22..7efc2c084 100644
--- a/src/tests/dlopen-tests.c
+++ b/src/tests/dlopen-tests.c
@@ -46,6 +46,7 @@ struct so {
{ "libsss_nss_idmap.so", { LIBPFX"libsss_nss_idmap.so", NULL } },
{ "libnss_sss.so", { LIBPFX"libnss_sss.so", NULL } },
{ "libsss_certmap.so", { LIBPFX"libsss_certmap.so", NULL } },
+ { "libsss_certmap_openssl.so", { LIBPFX"libsss_certmap_openssl.so", NULL } },
{ "pam_sss.so", { LIBPFX"pam_sss.so", NULL } },
#ifdef BUILD_LIBWBCLIENT
{ "libwbclient.so", { LIBPFX"libwbclient.so", NULL } },