⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sslinfo.c

📁 业界著名的tomcat服务器的最新6.0的源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/** SSL info wrapper
 *
 * @author Mladen Turk
 * @version $Revision: 481766 $, $Date: 2006-12-03 13:40:18 +0100 (dim., 03 déc. 2006) $
 */

#include "tcn.h"
#include "apr_file_io.h"
#include "apr_thread_mutex.h"
#include "apr_poll.h"

#ifdef HAVE_OPENSSL
#include "ssl_private.h"

static const char *hex_basis = "0123456789ABCDEF";

static char *convert_to_hex(const void *buf, size_t len)
{
    const unsigned char *p = ( const unsigned char *)buf;
    char *str, *s;
    size_t i;

    if ((len < 1) || ((str = malloc(len * 2 + 1)) == NULL))
        return NULL;
    for (i = 0, s = str; i < len; i++) {
        unsigned char c = *p++;
        *s++ = hex_basis[c >> 4];
        *s++ = hex_basis[c & 0x0F];
    }
    *s = '\0';
    return str;
}

#define DIGIT2NUM(x) (((x)[0] - '0') * 10 + (x)[1] - '0')

static int get_days_remaining(ASN1_UTCTIME *tm)
{
    apr_time_t then, now = apr_time_now();
    apr_time_exp_t exp = {0};
    int diff;

    /* Fail if the time isn't a valid ASN.1 UTCTIME; RFC3280 mandates
     * that the seconds digits are present even though ASN.1
     * doesn't. */
    if (tm->length < 11 || !ASN1_UTCTIME_check(tm))
        return 0;

    exp.tm_year = DIGIT2NUM(tm->data);
    exp.tm_mon  = DIGIT2NUM(tm->data + 2) - 1;
    exp.tm_mday = DIGIT2NUM(tm->data + 4) + 1;
    exp.tm_hour = DIGIT2NUM(tm->data + 6);
    exp.tm_min  = DIGIT2NUM(tm->data + 8);
    exp.tm_sec  = DIGIT2NUM(tm->data + 10);

    if (exp.tm_year <= 50)
        exp.tm_year += 100;
    if (apr_time_exp_gmt_get(&then, &exp) != APR_SUCCESS)
        return 0;

    diff = (int)((apr_time_sec(then) - apr_time_sec(now)) / (60*60*24));
    return diff > 0 ? diff : 0;
}

static char *get_cert_valid(ASN1_UTCTIME *tm)
{
    char *result;
    BIO* bio;
    int n;

    if ((bio = BIO_new(BIO_s_mem())) == NULL)
        return NULL;
    ASN1_UTCTIME_print(bio, tm);
    n = BIO_pending(bio);
    result = malloc(n+1);
    n = BIO_read(bio, result, n);
    result[n] = '\0';
    BIO_free(bio);
    return result;
}

static char *get_cert_PEM(X509 *xs)
{
    char *result = NULL;
    BIO *bio;

    if ((bio = BIO_new(BIO_s_mem())) == NULL)
        return NULL;
    if (PEM_write_bio_X509(bio, xs)) {
        int n = BIO_pending(bio);
        result = malloc(n+1);
        n = BIO_read(bio, result, n);
        result[n] = '\0';
    }
    BIO_free(bio);
    return result;
}

static unsigned char *get_cert_ASN1(X509 *xs, int *len)
{
    unsigned char *result = NULL;
    BIO *bio;

    *len = 0;
    if ((bio = BIO_new(BIO_s_mem())) == NULL)
        return NULL;
    if (i2d_X509_bio(bio, xs)) {
        int n = BIO_pending(bio);
        result = malloc(n);
        n = BIO_read(bio, result, n);
        *len = n;
    }
    BIO_free(bio);
    return result;
}


static char *get_cert_serial(X509 *xs)
{
    char *result;
    BIO *bio;
    int n;

    if ((bio = BIO_new(BIO_s_mem())) == NULL)
        return NULL;
    i2a_ASN1_INTEGER(bio, X509_get_serialNumber(xs));
    n = BIO_pending(bio);
    result = malloc(n+1);
    n = BIO_read(bio, result, n);
    result[n] = '\0';
    BIO_free(bio);
    return result;
}

static const struct {
    int   fid;
    int   nid;
} info_cert_dn_rec[] = {
    { SSL_INFO_DN_COUNTRYNAME,            NID_countryName            },
    { SSL_INFO_DN_STATEORPROVINCENAME,    NID_stateOrProvinceName    },
    { SSL_INFO_DN_LOCALITYNAME,           NID_localityName           },
    { SSL_INFO_DN_ORGANIZATIONNAME,       NID_organizationName       },
    { SSL_INFO_DN_ORGANIZATIONALUNITNAME, NID_organizationalUnitName },
    { SSL_INFO_DN_COMMONNAME,             NID_commonName             },
    { SSL_INFO_DN_TITLE,                  NID_title                  },
    { SSL_INFO_DN_INITIALS,               NID_initials               },
    { SSL_INFO_DN_GIVENNAME,              NID_givenName              },
    { SSL_INFO_DN_SURNAME,                NID_surname                },
    { SSL_INFO_DN_DESCRIPTION,            NID_description            },
    { SSL_INFO_DN_UNIQUEIDENTIFIER,       NID_x500UniqueIdentifier   },
    { SSL_INFO_DN_EMAILADDRESS,           NID_pkcs9_emailAddress     },
    { 0,                                  0                          }
};

static char *lookup_ssl_cert_dn(X509_NAME *xsname, int dnidx)
{
    char *result;
    X509_NAME_ENTRY *xsne;
    int i, j, n, idx = 0;

    result = NULL;

    for (i = 0; info_cert_dn_rec[i].fid != 0; i++) {
        if (info_cert_dn_rec[i].fid == dnidx) {
            for (j = 0; j < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *)
                                                   (xsname->entries)); j++) {
                xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *)
                                                (xsname->entries), j);

                n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));
                if (n == info_cert_dn_rec[i].nid && idx-- == 0) {
                    result = malloc(xsne->value->length + 1);
                    memcpy(result, xsne->value->data,
                                   xsne->value->length);
                    result[xsne->value->length] = '\0';

#if APR_CHARSET_EBCDIC
                    ap_xlate_proto_from_ascii(result, xsne->value->length);
#endif /* APR_CHARSET_EBCDIC */
                    break;
                }
            }
            break;
        }
    }
    return result;
}

TCN_IMPLEMENT_CALL(jobject, SSLSocket, getInfoB)(TCN_STDARGS, jlong sock,
                                                 jint what)
{
    tcn_socket_t   *a = J2P(sock, tcn_socket_t *);
    tcn_ssl_conn_t *s;
    jbyteArray array = NULL;
    apr_status_t rv = APR_SUCCESS;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);

    s = (tcn_ssl_conn_t *)(a->opaque);
    switch (what) {
        case SSL_INFO_SESSION_ID:
        {
            SSL_SESSION *session  = SSL_get_session(s->ssl);
            if (session) {
                array = tcn_new_arrayb(e, &session->session_id[0],
                                       session->session_id_length);
            }
        }
        break;
        default:
            rv = APR_EINVAL;
        break;
    }
    if (what & SSL_INFO_CLIENT_MASK) {
        X509 *xs;
        unsigned char *result;
        int len;
        if ((xs = SSL_get_peer_certificate(s->ssl)) != NULL) {
            switch (what) {
                case SSL_INFO_CLIENT_CERT:
                    if ((result = get_cert_ASN1(xs, &len))) {
                        array = tcn_new_arrayb(e, result, len);
                        free(result);
                    }
                break;
            }
            X509_free(xs);
        }
        rv = APR_SUCCESS;
    }
    else if (what & SSL_INFO_SERVER_MASK) {
        X509 *xs;
        unsigned char *result;
        int len;
        if ((xs = SSL_get_certificate(s->ssl)) != NULL) {
            switch (what) {
                case SSL_INFO_SERVER_CERT:
                    if ((result = get_cert_ASN1(xs, &len))) {
                        array = tcn_new_arrayb(e, result, len);
                        free(result);
                    }
                break;
            }
            /* XXX: No need to call the X509_free(xs); */
        }
        rv = APR_SUCCESS;
    }
    else if (what & SSL_INFO_CLIENT_CERT_CHAIN) {
        X509 *xs;
        unsigned char *result;
        STACK_OF(X509) *sk =  SSL_get_peer_cert_chain(s->ssl);
        int len, n = what & 0x0F;
        if (n < sk_X509_num(sk)) {
            xs = sk_X509_value(sk, n);
            if ((result = get_cert_ASN1(xs, &len))) {
                array = tcn_new_arrayb(e, result, len);
                free(result);
            }
        }
        rv = APR_SUCCESS;
    }
    if (rv != APR_SUCCESS)
        tcn_ThrowAPRException(e, rv);

    return array;
}

TCN_IMPLEMENT_CALL(jstring, SSLSocket, getInfoS)(TCN_STDARGS, jlong sock,
                                                 jint what)
{
    tcn_socket_t   *a = J2P(sock, tcn_socket_t *);
    tcn_ssl_conn_t *s;
    jstring value = NULL;
    apr_status_t rv = APR_SUCCESS;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);

    s = (tcn_ssl_conn_t *)(a->opaque);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -