Mercurial > illumos > illumos-gate
changeset 12611:d9f75b73c5fd
PSARC/2010/177 KMF Certificate Name mapping extensions
PSARC/2010/178 KMF Common Name Mapper
6942888 KMF should provide certificate to name mapping capabilities
6949176 KMF cert-to-name mapping framework needs a CN mapper
line wrap: on
line diff
--- a/usr/src/cmd/cmd-crypto/kmfcfg/create.c Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/cmd/cmd-crypto/kmfcfg/create.c Fri Jun 11 01:25:07 2010 -0700 @@ -18,12 +18,9 @@ * * CDDL HEADER END * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <strings.h> #include <ctype.h> @@ -71,6 +68,10 @@ "X:(crl-proxy)" "S:(crl-ignore-crl-sign)" "D:(crl-ignore-crl-date)" + "m:(mapper-name)" + "M:(mapper-directory)" + "Q:(mapper-pathname)" + "q:(mapper-options)" "u:(keyusage)" "E:(ekunames)" "O:(ekuoids)")) != EOF) { @@ -374,6 +375,39 @@ rv = KC_ERR_USAGE; } break; + case 'm': + plc.mapper.mapname = get_string(optarg_av, &rv); + if (plc.mapper.mapname == NULL) { + (void) fprintf(stderr, + gettext("Error mapper-name " + "input.\n")); + } + break; + case 'M': + plc.mapper.dir = get_string(optarg_av, &rv); + if (plc.mapper.dir == NULL) { + (void) fprintf(stderr, + gettext("Error mapper-dir " + "input.\n")); + } + break; + case 'Q': + plc.mapper.pathname = get_string(optarg_av, + &rv); + if (plc.mapper.pathname == NULL) { + (void) fprintf(stderr, + gettext("Error mapper-pathname " + "input.\n")); + } + break; + case 'q': + plc.mapper.options = get_string(optarg_av, &rv); + if (plc.mapper.options == NULL) { + (void) fprintf(stderr, + gettext("Error mapper-options " + "input.\n")); + } + break; default: (void) fprintf(stderr, gettext("Error input option.\n")); @@ -463,6 +497,23 @@ } /* + * Setting mapper-name (with optional mapper-dir) and mapper-pathname is + * mutually exclusive. Also, you cannot set options only, you need the + * name or pathname, and you can set the directory only with the name, + * not the pathname. + */ + if ((plc.mapper.mapname != NULL && plc.mapper.pathname != NULL) || + (plc.mapper.dir != NULL && plc.mapper.pathname != NULL) || + (plc.mapper.dir != NULL && plc.mapper.mapname == NULL) || + (plc.mapper.options != NULL && plc.mapper.mapname == NULL && + plc.mapper.pathname == NULL)) { + (void) fprintf(stderr, + gettext("Error in mapper input options\n")); + rv = KC_ERR_USAGE; + goto out; + } + + /* * If any CRL attribute is set, turn on the CRL checking flag. */ if (crl_set_attr > 0)
--- a/usr/src/cmd/cmd-crypto/kmfcfg/kmfcfg.c Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/cmd/cmd-crypto/kmfcfg/kmfcfg.c Fri Jun 11 01:25:07 2010 -0700 @@ -17,13 +17,9 @@ * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END + * + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" #include <stdio.h> #include <strings.h> @@ -94,7 +90,11 @@ "\t\tipsecEndSystem | ipsecTunnel |\n\t" "\t\tipsecUser | timeStamping |\n\t" "\t\tOCSPSigning],[...]\n" - "\t\t[ekuoids=OID,OID,OID...]\n" }, + "\t\t[ekuoids=OID,OID,OID...]\n" + "\t\t[mapper-name=name of mapper library]\n" + "\t\t[mapper-directory=dir where mapper library resides]\n" + "\t\t[mapper-path=full pathname of mapper library]\n" + "\t\t[mapper-options=mapper options]\n"}, { "modify", kc_modify, "modify [dbfile=dbfile] policy=policyname\n" "\t\t[ignore-date=true|false]\n" @@ -130,6 +130,10 @@ "\t\tOCSPSigning],[...]\n" "\t\t[ekuoids=OID,OID,OID...]\n" "\t\t[eku-none=true|false]\n\n" + "\t\t[mapper-name=name of mapper library]\n" + "\t\t[mapper-directory=dir where mapper library resides]\n" + "\t\t[mapper-path=full pathname of mapper library]\n" + "\t\t[mapper-options=mapper options]\n" "\tmodify plugin keystore=keystorename option=optionstring\n"}, { "import", kc_import, "import [dbfile=dbfile] policy=policyname "
--- a/usr/src/cmd/cmd-crypto/kmfcfg/kmfpolicy.dtd Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/cmd/cmd-crypto/kmfcfg/kmfpolicy.dtd Fri Jun 11 01:25:07 2010 -0700 @@ -1,8 +1,7 @@ <?xml version='1.0' encoding='UTF-8' ?> <!-- - Copyright 2006 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. + Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. CDDL HEADER START @@ -22,8 +21,6 @@ information: Portions Copyright [yyyy] [name of copyright owner] CDDL HEADER END - - ident "%Z%%M% %I% %E% SMI" --> <!--Element Definitions--> @@ -31,7 +28,7 @@ <!ELEMENT kmf-policy-db (kmf-policy*)> <!ATTLIST kmf-policy-db allow-local-files (TRUE|FALSE) #IMPLIED> -<!ELEMENT kmf-policy (validation-methods, key-usage-set?, ext-key-usage?)> +<!ELEMENT kmf-policy (validation-methods, key-usage-set?, ext-key-usage?, cert-to-name-mapping?)> <!ATTLIST kmf-policy name CDATA #REQUIRED> <!ATTLIST kmf-policy ignore-date (TRUE|FALSE) #IMPLIED> <!ATTLIST kmf-policy ignore-unknown-eku (TRUE|FALSE) #IMPLIED> @@ -82,3 +79,9 @@ timeStamping | OCSPSigning) #IMPLIED > <!ELEMENT eku-oid EMPTY> <!ATTLIST eku-oid oid CDATA #IMPLIED> + +<!ELEMENT cert-to-name-mapping ANY> +<!ATTLIST cert-to-name-mapping mapper-name CDATA #IMPLIED> +<!ATTLIST cert-to-name-mapping mapper-directory CDATA #IMPLIED> +<!ATTLIST cert-to-name-mapping mapper-pathname CDATA #IMPLIED> +<!ATTLIST cert-to-name-mapping mapper-options CDATA #IMPLIED>
--- a/usr/src/cmd/cmd-crypto/kmfcfg/list.c Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/cmd/cmd-crypto/kmfcfg/list.c Fri Jun 11 01:25:07 2010 -0700 @@ -18,12 +18,9 @@ * * CDDL HEADER END * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <strings.h> #include <ctype.h> @@ -161,6 +158,14 @@ plc->validation_info.crl_info.ignore_crl_date ? gettext("true") : gettext("false")); } + (void) printf(gettext("Mapper name: %s\n"), + plc->mapper.mapname ? plc->mapper.mapname : "<null>"); + (void) printf(gettext("Mapper pathname: %s\n"), + plc->mapper.pathname ? plc->mapper.pathname : "<null>"); + (void) printf(gettext("Mapper directory: %s\n"), + plc->mapper.dir ? plc->mapper.dir : "<null>"); + (void) printf(gettext("Mapper options: %s\n"), + plc->mapper.options ? plc->mapper.options : "<null>"); (void) printf("\n"); }
--- a/usr/src/cmd/cmd-crypto/kmfcfg/modify.c Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/cmd/cmd-crypto/kmfcfg/modify.c Fri Jun 11 01:25:07 2010 -0700 @@ -18,12 +18,9 @@ * * CDDL HEADER END * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <strings.h> #include <ctype.h> @@ -61,9 +58,17 @@ #define KC_KEYUSAGE_NONE 0x0400000 #define KC_EKUS 0x0800000 #define KC_EKUS_NONE 0x1000000 +#define KC_MAPPER_OPTIONS 0x2000000 static int err; /* To store errno which may be overwritten by gettext() */ +#define UPDATE_IF_DIFFERENT(old, new) \ + if ((old != NULL && new != NULL && strcmp(old, new) != 0) || \ + (old == NULL && new != NULL)) { \ + if (old != NULL) \ + free(old); \ + old = new; \ + } int kc_modify_policy(int argc, char *argv[]) @@ -74,6 +79,9 @@ extern int optind_av; extern char *optarg_av; char *filename = NULL; + char *mapper_name = NULL; + char *mapper_dir = NULL; + char *mapper_pathname = NULL; uint32_t flags = 0; boolean_t ocsp_none_opt = B_FALSE; boolean_t crl_none_opt = B_FALSE; @@ -114,6 +122,10 @@ "Y:(keyusage-none)" "E:(ekunames)" "O:(ekuoids)" + "m:(mapper-name)" + "M:(mapper-directory)" + "Q:(mapper-pathname)" + "q:(mapper-options)" "Z:(eku-none)")) != EOF) { switch (opt) { case 'i': @@ -485,6 +497,35 @@ flags |= KC_EKUS_NONE; } break; + case 'm': + mapper_name = get_string(optarg_av, &rv); + if (mapper_name == NULL) { + (void) fprintf(stderr, + gettext("Error mapper-name " + "input.\n")); + } + break; + case 'M': + mapper_dir = get_string(optarg_av, &rv); + if (mapper_dir == NULL) { + (void) fprintf(stderr, + gettext("Error mapper-directory " + "input.\n")); + } + break; + case 'Q': + mapper_pathname = get_string(optarg_av, &rv); + if (mapper_pathname == NULL) { + (void) fprintf(stderr, + gettext("Error mapper-pathname " + "input.\n")); + } + break; + case 'q': + plc.mapper.options = get_string(optarg_av, &rv); + rv = 0; /* its ok for this to be NULL */ + flags |= KC_MAPPER_OPTIONS; + break; default: (void) fprintf(stderr, gettext("Error input option.\n")); @@ -577,6 +618,55 @@ oplc.ta_serial = plc.ta_serial; } + /* + * There are some combinations of attributes that are not valid. + * + * First, setting mapper-name (with optional mapper-directory) and + * mapper-pathname is mutually exclusive. + */ + if ((mapper_name != NULL && mapper_pathname != NULL) || + (mapper_name != NULL && oplc.mapper.pathname != NULL) || + (mapper_pathname != NULL && oplc.mapper.mapname != NULL) || + /* Mapper directory can be set only if mapper name is set. */ + (mapper_dir != NULL && mapper_pathname != NULL) || + (mapper_dir != NULL && mapper_name == NULL && + oplc.mapper.mapname == NULL) || + (mapper_dir != NULL && oplc.mapper.pathname != NULL) || + /* Options can be set only if mapper name or pathname is set. */ + ((plc.mapper.options != NULL || oplc.mapper.options != NULL) && + (mapper_name == NULL && oplc.mapper.mapname == NULL && + mapper_pathname == NULL && oplc.mapper.pathname == NULL))) { + (void) fprintf(stderr, + gettext("Error in mapper input options\n")); + if (mapper_name != NULL) + free(mapper_name); + if (mapper_pathname != NULL) + free(mapper_pathname); + if (mapper_dir != NULL) + free(mapper_dir); + if (flags & KC_MAPPER_OPTIONS && plc.mapper.options != NULL) + free(plc.mapper.options); + rv = KC_ERR_USAGE; + goto out; + } else { + if (mapper_name != NULL) + plc.mapper.mapname = mapper_name; + if (mapper_pathname != NULL) + plc.mapper.pathname = mapper_pathname; + if (mapper_dir != NULL) + plc.mapper.dir = mapper_dir; + } + + UPDATE_IF_DIFFERENT(oplc.mapper.mapname, plc.mapper.mapname); + UPDATE_IF_DIFFERENT(oplc.mapper.pathname, plc.mapper.pathname); + UPDATE_IF_DIFFERENT(oplc.mapper.dir, plc.mapper.dir); + + if (flags & KC_MAPPER_OPTIONS) { + if (oplc.mapper.options != NULL) + free(oplc.mapper.options); + oplc.mapper.options = plc.mapper.options; + } + /* Update the OCSP policy */ if (ocsp_none_opt == B_TRUE) { if (ocsp_set_attr > 0) { @@ -849,7 +939,6 @@ return (rv); } - static int kc_modify_plugin(int argc, char *argv[]) {
--- a/usr/src/lib/libkmf/Makefile Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/lib/libkmf/Makefile Fri Jun 11 01:25:07 2010 -0700 @@ -18,10 +18,7 @@ # # CDDL HEADER END # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # # KMF Prototype Makefile # @@ -30,7 +27,7 @@ LIBRARY= libkmf.a VERS= 1 -SUBDIRS = ber_der libkmf plugins +SUBDIRS = ber_der libkmf plugins mappers HDRS= kmfapi.h kmftypes.h HDRDIR= include
--- a/usr/src/lib/libkmf/include/kmfapi.h Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/lib/libkmf/include/kmfapi.h Fri Jun 11 01:25:07 2010 -0700 @@ -17,11 +17,8 @@ * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. * + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * * Constant definitions and function prototypes for the KMF library. * Commonly used data types are defined in "kmftypes.h". @@ -340,6 +337,25 @@ void kmf_set_attr_at_index(KMF_ATTRIBUTE *, int, KMF_ATTR_TYPE, void *, uint32_t); +/* + * Certificate to name mapping functions. + */ +KMF_RETURN kmf_cert_to_name_mapping_initialize(KMF_HANDLE_T, int, + KMF_ATTRIBUTE *); +KMF_RETURN kmf_cert_to_name_mapping_finalize(KMF_HANDLE_T); +KMF_RETURN kmf_map_cert_to_name(KMF_HANDLE_T, KMF_DATA *, KMF_DATA *); +KMF_RETURN kmf_match_cert_to_name(KMF_HANDLE_T, KMF_DATA *, KMF_DATA *, + KMF_DATA *); +KMF_RETURN kmf_get_mapper_error_str(KMF_HANDLE_T, char **); +/* + * Helper functions for handling the mapper internal state. They are part of the + * public interface, too. + */ +void kmf_set_mapper_lasterror(KMF_HANDLE_T, uint32_t); +uint32_t kmf_get_mapper_lasterror(KMF_HANDLE_T); +void kmf_set_mapper_options(KMF_HANDLE_T, void *); +void *kmf_get_mapper_options(KMF_HANDLE_T); + #ifdef __cplusplus } #endif
--- a/usr/src/lib/libkmf/include/kmfapiP.h Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/lib/libkmf/include/kmfapiP.h Fri Jun 11 01:25:07 2010 -0700 @@ -17,10 +17,8 @@ * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _KMFAPIP_H #define _KMFAPIP_H @@ -182,6 +180,7 @@ KMF_ERROR lasterr; KMF_POLICY_RECORD *policy; KMF_PLUGIN_LIST *plugins; + KMF_MAPPER_STATE *mapstate; } KMF_HANDLE; #define CLEAR_ERROR(h, rv) { \ @@ -348,8 +347,9 @@ extern boolean_t is_valid_keystore_type(KMF_KEYSTORE_TYPE); extern KMF_BOOL is_eku_present(KMF_X509EXT_EKU *, KMF_OID *); extern KMF_RETURN parse_eku_data(const KMF_DATA *, KMF_X509EXT_EKU *); -extern KMF_RETURN -copy_extension_data(KMF_X509_EXTENSION *, KMF_X509_EXTENSION *); +extern KMF_RETURN copy_extension_data(KMF_X509_EXTENSION *, + KMF_X509_EXTENSION *); +extern char *get_mapper_pathname(char *, char *); #ifdef __cplusplus }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libkmf/include/kmfmapper.h Fri Jun 11 01:25:07 2010 -0700 @@ -0,0 +1,81 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * + * This is a private header file for the KMF certificate to name mapping + * framework. + */ +#ifndef _KMFMAPPER_H +#define _KMFMAPPER_H + +#pragma ident "@(#)kmfmapper.h 1.1 08/02/27 SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAPPER_NAME_TEMPLATE "kmf_mapper_%s.so.1" + +#define MAPPER_ERROR_STRING_FUNCTION "mapper_get_error_str" +#define MAP_CERT_TO_NAME_FUNCTION "mapper_map_cert_to_name" +#define MATCH_CERT_TO_NAME_FUNCTION "mapper_match_cert_to_name" +#define MAPPER_FINISH_FUNCTION "mapper_finalize" +#define MAPPER_INIT_FUNCTION "mapper_initialize" + +/* KMF mapper policy record. */ +typedef struct { + /* + * Those four attributes are initialized from the policy database and + * are not to be changed for the life of the KMF session. + */ + char *mapname; + char *options; + char *pathname; + char *dir; + /* Current mapper. */ + void *dldesc; + /* + * The presently open mapper pathname and options. Can be based on the + * policy attributes or attributes provided directly to the + * kmf_cert_to_name_mapping_init(), thus overriding the policy settings. + */ + char *curpathname; + char *curoptions; +} KMF_MAPPER_RECORD; + +/* KMF mapper state record. */ +typedef struct { + /* + * (Processed) options. Transparent to KMF. Each mapper can store its + * data there since options can be unique to every KMF handle. + */ + void *options; + /* + * If the mapper returns KMF_ERR_INTERNAL the application may ask for + * the internal mapper error string. That error code is stored here. + */ + uint32_t lastmappererr; +} KMF_MAPPER_STATE; + +#ifdef __cplusplus +} +#endif +#endif /* _KMFMAPPER_H */
--- a/usr/src/lib/libkmf/include/kmfpolicy.h Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/lib/libkmf/include/kmfpolicy.h Fri Jun 11 01:25:07 2010 -0700 @@ -18,15 +18,13 @@ * * CDDL HEADER END * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _KMFPOLICY_H #define _KMFPOLICY_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <kmfapi.h> +#include <kmfmapper.h> #include <libxml/tree.h> #include <libxml/parser.h> @@ -72,15 +70,14 @@ KMF_OID *ekulist; }KMF_EKU_POLICY; - #define KMF_REVOCATION_METHOD_CRL 0x1 #define KMF_REVOCATION_METHOD_OCSP 0x2 - typedef struct { char *name; KMF_VALIDATION_POLICY validation_info; KMF_EKU_POLICY eku_set; + KMF_MAPPER_RECORD mapper; /* kmfmapper.h */ uint32_t ku_bits; boolean_t ignore_date; boolean_t ignore_unknown_ekus; @@ -173,6 +170,12 @@ #define KMF_EKU_OID_ELEMENT "eku-oid" #define KMF_EKU_OID_ATTR "oid" +#define KMF_CERT_MAPPER_ELEMENT "cert-to-name-mapping" +#define KMF_CERT_MAPPER_NAME_ATTR "mapper-name" +#define KMF_CERT_MAPPER_DIR_ATTR "mapper-directory" +#define KMF_CERT_MAPPER_PATH_ATTR "mapper-pathname" +#define KMF_CERT_MAPPER_OPTIONS_ATTR "mapper-options" + #define TMPFILE_TEMPLATE "policyXXXXXX" extern int parsePolicyElement(xmlNodePtr, KMF_POLICY_RECORD *);
--- a/usr/src/lib/libkmf/include/kmftypes.h Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/lib/libkmf/include/kmftypes.h Fri Jun 11 01:25:07 2010 -0700 @@ -2,8 +2,7 @@ * Copyright (c) 1995-2000 Intel Corporation. All rights reserved. */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _KMFTYPES_H @@ -345,7 +344,11 @@ KMF_ERR_UNEXTRACTABLE_KEY = 0x52, KMF_ERR_KEY_MISMATCH = 0x53, KMF_ERR_ATTR_NOT_FOUND = 0x54, - KMF_ERR_KMF_CONF = 0x55 + KMF_ERR_KMF_CONF = 0x55, + KMF_ERR_NAME_NOT_MATCHED = 0x56, + KMF_ERR_MAPPER_OPEN = 0x57, + KMF_ERR_MAPPER_NOT_FOUND = 0x58, + KMF_ERR_MAPPING_FAILED = 0x59 } KMF_RETURN; /* Data structures for OCSP support */ @@ -795,7 +798,10 @@ KMF_VALIDATE_RESULT_ATTR, KMF_KEY_DATA_ATTR, KMF_PK11_USER_TYPE_ATTR, - KMF_ECC_CURVE_OID_ATTR + KMF_ECC_CURVE_OID_ATTR, + KMF_MAPPER_NAME_ATTR, + KMF_MAPPER_PATH_ATTR, + KMF_MAPPER_OPTIONS_ATTR } KMF_ATTR_TYPE; typedef struct {
--- a/usr/src/lib/libkmf/libkmf/Makefile.com Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/lib/libkmf/libkmf/Makefile.com Fri Jun 11 01:25:07 2010 -0700 @@ -18,8 +18,7 @@ # # CDDL HEADER END # -# Copyright 2010 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # LIBRARY= libkmf.a @@ -34,6 +33,7 @@ generalop.o \ keyop.o \ kmfoids.o \ + mapping.o \ pem_encode.o \ pk11tokens.o \ policy.o \
--- a/usr/src/lib/libkmf/libkmf/common/generalop.c Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/lib/libkmf/libkmf/common/generalop.c Fri Jun 11 01:25:07 2010 -0700 @@ -18,9 +18,7 @@ * * CDDL HEADER END * - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <stdio.h> @@ -136,7 +134,11 @@ {KMF_ERR_UNEXTRACTABLE_KEY, "KMF_ERR_UNEXTRACTABLE_KEY"}, {KMF_ERR_KEY_MISMATCH, "KMF_ERR_KEY_MISMATCH"}, {KMF_ERR_ATTR_NOT_FOUND, "KMF_ERR_ATTR_NOT_FOUND"}, - {KMF_ERR_KMF_CONF, "KMF_ERR_KMF_CONF"} + {KMF_ERR_KMF_CONF, "KMF_ERR_KMF_CONF"}, + {KMF_ERR_NAME_NOT_MATCHED, "KMF_ERR_NAME_NOT_MATCHED"}, + {KMF_ERR_MAPPER_OPEN, "KMF_ERR_MAPPER_OPEN"}, + {KMF_ERR_MAPPER_NOT_FOUND, "KMF_ERR_MAPPER_NOT_FOUND"}, + {KMF_ERR_MAPPING_FAILED, "KMF_ERR_MAPPING_FAILED"} }; typedef struct { @@ -491,6 +493,26 @@ if (ret != KMF_OK) goto errout; + /* + * Let's have the mapper status structure even if no cert-to-name + * mapping is initialized. It's better not to coredump in the + * kmf_get_mapper_lasterror function, for example, when there is no + * mapping initialized. + */ + handle->mapstate = malloc(sizeof (KMF_MAPPER_STATE)); + if (handle->mapstate == NULL) { + ret = KMF_ERR_MEMORY; + goto errout; + } + handle->mapstate->lastmappererr = KMF_OK; + handle->mapstate->options = NULL; + + /* + * Initialize the mapping scheme according to the policy. If no mapping + * is set in the policy database we silently ignore the error. + */ + (void) kmf_cert_to_name_mapping_initialize(handle, 0, NULL); + CLEAR_ERROR(handle, ret); errout: if (ret != KMF_OK) {
--- a/usr/src/lib/libkmf/libkmf/common/mapfile-vers Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/lib/libkmf/libkmf/common/mapfile-vers Fri Jun 11 01:25:07 2010 -0700 @@ -18,8 +18,7 @@ # # CDDL HEADER END # -# Copyright 2010 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # # # MAPFILE HEADER START @@ -237,6 +236,8 @@ kmf_add_csr_eku; kmf_add_policy_to_db; kmf_build_pk12; + kmf_cert_to_name_mapping_initialize; + kmf_cert_to_name_mapping_finalize; kmf_check_cert_date; kmf_check_crl_date; kmf_compare_rdns; @@ -314,6 +315,9 @@ kmf_get_encoded_ocsp_response; kmf_get_file_format; kmf_get_kmf_error_str; + kmf_get_mapper_error_str; + kmf_get_mapper_lasterror; + kmf_get_mapper_options; kmf_get_ocsp_for_cert; kmf_get_ocsp_status_for_cert; kmf_get_pk11_handle; @@ -332,6 +336,8 @@ kmf_is_crl_file; kmf_ku_to_string; kmf_list_crl; + kmf_map_cert_to_name; + kmf_match_cert_to_name; kmf_oid_to_ekuname; kmf_oid_to_string; kmf_pem_to_der; @@ -359,6 +365,8 @@ kmf_set_csr_subject; kmf_set_csr_subject_altname; kmf_set_csr_version; + kmf_set_mapper_lasterror; + kmf_set_mapper_options; kmf_set_policy; kmf_set_token_pin; kmf_sign_cert; @@ -381,20 +389,21 @@ SUNWprivate_1.1 { global: - GetIDFromSPKI; - IsEqualOid; copy_extension_data; dup_entry; free_entry; free_entrylist; get_entrylist; - kmf_select_token; + get_mapper_pathname; + get_pk11_data; + GetIDFromSPKI; + IsEqualOid; kmf_create_pk11_session; + kmf_select_token; parsePolicyElement; - PKCS_VerifyData; PKCS_DigestData; PKCS_EncryptData; - get_pk11_data; + PKCS_VerifyData; x509_algid_to_algoid; x509_algoid_to_algid; local:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libkmf/libkmf/common/mapping.c Fri Jun 11 01:25:07 2010 -0700 @@ -0,0 +1,405 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * + * This file implements the KMF certificate to name mapping framework. + */ +#include <stdlib.h> +#include <string.h> +#include <dlfcn.h> +#include <libgen.h> +#include <kmftypes.h> +#include <kmfapiP.h> + +/* Mappers go in the same dir as plugins. */ +#define DEFAULT_MAPPER_DIR KMF_PLUGIN_PATH + +static void +cleanup_mapper(KMF_HANDLE_T handle) +{ + KMF_MAPPER_RECORD *mapper = &handle->policy->mapper; + void (*finalize)(KMF_HANDLE_T); + + if (mapper->curpathname != NULL) { + free(mapper->curpathname); + mapper->curpathname = NULL; + } + if (mapper->curoptions != NULL) { + free(mapper->curoptions); + mapper->curoptions = NULL; + } + if (mapper->dldesc != NULL) { + finalize = (void(*)())dlsym(mapper->dldesc, + MAPPER_FINISH_FUNCTION); + /* Optional, not an error if it does not exist. */ + if (finalize != NULL) + finalize(handle); + + (void) dlclose(mapper->dldesc); + mapper->dldesc = NULL; + } +} + +/* The caller is expected to free the returned string. */ +char * +get_mapper_pathname(char *name, char *dir) +{ + char *pathname = NULL; + int len; + + if (name == NULL) + return (NULL); + + if (dir == NULL) + dir = DEFAULT_MAPPER_DIR; + + /* + * MAPPER_NAME_TEMPLATE has 2 extra characters (%s) which make up for + * the "/" and the terminating NULL when computing the total length. + */ + len = strlen(name) + strlen(MAPPER_NAME_TEMPLATE) + strlen(dir); + + pathname = malloc(len); + if (pathname == NULL) + return (NULL); + (void) memset(pathname, 0, len); + /* Avoid double forward slash if the dir's last character is "/". */ + (void) snprintf(pathname, len, "%s%s" MAPPER_NAME_TEMPLATE, + dir, dir[strlen(dir) - 1] == '/' ? "" : "/", name); + + return (pathname); +} + +static KMF_RETURN +open_mapper_library(KMF_MAPPER_RECORD *map) +{ + KMF_RETURN ret = KMF_OK; + + map->dldesc = dlopen(map->curpathname, RTLD_LAZY | RTLD_PARENT); + if (map->dldesc == NULL) + return (KMF_ERR_MAPPER_OPEN); + + return (ret); +} + +/* + * The mapping framework uses either attributes or the policy file. Those two + * sources are never mixed. We always need a mapper name or a mapper pathname + * but these two are mutually exclusive. Directory can be set only if name is + * set. + */ +KMF_RETURN +kmf_cert_to_name_mapping_initialize(KMF_HANDLE_T handle, int numattr, + KMF_ATTRIBUTE *attrlist) +{ + KMF_RETURN ret = KMF_OK; + KMF_RETURN (*initialize)(KMF_HANDLE_T, char *); + KMF_MAPPER_RECORD *map = NULL; + char *dir = NULL; + char *name = NULL; + char *opts = NULL; + char *path = NULL; + char *tmppath = NULL; + char *old_curpathname = NULL; + char *old_curoptions = NULL; + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); + + map = &handle->policy->mapper; + old_curpathname = map->curpathname; + old_curoptions = map->curoptions; + + name = kmf_get_attr_ptr(KMF_MAPPER_NAME_ATTR, attrlist, numattr); + dir = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); + path = kmf_get_attr_ptr(KMF_MAPPER_PATH_ATTR, attrlist, numattr); + opts = kmf_get_attr_ptr(KMF_MAPPER_OPTIONS_ATTR, attrlist, numattr); + + if (path != NULL) { + /* Mutually exclusive. */ + if (name != NULL || dir != NULL) + return (KMF_ERR_BAD_PARAMETER); + tmppath = strdup(path); + if (tmppath == NULL) + return (KMF_ERR_MEMORY); + /* If we only have a name and possibly a dir, we can find the path. */ + } else if (name != NULL) { + tmppath = get_mapper_pathname(name, dir); + /* + * If we were given name but the returned path is still NULL, + * return an error. + */ + if (tmppath == NULL) + return (KMF_ERR_MEMORY); + /* Can not exist standalone. */ + } else if (dir != NULL || opts != NULL) { + return (KMF_ERR_BAD_PARAMETER); + /* No attributes define the mapper so let's use the policy database. */ + } else if (map->pathname != NULL) { + tmppath = strdup(map->pathname); + if (tmppath == NULL) + return (KMF_ERR_MEMORY); + opts = map->options; + } else if (map->mapname != NULL) { + tmppath = get_mapper_pathname(map->mapname, map->dir); + /* + * If we were given name but the returned path is still NULL, + * return an error. + */ + if (tmppath == NULL) + return (KMF_ERR_MEMORY); + opts = map->options; + } else { + /* + * Either a name or a full pathname must be provided whether + * from attributes or the policy database. + */ + return (KMF_ERR_BAD_PARAMETER); + } + + /* + * Dlopen the mapper specified by the policy. If anything goes wrong + * just return an error. We do not have to worry about resetting + * curpathname and curoptions to the previous values since there was no + * mapper initialized beforehand. + * + * No mapper was open so stored curoptions and curpathname are + * already NULL and need not to be freed. + */ + if (map->dldesc == NULL) { + map->curpathname = tmppath; + if (opts != NULL) { + map->curoptions = strdup(opts); + if (map->curoptions == NULL) { + free(map->curpathname); + map->curpathname = NULL; + return (KMF_ERR_MEMORY); + } + } else + map->curoptions = NULL; + + if ((ret = open_mapper_library(map)) != KMF_OK) { + free(map->curpathname); + map->curpathname = NULL; + if (map->curoptions != NULL) { + free(map->curoptions); + map->curoptions = NULL; + } + return (ret); + } + + goto end; + } + + /* + * We already have an open mapper, let's see if this is a new mapper + * library. + */ + if (map->curpathname != NULL && + /* No change in mapper pathname. */ + strcmp(map->curpathname, tmppath) == 0) { + /* New options are empty while we had some before. */ + if (map->curoptions != NULL && opts == NULL) { + map->curoptions = NULL; + /* We have some options now while we had none before. */ + } else if (map->curoptions == NULL && opts != NULL) { + if ((map->curoptions = strdup(opts)) == NULL) + goto err_mem; + /* We got different options. */ + } else if (strcmp(map->curoptions, opts) != 0) { + if ((map->curoptions = strdup(opts)) == NULL) + goto err_mem; + } else { + /* + * Same options, no free() of current options is + * required. + */ + old_curoptions = NULL; + } + + /* Free old options if applicable. */ + if (old_curoptions != NULL) + free(old_curoptions); + } else { + /* + * This is a new mapper path, clean up the old data and open the + * new mapper. + */ + cleanup_mapper(handle); + /* These two are no longer valid. */ + old_curoptions = NULL; + old_curpathname = NULL; + map->curpathname = tmppath; + if (opts != NULL) { + map->curoptions = strdup(opts); + if (map->curoptions == NULL) + goto err_mem; + } + if ((ret = open_mapper_library(map)) != KMF_OK) { + /* + * This will cleanup curoptions and curpathname, and + * ignores the dldesc since it is NULL. Do not free + * tmppath, it will be freed through map->curpathname. + */ + cleanup_mapper(handle); + return (ret); + } + } + +end: + initialize = (KMF_RETURN(*)())dlsym(map->dldesc, + MAPPER_INIT_FUNCTION); + /* Optional, not an error if it does not exist. */ + ret = KMF_OK; + if (initialize != NULL) + ret = initialize(handle, map->curoptions); + + if (ret != KMF_OK) + cleanup_mapper(handle); + + return (ret); + +err_mem: + /* + * Try to put the old curpathname and curoptions back there. In theory, + * the application might be able to continue to use the old mapping + * unless we already called cleanup_mapper(). However, it's neither + * recommended nor officially supported. The app should initialize the + * old mapping again. + */ + if (tmppath != NULL) + free(tmppath); + map->curoptions = old_curoptions; + map->curpathname = old_curpathname; + return (KMF_ERR_MEMORY); +} + +KMF_RETURN +kmf_cert_to_name_mapping_finalize(KMF_HANDLE_T handle) +{ + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); + + cleanup_mapper(handle); + + return (KMF_OK); +} + +KMF_RETURN +kmf_map_cert_to_name(KMF_HANDLE_T handle, KMF_DATA *cert, KMF_DATA *name) +{ + KMF_MAPPER_RECORD *map = NULL; + KMF_RETURN (*cert2name)(KMF_HANDLE *, KMF_DATA *, KMF_DATA *); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); + + map = &handle->policy->mapper; + if (map->dldesc == NULL) + return (KMF_ERR_MAPPER_NOT_FOUND); + + cert2name = (KMF_RETURN(*)())dlsym(map->dldesc, + MAP_CERT_TO_NAME_FUNCTION); + if (cert2name == NULL) + return (KMF_ERR_FUNCTION_NOT_FOUND); + + return (cert2name(handle, cert, name)); +} + +/* + * If mapped_name is non-NULL the caller is later expected to free its Data + * after use. + */ +KMF_RETURN +kmf_match_cert_to_name(KMF_HANDLE_T handle, KMF_DATA *cert, + KMF_DATA *name_to_match, KMF_DATA *mapped_name) +{ + KMF_MAPPER_RECORD *map = NULL; + KMF_RETURN (*cert2name)(KMF_HANDLE *, KMF_DATA *, KMF_DATA *, + KMF_DATA *); + + if (handle == NULL) + return (KMF_ERR_BAD_PARAMETER); + + map = &handle->policy->mapper; + + if (map->curpathname == NULL || map->dldesc == NULL) + return (KMF_ERR_MAPPER_NOT_FOUND); + + cert2name = (KMF_RETURN(*)())dlsym(map->dldesc, + MATCH_CERT_TO_NAME_FUNCTION); + if (cert2name == NULL) + return (KMF_ERR_FUNCTION_NOT_FOUND); + + return (cert2name(handle, cert, name_to_match, mapped_name)); +} + +/* + * The caller is responsible for freeing the error string (ie., *errstr) when + * done with it. + */ +KMF_RETURN +kmf_get_mapper_error_str(KMF_HANDLE_T handle, char **errstr) +{ + KMF_HANDLE *h = NULL; + KMF_MAPPER_RECORD *map = NULL; + KMF_RETURN (*err2string)(KMF_HANDLE *, char **); + + if (handle == NULL || errstr == NULL) + return (KMF_ERR_BAD_PARAMETER); + + h = (KMF_HANDLE *)handle; + map = &(h->policy->mapper); + + if (map->curpathname == NULL || map->dldesc == NULL) + return (KMF_ERR_MAPPER_NOT_FOUND); + + err2string = (KMF_RETURN(*)())dlsym(map->dldesc, + MAPPER_ERROR_STRING_FUNCTION); + if (err2string == NULL) + return (KMF_ERR_FUNCTION_NOT_FOUND); + + return (err2string(h, errstr)); +} + +void +kmf_set_mapper_lasterror(KMF_HANDLE_T handle, uint32_t err) +{ + handle->mapstate->lastmappererr = err; +} + +uint32_t +kmf_get_mapper_lasterror(KMF_HANDLE_T handle) +{ + return (handle->mapstate->lastmappererr); +} + +void +kmf_set_mapper_options(KMF_HANDLE_T handle, void *opts) +{ + handle->mapstate->options = opts; +} + +void * +kmf_get_mapper_options(KMF_HANDLE_T handle) +{ + return (handle->mapstate->options); +}
--- a/usr/src/lib/libkmf/libkmf/common/policy.c Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/lib/libkmf/libkmf/common/policy.c Fri Jun 11 01:25:07 2010 -0700 @@ -17,11 +17,8 @@ * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END - */ - -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <stdlib.h> @@ -29,6 +26,7 @@ #include <strings.h> #include <unistd.h> #include <errno.h> +#include <libgen.h> #include <sys/param.h> #include <sys/stat.h> @@ -387,6 +385,31 @@ return (ret); } +static KMF_RETURN +parseMapper(xmlNodePtr node, KMF_MAPPER_RECORD *mapper) +{ + xmlNodePtr n; + + n = node; + mapper->mapname = (char *)xmlGetProp(n, + (const xmlChar *)KMF_CERT_MAPPER_NAME_ATTR); + mapper->dir = (char *)xmlGetProp(n, + (const xmlChar *)KMF_CERT_MAPPER_DIR_ATTR); + mapper->pathname = (char *)xmlGetProp(n, + (const xmlChar *)KMF_CERT_MAPPER_PATH_ATTR); + mapper->options = (char *)xmlGetProp(n, + (const xmlChar *)KMF_CERT_MAPPER_OPTIONS_ATTR); + + /* + * These are set according to whether mapper setting is taken from the + * database or init function attributes. + */ + mapper->curpathname = NULL; + mapper->curoptions = NULL; + + return (KMF_OK); +} + int parsePolicyElement(xmlNodePtr node, KMF_POLICY_RECORD *policy) { @@ -449,6 +472,11 @@ ret = parseExtKeyUsage(n, &policy->eku_set); if (ret != KMF_OK) return (ret); + } else if (!xmlStrcmp((const xmlChar *)n->name, + (const xmlChar *)KMF_CERT_MAPPER_ELEMENT)) { + ret = parseMapper(n, &policy->mapper); + if (ret != KMF_OK) + return (ret); } n = n->next; @@ -637,6 +665,57 @@ } /* + * Add mapper policy info to the policy tree. + * Return non-zero on any failure, else 0 for success. + */ +static KMF_RETURN +AddMapperPolicyNodes(xmlNodePtr parent, KMF_MAPPER_RECORD *mapper) +{ + KMF_RETURN ret = KMF_OK; + xmlNodePtr mapper_node; + + addFormatting(parent, "\n\t"); + mapper_node = xmlNewChild(parent, NULL, + (const xmlChar *)KMF_CERT_MAPPER_ELEMENT, NULL); + if (mapper_node == NULL) + return (KMF_ERR_POLICY_ENGINE); + + if (mapper->mapname != NULL && + newprop(mapper_node, KMF_CERT_MAPPER_NAME_ATTR, mapper->mapname)) { + ret = KMF_ERR_POLICY_ENGINE; + goto end; + } + + if (mapper->pathname != NULL && + newprop(mapper_node, KMF_CERT_MAPPER_PATH_ATTR, mapper->pathname)) { + ret = KMF_ERR_POLICY_ENGINE; + goto end; + } + + if (mapper->dir != NULL && + newprop(mapper_node, KMF_CERT_MAPPER_DIR_ATTR, mapper->dir)) { + ret = KMF_ERR_POLICY_ENGINE; + goto end; + } + + if (mapper->options != NULL && + newprop(mapper_node, KMF_CERT_MAPPER_OPTIONS_ATTR, mapper->options)) + ret = KMF_ERR_POLICY_ENGINE; + + if (ret == KMF_OK) { + addFormatting(mapper_node, "\n\t"); + addFormatting(parent, "\n"); + } + +end: + if (ret != KMF_OK) { + xmlUnlinkNode(mapper_node); + xmlFreeNode(mapper_node); + } + return (ret); +} + +/* * Add Key Usage information to the policy tree. * Return non-zero on any failure, else 0 for success. */ @@ -760,6 +839,10 @@ FREE_POLICY_STR(policy->validity_adjusttime) FREE_POLICY_STR(policy->ta_name) FREE_POLICY_STR(policy->ta_serial) + FREE_POLICY_STR(policy->mapper.mapname) + FREE_POLICY_STR(policy->mapper.pathname) + FREE_POLICY_STR(policy->mapper.options) + FREE_POLICY_STR(policy->mapper.dir) kmf_free_eku_policy(&policy->eku_set); @@ -1181,6 +1264,9 @@ if ((ret = AddExtKeyUsageNodes(pnode, &policy->eku_set))) { goto out; } + if ((ret = AddMapperPolicyNodes(pnode, &policy->mapper))) { + goto out; + } } else { ret = KMF_ERR_BAD_PARAMETER; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libkmf/mappers/Makefile Fri Jun 11 01:25:07 2010 -0700 @@ -0,0 +1,45 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# +# Makefile for KMF mappers. +# +include ../../Makefile.lib + +SUBDIRS = kmf_mapper_cn + +HDRS = +HDRDIR = include + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +lint := TARGET= lint + +all clean clobber install lint: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include $(SRC)/lib/Makefile.targ
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libkmf/mappers/kmf_mapper_cn/Makefile Fri Jun 11 01:25:07 2010 -0700 @@ -0,0 +1,45 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# +# The CN KMF mapper. Maps a certificate to its Common Name value. +# +include $(SRC)/lib/Makefile.lib + +SUBDIRS = $(MACH) + +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET= all +check := TARGET= check +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +lint := TARGET= lint + +.KEEP_STATE: + +all clean clobber install lint: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libkmf/mappers/kmf_mapper_cn/Makefile.com Fri Jun 11 01:25:07 2010 -0700 @@ -0,0 +1,62 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# +# KMF CN mapper. Maps a certificate to its Common Name value. +# + +LIBRARY = kmf_mapper_cn.a +VERS = .1 + +OBJECTS = mapper_cn.o + +include $(SRC)/lib/Makefile.lib + +LIBLINKS = $(DYNLIB:.so.1=.so) +KMFINC = -I../../../include + +SRCDIR = ../common +INCDIR = ../../include + +SRCS = $(OBJECTS:%.o=$(SRCDIR)/%.c) + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I../../../include -I$(INCDIR) +LINTFLAGS64 += -errchk=longptr64 + +PICS = $(OBJECTS:%=pics/%) + +LDLIBS += -lkmf -lc + +ROOTLIBDIR = $(ROOTFS_LIBDIR)/crypto +ROOTLIBDIR64 = $(ROOTFS_LIBDIR)/crypto/$(MACH64) + +.KEEP_STATE: + +LIBS = $(DYNLIB) + +all: $(LIBS) $(LINTLIB) + +lint: lintcheck + +FRC: + +include $(SRC)/lib/Makefile.targ
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libkmf/mappers/kmf_mapper_cn/amd64/Makefile Fri Jun 11 01:25:07 2010 -0700 @@ -0,0 +1,27 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +install: $(ROOTLIBS64)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libkmf/mappers/kmf_mapper_cn/common/mapfile-vers Fri Jun 11 01:25:07 2010 -0700 @@ -0,0 +1,48 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# + +# +# MAPFILE HEADER START +# +# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. +# Object versioning must comply with the rules detailed in +# +# usr/src/lib/README.mapfiles +# +# You should not be making modifications here until you've read the most current +# copy of that file. If you need help, contact a gatekeeper for guidance. +# +# MAPFILE HEADER END +# + +SUNWprivate { + global: + mapper_finalize; + mapper_get_error_str; + mapper_initialize; + mapper_map_cert_to_name; + mapper_match_cert_to_name; + local: + *; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libkmf/mappers/kmf_mapper_cn/common/mapper_cn.c Fri Jun 11 01:25:07 2010 -0700 @@ -0,0 +1,222 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + */ + +/* + * KMF CN certificate-to-name mapper. + */ + +#include <kmftypes.h> +#include <kmfapi.h> +#include <fcntl.h> + +/* + * KMF uses long identifiers for RDN processing which makes it hard to keep + * cstyle cleanliness without using some auxiliary macros. Parameter 'x' is of + * the KMF_X509_NAME type. + */ +#define RDN_VALUE(x, i) \ + (&x.RelativeDistinguishedName[i].AttributeTypeAndValue->value) + +#define RDN_OID(x, i) \ + (&x.RelativeDistinguishedName[i].AttributeTypeAndValue->type) + +#define RDN_NPAIRS(x, i) (x.RelativeDistinguishedName[i].numberOfPairs) + +/* Error codes specific to this mapper. */ +#define CN_MAPPER_CN_RDN_NOT_PRESENT 1 + +typedef struct cooked_opts { + int casesensitive; +} cooked_opts; + +KMF_RETURN +mapper_initialize(KMF_HANDLE_T h, char *options) +{ + cooked_opts *opts; + + if ((opts = malloc(sizeof (cooked_opts))) == NULL) + return (KMF_ERR_MEMORY); + + /* This is the default. */ + opts->casesensitive = B_FALSE; + + if (options != NULL) { + if (strcmp(options, "casesensitive") == 0) + opts->casesensitive = B_TRUE; + } + + kmf_set_mapper_options(h, opts); + + return (KMF_OK); +} + +void +mapper_finalize(KMF_HANDLE_T h) +{ + void *opts; + + if ((opts = kmf_get_mapper_options(h)) != NULL) + free(opts); + kmf_set_mapper_options(h, NULL); +} + +/* + * The CN string returned in name.Data will be NULL-terminated. The caller is + * expected to free name->Data after use. + */ +KMF_RETURN +mapper_map_cert_to_name(KMF_HANDLE_T h, KMF_DATA *cert, KMF_DATA *name) +{ + int i, j; + char *dn; + KMF_RETURN rv; + uchar_t *cn = NULL; + KMF_X509_NAME x509name; + + kmf_set_mapper_lasterror(h, KMF_OK); + + if ((rv = kmf_get_cert_subject_str(h, cert, &dn)) != KMF_OK) + return (rv); + + if ((rv = kmf_dn_parser(dn, &x509name)) != KMF_OK) + return (rv); + + /* Go through the list of RDNs and look for the CN. */ + for (i = 0; i < x509name.numberOfRDNs; ++i) { + for (j = 0; j < RDN_NPAIRS(x509name, i); ++j) { + KMF_OID *oid = RDN_OID(x509name, i); + KMF_DATA *data = RDN_VALUE(x509name, i); + + if (oid == NULL) + continue; + + /* Is this RDN a Common Name? */ + if (oid->Length == KMFOID_CommonName.Length && + memcmp(oid->Data, KMFOID_CommonName.Data, + oid->Length) == 0) { + if ((cn = malloc(data->Length + 1)) == NULL) { + kmf_free_dn(&x509name); + return (KMF_ERR_MEMORY); + } + (void) memcpy(cn, data->Data, data->Length); + /* Terminate the string. */ + cn[data->Length] = '\0'; + name->Length = data->Length + 1; + name->Data = cn; + goto finished; + } + } + } + +finished: + kmf_free_dn(&x509name); + if (cn != NULL) + return (KMF_OK); + else { + kmf_set_mapper_lasterror(h, CN_MAPPER_CN_RDN_NOT_PRESENT); + return (KMF_ERR_INTERNAL); + } +} + +/* + * Note that name_to_match->Data might or might not be NULL terminated. If + * mapped_name->Length returned is greater than zero the caller is expected to + * free mapped_name->Data after use. + */ +KMF_RETURN +mapper_match_cert_to_name(KMF_HANDLE_T h, KMF_DATA *cert, + KMF_DATA *name_to_match, KMF_DATA *mapped_name) +{ + int ret; + KMF_RETURN rv; + KMF_DATA get_name; + cooked_opts *opts = NULL; + + opts = (cooked_opts *)kmf_get_mapper_options(h); + + /* Initialize the output parameter. */ + if (mapped_name != NULL) { + mapped_name->Length = 0; + mapped_name->Data = NULL; + } + + if ((rv = mapper_map_cert_to_name(h, cert, &get_name)) != KMF_OK) + return (rv); + + /* + * If name_to_match->Data is not NULL terminated, check that we have the + * same number of characters. + */ + if (name_to_match->Data[name_to_match->Length - 1] != '\0') + /* We know that get_name.Data is NULL terminated. */ + if (name_to_match->Length != get_name.Length - 1) + return (KMF_ERR_NAME_NOT_MATCHED); + + /* + * Compare the strings. We must use name_to_match->Length in case + * name_to_match->Data was not NULL terminated. If we used + * get_name.Length we could overrun name_to_match->Data by one byte. + */ + if (opts->casesensitive == B_TRUE) + ret = strncmp((char *)name_to_match->Data, + (char *)get_name.Data, name_to_match->Length); + else + ret = strncasecmp((char *)name_to_match->Data, + (char *)get_name.Data, name_to_match->Length); + + if (mapped_name != NULL) { + mapped_name->Length = get_name.Length; + mapped_name->Data = get_name.Data; + } else + kmf_free_data(&get_name); + + if (ret == 0) + return (KMF_OK); + else + return (KMF_ERR_NAME_NOT_MATCHED); +} + +/* The caller is responsible for freeing the error string when done with it. */ +KMF_RETURN +mapper_get_error_str(KMF_HANDLE_T h, char **errstr) +{ + uint32_t lasterr; + + lasterr = kmf_get_mapper_lasterror(h); + *errstr = NULL; + if (lasterr == 0) + return (KMF_ERR_MISSING_ERRCODE); + + switch (lasterr) { + case CN_MAPPER_CN_RDN_NOT_PRESENT: + *errstr = (char *)strdup("CN_MAPPER_CN_RDN_NOT_PRESENT"); + break; + default: + *errstr = (char *)strdup("KMF_ERR_MISSING_MAPPER_ERRCODE"); + } + + if (*errstr == NULL) + return (KMF_ERR_MEMORY); + + return (KMF_OK); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libkmf/mappers/kmf_mapper_cn/i386/Makefile Fri Jun 11 01:25:07 2010 -0700 @@ -0,0 +1,26 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# + +include ../Makefile.com + +install: $(ROOTLIBS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libkmf/mappers/kmf_mapper_cn/sparc/Makefile Fri Jun 11 01:25:07 2010 -0700 @@ -0,0 +1,26 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# + +include ../Makefile.com + +install: $(ROOTLIBS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libkmf/mappers/kmf_mapper_cn/sparcv9/Makefile Fri Jun 11 01:25:07 2010 -0700 @@ -0,0 +1,27 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# + +include ../Makefile.com +include ../../../../Makefile.lib.64 + +install: $(ROOTLIBS64)
--- a/usr/src/pkg/manifests/system-library.mf Fri Jun 11 11:54:13 2010 +0800 +++ b/usr/src/pkg/manifests/system-library.mf Fri Jun 11 01:25:07 2010 -0700 @@ -156,6 +156,8 @@ file path=lib/crypto/kmf_nss.so.1 file path=lib/crypto/kmf_openssl.so.1 file path=lib/crypto/kmf_pkcs11.so.1 +file path=lib/crypto/$(ARCH64)/kmf_mapper_cn.so.1 +file path=lib/crypto/kmf_mapper_cn.so.1 file path=lib/ld.so.1 file path=lib/libadm.so.1 file path=lib/libaio.so.1