269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * CDDL HEADER START
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * The contents of this file are subject to the terms of the
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * Common Development and Distribution License (the "License").
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * You may not use this file except in compliance with the License.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * or http://www.opensolaris.org/os/licensing.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * See the License for the specific language governing permissions
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * and limitations under the License.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * When distributing Covered Code, include this CDDL HEADER in each
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * If applicable, add the following below this CDDL HEADER, with the
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * fields enclosed by brackets "[]" replaced with your own identifying
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * information: Portions Copyright [yyyy] [name of copyright owner]
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * CDDL HEADER END
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * KMF CN certificate-to-name mapper.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#include <kmftypes.h>
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#include <kmfapi.h>
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#include <fcntl.h>
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * KMF uses long identifiers for RDN processing which makes it hard to keep
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * cstyle cleanliness without using some auxiliary macros. Parameter 'x' is of
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * the KMF_X509_NAME type.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#define RDN_VALUE(x, i) \
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec (&x.RelativeDistinguishedName[i].AttributeTypeAndValue->value)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#define RDN_OID(x, i) \
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec (&x.RelativeDistinguishedName[i].AttributeTypeAndValue->type)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#define RDN_NPAIRS(x, i) (x.RelativeDistinguishedName[i].numberOfPairs)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/* Error codes specific to this mapper. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec#define CN_MAPPER_CN_RDN_NOT_PRESENT 1
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanectypedef struct cooked_opts {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec int casesensitive;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec} cooked_opts;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan PechanecKMF_RETURN
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecmapper_initialize(KMF_HANDLE_T h, char *options)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec cooked_opts *opts;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if ((opts = malloc(sizeof (cooked_opts))) == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MEMORY);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* This is the default. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec opts->casesensitive = B_FALSE;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (options != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (strcmp(options, "casesensitive") == 0)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec opts->casesensitive = B_TRUE;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec kmf_set_mapper_options(h, opts);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_OK);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecvoid
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecmapper_finalize(KMF_HANDLE_T h)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec void *opts;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if ((opts = kmf_get_mapper_options(h)) != NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec free(opts);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec kmf_set_mapper_options(h, NULL);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * The CN string returned in name.Data will be NULL-terminated. The caller is
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * expected to free name->Data after use.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan PechanecKMF_RETURN
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecmapper_map_cert_to_name(KMF_HANDLE_T h, KMF_DATA *cert, KMF_DATA *name)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec int i, j;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec char *dn;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_RETURN rv;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec uchar_t *cn = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_X509_NAME x509name;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec kmf_set_mapper_lasterror(h, KMF_OK);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if ((rv = kmf_get_cert_subject_str(h, cert, &dn)) != KMF_OK)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (rv);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if ((rv = kmf_dn_parser(dn, &x509name)) != KMF_OK)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (rv);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* Go through the list of RDNs and look for the CN. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec for (i = 0; i < x509name.numberOfRDNs; ++i) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec for (j = 0; j < RDN_NPAIRS(x509name, i); ++j) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_OID *oid = RDN_OID(x509name, i);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_DATA *data = RDN_VALUE(x509name, i);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (oid == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec continue;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* Is this RDN a Common Name? */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (oid->Length == KMFOID_CommonName.Length &&
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec memcmp(oid->Data, KMFOID_CommonName.Data,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec oid->Length) == 0) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if ((cn = malloc(data->Length + 1)) == NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec kmf_free_dn(&x509name);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MEMORY);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec (void) memcpy(cn, data->Data, data->Length);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* Terminate the string. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec cn[data->Length] = '\0';
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec name->Length = data->Length + 1;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec name->Data = cn;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec goto finished;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecfinished:
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec kmf_free_dn(&x509name);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (cn != NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_OK);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec else {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec kmf_set_mapper_lasterror(h, CN_MAPPER_CN_RDN_NOT_PRESENT);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_INTERNAL);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * Note that name_to_match->Data might or might not be NULL terminated. If
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * mapped_name->Length returned is greater than zero the caller is expected to
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * free mapped_name->Data after use.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan PechanecKMF_RETURN
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecmapper_match_cert_to_name(KMF_HANDLE_T h, KMF_DATA *cert,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_DATA *name_to_match, KMF_DATA *mapped_name)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec int ret;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_RETURN rv;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec KMF_DATA get_name;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec cooked_opts *opts = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec opts = (cooked_opts *)kmf_get_mapper_options(h);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* Initialize the output parameter. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (mapped_name != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec mapped_name->Length = 0;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec mapped_name->Data = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if ((rv = mapper_map_cert_to_name(h, cert, &get_name)) != KMF_OK)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (rv);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * If name_to_match->Data is not NULL terminated, check that we have the
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * same number of characters.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (name_to_match->Data[name_to_match->Length - 1] != '\0')
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /* We know that get_name.Data is NULL terminated. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (name_to_match->Length != get_name.Length - 1)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_NAME_NOT_MATCHED);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec /*
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * Compare the strings. We must use name_to_match->Length in case
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * name_to_match->Data was not NULL terminated. If we used
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec * get_name.Length we could overrun name_to_match->Data by one byte.
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (opts->casesensitive == B_TRUE)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec ret = strncmp((char *)name_to_match->Data,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec (char *)get_name.Data, name_to_match->Length);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec else
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec ret = strncasecmp((char *)name_to_match->Data,
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec (char *)get_name.Data, name_to_match->Length);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (mapped_name != NULL) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec mapped_name->Length = get_name.Length;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec mapped_name->Data = get_name.Data;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec } else
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec kmf_free_data(&get_name);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (ret == 0)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_OK);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec else
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_NAME_NOT_MATCHED);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec/* The caller is responsible for freeing the error string when done with it. */
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan PechanecKMF_RETURN
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanecmapper_get_error_str(KMF_HANDLE_T h, char **errstr)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec{
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec uint32_t lasterr;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec lasterr = kmf_get_mapper_lasterror(h);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *errstr = NULL;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (lasterr == 0)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MISSING_ERRCODE);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec switch (lasterr) {
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec case CN_MAPPER_CN_RDN_NOT_PRESENT:
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *errstr = (char *)strdup("CN_MAPPER_CN_RDN_NOT_PRESENT");
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec break;
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec default:
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec *errstr = (char *)strdup("KMF_ERR_MISSING_MAPPER_ERRCODE");
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec }
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec if (*errstr == NULL)
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_ERR_MEMORY);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec return (KMF_OK);
269e59f9a28bf47e0f463e64fc5af4a408b73b21Jan Pechanec}