5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ====================================================================
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Redistribution and use in source and binary forms, with or without
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * modification, are permitted provided that the following conditions
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * are met:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 1. Redistributions of source code must retain the above copyright
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * notice, this list of conditions and the following disclaimer.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 2. Redistributions in binary form must reproduce the above copyright
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * notice, this list of conditions and the following disclaimer in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the documentation and/or other materials provided with the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * distribution.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 3. All advertising materials mentioning features or use of this
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * software must display the following acknowledgment:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * "This product includes software developed by the OpenSSL Project
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * endorse or promote products derived from this software without
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * prior written permission. For written permission, please contact
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * licensing@OpenSSL.org.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 5. Products derived from this software may not be called "OpenSSL"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * nor may "OpenSSL" appear in their names without prior written
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * permission of the OpenSSL Project.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 6. Redistributions of any form whatsoever must retain the following
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * acknowledgment:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * "This product includes software developed by the OpenSSL Project
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * OF THE POSSIBILITY OF SUCH DAMAGE.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ====================================================================
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This product includes cryptographic software written by Eric Young
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * (eay@cryptsoft.com). This product includes software written by Tim
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Hudson (tjh@cryptsoft.com).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Use is subject to license terms.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle/*
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle */
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <strings.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdlib.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <assert.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <openssl/crypto.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <openssl/err.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <openssl/x509.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <openssl/pem.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <openssl/pkcs12.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include "p12lib.h"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * OpenSSL provides a framework for pushing error codes onto a stack.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * When an error occurs, the consumer may use the framework to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pop the errors off the stack and provide a trace of where the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * errors occurred.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Our PKCS12 code plugs into this framework by calling
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ERR_load_SUNW_strings(). To push an error (which by the way, consists
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of a function code and an error code) onto the stack our PKCS12 code
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * calls SUNWerr().
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Consumers of our PKCS12 code can then call the OpenSSL error routines
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * when an error occurs and retrieve the stack of errors.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#ifndef OPENSSL_NO_ERR
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* Function codes and their matching strings */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic ERR_STRING_DATA SUNW_str_functs[] = {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_USE_X509CERT, 0), "sunw_use_x509cert" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_USE_PKEY, 0), "sunw_use_pkey" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_USE_TASTORE, 0), "sunw_use_tastore" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_USE_CERTFILE, 0), "sunw_p12_use_certfile" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_USE_KEYFILE, 0), "sunw_p12_use_keyfile" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_USE_TRUSTFILE, 0), "sunw_p12_use_trustfile" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_READ_FILE, 0), "p12_read_file" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_DOPARSE, 0), "p12_doparse" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_PKCS12_PARSE, 0), "sunw_PKCS12_parse" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_PKCS12_CONTENTS, 0), "sunw_PKCS12_contents" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_PARSE_ONE_BAG, 0), "parse_one_bag" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_PKCS12_CREATE, 0), "sunw_PKCS12_create" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_SPLIT_CERTS, 0), "sunw_split_certs" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_FIND_LOCALKEYID, 0), "sunw_find_localkeyid" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_SET_LOCALKEYID, 0), "sunw_set_localkeyid" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_GET_LOCALKEYID, 0), "sunw_get_localkeyid" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_SET_FNAME, 0), "sunw_set_fname" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_GET_PKEY_FNAME, 0), "sunw_get_pkey_fname" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_APPEND_KEYS, 0), "sunw_append_keys" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_PEM_CONTENTS, 0), "sunw_PEM_contents" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_PEM_INFO, 0), "pem_info" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_ASC2BMPSTRING, 0), "asc2bmpstring" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_UTF82ASCSTR, 0), "utf82ascstr" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_FINDATTR, 0), "findattr" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_TYPE2ATTRIB, 0), "type2attrib" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_MOVE_CERTS, 0), "move_certs" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_FIND_FNAME, 0), "sunw_find_fname" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_PARSE_OUTER, 0), "parse_outer" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { ERR_PACK(0, SUNW_F_CHECKFILE, 0), "checkfile" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { 0, NULL }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland};
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* Error codes and their matching strings */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic ERR_STRING_DATA SUNW_str_reasons[] = {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_INVALID_ARG, "invalid argument" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_MEMORY_FAILURE, "memory failure" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_MAC_VERIFY_FAILURE, "mac verify failure" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_MAC_CREATE_FAILURE, "mac create failure" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_BAD_FILETYPE, "bad file type" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_BAD_PKEY, "bad or missing private key" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_BAD_PKEYTYPE, "unsupported key type" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_PKEY_READ_ERR, "unable to read private key" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_NO_TRUST_ANCHOR, "no trust anchors found" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_READ_TRUST_ERR, "unable to read trust anchor" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_ADD_TRUST_ERR, "unable to add trust anchor" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_PKCS12_PARSE_ERR, "PKCS12 parse error" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_PKCS12_CREATE_ERR, "PKCS12 create error" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_BAD_CERTTYPE, "unsupported certificate type" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_PARSE_CERT_ERR, "error parsing PKCS12 certificate" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_PARSE_BAG_ERR, "error parsing PKCS12 bag" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_MAKE_BAG_ERR, "error making PKCS12 bag" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_BAD_LKID, "bad localKeyID format" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_SET_LKID_ERR, "error setting localKeyID" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_BAD_FNAME, "bad friendlyName format" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_SET_FNAME_ERR, "error setting friendlyName" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_BAD_TRUST, "bad or missing trust anchor" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_BAD_BAGTYPE, "unsupported bag type" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_CERT_ERR, "certificate error" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_PKEY_ERR, "private key error" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_READ_ERR, "error reading file" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_ADD_ATTR_ERR, "error adding attribute" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_STR_CONVERT_ERR, "error converting string" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_PKCS12_EMPTY_ERR, "empty PKCS12 structure" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { SUNW_R_PASSWORD_ERR, "bad password" },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { 0, NULL }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland};
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The library name that our module will be known as. This name
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * may be retrieved via OpenSSLs error APIs.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic ERR_STRING_DATA SUNW_lib_name[] = {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { 0, SUNW_LIB_NAME },
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland { 0, NULL }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland};
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#endif
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The value of this variable (initialized by a call to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ERR_load_SUNW_strings()) is what identifies our errors
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to OpenSSL as being ours.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int SUNW_lib_error_code = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* local routines */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int parse_pkcs12(PKCS12 *, const char *, int, char *, int, char *,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland EVP_PKEY **, X509 **, STACK_OF(X509) **);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int pem_info(FILE *, pem_password_cb, void *,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) **, STACK_OF(X509) **);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int parse_outer(PKCS12 *, const char *, STACK_OF(EVP_PKEY) *,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int parse_all_bags(STACK_OF(PKCS12_SAFEBAG) *, const char *,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) *, STACK_OF(X509) *);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int parse_one_bag(PKCS12_SAFEBAG *, const char *,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) *, STACK_OF(X509) *);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic X509_ATTRIBUTE *type2attrib(ASN1_TYPE *, int);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic ASN1_TYPE *attrib2type(X509_ATTRIBUTE *);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic uchar_t *utf82ascstr(ASN1_UTF8STRING *);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic ASN1_BMPSTRING *asc2bmpstring(const char *, int);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int find_attr_by_nid(STACK_OF(X509_ATTRIBUTE) *, int);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int find_attr(int, ASN1_STRING *, STACK_OF(EVP_PKEY) *,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland EVP_PKEY **, STACK_OF(X509) *, X509 **);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic chk_errs_t check_time(chk_actions_t, X509 *);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int get_key_cert(int, STACK_OF(EVP_PKEY) *, EVP_PKEY **,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *, X509 **cert);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int move_certs(STACK_OF(X509) *, STACK_OF(X509) *);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int sunw_append_keys(STACK_OF(EVP_PKEY) *,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) *);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int set_results(STACK_OF(EVP_PKEY) **,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) **, STACK_OF(X509) **, STACK_OF(X509) **,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) **, STACK_OF(X509) **,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) **, STACK_OF(EVP_PKEY) **);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ----------------------------------------------------------------------------
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Public routines
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ----------------------------------------------------------------------------
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_PKCS12_parse - Parse a PKCS12 structure and break it into its parts.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Parse and decrypt a PKCS#12 structure returning user key, user cert and/or
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * other (CA) certs. Note either ca should be NULL, *ca should be NULL,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * or it should point to a valid STACK_OF(X509) structure. pkey and cert can
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * be passed uninitialized.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * p12 - Structure with pkcs12 info to be parsed
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pass - Pass phrase for the private key (possibly empty) or NULL if
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * there is none.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * matchty - Info about which certs/keys to return if many are in the file.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keyid - If private key localkeyids friendlynames are to match a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * predetermined value, the value to match. This value should
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * be an octet string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keyid_len- Length of the keyid byte string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * name_str - If friendlynames are to match a predetermined value, the value
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to match. This value should be a NULL terminated string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkey - Points to location pointing to the private key returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert - Points to locaiton which points to the client cert returned
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ca - Points to location that points to a stack of 'certificate
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * authority' certs/trust anchors.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Match based on the value of 'matchty' and the contents of 'keyid'
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and/or 'name_str', as appropriate. Go through the lists of certs and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * private keys which were taken from the pkcs12 structure, looking for
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * matches of the requested type. This function only searches the lists of
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * matching private keys and client certificates. Kinds of matches allowed,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and the order in which they will be checked, are:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 1) Find the key and/or cert whose localkeyid attributes matches
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 'keyid'.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 2) Find the key and/or cert whose friendlyname attributes matches
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 'name_str'
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 3) Return the first matching key/cert pair found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 4) Return the last matching key/cert pair found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 5) Return whatever cert and/or key are available, even unmatching.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Append to the CA list, the certs which do not have matching private
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keys and which were not selected.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If none of the bits are set, no client certs or private keys will be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * returned. CA (aka trust anchor) certs can be.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Notes: If #3 is selected, then #4 will never occur. CA certs will be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * selected after a cert/key pairs are isolated.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * < 0 - An error returned. Call ERR_get_error() to get errors information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Where possible, memory has been freed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * >= 0 - Objects were found and returned. Which objects are indicated by
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * which bits are set (FOUND_PKEY, FOUND_CERT, FOUND_CA_CERTS).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_PKCS12_parse(PKCS12 *p12, const char *pass, int matchty, char *keyid,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int keyid_len, char *name_str, EVP_PKEY **pkey, X509 **cert,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) **ca)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland boolean_t ca_supplied;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* If NULL PKCS12 structure, this is an error */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (p12 == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_INVALID_ARG);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Set up arguments.... These will be allocated if needed */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pkey = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *cert = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If there is already a ca list, use it. Otherwise, allocate one
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and free is later if an error occurs or whatever.)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ca_supplied = (ca != NULL && *ca != NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ca != NULL && *ca == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((*ca = sk_X509_new_null()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If password is zero length or NULL then try verifying both cases
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to determine which password is correct. The reason for this is that
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * under PKCS#12 password based encryption no password and a zero
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * length password are two different things. If the password has a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * non-zero length and is not NULL then call PKCS12_verify_mac() with
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a length of '-1' and let it use strlen() to figure out the length
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of the password.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Check the mac */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pass == NULL || *pass == '\0') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (PKCS12_verify_mac(p12, NULL, 0))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pass = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else if (PKCS12_verify_mac(p12, "", 0))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pass = "";
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_PARSE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MAC_VERIFY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (PKCS12_verify_mac(p12, pass, -1) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_MAC_VERIFY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = parse_pkcs12(p12, pass, matchty, keyid, keyid_len,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland name_str, pkey, cert, ca);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_PKCS12_PARSE_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlanderr:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey && *pkey) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sunw_evp_pkey_free(*pkey);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert && *cert)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_free(*cert);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ca_supplied == B_FALSE && ca != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_X509_pop_free(*ca, X509_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_PEM_contents() parses a PEM file and returns component parts found
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Parse and decrypt a PEM file, returning any user keys and certs.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * There are some limits to this function. It will ignore the following:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - certificates identified by "TRUSTED CERTIFICATE"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - CERTIFICATE REQUEST and NEW CERTIFICATE REQUEST records.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - X509 CRL
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - DH PARAMETERS
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - DSA PARAMETERS
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - Any PUBLIC KEY
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - PKCS7
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - PRIVATE KEY or ENCRYPTED PRIVATE KEY (PKCS 8)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * fp - File pointer for file containing PEM data.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pass - Pass phrase for the private key or NULL if there is none.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkeys - Points to address of a stack of private keys to return.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * certs - Points to address of a stack of client certs to return.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The pointers to stacks should either be NULL or their contents should
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * either be NULL or should point to a valid STACK_OF(X509) structure.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If the stacks contain information, corresponding information from the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file will be appended to the original contents.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Note: Client certs and and their matching private keys will be in any
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * order.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Certs which have no matching private key are assumed to be ca certs.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * < 0 - An error returned. Call ERR_get_error() to get errors information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Where possible, memory has been freed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * >= 0 - Objects were found and returned. Which objects are indicated by
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * which bits are set (FOUND_PKEY, FOUND_CERT)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint sunw_PEM_contents(FILE *fp, pem_password_cb *cb, void *userdata,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) **pkey, STACK_OF(X509) **certs)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) *work_kl = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *work_ca = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Allocate the working stacks for private key and for the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ca certs.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((work_kl = sk_EVP_PKEY_new_null()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PEM_CONTENTS, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((work_ca = sk_X509_new_null()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PEM_CONTENTS, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Error strings are set within the following. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pem_info(fp, cb, userdata, &work_kl, &work_ca) <= 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* on error, set_results() returns an error on the stack */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = set_results(pkey, &work_kl, certs, &work_ca, NULL, NULL, NULL,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandcleanup:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (work_kl != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (work_ca != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_X509_pop_free(work_ca, X509_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_PKCS12_contents() parses a pkcs#12 structure and returns component
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * parts found, without evaluation.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Parse and decrypt a PKCS#12 structure returning any user keys and/or
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * various certs. Note these should either be NULL, *whatever should
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * be NULL, or it should point to a valid STACK_OF(X509) structure.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * p12 - Structure with pkcs12 info to be parsed
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pass - Pass phrase for the private key and entire pkcs12 wad (possibly
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * empty) or NULL if there is none.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkeys - Points to address of a stack of private keys to return.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * certs - Points to address of a stack of client certs return.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Note: The certs and keys being returned are in random order.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * < 0 - An error returned. Call ERR_get_error() to get errors information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Where possible, memory has been freed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * >= 0 - Objects were found and returned. Which objects are indicated by
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * which bits are set (FOUND_PKEY or FOUND_CERT)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_PKCS12_contents(PKCS12 *p12, const char *pass, STACK_OF(EVP_PKEY) **pkey,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) **certs)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) *work_kl = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *work_ca = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Allocate the working stacks for private key and for the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ca certs.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((work_kl = sk_EVP_PKEY_new_null()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CONTENTS, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((work_ca = sk_X509_new_null()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CONTENTS, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (parse_outer(p12, pass, work_kl, work_ca) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Error already on stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* on error, set_results() returns an error on the stack */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = set_results(pkey, &work_kl, certs, &work_ca, NULL,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland NULL, NULL, NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandcleanup:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (work_kl != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_split_certs() - Given a list of certs and a list of private keys,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * moves certs which match one of the keys to a different stack.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * allkeys - Points to a stack of private keys to search.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * allcerts - Points to a stack of certs to be searched.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keycerts - Points to address of a stack of certs with matching private
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keys. They are moved from 'allcerts'. This may not be NULL
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * when called. If *keycerts is NULL upon entry, a new stack will
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * be allocated. Otherwise, it must be a valid STACK_OF(509).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * nocerts - Points to address of a stack for keys which have no matching
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * certs. Keys are moved from 'allkeys' here when they have no
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * matching certs. If this is NULL, matchless keys will be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * discarded.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Notes: If an error occurs while moving certs, the cert being move may be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * lost. 'keycerts' may only contain part of the matching certs. The number
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of certs successfully moved can be found by checking sk_X509_num(keycerts).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If there is a key which does not have a matching cert, it is moved to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the list nocerts.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If all certs are removed from 'certs' and/or 'pkeys', it will be the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * caller's responsibility to free the empty stacks.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * < 0 - An error returned. Call ERR_get_error() to get errors information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Where possible, memory has been freed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * >= 0 - The number of certs moved from 'cert' to 'pkcerts'.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_split_certs(STACK_OF(EVP_PKEY) *allkeys, STACK_OF(X509) *allcerts,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) **keycerts, STACK_OF(EVP_PKEY) **nocerts)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *matching;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) *nomatch;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland EVP_PKEY *tmpkey;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509 *tmpcert;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int count = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int found;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int res;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int k;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *keycerts = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (nocerts != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *nocerts = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nomatch = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((matching = sk_X509_new_null()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_SPLIT_CERTS, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *keycerts = matching;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland k = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (k < sk_EVP_PKEY_num(allkeys)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland found = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpkey = sk_EVP_PKEY_value(allkeys, k);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < sk_X509_num(allcerts); i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpcert = sk_X509_value(allcerts, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland res = X509_check_private_key(tmpcert, tmpkey);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (res != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland count++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland found = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpcert = sk_X509_delete(allcerts, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_X509_push(matching, tmpcert) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_free(tmpcert);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_SPLIT_CERTS,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (found != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Found a match - keep the key & check out the next
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * one.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland k++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * No cert matching this key. Move the key if
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * possible or discard it. Don't increment the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * index.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (nocerts == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpkey = sk_EVP_PKEY_delete(allkeys, k);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sunw_evp_pkey_free(tmpkey);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*nocerts == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nomatch = sk_EVP_PKEY_new_null();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (nomatch == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_SPLIT_CERTS,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *nocerts = nomatch;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpkey = sk_EVP_PKEY_delete(allkeys, k);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_EVP_PKEY_push(nomatch, tmpkey) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sunw_evp_pkey_free(tmpkey);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_SPLIT_CERTS,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (count);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_PKCS12_create() creates a pkcs#12 structure and given component parts.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Given one or more of user private key, user cert and/or other (CA) certs,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * return an encrypted PKCS12 structure containing them.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pass - Pass phrase for the pkcs12 structure and private key (possibly
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * empty) or NULL if there is none. It will be used to encrypt
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * both the private key(s) and as the pass phrase for the whole
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkcs12 wad.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkeys - Points to stack of private keys.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * certs - Points to stack of client (public ke) certs
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cacerts - Points to stack of 'certificate authority' certs (or trust
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * anchors).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Note that any of these may be NULL.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * NULL - An error occurred.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != NULL - Address of PKCS12 structure. The user is responsible for
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * freeing the memory when done.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah WaterlandPKCS12 *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_PKCS12_create(const char *pass, STACK_OF(EVP_PKEY) *pkeys,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *certs, STACK_OF(X509) *cacerts)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(PKCS7) *safes = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS12_SAFEBAG *bag = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS8_PRIV_KEY_INFO *p8 = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland EVP_PKEY *pkey = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS12 *ret_p12 = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS12 *p12 = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS7 *authsafe = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509 *cert = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland uchar_t *str = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int certs_there = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int keys_there = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int len;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((safes = sk_PKCS7_new_null()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((bags = sk_PKCS12_SAFEBAG_new_null()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (certs != NULL && sk_X509_num(certs) > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < sk_X509_num(certs); i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cert = sk_X509_value(certs, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Add user certificate */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((bag = M_PKCS12_x5092certbag(cert)) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_CERT_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert->aux != NULL && cert->aux->alias != NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cert->aux->alias->type == V_ASN1_UTF8STRING) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str = utf82ascstr(cert->aux->alias);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (str == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Error already on stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (PKCS12_add_friendlyname_asc(bag,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (char const *) str,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland strlen((char const *) str)) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_ADD_ATTR_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert->aux != NULL && cert->aux->keyid != NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cert->aux->keyid->type == V_ASN1_OCTET_STRING) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str = cert->aux->keyid->data;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland len = cert->aux->keyid->length;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (str != NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS12_add_localkeyid(bag, str, len) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_ADD_ATTR_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_PKCS12_SAFEBAG_push(bags, bag) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland certs_there++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bag = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cacerts != NULL && sk_X509_num(cacerts) > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Put all certs in structure */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < sk_X509_num(cacerts); i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cert = sk_X509_value(cacerts, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((bag = M_PKCS12_x5092certbag(cert)) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_CERT_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert->aux != NULL && cert->aux->alias != NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cert->aux->alias->type == V_ASN1_UTF8STRING) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str = utf82ascstr(cert->aux->alias);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (str == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Error already on stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (PKCS12_add_friendlyname_asc(
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bag, (char const *) str,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland strlen((char const *) str)) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_ADD_ATTR_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert->aux != NULL && cert->aux->keyid != NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cert->aux->keyid->type == V_ASN1_OCTET_STRING) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str = cert->aux->keyid->data;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland len = cert->aux->keyid->length;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (str != NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS12_add_localkeyid(bag, str, len) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_ADD_ATTR_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_PKCS12_SAFEBAG_push(bags, bag) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland certs_there++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bag = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (certs != NULL || cacerts != NULL && certs_there) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Turn certbags into encrypted authsafe */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland authsafe = PKCS12_pack_p7encdata(nid_cert, pass, -1,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland NULL, 0, PKCS12_DEFAULT_ITER, bags);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (authsafe == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_CERT_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bags = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_PKCS7_push(safes, authsafe) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland authsafe = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkeys != NULL && sk_EVP_PKEY_num(pkeys) > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (bags == NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (bags = sk_PKCS12_SAFEBAG_new_null()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < sk_EVP_PKEY_num(pkeys); i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkey = sk_EVP_PKEY_value(pkeys, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Make a shrouded key bag */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((p8 = EVP_PKEY2PKCS8(pkey)) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_PKEY_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS12_DEFAULT_ITER, p8);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (bag == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MAKE_BAG_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS8_PRIV_KEY_INFO_free(p8);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland p8 = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland len = sunw_get_pkey_fname(GETDO_COPY, pkey,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (char **)&str);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (str != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (PKCS12_add_friendlyname_asc(bag,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (const char *)str, len) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_ADD_ATTR_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland len = sunw_get_pkey_localkeyid(GETDO_COPY, pkey,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (char **)&str, &len);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (str != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (PKCS12_add_localkeyid(bag, str, len) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_ADD_ATTR_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_PKCS12_SAFEBAG_push(bags, bag) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland keys_there++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bag = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keys_there) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Turn into unencrypted authsafe */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland authsafe = PKCS12_pack_p7data(bags);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (authsafe == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_PKCS12_CREATE_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bags = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_PKCS7_push(safes, authsafe) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland authsafe = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (certs_there == 0 && keys_there == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_PKCS12_EMPTY_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((p12 = PKCS12_init(NID_pkcs7_data)) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_PKCS12_CREATE_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Note that safes is copied by the following. Therefore, it needs
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to be freed whether or not the following succeeds.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (M_PKCS12_pack_authsafes(p12, safes) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_PKCS12_CREATE_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (PKCS12_set_mac(p12, pass, -1, NULL, 0, 2048, NULL) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MAC_CREATE_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto err_ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ret_p12 = p12;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland p12 = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Fallthrough is intentional */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlanderr_ret:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (str != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(str);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (p8 != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS8_PRIV_KEY_INFO_free(p8);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (bag != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS12_SAFEBAG_free(bag);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (bags != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (authsafe != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS7_free(authsafe);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (safes != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_PKCS7_pop_free(safes, PKCS7_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (p12 != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS12_free(p12);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (ret_p12);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_evp_pkey_free() Given an EVP_PKEY structure, free any attributes
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * that are attached. Then free the EVP_PKEY itself.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This is a replacement for EVP_PKEY_free() for the sunw stuff.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * It should be used in places where EVP_PKEY_free would be used,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * including calls to sk_EVP_PKEY_pop_free().
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkey - Entry which potentially has attributes to be freed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * None.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandvoid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_evp_pkey_free(EVP_PKEY *pkey)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey->attributes != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_X509_ATTRIBUTE_pop_free(pkey->attributes,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkey->attributes = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland EVP_PKEY_free(pkey);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_set_localkeyid() sets the localkeyid in a cert, a private key or
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * both. Any existing localkeyid will be discarded.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keyid_str- A byte string with the localkeyid to set
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keyid_len- Length of the keyid byte string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkey - Points to a private key to set the keyidstr in.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert - Points to a cert to set the keyidstr in.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Note that setting a keyid into a cert which will not be written out as
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a PKCS12 cert is pointless since it will be lost.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 0 - Success.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * < 0 - An error occurred. It was probably an error in allocating
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * memory. The error will be set in the error stack. Call
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ERR_get_error() to get specific information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_set_localkeyid(const char *keyid_str, int keyid_len, EVP_PKEY *pkey,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509 *cert)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE *attr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_STRING *str = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE *keyid = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (X509_keyid_set1(cert, (uchar_t *)keyid_str, keyid_len)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_SET_LKID_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str = (ASN1_STRING *)M_ASN1_OCTET_STRING_new();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (str == NULL ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland M_ASN1_OCTET_STRING_set(str, keyid_str, keyid_len) == 0 ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (keyid = ASN1_TYPE_new()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE_set(keyid, V_ASN1_OCTET_STRING, str);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr = type2attrib(keyid, NID_localKeyID);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (attr == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Error already on stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland keyid = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey->attributes == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkey->attributes = sk_X509_ATTRIBUTE_new_null();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey->attributes == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_SET_LOCALKEYID,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i = find_attr_by_nid(pkey->attributes, NID_localKeyID);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i >= 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_X509_ATTRIBUTE_delete(pkey->attributes, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandcleanup:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (str != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_STRING_free(str);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keyid != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE_free(keyid);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (attr != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE_free(attr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_get_pkey_localkeyid() gets the localkeyid from a private key. It can
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * optionally remove the value found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * dowhat - What to do with the attributes (remove them or copy them).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkey - Points to a private key to set the keyidstr in.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keyid_str- Points to a location which will receive the pointer to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a byte string containing the binary localkeyid. Note that
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * this is a copy, and the caller must free it.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keyid_len- Length of keyid_str.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * >= 0 - The number of characters in the keyid returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * < 0 - An error occurred. It was probably an error in allocating
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * memory. The error will be set in the error stack. Call
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ERR_get_error() to get specific information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_get_pkey_localkeyid(getdo_actions_t dowhat, EVP_PKEY *pkey,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char **keyid_str, int *keyid_len)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE *attr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_OCTET_STRING *str = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE *ty = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int len = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keyid_str != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *keyid_str = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keyid_len != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *keyid_len = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey == NULL || pkey->attributes == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((i = find_attr_by_nid(pkey->attributes, NID_localKeyID)) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ty = attrib2type(attr)) == NULL ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ty->type != V_ASN1_OCTET_STRING) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (dowhat == GETDO_DEL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr = sk_X509_ATTRIBUTE_delete(pkey->attributes, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (attr != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE_free(attr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str = ty->value.octet_string;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland len = str->length;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((*keyid_str = malloc(len)) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_GET_LOCALKEYID, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) memcpy(*keyid_str, str->data, len);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *keyid_len = len;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (len);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_get_pkey_fname() gets the friendlyName from a private key. It can
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * optionally remove the value found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * dowhat - What to do with the attributes (remove them or copy them).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkey - Points to a private key to get the frientlyname from
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * fname - Points to a location which will receive the pointer to a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * byte string with the ASCII friendlyname
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * >= 0 - The number of characters in the frienlyname returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * < 0 - An error occurred. It was probably an error in allocating
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * memory. The error will be set in the error stack. Call
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ERR_get_error() to get specific information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_get_pkey_fname(getdo_actions_t dowhat, EVP_PKEY *pkey, char **fname)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE *attr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_BMPSTRING *str = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE *ty = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int len = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fname != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *fname = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey == NULL || pkey->attributes == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((i = find_attr_by_nid(pkey->attributes, NID_friendlyName)) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ty = attrib2type(attr)) == NULL ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ty->type != V_ASN1_BMPSTRING) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (dowhat == GETDO_DEL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr = sk_X509_ATTRIBUTE_delete(pkey->attributes, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (attr != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE_free(attr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str = ty->value.bmpstring;
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle#if OPENSSL_VERSION_NUMBER < 0x10000000L
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *fname = uni2asc(str->data, str->length);
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle#else
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle *fname = OPENSSL_uni2asc(str->data, str->length);
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle#endif
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*fname == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_GET_PKEY_FNAME, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland len = strlen(*fname);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (len);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_find_localkeyid() searches stacks of certs and private keys,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and returns the first matching cert/private key found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Look for a keyid in a stack of certs. if 'certs' is NULL and 'pkeys' is
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * not NULL, search the list of private keys. Move the matching cert to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 'matching_cert' and its matching private key to 'matching_pkey'. If no
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert or keys match, no match occurred.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keyid_str- A byte string with the localkeyid to match
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keyid_len- Length of the keyid byte string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkeys - Points to a stack of private keys which match the certs.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This may be NULL, in which case no keys are returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * certs - Points to a stack of certs to search. If NULL, search the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * stack of keys instead.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * matching_pkey
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - Pointer to receive address of first matching pkey found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 'matching_pkey' must not be NULL; '*matching_pkey' will be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * reset.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * matching_cert
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - Pointer to receive address of first matching cert found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 'matching_cert' must not be NULL; '*matching_cert' will be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * reset.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * < 0 - An error returned. Call ERR_get_error() to get errors information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Where possible, memory has been freed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * >= 0 - Objects were found and returned. Which objects are indicated by
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * which bits are set (FOUND_PKEY and/or FOUND_CERT).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_find_localkeyid(char *keyid_str, int len, STACK_OF(EVP_PKEY) *pkeys,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah WaterlandSTACK_OF(X509) *certs, EVP_PKEY **matching_pkey, X509 **matching_cert)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_STRING *cmpstr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland EVP_PKEY *tmp_pkey = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509 *tmp_cert = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* If NULL arguments, this is an error */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keyid_str == NULL ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (pkeys == NULL || certs == NULL) ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (pkeys != NULL && matching_pkey == NULL) ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (certs != NULL && matching_cert == NULL)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_FIND_LOCALKEYID, SUNW_R_INVALID_ARG);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (matching_pkey != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *matching_pkey = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (matching_cert != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *matching_cert = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cmpstr = (ASN1_STRING *)M_ASN1_OCTET_STRING_new();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cmpstr == NULL ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland M_ASN1_OCTET_STRING_set(cmpstr, keyid_str, len) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_FIND_LOCALKEYID, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = find_attr(NID_localKeyID, cmpstr, pkeys, &tmp_pkey, certs,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland &tmp_cert);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_STRING_free(cmpstr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (matching_pkey != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *matching_pkey = tmp_pkey;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (matching_cert != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *matching_cert = tmp_cert;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_find_fname() searches stacks of certs and private keys for one with
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a matching friendlyname and returns the first matching cert/private
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * key found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Look for a friendlyname in a stack of certs. if 'certs' is NULL and 'pkeys'
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * is not NULL, search the list of private keys. Move the matching cert to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 'matching_cert' and its matching private key to 'matching_pkey'. If no
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert or keys match, no match occurred.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * fname - Friendlyname to find (NULL-terminated ASCII string).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkeys - Points to a stack of private keys which match the certs.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This may be NULL, in which case no keys are returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * certs - Points to a stack of certs to search. If NULL, search the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * stack of keys instead.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * matching_pkey
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - Pointer to receive address of first matching pkey found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * matching_cert
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - Pointer to receive address of first matching cert found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * < 0 - An error returned. Call ERR_get_error() to get errors information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Where possible, memory has been freed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * >= 0 - Objects were found and returned. Which objects are indicated by
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * which bits are set (FOUND_PKEY and/or FOUND_CERT).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_find_fname(char *fname, STACK_OF(EVP_PKEY) *pkeys, STACK_OF(X509) *certs,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland EVP_PKEY **matching_pkey, X509 ** matching_cert)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_STRING *cmpstr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland EVP_PKEY *tmp_pkey = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509 *tmp_cert = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* If NULL arguments, this is an error */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fname == NULL ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (pkeys == NULL && certs == NULL) ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (pkeys != NULL && matching_pkey == NULL) ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (certs != NULL && matching_cert == NULL)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_FIND_FNAME, SUNW_R_INVALID_ARG);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (matching_pkey != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *matching_pkey = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (matching_cert != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *matching_cert = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cmpstr = (ASN1_STRING *)asc2bmpstring(fname, strlen(fname));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cmpstr == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Error already on stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = find_attr(NID_friendlyName, cmpstr, pkeys, &tmp_pkey, certs,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland &tmp_cert);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_STRING_free(cmpstr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (matching_pkey != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *matching_pkey = tmp_pkey;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (matching_cert != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *matching_cert = tmp_cert;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_get_cert_fname() gets the fiendlyname from a cert. It can
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * optionally remove the value found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * dowhat - What to do with the attributes (remove them or copy them).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert - Points to a cert to get the friendlyName from.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * fname - Points to a location which will receive the pointer to a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * byte string with the ASCII friendlyname
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * >= 0 - The number of characters in the friendlyname returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * < 0 - An error occurred. It was probably an error in allocating
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * memory. The error will be set in the error stack. Call
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ERR_get_error() to get specific information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_get_cert_fname(getdo_actions_t dowhat, X509 *cert, char **fname)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int len;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fname != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *fname = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert == NULL || cert->aux == NULL || cert->aux->alias == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (dowhat == GETDO_DEL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Delete the entry */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_UTF8STRING_free(cert->aux->alias);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cert->aux->alias = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *((uchar_t **)fname) = utf82ascstr(cert->aux->alias);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*fname == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Error already on stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland len = strlen(*fname);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (len);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_set_fname() sets the friendlyName in a cert, a private key or
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * both. Any existing friendlyname will be discarded.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ascname - An ASCII string with the friendlyName to set
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkey - Points to a private key to set the fname in.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert - Points to a cert to set the fname in.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Note that setting a friendlyName into a cert which will not be written out
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * as a PKCS12 cert is pointless since it will be lost.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 0 - Success.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * <0 - An error occurred. It was probably an error in allocating
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * memory. The error will be set in the error stack. Call
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ERR_get_error() to get specific information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_set_fname(const char *ascname, EVP_PKEY *pkey, X509 *cert)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE *attr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_BMPSTRING *str = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE *fname = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland unsigned char *data = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int len;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str = asc2bmpstring(ascname, strlen(ascname));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (str == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Error already on stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert->aux != NULL && cert->aux->alias != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_UTF8STRING_free(cert->aux->alias);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland len = ASN1_STRING_to_UTF8(&data, str);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i = -23;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (len <= 0 || (i = X509_alias_set1(cert, data, len)) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_SET_FNAME, SUNW_R_SET_FNAME_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((fname = ASN1_TYPE_new()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_SET_FNAME, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE_set(fname, V_ASN1_BMPSTRING, str);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr = type2attrib(fname, NID_friendlyName);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (attr == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Error already on stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fname = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey->attributes == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkey->attributes = sk_X509_ATTRIBUTE_new_null();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey->attributes == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_SET_FNAME,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if ((i = find_attr_by_nid(pkey->attributes,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland NID_friendlyName)) >= 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) sk_X509_ATTRIBUTE_delete(pkey->attributes, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_SET_FNAME, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandcleanup:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (data != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland OPENSSL_free(data);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (str != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_BMPSTRING_free(str);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fname != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE_free(fname);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (attr != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE_free(attr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_check_keys() compares the public key in the certificate and a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * private key to ensure that they match.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert - Points to a certificate.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkey - Points to a private key.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == 0 - These do not match.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != 0 - The cert's public key and the private key match.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_check_keys(X509 *cert, EVP_PKEY *pkey)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey != NULL && cert != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = X509_check_private_key(cert, pkey);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_check_cert_times() compares the time fields in a certificate
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Compare the 'not before' and the 'not after' times in the cert
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to the current time. Return the results of the comparison (bad time formats,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert not yet in force, cert expired or in range)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * dowhat - what field(s) to check.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert - Points to a cert to check
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Results of the comparison.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandchk_errs_t
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_check_cert_times(chk_actions_t chkwhat, X509 *cert)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (check_time(chkwhat, cert));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ----------------------------------------------------------------------------
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Local routines
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ----------------------------------------------------------------------------
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * parse_pkcs12 - Oversee parsing of the pkcs12 structure. Get it
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * parsed. After that either return what's found directly, or
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * do any required matching.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * p12 - Structure with pkcs12 info to be parsed
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pass - Pass phrase for the private key (possibly empty) or NULL if
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * there is none.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * matchty - Info about which certs/keys to return if many are in the file.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keyid - If private key localkeyids friendlynames are to match a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * predetermined value, the value to match. This value should
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * be an octet string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keyid_len- Length of the keyid byte string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * name_str - If friendlynames are to match a predetermined value, the value
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to match. This value should be a NULL terminated string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkey - Points to location pointing to the private key returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert - Points to locaiton which points to the client cert returned
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ca - Points to location that points to a stack of 'certificate
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * authority' certs/trust anchors.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Note about error codes: This function is an internal function, and the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * place where it is called sets error codes. Therefore only set an error
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * code if it is something that is unique or if the function which detected
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the error doesn't set one.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == -1 - An error occurred. Call ERR_get_error() to get error information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Where possible, memory has been freed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == 0 - No matching returns were found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * > 0 - This is the aithmetic 'or' of the FOUND_* bits that indicate which
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of the requested entries were found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandparse_pkcs12(PKCS12 *p12, const char *pass, int matchty, char *keyid,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int kstr_len, char *name_str, EVP_PKEY **pkey, X509 **cert,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) **ca)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) *work_kl = NULL; /* Head for private key list */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) *nocerts = NULL; /* Head for alt. key list */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *work_ca = NULL; /* Head for cert list */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *work_cl = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int n;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = sunw_PKCS12_contents(p12, pass, &work_kl, &work_ca);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (retval == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Not really an error here - its just that nothing was found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_EVP_PKEY_num(work_kl) > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sunw_split_certs(work_kl, work_ca, &work_cl, &nocerts)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Go through the lists of certs and private keys which were
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * returned, looking for matches of the appropriate type. Do these
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * in the order described above.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((matchty & DO_FIND_KEYID) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keyid == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_INVALID_ARG);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* See if string matches localkeyid's */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = sunw_find_localkeyid(keyid, kstr_len,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland work_kl, work_cl, pkey, cert);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval == -1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto last_part;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((matchty & DO_FIND_FN) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (name_str == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_INVALID_ARG);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* See if string matches friendly names */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = sunw_find_fname(name_str, work_kl, work_cl,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkey, cert);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval == -1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto last_part;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (matchty & DO_FIRST_PAIR) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Find the first cert and private key and return them */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = get_key_cert(0, work_kl, pkey, work_cl, cert);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval == -1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto last_part;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (matchty & DO_LAST_PAIR) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Find the last matching cert and private key and return
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * them. Since keys which don't have matching client certs
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * are at the end of the list of keys, use the number of
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * client certs to compute the position of the last private
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * key which matches a client cert.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland n = sk_X509_num(work_cl) - 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = get_key_cert(n, work_kl, pkey, work_cl, cert);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval == -1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto last_part;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (matchty & DO_UNMATCHING) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) *tmpk;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *tmpc;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Find the first cert and private key and return them */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpc = work_cl;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (work_cl == NULL || sk_X509_num(work_cl) == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpc = work_ca;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpk = work_kl;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (work_kl == NULL || sk_EVP_PKEY_num(work_kl) == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpk = nocerts;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = get_key_cert(0, tmpk, pkey, tmpc, cert);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval == -1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto last_part;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandlast_part:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* If no errors, terminate normally */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval != -1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval |= set_results(NULL, NULL, NULL, NULL, ca, &work_ca,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland NULL, NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval >= 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto clean_part;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Fallthrough is intentional in error cases. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandcleanup:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey != NULL && *pkey != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sunw_evp_pkey_free(*pkey);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pkey = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert != NULL && *cert != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_free(*cert);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *cert = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandclean_part:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (work_kl != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (work_ca != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_X509_pop_free(work_ca, X509_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (work_cl != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_X509_pop_free(work_cl, X509_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * parse_outer - Unpack the outer PKCS#12 structure and go through the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * individual bags. Return stacks of certs, private keys found and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CA certs found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Note about error codes: This function is an internal function, and the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * place where it is called sets error codes.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 0 - An error returned. Call ERR_get_error() to get errors information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Where possible, memory has been freed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 1 - PKCS12 data object was parsed and lists of certs and private keys
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * were returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandparse_outer(PKCS12 *p12, const char *pass, STACK_OF(EVP_PKEY) *kl,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *cl)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(PKCS12_SAFEBAG) *bags;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(PKCS7) *asafes;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i, bagnid;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS7 *p7;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((asafes = M_PKCS12_unpack_authsafes(p12)) == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < sk_PKCS7_num(asafes); i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland p7 = sk_PKCS7_value(asafes, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bagnid = OBJ_obj2nid(p7->type);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (bagnid == NID_pkcs7_data) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bags = M_PKCS12_unpack_p7data(p7);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (bagnid == NID_pkcs7_encrypted) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * A length of '-1' means strlen() can be used
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to determine the password length.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bags = M_PKCS12_unpack_p7encdata(p7, pass, -1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_OUTER, SUNW_R_BAD_BAGTYPE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (bags == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_OUTER, SUNW_R_PARSE_BAG_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_PKCS7_pop_free(asafes, PKCS7_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (parse_all_bags(bags, pass, kl, cl) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_PKCS7_pop_free(asafes, PKCS7_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * parse_all_bags - go through the stack of bags, parsing each.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Note about error codes: This function is an internal function, and the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * place where it is called sets error codes.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 0 - An error returned. Call ERR_get_error() to get errors information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Where possible, memory has been freed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 1 - Stack of safebags was parsed and lists of certs and private keys
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * were returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandparse_all_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) *kl, STACK_OF(X509) *cl)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (parse_one_bag(sk_PKCS12_SAFEBAG_value(bags, i),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pass, kl, cl) == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * parse_one_bag - Parse an individual bag
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * i = parse_one_bag(bag, pass, kl, cl);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * bag - pkcs12 safebag to parse.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pass - password for use in decryption of shrouded keybag
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * kl - Stack of private keys found so far. New private keys will
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * be added here if found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cl - Stack of certs found so far. New certificates will be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * added here if found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 0 - An error returned. Call ERR_get_error() to get errors information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Where possible, memory has been freed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 1 - one safebag was parsed. If it contained a cert or private key, it
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * was added to the stack of certs or private keys found, respectively.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * localKeyId or friendlyName attributes are returned with the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * private key or certificate.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandparse_one_bag(PKCS12_SAFEBAG *bag, const char *pass, STACK_OF(EVP_PKEY) *kl,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *cl)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE *attr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE *keyid = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE *fname = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS8_PRIV_KEY_INFO *p8;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland EVP_PKEY *pkey = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509 *x509 = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland uchar_t *data = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *str = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland keyid = PKCS12_get_attr(bag, NID_localKeyID);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fname = PKCS12_get_attr(bag, NID_friendlyName);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland switch (M_PKCS12_bag_type(bag)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case NID_keyBag:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((pkey = EVP_PKCS82PKEY(bag->value.keybag)) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_PARSE_BAG_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case NID_pkcs8ShroudedKeyBag:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * A length of '-1' means strlen() can be used
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to determine the password length.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((p8 = M_PKCS12_decrypt_skey(bag, pass, -1)) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_PARSE_BAG_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkey = EVP_PKCS82PKEY(p8);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PKCS8_PRIV_KEY_INFO_free(p8);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_PARSE_BAG_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case NID_certBag:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_BAD_CERTTYPE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((x509 = M_PKCS12_certbag2x509(bag)) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_PARSE_CERT_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keyid != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keyid->type != V_ASN1_OCTET_STRING) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_BAD_LKID);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (X509_keyid_set1(x509,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland keyid->value.octet_string->data,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland keyid->value.octet_string->length) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_SET_LKID_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fname != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_STRING *tmpstr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int len;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fname->type != V_ASN1_BMPSTRING) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_BAD_FNAME);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpstr = fname->value.asn1_string;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland len = ASN1_STRING_to_UTF8(&data, tmpstr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (len < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_SET_FNAME_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (X509_alias_set1(x509, data, len) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_SET_FNAME_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_X509_push(cl, x509) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland x509 = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland case NID_safeContentsBag:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keyid != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE_free(keyid);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fname != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE_free(fname);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (parse_all_bags(bag->value.safes, pass, kl, cl) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Error already on stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland default:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keyid != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE_free(keyid);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fname != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE_free(fname);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_BAD_BAGTYPE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval != 0 && (keyid != NULL || fname != NULL) &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkey->attributes == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkey->attributes = sk_X509_ATTRIBUTE_new_null();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey->attributes == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval != 0 && keyid != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr = type2attrib(keyid, NID_localKeyID);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (attr == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Error already on stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland keyid = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_X509_ATTRIBUTE_push(pkey->attributes,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval != 0 && fname != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr = type2attrib(fname, NID_friendlyName);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (attr == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Error already on stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fname = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_X509_ATTRIBUTE_push(pkey->attributes,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Save the private key */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_EVP_PKEY_push(kl, pkey) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PARSE_ONE_BAG,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkey = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sunw_evp_pkey_free(pkey);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (x509 != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_free(x509);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (keyid != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE_free(keyid);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fname != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE_free(fname);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (attr != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE_free(attr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (data != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland OPENSSL_free(data);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (str != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland OPENSSL_free(str);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function uses the only function that reads PEM files, regardless of
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the kinds of information included (private keys, public keys, cert requests,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * certs). Other interfaces that read files require that the application
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * specifically know what kinds of things to read next, and call different
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * interfaces for the different kinds of entities.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * There is only one aspect of this function that's a bit problematic.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If it finds an encrypted private key, it does not decrypt it. It returns
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the encrypted data and other information needed to decrypt it. The caller
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * must do the decryption. This function does the decoding.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandpem_info(FILE *fp, pem_password_cb cb, void *userdata,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) **pkeys, STACK_OF(X509) **certs)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509_INFO) *info;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) *work_kl;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *work_cl;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_INFO *x;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland info = PEM_X509_INFO_read(fp, NULL, cb, userdata);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (info == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PEM_INFO, SUNW_R_READ_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Allocate the working stacks for private key(s) and for the cert(s).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((work_kl = sk_EVP_PKEY_new_null()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PEM_INFO, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((work_cl = sk_X509_new_null()) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PEM_INFO, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Go through the entries in the info structure.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < sk_X509_INFO_num(info); i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland x = sk_X509_INFO_value(info, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (x->x509) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_X509_push(work_cl, x->x509) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland x->x509 = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (x->x_pkey != NULL && x->x_pkey->dec_pkey != NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (x->x_pkey->dec_pkey->type == EVP_PKEY_RSA ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland x->x_pkey->dec_pkey->type == EVP_PKEY_DSA)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland const uchar_t *p;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If the key was encrypted, PEM_X509_INFO_read does
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * not decrypt it. If that is the case, the 'enc_pkey'
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * field is set to point to the unencrypted key data.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Go through the additional steps to decode it before
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * going on.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (x->x_pkey->enc_pkey != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (PEM_do_header(&x->enc_cipher,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (uchar_t *)x->enc_data,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (long *)&x->enc_len,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cb, userdata) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ERR_GET_REASON(ERR_peek_error()) ==
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland PEM_R_BAD_PASSWORD_READ) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PEM_INFO,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_PASSWORD_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PEM_INFO,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_PKEY_READ_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (x->x_pkey->dec_pkey->type == EVP_PKEY_RSA) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland RSA **pp;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pp = &(x->x_pkey->dec_pkey->pkey.rsa);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland p = (uchar_t *)x->enc_data;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (d2i_RSAPrivateKey(pp, &p,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland x->enc_len) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PEM_INFO,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_PKEY_READ_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland DSA **pp;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pp = &(x->x_pkey->dec_pkey->pkey.dsa);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland p = (uchar_t *)x->enc_data;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (d2i_DSAPrivateKey(pp, &p,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland x->enc_len) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PEM_INFO,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_R_PKEY_READ_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Save the key. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = sk_EVP_PKEY_push(work_kl, x->x_pkey->dec_pkey);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland x->x_pkey->dec_pkey = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (x->x_pkey != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_PEM_INFO, SUNW_R_BAD_PKEYTYPE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retval == -1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto cleanup;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* If error occurs, then error already on stack */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval = set_results(pkeys, &work_kl, certs, &work_cl, NULL, NULL,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland NULL, NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandcleanup:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (work_kl != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (work_cl != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_X509_pop_free(work_cl, X509_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_X509_INFO_pop_free(info, X509_INFO_free);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sunw_append_keys - Given two stacks of private keys, remove the keys from
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the second stack and append them to the first. Both stacks must exist
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * at time of call.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * dst - the stack to receive the keys from 'src'
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * src - the stack whose keys are to be moved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -1 - An error occurred. The error status is set.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * >= 0 - The number of keys that were copied.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsunw_append_keys(STACK_OF(EVP_PKEY) *dst, STACK_OF(EVP_PKEY) *src)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland EVP_PKEY *tmpk;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int count = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (sk_EVP_PKEY_num(src) > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpk = sk_EVP_PKEY_delete(src, 0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_EVP_PKEY_push(dst, tmpk) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sunw_evp_pkey_free(tmpk);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_APPEND_KEYS, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland count ++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (count);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * move_certs - Given two stacks of certs, remove the certs from
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the second stack and append them to the first.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * dst - the stack to receive the certs from 'src'
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * src - the stack whose certs are to be moved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -1 - An error occurred. The error status is set.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * >= 0 - The number of certs that were copied.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandmove_certs(STACK_OF(X509) *dst, STACK_OF(X509) *src)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509 *tmpc;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int count = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (sk_X509_num(src) > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpc = sk_X509_delete(src, 0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_X509_push(dst, tmpc) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_free(tmpc);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_MOVE_CERTS, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland count++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (count);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * get_key_cert - Get a cert and its matching key from the stacks of certs
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and keys. They are removed from the stacks.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * n - Offset of the entries to return.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * kl - Points to a stack of private keys that matches the list of
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * certs below.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkey - Points at location where the address of the matching private
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * key will be stored.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cl - Points to a stack of client certs with matching private keys.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert - Points to locaiton where the address of the matching client cert
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * will be returned
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The assumption is that the stacks of keys and certs contain key/cert pairs,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * with entries in the same order and hence at the same offset. Provided
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the key and cert selected match, each will be removed from its stack and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * A stack of certs can be passed in without a stack of private keys, and vise
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * versa. In that case, the indicated key/cert will be returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 0 - No matches were found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * > 0 - Bits set based on FOUND_* definitions, indicating what is returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This can be FOUND_PKEY, FOUND_CERT or (FOUND_PKEY | FOUND_CERT).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandget_key_cert(int n, STACK_OF(EVP_PKEY) *kl, EVP_PKEY **pkey, STACK_OF(X509) *cl,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509 **cert)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int nk;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int nc;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nk = (kl != NULL) ? sk_EVP_PKEY_num(kl) : 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nc = (cl != NULL) ? sk_X509_num(cl) : 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey != NULL && *pkey == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (nk > 0 && n >= 0 || n < nk) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pkey = sk_EVP_PKEY_delete(kl, n);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*pkey != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval |= FOUND_PKEY;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert != NULL && *cert == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (nc > 0 && n >= 0 && n < nc) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *cert = sk_X509_delete(cl, n);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*cert != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval |= FOUND_CERT;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * asc2bmpstring - Convert a regular C ASCII string to an ASn1_STRING in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ASN1_BMPSTRING format.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * str - String to be convered.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * len - Length of the string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == NULL - An error occurred. Error information (accessible by
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ERR_get_error()) is set.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != NULL - Points to an ASN1_BMPSTRING structure with the converted
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * string as a value.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic ASN1_BMPSTRING *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandasc2bmpstring(const char *str, int len)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_BMPSTRING *bmp = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland uchar_t *uni = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int unilen;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Convert the character to the bmp format. */
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle#if OPENSSL_VERSION_NUMBER < 0x10000000L
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (asc2uni(str, len, &uni, &unilen) == 0) {
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle#else
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle if (OPENSSL_asc2uni(str, len, &uni, &unilen) == 0) {
70f9559bd0c02885d84a425eaafc8c280df10efbTheo Schlossnagle#endif
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_ASC2BMPSTRING, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Adjust for possible pair of NULL bytes at the end because
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * asc2uni() returns a doubly null terminated string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (uni[unilen - 1] == '\0' && uni[unilen - 2] == '\0')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland unilen -= 2;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Construct comparison string with correct format */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bmp = M_ASN1_BMPSTRING_new();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (bmp == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_ASC2BMPSTRING, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland OPENSSL_free(uni);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bmp->data = uni;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bmp->length = unilen;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (bmp);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * utf82ascstr - Convert a UTF8STRING string to a regular C ASCII string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This goes through an intermediate step with a ASN1_STRING type of
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * IA5STRING (International Alphabet 5, which is the same as ASCII).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * str - UTF8STRING to be converted.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == NULL - An error occurred. Error information (accessible by
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ERR_get_error()) is set.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != NULL - Points to a NULL-termianted ASCII string. The caller must
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * free it.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic uchar_t *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandutf82ascstr(ASN1_UTF8STRING *ustr)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_STRING tmpstr;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_STRING *astr = &tmpstr;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland uchar_t *retstr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int mbflag;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ustr == NULL || ustr->type != V_ASN1_UTF8STRING) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_UTF82ASCSTR, SUNW_R_INVALID_ARG);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland mbflag = MBSTRING_ASC;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpstr.data = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tmpstr.length = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ret = ASN1_mbstring_copy(&astr, ustr->data, ustr->length, mbflag,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland B_ASN1_IA5STRING);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ret < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_UTF82ASCSTR, SUNW_R_STR_CONVERT_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retstr = OPENSSL_malloc(astr->length + 1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (retstr == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_UTF82ASCSTR, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) memcpy(retstr, astr->data, astr->length);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retstr[astr->length] = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland OPENSSL_free(astr->data);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retstr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * type2attrib - Given a ASN1_TYPE, return a X509_ATTRIBUTE of the type
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * specified by the given NID.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ty - Type structure to be made into an attribute
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * nid - NID of the attribute
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * NULL An error occurred.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != NULL An X509_ATTRIBUTE structure.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah WaterlandX509_ATTRIBUTE *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandtype2attrib(ASN1_TYPE *ty, int nid)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE *a;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((a = X509_ATTRIBUTE_new()) == NULL ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (a->value.set = sk_ASN1_TYPE_new_null()) == NULL ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_ASN1_TYPE_push(a->value.set, ty) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (a != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE_free(a);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_TYPE2ATTRIB, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland a->single = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland a->object = OBJ_nid2obj(nid);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (a);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * attrib2type - Given a X509_ATTRIBUTE, return pointer to the ASN1_TYPE
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * component
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * attr - Attribute structure containing a type.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * NULL An error occurred.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != NULL An ASN1_TYPE structure.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic ASN1_TYPE *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandattrib2type(X509_ATTRIBUTE *attr)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE *ty = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (attr == NULL || attr->single == 1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sk_ASN1_TYPE_num(attr->value.set) > 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ty = sk_ASN1_TYPE_value(attr->value.set, 0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (ty);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * find_attr_by_nid - Given a ASN1_TYPE, return the offset of a X509_ATTRIBUTE
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of the type specified by the given NID.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * attrs - Stack of attributes to search
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * nid - NID of the attribute being searched for
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -1 None found
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * != -1 Offset of the matching attribute.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandfind_attr_by_nid(STACK_OF(X509_ATTRIBUTE) *attrs, int nid)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509_ATTRIBUTE *a;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (attrs == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland a = sk_X509_ATTRIBUTE_value(attrs, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (OBJ_obj2nid(a->object) == nid)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Called by our PKCS12 code to read our function and error codes
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * into memory so that the OpenSSL framework can retrieve them.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandvoid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah WaterlandERR_load_SUNW_strings(void)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland assert(SUNW_lib_error_code == 0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#ifndef OPENSSL_NO_ERR
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Have OpenSSL provide us with a unique ID.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_lib_error_code = ERR_get_next_error_library();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ERR_load_strings(SUNW_lib_error_code, SUNW_str_functs);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ERR_load_strings(SUNW_lib_error_code, SUNW_str_reasons);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNW_lib_name->error = ERR_PACK(SUNW_lib_error_code, 0, 0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ERR_load_strings(0, SUNW_lib_name);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#endif
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The SUNWerr macro resolves to this routine. So when we need
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to push an error, this routine does it for us. Notice that
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the SUNWerr macro provides a filename and line #.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandvoid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah WaterlandERR_SUNW_error(int function, int reason, char *file, int line)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland assert(SUNW_lib_error_code != 0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#ifndef OPENSSL_NO_ERR
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ERR_PUT_error(SUNW_lib_error_code, function, reason, file, line);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#endif
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * check_time - Given an indication of the which time(s) to check, check
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * that time or those times against the current time and return the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * relationship.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * chkwhat - What kind of check to do.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert - The cert to check.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CHKERR_* values.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic chk_errs_t
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandcheck_time(chk_actions_t chkwhat, X509 *cert)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (chkwhat == CHK_NOT_BEFORE || chkwhat == CHK_BOTH) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i = X509_cmp_time(X509_get_notBefore(cert), NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (CHKERR_TIME_BEFORE_BAD);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i > 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (CHKERR_TIME_IS_BEFORE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* The current time is after the 'not before' time */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (chkwhat == CHK_NOT_AFTER || chkwhat == CHK_BOTH) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i = X509_cmp_time(X509_get_notAfter(cert), NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (CHKERR_TIME_AFTER_BAD);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i < 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (CHKERR_TIME_HAS_EXPIRED);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (CHKERR_TIME_OK);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * find_attr - Look for a given attribute of the type associated with the NID.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * nid - NID for the attribute to be found (either NID_friendlyName or
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * NID_locakKeyId)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * str - ASN1_STRING-type structure containing the value to be found,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * FriendlyName expects a ASN1_BMPSTRING and localKeyID uses a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ASN1_STRING.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * kl - Points to a stack of private keys.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkey - Points at a location where the address of the matching private
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * key will be stored.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cl - Points to a stack of client certs with matching private keys.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cert - Points to locaiton where the address of the matching client cert
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * will be returned
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function is designed to process lists of certs and private keys.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This is made complex because these the attributes are stored differently
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * for certs and for keys. For certs, only a few attributes are retained.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * FriendlyName is stored in the aux structure, under the name 'alias'.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * LocalKeyId is also stored in the aux structure, under the name 'keyid'.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * A pkey structure has a stack of attributes.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The basic approach is:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - If there there is no stack of certs but a stack of private keys exists,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * search the stack of keys for a match. Alternately, if there is a stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of certs and no private keys, search the certs.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - If there are both certs and keys, assume that the matching certs and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * keys are in their respective stacks, with matching entries in the same
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * order. Search for the name or keyid in the stack of certs. If it is
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * not found, then this function returns 0 (nothing found).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - Once a cert is found, verify that the key actually matches by
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * comparing the private key with the public key (in the cert).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If they don't match, return an error.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * A pointer to cert and/or pkey which matches the name or keyid is stored
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * in the return arguments.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 0 - No matches were found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * > 0 - Bits set based on FOUND_* definitions, indicating what was found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This can be FOUND_PKEY, FOUND_CERT or (FOUND_PKEY | FOUND_CERT).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandfind_attr(int nid, ASN1_STRING *str, STACK_OF(EVP_PKEY) *kl, EVP_PKEY **pkey,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) *cl, X509 **cert)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_UTF8STRING *ustr = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_STRING *s;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_TYPE *t;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland EVP_PKEY *p;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland uchar_t *fname = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland X509 *x;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int found = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int chkcerts;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int len;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int res;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int c = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int k = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland chkcerts = (cert != NULL || pkey != NULL) && cl != NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (chkcerts && nid == NID_friendlyName &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland str->type == V_ASN1_BMPSTRING) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ustr = ASN1_UTF8STRING_new();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ustr == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_FINDATTR, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland len = ASN1_STRING_to_UTF8(&fname, str);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fname == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_UTF8STRING_free(ustr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_FINDATTR, SUNW_R_STR_CONVERT_ERR);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ASN1_STRING_set(ustr, fname, len) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_UTF8STRING_free(ustr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland OPENSSL_free(fname);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland SUNWerr(SUNW_F_FINDATTR, SUNW_R_MEMORY_FAILURE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (chkcerts) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (c = 0; c < sk_X509_num(cl); c++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland res = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland x = sk_X509_value(cl, c);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (nid == NID_friendlyName && ustr != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (x->aux == NULL || x->aux->alias == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland s = x->aux->alias;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (s != NULL && s->type == ustr->type &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland s->data != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland res = ASN1_STRING_cmp(s, ustr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (x->aux == NULL || x->aux->keyid == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland s = x->aux->keyid;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (s != NULL && s->type == str->type &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland s->data != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland res = ASN1_STRING_cmp(s, str);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (res == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cert != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *cert = sk_X509_delete(cl, c);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland found = FOUND_CERT;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ustr != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ASN1_UTF8STRING_free(ustr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland OPENSSL_free(fname);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey != NULL && kl != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Looking for pkey to match a cert? If so, assume that
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * lists of certs and their matching pkeys are in the same
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * order. Call X509_check_private_key() to verify this
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * assumption.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (found != 0 && cert != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland k = c;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland p = sk_EVP_PKEY_value(kl, k);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (X509_check_private_key(x, p) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pkey = sk_EVP_PKEY_delete(kl, k);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland found |= FOUND_PKEY;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (cert == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (k = 0; k < sk_EVP_PKEY_num(kl); k++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland p = sk_EVP_PKEY_value(kl, k);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (p == NULL || p->attributes == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland t = PKCS12_get_attr_gen(p->attributes, nid);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (t != NULL || ASN1_STRING_cmp(str,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland t->value.asn1_string) == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland found |= FOUND_PKEY;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkey != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pkey = sk_EVP_PKEY_delete(kl, k);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (found);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * set_results - Given two pointers to stacks of private keys, certs or CA
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CA certs, either copy the second stack to the first, or append the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * contents of the second to the first.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkeys - Points to stack of pkeys
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * work_kl - Points to working stack of pkeys
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * certs - Points to stack of certs
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * work_cl - Points to working stack of certs
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * cacerts - Points to stack of CA certs
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * work_ca - Points to working stack of CA certs
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * xtrakeys - Points to stack of unmatcned pkeys
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * work_xl - Points to working stack of unmatcned pkeys
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The arguments are in pairs. The first of each pair points to a stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of keys or certs. The second of the pair points at a 'working stack'
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of the same type of entities. Actions taken are as follows:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - If either the first or second argument is NULL, or if there are no
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * members in the second stack, there is nothing to do.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - If the first argument points to a pointer which is NULL, then there
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * is no existing stack for the first argument. Copy the stack pointer
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * from the second argument to the first argument and NULL out the stack
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pointer for the second.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - Otherwise, go through the elements of the second stack, removing each
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and adding it to the first stack.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == -1 - An error occurred. Call ERR_get_error() to get error information.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * == 0 - No matching returns were found.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * > 0 - This is the arithmetic 'or' of the FOUND_* bits that indicate which
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of the requested entries were manipulated.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandset_results(STACK_OF(EVP_PKEY) **pkeys, STACK_OF(EVP_PKEY) **work_kl,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) **certs, STACK_OF(X509) **work_cl,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(X509) **cacerts, STACK_OF(X509) **work_ca,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland STACK_OF(EVP_PKEY) **xtrakeys, STACK_OF(EVP_PKEY) **work_xl)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int retval = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkeys != NULL && work_kl != NULL && *work_kl != NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_EVP_PKEY_num(*work_kl) > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*pkeys == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pkeys = *work_kl;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *work_kl = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sunw_append_keys(*pkeys, *work_kl) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval |= FOUND_PKEY;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (certs != NULL && work_cl != NULL && *work_cl != NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_X509_num(*work_cl) > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*certs == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *certs = *work_cl;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *work_cl = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (move_certs(*certs, *work_cl) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval |= FOUND_CERT;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cacerts != NULL && work_ca != NULL && *work_ca != NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_X509_num(*work_ca) > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*cacerts == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *cacerts = *work_ca;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *work_ca = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (move_certs(*cacerts, *work_ca) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval |= FOUND_CA_CERTS;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (xtrakeys != NULL && work_xl != NULL && *work_xl != NULL &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sk_EVP_PKEY_num(*work_xl) > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*xtrakeys == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *xtrakeys = *work_xl;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *work_xl = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sunw_append_keys(*xtrakeys, *work_xl) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retval |= FOUND_XPKEY;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (retval);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}