Blame snmplib/snmp_openssl.c

Packit fcad23
/*
Packit fcad23
 * snmp_openssl.c
Packit fcad23
 *
Packit fcad23
 * Portions of this file are subject to the following copyright(s).  See
Packit fcad23
 * the Net-SNMP's COPYING file for more details and other copyrights
Packit fcad23
 * that may apply:
Packit fcad23
 *
Packit fcad23
 * Portions of this file are copyrighted by:
Packit fcad23
 * Copyright (c) 2016 VMware, Inc. All rights reserved.
Packit fcad23
 * Use is subject to license terms specified in the COPYING file
Packit fcad23
 * distributed with the Net-SNMP package.
Packit fcad23
 */
Packit fcad23
Packit fcad23
#include <net-snmp/net-snmp-config.h>
Packit fcad23
Packit fcad23
#include <net-snmp/net-snmp-includes.h>
Packit fcad23
Packit fcad23
#include <net-snmp/net-snmp-features.h>
Packit fcad23
Packit fcad23
/** OpenSSL compat functions for apps */
Packit fcad23
#if defined(NETSNMP_USE_OPENSSL)
Packit fcad23
Packit fcad23
#include <string.h>
Packit fcad23
#include <openssl/dh.h>
Packit fcad23
Packit fcad23
#ifndef HAVE_DH_GET0_PQG
Packit fcad23
void
Packit fcad23
DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
Packit fcad23
{
Packit fcad23
   if (p != NULL)
Packit fcad23
       *p = dh->p;
Packit fcad23
   if (q != NULL)
Packit fcad23
       *q = dh->q;
Packit fcad23
   if (g != NULL)
Packit fcad23
       *g = dh->g;
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifndef HAVE_DH_GET0_KEY
Packit fcad23
void
Packit fcad23
DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
Packit fcad23
{
Packit fcad23
   if (pub_key != NULL)
Packit fcad23
       *pub_key = dh->pub_key;
Packit fcad23
   if (priv_key != NULL)
Packit fcad23
       *priv_key = dh->priv_key;
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifndef HAVE_DH_SET0_PQG
Packit fcad23
int
Packit fcad23
DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
Packit fcad23
{
Packit fcad23
   /* If the fields p and g in d are NULL, the corresponding input
Packit fcad23
    * parameters MUST be non-NULL.  q may remain NULL.
Packit fcad23
    */
Packit fcad23
   if ((dh->p == NULL && p == NULL)
Packit fcad23
       || (dh->g == NULL && g == NULL))
Packit fcad23
       return 0;
Packit fcad23
Packit fcad23
   if (p != NULL) {
Packit fcad23
       BN_free(dh->p);
Packit fcad23
       dh->p = p;
Packit fcad23
   }
Packit fcad23
   if (q != NULL) {
Packit fcad23
       BN_free(dh->q);
Packit fcad23
       dh->q = q;
Packit fcad23
   }
Packit fcad23
   if (g != NULL) {
Packit fcad23
       BN_free(dh->g);
Packit fcad23
       dh->g = g;
Packit fcad23
   }
Packit fcad23
Packit fcad23
   if (q != NULL) {
Packit fcad23
       dh->length = BN_num_bits(q);
Packit fcad23
   }
Packit fcad23
Packit fcad23
   return 1;
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
#endif /* defined(NETSNMP_USE_OPENSSL) */
Packit fcad23
Packit fcad23
/** TLS/DTLS certificatte support */
Packit fcad23
#if defined(NETSNMP_USE_OPENSSL) && defined(HAVE_LIBSSL) && !defined(NETSNMP_FEATURE_REMOVE_CERT_UTIL)
Packit fcad23
Packit fcad23
netsnmp_feature_require(container_free_all)
Packit fcad23
Packit fcad23
netsnmp_feature_child_of(openssl_cert_get_subjectAltNames, netsnmp_unused)
Packit fcad23
netsnmp_feature_child_of(openssl_ht2nid, netsnmp_unused)
Packit fcad23
netsnmp_feature_child_of(openssl_err_log, netsnmp_unused)
Packit fcad23
netsnmp_feature_child_of(cert_dump_names, netsnmp_unused)
Packit fcad23
Packit fcad23
#include <ctype.h>
Packit fcad23
Packit fcad23
#include <openssl/evp.h>
Packit fcad23
#include <openssl/ssl.h>
Packit fcad23
#include <openssl/x509.h>
Packit fcad23
#include <openssl/x509v3.h>
Packit fcad23
#include <openssl/err.h>
Packit fcad23
#include <openssl/objects.h>
Packit fcad23
Packit fcad23
#include <net-snmp/library/snmp_debug.h>
Packit fcad23
#include <net-snmp/library/cert_util.h>
Packit fcad23
#include <net-snmp/library/snmp_openssl.h>
Packit fcad23
Packit fcad23
static u_char have_started_already = 0;
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * This code merely does openssl initialization so that multilpe
Packit fcad23
 * modules are safe to call netsnmp_init_openssl() for bootstrapping
Packit fcad23
 * without worrying about other callers that may have already done so.
Packit fcad23
 */
Packit fcad23
void netsnmp_init_openssl(void) {
Packit fcad23
Packit fcad23
    /* avoid duplicate calls */
Packit fcad23
    if (have_started_already)
Packit fcad23
        return;
Packit fcad23
    have_started_already = 1;
Packit fcad23
Packit fcad23
    DEBUGMSGTL(("snmp_openssl", "initializing\n"));
Packit fcad23
Packit fcad23
    /* Initializing OpenSSL */
Packit fcad23
#ifdef HAVE_SSL_LIBRARY_INIT
Packit fcad23
    SSL_library_init();
Packit fcad23
#endif
Packit fcad23
#ifdef HAVE_SSL_LOAD_ERROR_STRINGS
Packit fcad23
    SSL_load_error_strings();
Packit fcad23
#endif
Packit fcad23
    ERR_load_BIO_strings();
Packit fcad23
    OpenSSL_add_all_algorithms();
Packit fcad23
}
Packit fcad23
Packit fcad23
/** netsnmp_openssl_cert_get_name: get subject name field from cert
Packit fcad23
 * @internal
Packit fcad23
 */
Packit fcad23
/** instead of exposing this function, make helper functions for each
Packit fcad23
 * field, like netsnmp_openssl_cert_get_commonName, below */
Packit fcad23
static char *
Packit fcad23
_cert_get_name(X509 *ocert, int which, char **buf, int *len, int flags)
Packit fcad23
{
Packit fcad23
    X509_NAME       *osubj_name;
Packit fcad23
    int              space;
Packit fcad23
    char            *buf_ptr;
Packit fcad23
Packit fcad23
    if ((NULL == ocert) || ((buf && !len) || (len && !buf)))
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    osubj_name = X509_get_subject_name(ocert);
Packit fcad23
    if (NULL == osubj_name) {
Packit fcad23
        DEBUGMSGT(("openssl:cert:name", "no subject name!\n"));
Packit fcad23
        return NULL;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /** see if buf is big enough, or allocate buf if none specified */
Packit fcad23
    space = X509_NAME_get_text_by_NID(osubj_name, which, NULL, 0);
Packit fcad23
    if (-1 == space)
Packit fcad23
        return NULL;
Packit fcad23
    ++space; /* for NUL */
Packit fcad23
    if (buf && *buf) {
Packit fcad23
        if (*len < space)
Packit fcad23
            return NULL;
Packit fcad23
        buf_ptr = *buf;
Packit fcad23
    }
Packit fcad23
    else {
Packit fcad23
        buf_ptr = calloc(1,space);
Packit fcad23
        if (!buf_ptr)
Packit fcad23
            return NULL;
Packit fcad23
    }
Packit fcad23
    space = X509_NAME_get_text_by_NID(osubj_name, which, buf_ptr, space);
Packit fcad23
    if (len)
Packit fcad23
        *len = space;
Packit fcad23
Packit fcad23
    return buf_ptr;
Packit fcad23
}
Packit fcad23
Packit fcad23
/** netsnmp_openssl_cert_get_subjectName: get subject name field from cert
Packit fcad23
 */
Packit fcad23
char *
Packit fcad23
netsnmp_openssl_cert_get_subjectName(X509 *ocert, char **buf, int *len)
Packit fcad23
{
Packit fcad23
    X509_NAME       *osubj_name;
Packit fcad23
    int              space;
Packit fcad23
    char            *buf_ptr;
Packit fcad23
Packit fcad23
    if ((NULL == ocert) || ((buf && !len) || (len && !buf)))
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    osubj_name = X509_get_subject_name(ocert);
Packit fcad23
    if (NULL == osubj_name) {
Packit fcad23
        DEBUGMSGT(("openssl:cert:name", "no subject name!\n"));
Packit fcad23
        return NULL;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    if (buf) {
Packit fcad23
        buf_ptr = *buf;
Packit fcad23
        space = *len;
Packit fcad23
    }
Packit fcad23
    else {
Packit fcad23
        buf_ptr = NULL;
Packit fcad23
        space = 0;
Packit fcad23
    }
Packit fcad23
    buf_ptr = X509_NAME_oneline(osubj_name, buf_ptr, space);
Packit fcad23
    if (len)
Packit fcad23
        *len = strlen(buf_ptr);
Packit fcad23
Packit fcad23
    return buf_ptr;
Packit fcad23
}
Packit fcad23
Packit fcad23
/** netsnmp_openssl_cert_get_commonName: get commonName for cert.
Packit fcad23
 * if a pointer to a buffer and its length are specified, they will be
Packit fcad23
 * used. otherwise, a new buffer will be allocated, which the caller will
Packit fcad23
 * be responsbile for releasing.
Packit fcad23
 */
Packit fcad23
char *
Packit fcad23
netsnmp_openssl_cert_get_commonName(X509 *ocert, char **buf, int *len)
Packit fcad23
{
Packit fcad23
    return _cert_get_name(ocert, NID_commonName, buf, len, 0);
Packit fcad23
}
Packit fcad23
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_CERT_DUMP_NAMES
Packit fcad23
Packit fcad23
/** netsnmp_openssl_cert_dump_name: dump subject names in cert
Packit fcad23
 */
Packit fcad23
void
Packit fcad23
netsnmp_openssl_cert_dump_names(X509 *ocert)
Packit fcad23
{
Packit fcad23
    int              i, onid;
Packit fcad23
    X509_NAME_ENTRY *oname_entry;
Packit fcad23
    ASN1_STRING     *oname_value;
Packit fcad23
    X509_NAME       *osubj_name;
Packit fcad23
    const char      *prefix_short, *prefix_long;
Packit fcad23
Packit fcad23
    if (NULL == ocert)
Packit fcad23
        return;
Packit fcad23
Packit fcad23
    osubj_name = X509_get_subject_name(ocert);
Packit fcad23
    if (NULL == osubj_name) {
Packit fcad23
        DEBUGMSGT(("9:cert:dump:names", "no subject name!\n"));
Packit fcad23
        return;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    for (i = 0; i < X509_NAME_entry_count(osubj_name); i++) {
Packit fcad23
        oname_entry = X509_NAME_get_entry(osubj_name, i);
Packit fcad23
        netsnmp_assert(NULL != oname_entry);
Packit fcad23
        oname_value = X509_NAME_ENTRY_get_data(oname_entry);
Packit fcad23
Packit fcad23
        if (oname_value->type != V_ASN1_PRINTABLESTRING)
Packit fcad23
            continue;
Packit fcad23
Packit fcad23
        /** get NID */
Packit fcad23
        onid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(oname_entry));
Packit fcad23
        if (onid == NID_undef) {
Packit fcad23
            prefix_long = prefix_short = "UNKNOWN";
Packit fcad23
        }
Packit fcad23
        else {
Packit fcad23
            prefix_long = OBJ_nid2ln(onid);
Packit fcad23
            prefix_short = OBJ_nid2sn(onid);
Packit fcad23
        }
Packit fcad23
Packit fcad23
        DEBUGMSGT(("9:cert:dump:names",
Packit fcad23
                   "[%02d] NID type %d, ASN type %d\n", i, onid,
Packit fcad23
                   oname_value->type));
Packit fcad23
        DEBUGMSGT(("9:cert:dump:names", "%s/%s: '%s'\n", prefix_long,
Packit fcad23
                   prefix_short, ASN1_STRING_get0_data(oname_value)));
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_CERT_DUMP_NAMES */
Packit fcad23
Packit fcad23
static char *
Packit fcad23
_cert_get_extension(X509_EXTENSION  *oext, char **buf, int *len, int flags)
Packit fcad23
{
Packit fcad23
    int              space;
Packit fcad23
    char            *buf_ptr = NULL;
Packit fcad23
    u_char          *data;
Packit fcad23
    BIO             *bio;
Packit fcad23
    
Packit fcad23
    if ((NULL == oext) || ((buf && !len) || (len && !buf)))
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    bio = BIO_new(BIO_s_mem());
Packit fcad23
    if (NULL == bio) {
Packit fcad23
        snmp_log(LOG_ERR, "could not get bio for extension\n");
Packit fcad23
        return NULL;
Packit fcad23
    }
Packit fcad23
    if (X509V3_EXT_print(bio, oext, 0, 0) != 1) {
Packit fcad23
        snmp_log(LOG_ERR, "could not print extension!\n");
Packit fcad23
        BIO_vfree(bio);
Packit fcad23
        return NULL;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    space = BIO_get_mem_data(bio, &data);
Packit fcad23
    if (buf && *buf) {
Packit fcad23
        if (*len < space) 
Packit fcad23
            buf_ptr = NULL;
Packit fcad23
        else
Packit fcad23
            buf_ptr = *buf;
Packit fcad23
    }
Packit fcad23
    else
Packit fcad23
        buf_ptr = calloc(1,space + 1);
Packit fcad23
    
Packit fcad23
    if (!buf_ptr) {
Packit fcad23
        snmp_log(LOG_ERR,
Packit fcad23
                 "not enough space or error in allocation for extenstion\n");
Packit fcad23
        BIO_vfree(bio);
Packit fcad23
        return NULL;
Packit fcad23
    }
Packit fcad23
    memcpy(buf_ptr, data, space);
Packit fcad23
    buf_ptr[space] = 0;
Packit fcad23
    if (len)
Packit fcad23
        *len = space;
Packit fcad23
Packit fcad23
    BIO_vfree(bio);
Packit fcad23
Packit fcad23
    return buf_ptr;
Packit fcad23
}
Packit fcad23
Packit fcad23
/** netsnmp_openssl_cert_get_extension: get extension field from cert
Packit fcad23
 * @internal
Packit fcad23
 */
Packit fcad23
/** instead of exposing this function, make helper functions for each
Packit fcad23
 * field, like netsnmp_openssl_cert_get_subjectAltName, below */
Packit fcad23
X509_EXTENSION  *
Packit fcad23
_cert_get_extension_at(X509 *ocert, int pos, char **buf, int *len, int flags)
Packit fcad23
{
Packit fcad23
    X509_EXTENSION  *oext;
Packit fcad23
Packit fcad23
    if ((NULL == ocert) || ((buf && !len) || (len && !buf)))
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    oext = X509_get_ext(ocert,pos);
Packit fcad23
    if (NULL == oext) {
Packit fcad23
        snmp_log(LOG_ERR, "extension number %d not found!\n", pos);
Packit fcad23
        netsnmp_openssl_cert_dump_extensions(ocert);
Packit fcad23
        return NULL;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    return oext;
Packit fcad23
}
Packit fcad23
Packit fcad23
/** netsnmp_openssl_cert_get_extension: get extension field from cert
Packit fcad23
 * @internal
Packit fcad23
 */
Packit fcad23
/** instead of exposing this function, make helper functions for each
Packit fcad23
 * field, like netsnmp_openssl_cert_get_subjectAltName, below */
Packit fcad23
static char *
Packit fcad23
_cert_get_extension_str_at(X509 *ocert, int pos, char **buf, int *len,
Packit fcad23
                           int flags)
Packit fcad23
{
Packit fcad23
    X509_EXTENSION  *oext;
Packit fcad23
Packit fcad23
    if ((NULL == ocert) || ((buf && !len) || (len && !buf)))
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    oext = X509_get_ext(ocert,pos);
Packit fcad23
    if (NULL == oext) {
Packit fcad23
        snmp_log(LOG_ERR, "extension number %d not found!\n", pos);
Packit fcad23
        netsnmp_openssl_cert_dump_extensions(ocert);
Packit fcad23
        return NULL;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    return _cert_get_extension(oext, buf, len, flags);
Packit fcad23
}
Packit fcad23
Packit fcad23
/** _cert_get_extension_id: get extension field from cert
Packit fcad23
 * @internal
Packit fcad23
 */
Packit fcad23
/** instead of exposing this function, make helper functions for each
Packit fcad23
 * field, like netsnmp_openssl_cert_get_subjectAltName, below */
Packit fcad23
X509_EXTENSION *
Packit fcad23
_cert_get_extension_id(X509 *ocert, int which, char **buf, int *len, int flags)
Packit fcad23
{
Packit fcad23
    int pos;
Packit fcad23
Packit fcad23
    if ((NULL == ocert) || ((buf && !len) || (len && !buf)))
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    pos = X509_get_ext_by_NID(ocert,which,-1);
Packit fcad23
    if (pos < 0) {
Packit fcad23
        DEBUGMSGT(("openssl:cert:name", "no extension %d\n", which));
Packit fcad23
        return NULL;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    return _cert_get_extension_at(ocert, pos, buf, len, flags);
Packit fcad23
}
Packit fcad23
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_OPENSSL_CERT_GET_SUBJECTALTNAMES
Packit fcad23
/** _cert_get_extension_id_str: get extension field from cert
Packit fcad23
 * @internal
Packit fcad23
 */
Packit fcad23
/** instead of exposing this function, make helper functions for each
Packit fcad23
 * field, like netsnmp_openssl_cert_get_subjectAltName, below */
Packit fcad23
static char *
Packit fcad23
_cert_get_extension_id_str(X509 *ocert, int which, char **buf, int *len,
Packit fcad23
                           int flags)
Packit fcad23
{
Packit fcad23
    int pos;
Packit fcad23
Packit fcad23
    if ((NULL == ocert) || ((buf && !len) || (len && !buf)))
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    pos = X509_get_ext_by_NID(ocert,which,-1);
Packit fcad23
    if (pos < 0) {
Packit fcad23
        DEBUGMSGT(("openssl:cert:name", "no extension %d\n", which));
Packit fcad23
        return NULL;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    return _cert_get_extension_str_at(ocert, pos, buf, len, flags);
Packit fcad23
}
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_OPENSSL_CERT_GET_SUBJECTALTNAMES */
Packit fcad23
Packit fcad23
static char *
Packit fcad23
_extract_oname(const GENERAL_NAME *oname)
Packit fcad23
{
Packit fcad23
    char  ipbuf[60], *buf = NULL, *rtn = NULL;
Packit fcad23
Packit fcad23
    if (NULL == oname)
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    switch ( oname->type ) {
Packit fcad23
        case GEN_EMAIL:
Packit fcad23
        case GEN_DNS:
Packit fcad23
            /*case GEN_URI:*/
Packit fcad23
            ASN1_STRING_to_UTF8((unsigned char**)&buf, oname->d.ia5);
Packit fcad23
            if (buf)
Packit fcad23
                rtn = strdup(buf);
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case GEN_IPADD:
Packit fcad23
            if (oname->d.iPAddress->length == 4) {
Packit fcad23
                sprintf(ipbuf, "%d.%d.%d.%d", oname->d.iPAddress->data[0],
Packit fcad23
                        oname->d.iPAddress->data[1],
Packit fcad23
                        oname->d.iPAddress->data[2],
Packit fcad23
                        oname->d.iPAddress->data[3]);
Packit fcad23
                rtn = strdup(ipbuf);
Packit fcad23
            }
Packit fcad23
            else if ((oname->d.iPAddress->length == 16) ||
Packit fcad23
                     (oname->d.iPAddress->length == 20)) {
Packit fcad23
                char *pos = ipbuf;
Packit fcad23
                int   j;
Packit fcad23
                for(j = 0; j < oname->d.iPAddress->length; ++j) {
Packit fcad23
                    *pos++ = VAL2HEX(oname->d.iPAddress->data[j]);
Packit fcad23
                    *pos++ = ':';
Packit fcad23
                }
Packit fcad23
                *pos = '\0';
Packit fcad23
                rtn = strdup(ipbuf);
Packit fcad23
            }
Packit fcad23
            else
Packit fcad23
                NETSNMP_LOGONCE((LOG_WARNING, "unexpected ip addr length %d\n",
Packit fcad23
                       oname->d.iPAddress->length));
Packit fcad23
Packit fcad23
            break;
Packit fcad23
        default:
Packit fcad23
            DEBUGMSGT(("openssl:cert:san", "unknown/unsupported type %d\n",
Packit fcad23
                       oname->type));
Packit fcad23
            break;
Packit fcad23
    }
Packit fcad23
    DEBUGMSGT(("9:openssl:cert:san", "san=%s\n", buf));
Packit fcad23
    if (buf)
Packit fcad23
        OPENSSL_free(buf);
Packit fcad23
Packit fcad23
    return rtn;
Packit fcad23
}
Packit fcad23
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_OPENSSL_CERT_GET_SUBJECTALTNAMES
Packit fcad23
/** netsnmp_openssl_cert_get_subjectAltName: get subjectAltName for cert.
Packit fcad23
 * if a pointer to a buffer and its length are specified, they will be
Packit fcad23
 * used. otherwise, a new buffer will be allocated, which the caller will
Packit fcad23
 * be responsbile for releasing.
Packit fcad23
 */
Packit fcad23
char *
Packit fcad23
netsnmp_openssl_cert_get_subjectAltNames(X509 *ocert, char **buf, int *len)
Packit fcad23
{
Packit fcad23
    return _cert_get_extension_id_str(ocert, NID_subject_alt_name, buf, len, 0);
Packit fcad23
}
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_OPENSSL_CERT_GET_SUBJECTALTNAMES */
Packit fcad23
Packit fcad23
void
Packit fcad23
netsnmp_openssl_cert_dump_extensions(X509 *ocert)
Packit fcad23
{
Packit fcad23
    X509_EXTENSION  *extension;
Packit fcad23
    const char      *extension_name;
Packit fcad23
    char             buf[SNMP_MAXBUF_SMALL], *buf_ptr = buf, *str, *lf;
Packit fcad23
    int              i, num_extensions, buf_len, nid;
Packit fcad23
Packit fcad23
    if (NULL == ocert)
Packit fcad23
        return;
Packit fcad23
Packit fcad23
    DEBUGIF("9:cert:dump") 
Packit fcad23
        ;
Packit fcad23
    else
Packit fcad23
        return; /* bail if debug not enabled */
Packit fcad23
Packit fcad23
    num_extensions = X509_get_ext_count(ocert);
Packit fcad23
    if (0 == num_extensions)
Packit fcad23
        DEBUGMSGT(("9:cert:dump", "    0 extensions\n"));
Packit fcad23
    for(i = 0; i < num_extensions; i++) {
Packit fcad23
        extension = X509_get_ext(ocert, i);
Packit fcad23
        nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));
Packit fcad23
        extension_name = OBJ_nid2sn(nid);
Packit fcad23
        buf_len = sizeof(buf);
Packit fcad23
        str = _cert_get_extension_str_at(ocert, i, &buf_ptr, &buf_len, 0);
Packit fcad23
        lf = strchr(str, '\n'); /* look for multiline strings */
Packit fcad23
        if (NULL != lf)
Packit fcad23
            *lf = '\0'; /* only log first line of multiline here */
Packit fcad23
        DEBUGMSGT(("9:cert:dump", "    %2d: %s = %s\n", i,
Packit fcad23
                   extension_name, str));
Packit fcad23
        while(lf) { /* log remaining parts of multiline string */
Packit fcad23
            str = ++lf;
Packit fcad23
            if (*str == '\0')
Packit fcad23
               break;
Packit fcad23
            lf = strchr(str, '\n');
Packit fcad23
            if (NULL == lf) 
Packit fcad23
                break;
Packit fcad23
            *lf = '\0';
Packit fcad23
            DEBUGMSGT(("9:cert:dump", "        %s\n", str));
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
Packit fcad23
static int _htmap[NS_HASH_MAX + 1] = {
Packit fcad23
    0, NID_md5WithRSAEncryption, NID_sha1WithRSAEncryption,
Packit fcad23
    NID_sha224WithRSAEncryption, NID_sha256WithRSAEncryption,
Packit fcad23
    NID_sha384WithRSAEncryption, NID_sha512WithRSAEncryption };
Packit fcad23
Packit fcad23
int
Packit fcad23
_nid2ht(int nid)
Packit fcad23
{
Packit fcad23
    int i;
Packit fcad23
    for (i=1; i<= NS_HASH_MAX; ++i) {
Packit fcad23
        if (nid == _htmap[i])
Packit fcad23
            return i;
Packit fcad23
    }
Packit fcad23
    return 0;
Packit fcad23
}
Packit fcad23
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_OPENSSL_HT2NID
Packit fcad23
int
Packit fcad23
_ht2nid(int ht)
Packit fcad23
{
Packit fcad23
    if ((ht < 0) || (ht > NS_HASH_MAX))
Packit fcad23
        return 0;
Packit fcad23
    return _htmap[ht];
Packit fcad23
}
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_OPENSSL_HT2NID */
Packit fcad23
Packit fcad23
/**
Packit fcad23
 * returns allocated pointer caller must free.
Packit fcad23
 */
Packit fcad23
int
Packit fcad23
netsnmp_openssl_cert_get_hash_type(X509 *ocert)
Packit fcad23
{
Packit fcad23
    if (NULL == ocert)
Packit fcad23
        return 0;
Packit fcad23
Packit fcad23
    return _nid2ht(X509_get_signature_nid(ocert));
Packit fcad23
}
Packit fcad23
Packit fcad23
/**
Packit fcad23
 * returns allocated pointer caller must free.
Packit fcad23
 */
Packit fcad23
char *
Packit fcad23
netsnmp_openssl_cert_get_fingerprint(X509 *ocert, int alg)
Packit fcad23
{
Packit fcad23
    u_char           fingerprint[EVP_MAX_MD_SIZE];
Packit fcad23
    u_int            fingerprint_len, nid;
Packit fcad23
    const EVP_MD    *digest;
Packit fcad23
    char            *result = NULL;
Packit fcad23
Packit fcad23
    if (NULL == ocert)
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    nid = X509_get_signature_nid(ocert);
Packit fcad23
    DEBUGMSGT(("9:openssl:fingerprint", "alg %d, cert nid %d (%d)\n", alg, nid,
Packit fcad23
               _nid2ht(nid)));
Packit fcad23
        
Packit fcad23
    if ((-1 == alg) && nid)
Packit fcad23
        alg = _nid2ht(nid);
Packit fcad23
Packit fcad23
    switch (alg) {
Packit fcad23
        case NS_HASH_MD5:
Packit fcad23
            snmp_log(LOG_ERR, "hash type md5 not yet supported\n");
Packit fcad23
            return NULL;
Packit fcad23
            break;
Packit fcad23
        
Packit fcad23
        case NS_HASH_NONE:
Packit fcad23
            snmp_log(LOG_ERR, "hash type none not supported. using SHA1\n");
Packit fcad23
            /* FALLTHROUGH */
Packit fcad23
Packit fcad23
        case NS_HASH_SHA1:
Packit fcad23
            digest = EVP_sha1();
Packit fcad23
            break;
Packit fcad23
Packit fcad23
#ifdef HAVE_EVP_SHA224
Packit fcad23
        case NS_HASH_SHA224:
Packit fcad23
            digest = EVP_sha224();
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case NS_HASH_SHA256:
Packit fcad23
            digest = EVP_sha256();
Packit fcad23
            break;
Packit fcad23
Packit fcad23
#endif
Packit fcad23
#ifdef HAVE_EVP_SHA384
Packit fcad23
        case NS_HASH_SHA384:
Packit fcad23
            digest = EVP_sha384();
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case NS_HASH_SHA512:
Packit fcad23
            digest = EVP_sha512();
Packit fcad23
            break;
Packit fcad23
#endif
Packit fcad23
Packit fcad23
        default:
Packit fcad23
            snmp_log(LOG_ERR, "unknown hash algorithm %d\n", alg);
Packit fcad23
            return NULL;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    if (_nid2ht(nid) != alg) {
Packit fcad23
        DEBUGMSGT(("openssl:fingerprint",
Packit fcad23
                   "WARNING: alg %d does not match cert alg %d\n",
Packit fcad23
                   alg, _nid2ht(nid)));
Packit fcad23
    }
Packit fcad23
    if (X509_digest(ocert,digest,fingerprint,&fingerprint_len)) {
Packit fcad23
        binary_to_hex(fingerprint, fingerprint_len, &result);
Packit fcad23
        if (NULL == result)
Packit fcad23
            snmp_log(LOG_ERR, "failed to hexify fingerprint\n");
Packit fcad23
        else
Packit fcad23
            DEBUGMSGT(("9:openssl:fingerprint", "fingerprint %s\n", result));
Packit fcad23
    }
Packit fcad23
    else
Packit fcad23
        snmp_log(LOG_ERR,"failed to compute fingerprint\n");
Packit fcad23
Packit fcad23
    return result;
Packit fcad23
}
Packit fcad23
Packit fcad23
/**
Packit fcad23
 * get container of netsnmp_cert_map structures from an ssl connection
Packit fcad23
 * certificate chain.
Packit fcad23
 */
Packit fcad23
netsnmp_container *
Packit fcad23
netsnmp_openssl_get_cert_chain(SSL *ssl)
Packit fcad23
{
Packit fcad23
    X509                  *ocert, *ocert_tmp;
Packit fcad23
    STACK_OF(X509)        *ochain;
Packit fcad23
    char                  *fingerprint;
Packit fcad23
    netsnmp_container     *chain_map;
Packit fcad23
    netsnmp_cert_map      *cert_map;
Packit fcad23
    int                    i;
Packit fcad23
Packit fcad23
    netsnmp_assert_or_return(ssl != NULL, NULL);
Packit fcad23
    
Packit fcad23
    if (NULL == (ocert = SSL_get_peer_certificate(ssl))) {
Packit fcad23
        /** no peer cert */
Packit fcad23
        snmp_log(LOG_ERR, "SSL peer has no certificate\n");
Packit fcad23
        return NULL;
Packit fcad23
    }
Packit fcad23
    DEBUGIF("9:cert:dump") {
Packit fcad23
        netsnmp_openssl_cert_dump_extensions(ocert);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * get fingerprint and save it
Packit fcad23
     */
Packit fcad23
    fingerprint = netsnmp_openssl_cert_get_fingerprint(ocert, -1);
Packit fcad23
    if (NULL == fingerprint)
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * allocate cert map. Don't pass in fingerprint, since it would strdup
Packit fcad23
     * it and we've already got a copy.
Packit fcad23
     */
Packit fcad23
    cert_map = netsnmp_cert_map_alloc(NULL, ocert);
Packit fcad23
    if (NULL == cert_map) {
Packit fcad23
        free(fingerprint);
Packit fcad23
        return NULL;
Packit fcad23
    }
Packit fcad23
    cert_map->fingerprint = fingerprint;
Packit fcad23
    cert_map->hashType = netsnmp_openssl_cert_get_hash_type(ocert);
Packit fcad23
Packit fcad23
    chain_map = netsnmp_cert_map_container_create(0); /* no fp subcontainer */
Packit fcad23
    if (NULL == chain_map) {
Packit fcad23
        netsnmp_cert_map_free(cert_map);
Packit fcad23
        return NULL;
Packit fcad23
    }
Packit fcad23
    
Packit fcad23
    CONTAINER_INSERT(chain_map, cert_map);
Packit fcad23
Packit fcad23
    /** check for a chain to a CA */
Packit fcad23
    ochain = SSL_get_peer_cert_chain(ssl);
Packit fcad23
    if ((NULL == ochain) || (0 == sk_num((const void *)ochain))) {
Packit fcad23
        DEBUGMSGT(("ssl:cert:chain", "peer has no cert chain\n"));
Packit fcad23
    }
Packit fcad23
    else {
Packit fcad23
        /*
Packit fcad23
         * loop over chain, adding fingerprint / cert for each
Packit fcad23
         */
Packit fcad23
        DEBUGMSGT(("ssl:cert:chain", "examining cert chain\n"));
Packit fcad23
        for(i = 0; i < sk_num((const void *)ochain); ++i) {
Packit fcad23
            ocert_tmp = (X509*)sk_value((const void *)ochain,i);
Packit fcad23
            fingerprint = netsnmp_openssl_cert_get_fingerprint(ocert_tmp,
Packit fcad23
                                                               NS_HASH_SHA1);
Packit fcad23
            if (NULL == fingerprint)
Packit fcad23
                break;
Packit fcad23
            cert_map = netsnmp_cert_map_alloc(NULL, ocert);
Packit fcad23
            if (NULL == cert_map) {
Packit fcad23
                free(fingerprint);
Packit fcad23
                break;
Packit fcad23
            }
Packit fcad23
            cert_map->fingerprint = fingerprint;
Packit fcad23
            cert_map->hashType = netsnmp_openssl_cert_get_hash_type(ocert_tmp);
Packit fcad23
Packit fcad23
            CONTAINER_INSERT(chain_map, cert_map);
Packit fcad23
        } /* chain loop */
Packit fcad23
        /*
Packit fcad23
         * if we broke out of loop before finishing, clean up
Packit fcad23
         */
Packit fcad23
        if (i < sk_num((const void *)ochain)) 
Packit fcad23
            CONTAINER_FREE_ALL(chain_map, NULL);
Packit fcad23
    } /* got peer chain */
Packit fcad23
Packit fcad23
    DEBUGMSGT(("ssl:cert:chain", "found %" NETSNMP_PRIz "u certs in chain\n",
Packit fcad23
               CONTAINER_SIZE(chain_map)));
Packit fcad23
    if (CONTAINER_SIZE(chain_map) == 0) {
Packit fcad23
        CONTAINER_FREE(chain_map);
Packit fcad23
        chain_map = NULL;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    return chain_map;
Packit fcad23
}
Packit fcad23
Packit fcad23
/*
Packit fcad23
tlstmCertSANRFC822Name "Maps a subjectAltName's rfc822Name to a
Packit fcad23
                  tmSecurityName.  The local part of the rfc822Name is
Packit fcad23
                  passed unaltered but the host-part of the name must
Packit fcad23
                  be passed in lower case.
Packit fcad23
                  Example rfc822Name Field:  FooBar@Example.COM
Packit fcad23
                  is mapped to tmSecurityName: FooBar@example.com"
Packit fcad23
Packit fcad23
tlstmCertSANDNSName "Maps a subjectAltName's dNSName to a
Packit fcad23
                  tmSecurityName after first converting it to all
Packit fcad23
                  lower case."
Packit fcad23
Packit fcad23
tlstmCertSANIpAddress "Maps a subjectAltName's iPAddress to a
Packit fcad23
                  tmSecurityName by transforming the binary encoded
Packit fcad23
                  address as follows:
Packit fcad23
                  1) for IPv4 the value is converted into a decimal
Packit fcad23
                     dotted quad address (e.g. '192.0.2.1')
Packit fcad23
                  2) for IPv6 addresses the value is converted into a
Packit fcad23
                     32-character all lowercase hexadecimal string
Packit fcad23
                     without any colon separators.
Packit fcad23
Packit fcad23
                     Note that the resulting length is the maximum
Packit fcad23
                     length supported by the View-Based Access Control
Packit fcad23
                     Model (VACM).  Note that using both the Transport
Packit fcad23
                     Security Model's support for transport prefixes
Packit fcad23
                     (see the SNMP-TSM-MIB's
Packit fcad23
                     snmpTsmConfigurationUsePrefix object for details)
Packit fcad23
                     will result in securityName lengths that exceed
Packit fcad23
                     what VACM can handle."
Packit fcad23
Packit fcad23
tlstmCertSANAny "Maps any of the following fields using the
Packit fcad23
                  corresponding mapping algorithms:
Packit fcad23
                  | rfc822Name | tlstmCertSANRFC822Name |
Packit fcad23
                  | dNSName    | tlstmCertSANDNSName    |
Packit fcad23
                  | iPAddress  | tlstmCertSANIpAddress  |
Packit fcad23
                  The first matching subjectAltName value found in the
Packit fcad23
                  certificate of the above types MUST be used when
Packit fcad23
                  deriving the tmSecurityName."
Packit fcad23
*/
Packit fcad23
char *
Packit fcad23
_cert_get_san_type(X509 *ocert, int mapType)
Packit fcad23
{
Packit fcad23
    GENERAL_NAMES      *onames;
Packit fcad23
    const GENERAL_NAME *oname = NULL;
Packit fcad23
    char               *buf = NULL, *lower = NULL;
Packit fcad23
    int                 count, i;
Packit fcad23
 
Packit fcad23
    onames = (GENERAL_NAMES *)X509_get_ext_d2i(ocert, NID_subject_alt_name,
Packit fcad23
                                               NULL, NULL );
Packit fcad23
    if (NULL == onames)
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    count = sk_GENERAL_NAME_num(onames);
Packit fcad23
Packit fcad23
    for (i=0 ; i 
Packit fcad23
        oname = sk_GENERAL_NAME_value(onames, i);
Packit fcad23
Packit fcad23
        if (GEN_DNS == oname->type) {
Packit fcad23
            if ((TSNM_tlstmCertSANDNSName == mapType) ||
Packit fcad23
                (TSNM_tlstmCertSANAny == mapType)) {
Packit fcad23
                lower = buf = _extract_oname( oname );
Packit fcad23
                break;
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
        else if (GEN_IPADD == oname->type) {
Packit fcad23
            if ((TSNM_tlstmCertSANIpAddress == mapType) ||
Packit fcad23
                (TSNM_tlstmCertSANAny == mapType)) {
Packit fcad23
                buf = _extract_oname(oname);
Packit fcad23
                break;
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
        else if (GEN_EMAIL == oname->type) {
Packit fcad23
            if ((TSNM_tlstmCertSANRFC822Name == mapType) ||
Packit fcad23
                (TSNM_tlstmCertSANAny == mapType)) {
Packit fcad23
                buf = _extract_oname(oname);
Packit fcad23
                lower = strchr(buf, '@');
Packit fcad23
                if (NULL == lower) {
Packit fcad23
                    DEBUGMSGT(("openssl:secname:extract",
Packit fcad23
                               "email %s has no '@'!\n", buf));
Packit fcad23
                }
Packit fcad23
                else {
Packit fcad23
                    ++lower;
Packit fcad23
                    break;
Packit fcad23
                }
Packit fcad23
            }
Packit fcad23
            
Packit fcad23
        }
Packit fcad23
    } /* for loop */
Packit fcad23
Packit fcad23
    if (lower)
Packit fcad23
        for ( ; *lower; ++lower )
Packit fcad23
            if (isascii(*lower))
Packit fcad23
                *lower = tolower(0xFF & *lower);
Packit fcad23
    DEBUGMSGT(("openssl:cert:extension:san", "#%d type %d: %s\n", i,
Packit fcad23
               oname ? oname->type : -1, buf ? buf : "NULL"));
Packit fcad23
Packit fcad23
    return buf;
Packit fcad23
}
Packit fcad23
Packit fcad23
char *
Packit fcad23
netsnmp_openssl_extract_secname(netsnmp_cert_map *cert_map,
Packit fcad23
                                netsnmp_cert_map *peer_cert)
Packit fcad23
{
Packit fcad23
    char       *rtn = NULL;
Packit fcad23
Packit fcad23
    if (NULL == cert_map)
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    DEBUGMSGT(("openssl:secname:extract",
Packit fcad23
               "checking priority %d, san of type %d for %s\n",
Packit fcad23
               cert_map->priority, cert_map->mapType, peer_cert->fingerprint));
Packit fcad23
Packit fcad23
    switch(cert_map->mapType) {
Packit fcad23
        case TSNM_tlstmCertSpecified:
Packit fcad23
            rtn = strdup(cert_map->data);
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case TSNM_tlstmCertSANRFC822Name:
Packit fcad23
        case TSNM_tlstmCertSANDNSName:
Packit fcad23
        case TSNM_tlstmCertSANIpAddress:
Packit fcad23
        case TSNM_tlstmCertSANAny:
Packit fcad23
            if (NULL == peer_cert) {
Packit fcad23
                DEBUGMSGT(("openssl:secname:extract", "no peer cert for %s\n",
Packit fcad23
                           cert_map->fingerprint));
Packit fcad23
                break;
Packit fcad23
            }
Packit fcad23
            rtn = _cert_get_san_type(peer_cert->ocert, cert_map->mapType);
Packit fcad23
            if (NULL == rtn) {
Packit fcad23
                DEBUGMSGT(("openssl:secname:extract", "no san for %s\n",
Packit fcad23
                           peer_cert->fingerprint));
Packit fcad23
            }
Packit fcad23
            break;
Packit fcad23
Packit fcad23
        case TSNM_tlstmCertCommonName:
Packit fcad23
            rtn = netsnmp_openssl_cert_get_commonName(cert_map->ocert, NULL,
Packit fcad23
                                                       NULL);
Packit fcad23
            break;
Packit fcad23
        default:
Packit fcad23
            snmp_log(LOG_ERR, "cant extract secname for unknown map type %d\n",
Packit fcad23
                     cert_map->mapType);
Packit fcad23
            break;
Packit fcad23
    } /* switch mapType */
Packit fcad23
Packit fcad23
    if (rtn) {
Packit fcad23
        DEBUGMSGT(("openssl:secname:extract",
Packit fcad23
                   "found map %d, type %d for %s: %s\n", cert_map->priority,
Packit fcad23
                   cert_map->mapType, peer_cert->fingerprint, rtn));
Packit fcad23
        if (strlen(rtn) >32) {
Packit fcad23
            DEBUGMSGT(("openssl:secname:extract",
Packit fcad23
                       "secName longer than 32 chars! dropping...\n"));
Packit fcad23
            SNMP_FREE(rtn);
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
    else
Packit fcad23
        DEBUGMSGT(("openssl:secname:extract",
Packit fcad23
                   "no map of type %d for %s\n",
Packit fcad23
                   cert_map->mapType, peer_cert->fingerprint));
Packit fcad23
    return rtn;
Packit fcad23
}
Packit fcad23
Packit fcad23
int
Packit fcad23
netsnmp_openssl_cert_issued_by(X509 *issuer, X509 *cert)
Packit fcad23
{
Packit fcad23
    return (X509_check_issued(issuer, cert) == X509_V_OK);
Packit fcad23
}
Packit fcad23
Packit fcad23
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_OPENSSL_ERR_LOG
Packit fcad23
void
Packit fcad23
netsnmp_openssl_err_log(const char *prefix)
Packit fcad23
{
Packit fcad23
    unsigned long err;
Packit fcad23
    for (err = ERR_get_error(); err; err = ERR_get_error()) {
Packit fcad23
        snmp_log(LOG_ERR,"%s: %ld\n", prefix ? prefix: "openssl error", err);
Packit fcad23
        snmp_log(LOG_ERR, "library=%d, function=%d, reason=%d\n",
Packit fcad23
                 ERR_GET_LIB(err), ERR_GET_FUNC(err), ERR_GET_REASON(err));
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_OPENSSL_ERR_LOG */
Packit fcad23
Packit fcad23
void
Packit fcad23
netsnmp_openssl_null_checks(SSL *ssl, int *null_auth, int *null_cipher)
Packit fcad23
{
Packit fcad23
    const SSL_CIPHER *cipher;
Packit fcad23
    char           tmp_buf[128], *cipher_alg, *auth_alg;
Packit fcad23
Packit fcad23
    if (null_auth)
Packit fcad23
        *null_auth = -1; /* unknown */
Packit fcad23
    if (null_cipher)
Packit fcad23
        *null_cipher = -1; /* unknown */
Packit fcad23
    if (NULL == ssl)
Packit fcad23
        return;
Packit fcad23
Packit fcad23
    cipher = SSL_get_current_cipher(ssl);
Packit fcad23
    if (NULL == cipher) {
Packit fcad23
        DEBUGMSGTL(("ssl:cipher", "no cipher yet\n"));
Packit fcad23
        return;
Packit fcad23
    }
Packit fcad23
    SSL_CIPHER_description(NETSNMP_REMOVE_CONST(SSL_CIPHER *, cipher), tmp_buf, sizeof(tmp_buf));
Packit fcad23
    /** no \n since tmp_buf already has one */
Packit fcad23
    DEBUGMSGTL(("ssl:cipher", "current cipher: %s", tmp_buf));
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * run "openssl ciphers -v eNULL" and "openssl ciphers -v aNULL"
Packit fcad23
     * to see NULL encryption/authentication algorithms. e.g.
Packit fcad23
     *
Packit fcad23
     * EXP-ADH-RC4-MD5 SSLv3 Kx=DH(512) Au=None Enc=RC4(40) Mac=MD5  export
Packit fcad23
     * NULL-SHA        SSLv3 Kx=RSA     Au=RSA  Enc=None    Mac=SHA1
Packit fcad23
     */
Packit fcad23
    if (null_cipher) {
Packit fcad23
        cipher_alg = strstr(tmp_buf, "Enc=");
Packit fcad23
        if (cipher_alg) {
Packit fcad23
            cipher_alg += 4;
Packit fcad23
            if (strncmp(cipher_alg,"None", 4) == 0)
Packit fcad23
                *null_cipher = 1;
Packit fcad23
            else
Packit fcad23
                *null_cipher = 0;
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
    if (null_auth) {
Packit fcad23
        auth_alg = strstr(tmp_buf, "Au=");
Packit fcad23
        if (auth_alg) {
Packit fcad23
            auth_alg += 3;
Packit fcad23
            if (strncmp(auth_alg,"None", 4) == 0)
Packit fcad23
                *null_auth = 1;
Packit fcad23
            else
Packit fcad23
                *null_auth = 0;
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
Packit fcad23
#ifndef HAVE_X509_GET_SIGNATURE_NID
Packit fcad23
int X509_get_signature_nid(const X509 *x)
Packit fcad23
{
Packit fcad23
    return OBJ_obj2nid(x->sig_alg->algorithm);
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifndef HAVE_ASN1_STRING_GET0_DATA
Packit fcad23
const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x)
Packit fcad23
{
Packit fcad23
    return x->data;
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifndef HAVE_X509_NAME_ENTRY_GET_OBJECT
Packit fcad23
ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne)
Packit fcad23
{
Packit fcad23
    if (ne == NULL)
Packit fcad23
        return NULL;
Packit fcad23
    return ne->object;
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifndef HAVE_X509_NAME_ENTRY_GET_DATA
Packit fcad23
ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne)
Packit fcad23
{
Packit fcad23
    if (ne == NULL)
Packit fcad23
        return NULL;
Packit fcad23
    return ne->value;
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifndef HAVE_TLS_METHOD
Packit fcad23
const SSL_METHOD *TLS_method(void)
Packit fcad23
{
Packit fcad23
    return TLSv1_method();
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifndef HAVE_DTLS_METHOD
Packit fcad23
const SSL_METHOD *DTLS_method(void)
Packit fcad23
{
Packit fcad23
    return DTLSv1_method();
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#endif /* NETSNMP_USE_OPENSSL && HAVE_LIBSSL && !defined(NETSNMP_FEATURE_REMOVE_CERT_UTIL) */