diff options
Diffstat (limited to 'usr/src/lib')
| -rw-r--r-- | usr/src/lib/Makefile | 4 | ||||
| -rw-r--r-- | usr/src/lib/libipsecutil/Makefile.com | 9 | ||||
| -rw-r--r-- | usr/src/lib/libipsecutil/common/ipsec_libssl_setup.c | 326 | ||||
| -rw-r--r-- | usr/src/lib/libipsecutil/common/ipsec_util.c | 28 | ||||
| -rw-r--r-- | usr/src/lib/libipsecutil/common/ipsec_util.h | 16 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/include/kmfapi.h | 2 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/libkmf/Makefile.com | 5 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/libkmf/common/mapfile-vers | 2 | ||||
| -rw-r--r-- | usr/src/lib/libkmf/libkmf/common/rdn_parser.c | 218 |
9 files changed, 262 insertions, 348 deletions
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile index 654a35dd5d..bdff519dd6 100644 --- a/usr/src/lib/Makefile +++ b/usr/src/lib/Makefile @@ -635,9 +635,9 @@ libinetsvc: libscf libinstzones: libzonecfg libcontract libipadm: libinetutil libdlpi libdhcpagent libdladm libsecdb libdhcputil libipmp: libinetutil -libipsecutil: libtecla libtsol +libipsecutil: libtecla libtsol libkmf libiscsit: libstmf libuuid -libkmf: libcryptoutil pkcs11 +libkmf: libcryptoutil pkcs11 libcustr libkvm: ../cmd/sgs/libelf libldap5: libsasl libmapid: libresolv2 libscf diff --git a/usr/src/lib/libipsecutil/Makefile.com b/usr/src/lib/libipsecutil/Makefile.com index de17899c49..aef11c9c76 100644 --- a/usr/src/lib/libipsecutil/Makefile.com +++ b/usr/src/lib/libipsecutil/Makefile.com @@ -20,11 +20,12 @@ # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2018, Joyent, Inc. # LIBRARY = libipsecutil.a VERS = .1 -OBJECTS = ipsec_util.o algs.o ipsec_libssl_setup.o +OBJECTS = ipsec_util.o algs.o include ../../Makefile.lib @@ -32,14 +33,16 @@ LIBS += $(DYNLIB) $(LINTLIB) SRCDIR = ../common +BERDIR = $(SRC)/lib/libkmf/ber_der/inc + $(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) -LDLIBS += -ltecla -lsocket -lnsl -lc +LDLIBS += -ltecla -lsocket -lnsl -lc -lkmf -lkmfberder LAZYLIBS = $(ZLAZYLOAD) -ltsol $(ZNOLAZYLOAD) lint := LAZYLIBS = -ltsol LDLIBS += $(LAZYLIBS) CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I$(SRCDIR) +CPPFLAGS += -I$(SRCDIR) -I$(BERDIR) CERRWARN += -_gcc=-Wno-unused-function CERRWARN += -_gcc=-Wno-uninitialized diff --git a/usr/src/lib/libipsecutil/common/ipsec_libssl_setup.c b/usr/src/lib/libipsecutil/common/ipsec_libssl_setup.c deleted file mode 100644 index e63c1b51be..0000000000 --- a/usr/src/lib/libipsecutil/common/ipsec_libssl_setup.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * Thread setup portions of this code derived from - * OpenSSL 0.9.x file mt/mttest.c examples - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <libintl.h> -#include <synch.h> -#include <thread.h> -#include <dlfcn.h> -#include <openssl/lhash.h> -#include <openssl/crypto.h> -#include <openssl/ssl.h> -#include <openssl/err.h> -#include "ipsec_util.h" - -/* OpenSSL function pointers */ -static X509_NAME *(*d2i_X509_NAME_fn)() = NULL; -static int (*X509_NAME_print_ex_fp_fn)() = NULL; -static char *(*ERR_get_error_fn)() = NULL; -static char *(*ERR_error_string_fn)() = NULL; -static void (*SSL_load_error_strings_fn)() = NULL; -static void (*ERR_free_strings_fn)() = NULL; -static void (*CRYPTO_set_locking_callback_fn)() = NULL; -static void (*CRYPTO_set_id_callback_fn)() = NULL; -static void (*X509_NAME_free_fn)() = NULL; -static int (*CRYPTO_num_locks_fn)() = NULL; -static void *(*OPENSSL_malloc_fn)() = NULL; -static void (*OPENSSL_free_fn)() = NULL; - -static void solaris_locking_callback(int, int, char *, int); -static unsigned long solaris_thread_id(void); -static boolean_t thread_setup(void); -/* LINTED E_STATIC_UNUSED */ -static void thread_cleanup(void); - -mutex_t init_lock = DEFAULTMUTEX; -static mutex_t *lock_cs; -static long *lock_count; - -static boolean_t libssl_loaded = B_FALSE; -static boolean_t libcrypto_loaded = B_FALSE; - -void -libssl_load() -{ - void *dldesc; - - (void) mutex_lock(&init_lock); - if (libssl_loaded) { - (void) mutex_unlock(&init_lock); - return; - } - - dldesc = dlopen(LIBSSL, RTLD_LAZY); - if (dldesc != NULL) { - d2i_X509_NAME_fn = (X509_NAME*(*)())dlsym(dldesc, - "d2i_X509_NAME"); - if (d2i_X509_NAME_fn == NULL) - goto libssl_err; - - X509_NAME_print_ex_fp_fn = (int(*)())dlsym(dldesc, - "X509_NAME_print_ex_fp"); - if (X509_NAME_print_ex_fp_fn == NULL) - goto libssl_err; - - ERR_get_error_fn = (char *(*)())dlsym(dldesc, - "ERR_get_error"); - if (ERR_get_error_fn == NULL) - goto libssl_err; - - ERR_error_string_fn = (char *(*)())dlsym(dldesc, - "ERR_error_string"); - if (ERR_error_string_fn == NULL) - goto libssl_err; - - SSL_load_error_strings_fn = (void(*)())dlsym(dldesc, - "SSL_load_error_strings"); - if (SSL_load_error_strings_fn == NULL) - goto libssl_err; - - ERR_free_strings_fn = (void(*)())dlsym(dldesc, - "ERR_free_strings"); - if (ERR_free_strings_fn == NULL) - goto libssl_err; - - CRYPTO_set_locking_callback_fn = (void(*)())dlsym(dldesc, - "CRYPTO_set_locking_callback"); - if (CRYPTO_set_locking_callback_fn == NULL) - goto libssl_err; - - CRYPTO_set_id_callback_fn = (void(*)())dlsym(dldesc, - "CRYPTO_set_id_callback"); - if (CRYPTO_set_id_callback_fn == NULL) - goto libssl_err; - - X509_NAME_free_fn = (void(*)())dlsym(dldesc, - "X509_NAME_free"); - if (X509_NAME_free_fn == NULL) - goto libssl_err; - - if (thread_setup() == B_FALSE) - goto libssl_err; - - libssl_loaded = B_TRUE; - } - (void) mutex_unlock(&init_lock); - return; -libssl_err: - (void) dlclose(dldesc); - (void) mutex_unlock(&init_lock); -} - -void -libcrypto_load() -{ - void *dldesc; - - (void) mutex_lock(&init_lock); - if (libcrypto_loaded) { - (void) mutex_unlock(&init_lock); - return; - } - - dldesc = dlopen(LIBCRYPTO, RTLD_LAZY); - if (dldesc != NULL) { - CRYPTO_num_locks_fn = (int(*)())dlsym(dldesc, - "CRYPTO_num_locks"); - if (CRYPTO_num_locks_fn == NULL) - goto libcrypto_err; - - /* - * OPENSSL_free is really a macro, so we - * need to reference the actual symbol, - * which is CRYPTO_free. - */ - OPENSSL_free_fn = (void(*)())dlsym(dldesc, - "CRYPTO_free"); - if (OPENSSL_free_fn == NULL) - goto libcrypto_err; - - /* - * OPENSSL_malloc is really a macro, so we - * need to reference the actual symbol, - * which is CRYPTO_malloc. - */ - OPENSSL_malloc_fn = (void *(*)())dlsym(dldesc, - "CRYPTO_malloc"); - if (OPENSSL_malloc_fn == NULL) - goto libcrypto_err; - - libcrypto_loaded = B_TRUE; - } - (void) mutex_unlock(&init_lock); - return; -libcrypto_err: - (void) dlclose(dldesc); - (void) mutex_unlock(&init_lock); -} - -static boolean_t -thread_setup(void) -{ - int i; - - if ((lock_cs = OPENSSL_malloc_fn(CRYPTO_num_locks_fn() * - sizeof (mutex_t))) == NULL) - return (B_FALSE); - if ((lock_count = OPENSSL_malloc_fn(CRYPTO_num_locks_fn() * - sizeof (long))) == NULL) { - OPENSSL_free_fn(lock_cs); - return (B_FALSE); - } - - for (i = 0; i < CRYPTO_num_locks_fn(); i++) { - lock_count[i] = 0; - (void) mutex_init(&(lock_cs[i]), USYNC_THREAD, NULL); - } - - CRYPTO_set_id_callback_fn((unsigned long (*)())solaris_thread_id); - CRYPTO_set_locking_callback_fn((void (*)())solaris_locking_callback); - return (B_TRUE); -} - -static void -thread_cleanup(void) -{ - int i; - - (void) mutex_lock(&init_lock); - CRYPTO_set_locking_callback_fn(NULL); - CRYPTO_set_id_callback_fn(NULL); - for (i = 0; i < CRYPTO_num_locks_fn(); i++) - (void) mutex_destroy(&(lock_cs[i])); - OPENSSL_free_fn(lock_cs); - OPENSSL_free_fn(lock_count); - (void) mutex_unlock(&init_lock); -} - -/* ARGSUSED */ -static void -solaris_locking_callback(int mode, int type, char *file, int line) -{ - if (mode & CRYPTO_LOCK) { - (void) mutex_lock(&(lock_cs[type])); - lock_count[type]++; - } else { - (void) mutex_unlock(&(lock_cs[type])); - } -} - -static unsigned long -solaris_thread_id(void) -{ - unsigned long ret; - - ret = (unsigned long)thr_self(); - return (ret); -} - -void -print_asn1_name(FILE *file, const unsigned char *buf, long buflen) -{ - libcrypto_load(); - if (libcrypto_loaded) - libssl_load(); - - if (libssl_loaded && libcrypto_loaded) { - X509_NAME *x509name = NULL; - const unsigned char *p; - - /* Make an effort to decode the ASN1 encoded name */ - SSL_load_error_strings_fn(); - - /* - * Temporary variable is mandatory per d2i_X509(3). Upcoming - * call to d2i_X509_NAME_fn() will change the 'p' pointer. - */ - p = buf; - - x509name = d2i_X509_NAME_fn(NULL, &p, buflen); - if (x509name != NULL) { - (void) X509_NAME_print_ex_fp_fn(file, x509name, 0, - (ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE | - XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN)); - X509_NAME_free_fn(x509name); - (void) fprintf(file, "\n"); - } else { - char errbuf[80]; - - (void) fprintf(file, "\n# %s\n", - ERR_error_string_fn(ERR_get_error_fn(), errbuf)); - (void) fprintf(file, dgettext(TEXT_DOMAIN, - "<cannot interpret>\n")); - } - ERR_free_strings_fn(); - } else { - (void) fprintf(file, dgettext(TEXT_DOMAIN, "<cannot print>\n")); - } -} diff --git a/usr/src/lib/libipsecutil/common/ipsec_util.c b/usr/src/lib/libipsecutil/common/ipsec_util.c index 017259967c..e27a47e63b 100644 --- a/usr/src/lib/libipsecutil/common/ipsec_util.c +++ b/usr/src/lib/libipsecutil/common/ipsec_util.c @@ -24,6 +24,7 @@ * Use is subject to license terms. * Copyright 2012 Milan Juri. All rights reserved. * Copyright 2018 Joyent, Inc. + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ #include <unistd.h> @@ -47,6 +48,8 @@ #include <setjmp.h> #include <libgen.h> #include <libscf.h> +#include <kmfapi.h> +#include <ber_der.h> #include "ipsec_util.h" #include "ikedoor.h" @@ -3475,3 +3478,28 @@ ipsecutil_exit(exit_type_t type, char *fmri, FILE *fp, const char *fmt, ...) (void) fclose(fp); exit(exit_status); } + +void +print_asn1_name(FILE *file, const unsigned char *buf, long buflen) +{ + KMF_X509_NAME name = { 0 }; + KMF_DATA data = { 0 }; + char *str = NULL; + + data.Data = (unsigned char *)buf; + data.Length = buflen; + + if (DerDecodeName(&data, &name) != KMF_OK) + goto fail; + + if (kmf_dn_to_string(&name, &str) != KMF_OK) + goto fail; + + (void) fprintf(file, "%s\n", str); + kmf_free_dn(&name); + free(str); + return; +fail: + kmf_free_dn(&name); + (void) fprintf(file, dgettext(TEXT_DOMAIN, "<cannot interpret>\n")); +} diff --git a/usr/src/lib/libipsecutil/common/ipsec_util.h b/usr/src/lib/libipsecutil/common/ipsec_util.h index 44154e5c33..7f779bb95f 100644 --- a/usr/src/lib/libipsecutil/common/ipsec_util.h +++ b/usr/src/lib/libipsecutil/common/ipsec_util.h @@ -23,7 +23,7 @@ * Use is subject to license terms. */ /* - * Copyright 2017 Joyent, Inc. + * Copyright 2018 Joyent, Inc. */ #ifndef _IPSEC_UTIL_H @@ -214,20 +214,6 @@ extern int dbgstr2num(char *); extern int parsedbgopts(char *); /* - * SSL library (OpenSSL) - */ -#define LIBSSL "libssl.so" - -void libssl_load(void); - -/* - * crypto library (OpenSSL) - */ -#define LIBCRYPTO "libcrypto.so" - -void libcrypto_load(void); - -/* * functions to manipulate the IKEv1 kmcookie-label mapping file */ diff --git a/usr/src/lib/libkmf/include/kmfapi.h b/usr/src/lib/libkmf/include/kmfapi.h index 9aeb0ca202..dbe09b2db6 100644 --- a/usr/src/lib/libkmf/include/kmfapi.h +++ b/usr/src/lib/libkmf/include/kmfapi.h @@ -19,6 +19,7 @@ * CDDL HEADER END * * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2018, Joyent, Inc. * * Constant definitions and function prototypes for the KMF library. * Commonly used data types are defined in "kmftypes.h". @@ -275,6 +276,7 @@ extern KMF_RETURN kmf_get_kmf_error_str(KMF_RETURN, char **); * Miscellaneous */ extern KMF_RETURN kmf_dn_parser(char *, KMF_X509_NAME *); +extern KMF_RETURN kmf_dn_to_string(KMF_X509_NAME *, char **); extern KMF_RETURN kmf_read_input_file(KMF_HANDLE_T, char *, KMF_DATA *); extern KMF_RETURN kmf_der_to_pem(KMF_OBJECT_TYPE, unsigned char *, int, unsigned char **, int *); diff --git a/usr/src/lib/libkmf/libkmf/Makefile.com b/usr/src/lib/libkmf/libkmf/Makefile.com index a704d1e5a8..43de43cb1d 100644 --- a/usr/src/lib/libkmf/libkmf/Makefile.com +++ b/usr/src/lib/libkmf/libkmf/Makefile.com @@ -19,6 +19,7 @@ # CDDL HEADER END # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2018, Joyent, Inc. # LIBRARY= libkmf.a @@ -56,8 +57,8 @@ LIBS= $(DYNLIB) $(LINTLIB) $(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) -LDLIBS += $(BERDERLIB) $(CRYPTOUTILLIB) -lmd -lpkcs11 -lnsl -lsocket -lc -LDLIBS6 += $(BERDERLIB64) $(CRYPTOUTILLIB64) -lmd -lpkcs11 -lnsl -lsocket -lc +LDLIBS += $(BERDERLIB) $(CRYPTOUTILLIB) -lmd -lpkcs11 -lnsl -lsocket -lc +LDLIBS += -lcustr # DYNLIB libraries do not have lint libs and are not linted $(DYNLIB) := LDLIBS += -lxml2 diff --git a/usr/src/lib/libkmf/libkmf/common/mapfile-vers b/usr/src/lib/libkmf/libkmf/common/mapfile-vers index 4e8d0d848d..977112d733 100644 --- a/usr/src/lib/libkmf/libkmf/common/mapfile-vers +++ b/usr/src/lib/libkmf/libkmf/common/mapfile-vers @@ -19,6 +19,7 @@ # CDDL HEADER END # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2018, Joyent, Inc. # # # MAPFILE HEADER START @@ -401,6 +402,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { GetIDFromSPKI; IsEqualOid; kmf_create_pk11_session; + kmf_dn_to_string; kmf_select_token; parsePolicyElement; PKCS_DigestData; diff --git a/usr/src/lib/libkmf/libkmf/common/rdn_parser.c b/usr/src/lib/libkmf/libkmf/common/rdn_parser.c index 5cc22146d8..3e23c0ac56 100644 --- a/usr/src/lib/libkmf/libkmf/common/rdn_parser.c +++ b/usr/src/lib/libkmf/libkmf/common/rdn_parser.c @@ -33,6 +33,8 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * + * Copyright 2018, Joyent, Inc. + * * File: rdn_parser.c */ @@ -44,6 +46,7 @@ #include <rdn_parser.h> #include <stdio.h> #include <values.h> +#include <libcustr.h> /* * The order here is important. The OIDs are arranged in order of @@ -535,3 +538,218 @@ kmf_dn_parser(char *string, KMF_X509_NAME *name) err = ParseDistinguishedName(string, (int)strlen(string), name); return (err); } + +static const char hexdigits[] = "0123456789abcdef"; + +static KMF_RETURN +binvalue_to_string(KMF_DATA *data, custr_t *str) +{ + size_t i; + uchar_t c; + + if (custr_appendc(str, '#') != 0) + return (KMF_ERR_MEMORY); + + for (i = 0; i < data->Length; i++) { + c = data->Data[i]; + if (custr_appendc(str, hexdigits[(c >> 4) & 0xf]) != 0 || + custr_appendc(str, hexdigits[(c & 0xf)]) != 0) { + return (KMF_ERR_MEMORY); + } + } + + return (KMF_OK); +} + +/* + * Convert an RDN value into a printable name with appropriate escaping. + * The rules are taken from RFC4514. While it is dealing with LDAP + * distinguished names, both LDAP and x509 certificates are based on the + * same underlying ITU standards, and as far as I can determine, the same + * rules apply (or at least the rules for LDAP DNs apply the same to x509 + * DNs). + */ +static KMF_RETURN +value_to_string(KMF_DATA *data, custr_t *str) +{ + size_t i; + uchar_t c; + + for (i = 0; i < data->Length; i++) { + c = data->Data[i]; + + /* + * While technically not required, it is suggested that + * printable non-ascii characters (e.g. multi-byte UTF-8 + * characters) are converted as escaped hex (as well as + * unprintable characters). AFAIK there is no one canonical + * string representation (e.g. attribute names are case + * insensitive, so 'CN=foo' and 'cn=foo' convert to the same + * binary representation, but there is nothing to say if + * either string form is canonical), so this shouldn't + * pose a problem. + */ + if (c < ' ' || c >= 0x7f) { + /* + * RFC4514 specifies the hex form in a DN string as + * \{hex}{hex}. OpenSSL uses capitals for A-F so we + * do the same. + */ + if (custr_append_printf(str, "\\%02hhX", c) != 0) + return (KMF_ERR_MEMORY); + continue; + } + + switch (c) { + case '#': + /* Escape # if at the start of a value */ + if (i != 0) + break; + /* FALLTHROUGH */ + case ' ': + /* Escape ' ' if at the start or end of a value */ + if (i != 0 && i + 1 != data->Length) + break; + /* FALLTHROUGH */ + case '"': + case '+': + case ',': + case ';': + case '<': + case '>': + case '\\': + /* Escape these */ + if (custr_appendc(str, '\\') != 0) + return (KMF_ERR_MEMORY); + } + + if (custr_appendc(str, c) != 0) + return (KMF_ERR_MEMORY); + } + + return (KMF_OK); +} + +/* + * Translate an attribute/value pair into a string. If the attribute OID + * is a well known OID (in name2kinds) we use the name instead of the OID. + */ +static KMF_RETURN +ava_to_string(KMF_X509_TYPE_VALUE_PAIR *tvp, custr_t *str) +{ + KMF_OID *kind_oid; + KMF_OID *rdn_oid = &tvp->type; + const char *attr = NULL; + size_t i; + KMF_RETURN ret = KMF_OK; + boolean_t found = B_FALSE; + + for (i = 0; name2kinds[i].name != NULL; i++) { + kind_oid = name2kinds[i].OID; + + if (!IsEqualOid(kind_oid, rdn_oid)) + continue; + + attr = name2kinds[i].name; + found = B_TRUE; + break; + } + + if (!found && (attr = kmf_oid_to_string(rdn_oid)) == NULL) { + ret = KMF_ERR_MEMORY; + goto done; + } + if (custr_append(str, attr) != 0) { + ret = KMF_ERR_MEMORY; + goto done; + } + if (custr_appendc(str, '=') != 0) { + ret = KMF_ERR_MEMORY; + goto done; + } + + /* + * RFC4514 indicates that an oid=value pair should have the value + * printed as #xxxxxx. In addition, we also print as a binary + * value if the BER tag does not indicate the value is some sort + * of printable string. + */ + switch (tvp->valueType) { + case BER_UTF8_STRING: + case BER_PRINTABLE_STRING: + case BER_T61STRING: + case BER_IA5STRING: + if (found) { + ret = value_to_string(&tvp->value, str); + break; + } + /*FALLTHROUGH*/ + default: + ret = binvalue_to_string(&tvp->value, str); + break; + } + +done: + if (!found) + free((void *)attr); + + return (ret); +} + +static KMF_RETURN +rdn_to_string(KMF_X509_RDN *rdn, custr_t *str) +{ + KMF_RETURN ret; + size_t i; + + for (i = 0; i < rdn->numberOfPairs; i++) { + if (i > 0 && custr_appendc(str, '+') != 0) + return (KMF_ERR_MEMORY); + + ret = ava_to_string(&rdn->AttributeTypeAndValue[i], str); + if (ret != KMF_OK) + return (ret); + } + + return (KMF_OK); +} + +/* + * kmf_dn_to_string + * + * Take a binary KMF_X509_NAME and convert it into a human readable string. + */ +KMF_RETURN +kmf_dn_to_string(KMF_X509_NAME *name, char **string) +{ + custr_t *str = NULL; + KMF_RETURN err = KMF_OK; + size_t i; + + if (name == NULL || string == NULL) + return (KMF_ERR_BAD_PARAMETER); + + *string = NULL; + + if (custr_alloc(&str) != 0) + return (KMF_ERR_MEMORY); + + for (i = 0; i < name->numberOfRDNs; i++) { + KMF_X509_RDN *rdn = &name->RelativeDistinguishedName[i]; + + if (i > 0 && custr_append(str, ", ") != 0) { + err = KMF_ERR_MEMORY; + goto done; + } + + if ((err = rdn_to_string(rdn, str)) != KMF_OK) + goto done; + } + + if ((*string = strdup(custr_cstr(str))) == NULL) + err = KMF_ERR_MEMORY; + +done: + custr_free(str); + return (err); +} |
