sss_cert_content_crypto.c revision a20fb9cbd5f42a6ca895aea1b84347fdfea34b89
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose/*
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose SSSD - certificate handling utils - OpenSSL version
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose The calls defined here should be useable outside of SSSD as well, e.g. in
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose libsss_certmap.
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose Copyright (C) Sumit Bose <sbose@redhat.com> 2017
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose This program is free software; you can redistribute it and/or modify
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose it under the terms of the GNU General Public License as published by
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose the Free Software Foundation; either version 3 of the License, or
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose (at your option) any later version.
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose This program is distributed in the hope that it will be useful,
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose GNU General Public License for more details.
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose You should have received a copy of the GNU General Public License
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose*/
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#include "config.h"
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#include <talloc.h>
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#include <openssl/x509v3.h>
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#include <openssl/asn1.h>
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#include <openssl/asn1t.h>
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#include <openssl/err.h>
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#include <openssl/stack.h>
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#include <openssl/safestack.h>
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#include "util/crypto/sss_crypto.h"
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#include "util/cert.h"
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose#include "lib/certmap/sss_certmap.h"
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose#include "lib/certmap/sss_certmap_int.h"
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose/* backward compatible macros for OpenSSL < 1.1 */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#if OPENSSL_VERSION_NUMBER < 0x10100000L
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#define ASN1_STRING_get0_data(o) ASN1_STRING_data(o)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#define X509_get_extension_flags(o) ((o)->ex_flags)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#define X509_get_key_usage(o) ((o)->ex_kusage)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosetypedef struct PrincipalName_st {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_INTEGER *name_type;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose STACK_OF(ASN1_GENERALSTRING) *name_string;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose} PrincipalName;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit BoseASN1_SEQUENCE(PrincipalName) = {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_EXP(PrincipalName, name_type, ASN1_INTEGER, 0),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_EXP_SEQUENCE_OF(PrincipalName, name_string, ASN1_GENERALSTRING, 1)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose} ASN1_SEQUENCE_END(PrincipalName)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit BoseIMPLEMENT_ASN1_FUNCTIONS(PrincipalName)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosetypedef struct KRB5PrincipalName_st {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING *realm;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose PrincipalName *principal_name;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose} KRB5PrincipalName;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit BoseASN1_SEQUENCE(KRB5PrincipalName) = {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_EXP(KRB5PrincipalName, realm, ASN1_GENERALSTRING, 0),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_EXP(KRB5PrincipalName, principal_name, PrincipalName, 1)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose} ASN1_SEQUENCE_END(KRB5PrincipalName)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit BoseIMPLEMENT_ASN1_FUNCTIONS(KRB5PrincipalName)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Boseenum san_opt openssl_name_type_to_san_opt(int type)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose{
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose switch (type) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_OTHERNAME:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return SAN_OTHER_NAME;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_EMAIL:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return SAN_RFC822_NAME;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_DNS:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return SAN_DNS_NAME;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_X400:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return SAN_X400_ADDRESS;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_DIRNAME:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return SAN_DIRECTORY_NAME;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_EDIPARTY:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return SAN_EDIPART_NAME;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_URI:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return SAN_URI;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_IPADD:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return SAN_IP_ADDRESS;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_RID:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return SAN_REGISTERED_ID;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose default:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return SAN_INVALID;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose}
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int add_string_other_name_to_san_list(TALLOC_CTX *mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose enum san_opt san_opt,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose OTHERNAME *other_name,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list **item)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose{
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list *i = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose char oid_buf[128]; /* FIXME: any other size ?? */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int len;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose unsigned char *p;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = OBJ_obj2txt(oid_buf, sizeof(oid_buf), other_name->type_id, 1);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (len <= 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i = talloc_zero(mem_ctx, struct san_list);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->san_opt = san_opt;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->other_name_oid = talloc_strndup(i, oid_buf, len);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i->other_name_oid == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = i2d_ASN1_TYPE(other_name->value, NULL);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (len <= 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->bin_val = talloc_size(mem_ctx, len);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i->bin_val == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose /* i2d_TYPE increment the second argument so that it points to the end of
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose * the written data hence we cannot use i->bin_val directly. */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose p = i->bin_val;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->bin_val_len = i2d_ASN1_TYPE(other_name->value, &p);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = 0;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosedone:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret == 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose *item = i;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose } else {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose talloc_free(i);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose}
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int add_nt_princ_to_san_list(TALLOC_CTX *mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose enum san_opt san_opt,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose GENERAL_NAME *current,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list **item)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose{
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list *i = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose OTHERNAME *other_name = current->d.otherName;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ASN1_TYPE_get(other_name->value) != V_ASN1_UTF8STRING) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i = talloc_zero(mem_ctx, struct san_list);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->san_opt = san_opt;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->val = talloc_strndup(i,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose (const char *) ASN1_STRING_get0_data(
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose other_name->value->value.utf8string),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_length(other_name->value->value.utf8string));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i->val == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_short_name(i, i->val, '@', &(i->short_name));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = 0;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosedone:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret == 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose *item = i;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose } else {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose talloc_free(i);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose}
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosevoid *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose{
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (t == NULL || t->type != V_ASN1_SEQUENCE || t->value.sequence == NULL)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ASN1_item_unpack(t->value.sequence, it);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose}
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int add_pkinit_princ_to_san_list(TALLOC_CTX *mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose enum san_opt san_opt,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose GENERAL_NAME *current,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list **item)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose{
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list *i = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose KRB5PrincipalName *princ = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose size_t c;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const unsigned char *p;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const ASN1_STRING *oct;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_GENERALSTRING *name_comp;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose oct = current->d.otherName->value->value.sequence;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose p = oct->data;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose princ = d2i_KRB5PrincipalName(NULL, &p, oct->length);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (princ == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (princ->realm == NULL
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose || princ->principal_name == NULL
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose || princ->principal_name->name_string == NULL
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose || sk_ASN1_GENERALSTRING_num(princ->principal_name->name_string)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose == 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i = talloc_zero(mem_ctx, struct san_list);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->san_opt = san_opt;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->val = talloc_strdup(i, "");
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i->val == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose for (c = 0;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose c < sk_ASN1_GENERALSTRING_num(princ->principal_name->name_string);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose c++) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (c > 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->val = talloc_strdup_append(i->val, "/");
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i->val == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose name_comp = sk_ASN1_GENERALSTRING_value(
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose princ->principal_name->name_string, c);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->val = talloc_strndup_append(i->val,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose (const char *) ASN1_STRING_get0_data(name_comp),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_length(name_comp));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i->val == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->val = talloc_asprintf_append(i->val, "@%.*s",
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_length(princ->realm),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_get0_data(princ->realm));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i->val == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_short_name(i, i->val, '@', &(i->short_name));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = 0;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosedone:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose KRB5PrincipalName_free(princ);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret == 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose *item = i;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose } else {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose talloc_free(i);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose}
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int add_ip_to_san_list(TALLOC_CTX *mem_ctx, enum san_opt san_opt,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const uint8_t *data, size_t len,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list **item)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose{
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list *i = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i = talloc_zero(mem_ctx, struct san_list);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->san_opt = san_opt;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->val = talloc_strndup(i, (const char *) data, len);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i->val == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose talloc_free(i);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose *item = i;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return 0;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose}
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int get_rdn_list(TALLOC_CTX *mem_ctx, X509_NAME *name,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const char ***rdn_list)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose{
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose size_t c;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const char **list = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose X509_NAME_ENTRY *e;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING *rdn_str;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_OBJECT *rdn_name;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose BIO *bio_mem = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose char *tmp_str;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose long tmp_str_size;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int nid;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const char *sn;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose bio_mem = BIO_new(BIO_s_mem());
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (bio_mem == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose list = talloc_zero_array(mem_ctx, const char *,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose X509_NAME_entry_count(name) + 1);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (list == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose for (c = 0; c < X509_NAME_entry_count(name); c++) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose e = X509_NAME_get_entry(name, c);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose rdn_str = X509_NAME_ENTRY_get_data(e);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ASN1_STRING_print_ex(bio_mem, rdn_str, ASN1_STRFLGS_RFC2253);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret < 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = EIO;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose tmp_str_size = BIO_get_mem_data(bio_mem, &tmp_str);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (tmp_str_size == 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose rdn_name = X509_NAME_ENTRY_get_object(e);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose nid = OBJ_obj2nid(rdn_name);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose sn = OBJ_nid2sn(nid);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose list[c] = talloc_asprintf(list, "%s=%.*s", openssl_2_nss_attr_name(sn),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose (int) tmp_str_size, tmp_str);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = BIO_reset(bio_mem);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 1) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose /* BIO_reset() for BIO_s_mem returns 1 for sucess */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (list[c] == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = 0;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosedone:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose BIO_free_all(bio_mem);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret == 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose *rdn_list = list;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose } else {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose talloc_free(list);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose}
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int add_rdn_list_to_san_list(TALLOC_CTX *mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose enum san_opt san_opt,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose X509_NAME *name,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list **item)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose{
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list *i = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i = talloc_zero(mem_ctx, struct san_list);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->san_opt = san_opt;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_rdn_list(i, name, &(i->rdn_list));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose talloc_free(i);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose *item = i;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return 0;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose}
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int add_oid_to_san_list(TALLOC_CTX *mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose enum san_opt san_opt,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_OBJECT *oid,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list **item)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose{
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list *i = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose char oid_buf[128]; /* FIXME: any other size ?? */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int len;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = OBJ_obj2txt(oid_buf, sizeof(oid_buf), oid, 1);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (len <= 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i = talloc_zero(mem_ctx, struct san_list);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->san_opt = san_opt;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose i->val = talloc_strndup(i, oid_buf, len);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (i->val == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose talloc_free(i);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose *item = i;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return 0;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose}
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int get_san(TALLOC_CTX *mem_ctx, X509 *cert, struct san_list **san_list)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose{
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose STACK_OF(GENERAL_NAME) *extsan = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose GENERAL_NAME *current;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose size_t c;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int crit;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list *list = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list *item = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list *item_s = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list *item_p = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct san_list *item_pb = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int len;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose unsigned char *data;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose unsigned char *p;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose extsan = X509_get_ext_d2i(cert, NID_subject_alt_name, &crit, NULL);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (extsan == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (crit == -1) { /* extension could not be found */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return EOK;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose } else {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose for (c = 0; c < sk_GENERAL_NAME_num(extsan); c++) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose current = sk_GENERAL_NAME_value(extsan, c);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose switch (current->type) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_OTHERNAME:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_string_other_name_to_san_list(mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose SAN_STRING_OTHER_NAME,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose current->d.otherName,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose &item_s);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose DLIST_ADD(list, item_s);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose item_p = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (strcmp(item_s->other_name_oid, NT_PRINCIPAL_OID) == 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_nt_princ_to_san_list(mem_ctx, SAN_NT, current,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose &item_p);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose DLIST_ADD(list, item_p);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose } else if (strcmp(item_s->other_name_oid, PKINIT_OID) == 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_pkinit_princ_to_san_list(mem_ctx, SAN_PKINIT,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose current, &item_p);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose DLIST_ADD(list, item_p);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (item_p != NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_principal_to_san_list(mem_ctx, SAN_PRINCIPAL,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose item_p->val, &item_pb);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose DLIST_ADD(list, item_pb);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose break;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose break;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_EMAIL:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_to_san_list(mem_ctx, false,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose openssl_name_type_to_san_opt(current->type),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_get0_data(current->d.rfc822Name),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_length(current->d.rfc822Name),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose &item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_short_name(item, item->val, '@', &(item->short_name));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose DLIST_ADD(list, item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose break;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_DNS:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_to_san_list(mem_ctx, false,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose openssl_name_type_to_san_opt(current->type),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_get0_data(current->d.dNSName),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_length(current->d.dNSName),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose &item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_short_name(item, item->val, '.', &(item->short_name));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose DLIST_ADD(list, item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose break;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_URI:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_to_san_list(mem_ctx, false,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose openssl_name_type_to_san_opt(current->type),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_get0_data(current->d.uniformResourceIdentifier),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_length(current->d.uniformResourceIdentifier),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose &item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose break;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_IPADD:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_ip_to_san_list(mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose openssl_name_type_to_san_opt(current->type),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_get0_data(current->d.iPAddress),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ASN1_STRING_length(current->d.iPAddress),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose &item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose DLIST_ADD(list, item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose break;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_DIRNAME:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_rdn_list_to_san_list(mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose openssl_name_type_to_san_opt(current->type),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose current->d.directoryName, &item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose DLIST_ADD(list, item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose break;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_RID:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_oid_to_san_list(mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose openssl_name_type_to_san_opt(current->type),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose current->d.registeredID, &item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose DLIST_ADD(list, item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose break;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_X400:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = i2d_ASN1_TYPE(current->d.x400Address, NULL);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (len <= 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose data = talloc_size(mem_ctx, len);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (data == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose /* i2d_TYPE increment the second argument so that it points to the end of
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose * the written data hence we cannot use i->bin_val directly. */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose p = data;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = i2d_ASN1_TYPE(current->d.x400Address, &p);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_to_san_list(mem_ctx, true,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose openssl_name_type_to_san_opt(current->type),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose data, len, &item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose DLIST_ADD(list, item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose break;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose case GEN_EDIPARTY:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = i2d_EDIPARTYNAME(current->d.ediPartyName, NULL);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (len <= 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose data = talloc_size(mem_ctx, len);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (data == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose /* i2d_TYPE increment the second argument so that it points to the end of
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose * the written data hence we cannot use i->bin_val directly. */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose p = data;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = i2d_EDIPARTYNAME(current->d.ediPartyName, &data);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = add_to_san_list(mem_ctx, true,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose openssl_name_type_to_san_opt(current->type),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose data, len, &item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose DLIST_ADD(list, item);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose break;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose default:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosedone:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose GENERAL_NAMES_free(extsan);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret == EOK) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose *san_list = list;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose}
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosestatic int get_extended_key_usage_oids(TALLOC_CTX *mem_ctx,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose X509 *cert,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const char ***_oids)
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose{
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const char **oids_list = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose size_t c;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose char oid_buf[128]; /* FIXME: any other size ?? */
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int len;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose EXTENDED_KEY_USAGE *extusage = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose extusage = X509_get_ext_d2i(cert, NID_ext_key_usage, NULL, NULL);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (extusage == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return EIO;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose oids_list = talloc_zero_array(mem_ctx, const char *,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose sk_ASN1_OBJECT_num(extusage) + 1);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (oids_list == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose for (c = 0; c < sk_ASN1_OBJECT_num(extusage); c++) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose len = OBJ_obj2txt(oid_buf, sizeof(oid_buf),
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose sk_ASN1_OBJECT_value(extusage, c), 1);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (len < 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return EIO;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose oids_list[c] = talloc_strndup(oids_list, oid_buf, len);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (oids_list[c] == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = 0;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosedone:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret == 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose *_oids = oids_list;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose } else {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose talloc_free(oids_list);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose}
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Boseint sss_cert_get_content(TALLOC_CTX *mem_ctx,
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose const uint8_t *der_blob, size_t der_size,
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose struct sss_cert_content **content)
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose{
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose int ret;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose struct sss_cert_content *cont = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose X509 *cert = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose const unsigned char *der;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose BIO *bio_mem = NULL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose X509_NAME *tmp_name;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (der_blob == NULL || der_size == 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose cont = talloc_zero(mem_ctx, struct sss_cert_content);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (cont == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose bio_mem = BIO_new(BIO_s_mem());
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (bio_mem == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose der = (const unsigned char *) der_blob;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose cert = d2i_X509(NULL, &der, (int) der_size);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (cert == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose tmp_name = X509_get_issuer_name(cert);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_rdn_list(cont, tmp_name, &cont->issuer_rdn_list);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = rdn_list_2_dn_str(cont, NULL, cont->issuer_rdn_list,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose &cont->issuer_str);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose tmp_name = X509_get_subject_name(cert);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_rdn_list(cont, tmp_name, &cont->subject_rdn_list);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = rdn_list_2_dn_str(cont, NULL, cont->subject_rdn_list,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose &cont->subject_str);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = X509_check_purpose(cert, -1, -1);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret < 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = EIO;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (!(X509_get_extension_flags(cert) & EXFLAG_KUSAGE)) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = EINVAL;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose cont->key_usage = X509_get_key_usage(cert);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_extended_key_usage_oids(cont, cert,
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose &(cont->extended_key_usage_oids));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = get_san(cont, cert, &(cont->san_list));
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret != 0) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose cont->cert_der = talloc_memdup(cont, der_blob, der_size);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (cont->cert_der == NULL) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = ENOMEM;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose goto done;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose cont->cert_der_size = der_size;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose ret = EOK;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bosedone:
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose X509_free(cert);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose BIO_free_all(bio_mem);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose CRYPTO_cleanup_all_ex_data();
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose if (ret == EOK) {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose *content = cont;
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose } else {
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose talloc_free(cont);
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose }
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose
a20fb9cbd5f42a6ca895aea1b84347fdfea34b89Sumit Bose return ret;
31a6661ff2a640fbcf97460df2415fd1bab309b5Sumit Bose}