2 Star 1 Fork 0

TappaT/clixon-libevhtp

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
sslutils.c 11.57 KB
一键复制 编辑 原始数据 按行查看 历史
Olof hagsand 提交于 2021-03-31 10:57 . Fixed include files for building
#ifdef HAVE_CONFIG_H
#include "libevhtp-config.h" /* generated by config & autoconf */
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <assert.h>
#include "internal.h"
#include "evhtp/evhtp.h"
#include "evhtp/sslutils.h"
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define X509_get0_notBefore(x) X509_get_notBefore(x)
#define X509_get0_notAfter(x) X509_get_notAfter(x)
#endif
unsigned char *
htp_sslutil_subject_tostr(evhtp_ssl_t * ssl) {
unsigned char * subj_str;
char * p;
X509 * cert;
X509_NAME * name;
if (!ssl) {
return NULL;
}
if (!(cert = SSL_get_peer_certificate(ssl))) {
return NULL;
}
if (!(name = X509_get_subject_name(cert))) {
X509_free(cert);
return NULL;
}
if (!(p = X509_NAME_oneline(name, NULL, 0))) {
X509_free(cert);
return NULL;
}
subj_str = (unsigned char *)strdup(p);
OPENSSL_free(p);
X509_free(cert);
return subj_str;
}
unsigned char *
htp_sslutil_issuer_tostr(evhtp_ssl_t * ssl) {
X509 * cert;
X509_NAME * name;
char * p;
unsigned char * issr_str;
if (!ssl) {
return NULL;
}
if (!(cert = SSL_get_peer_certificate(ssl))) {
return NULL;
}
if (!(name = X509_get_issuer_name(cert))) {
X509_free(cert);
return NULL;
}
if (!(p = X509_NAME_oneline(name, NULL, 0))) {
X509_free(cert);
return NULL;
}
issr_str = (unsigned char *)strdup(p);
OPENSSL_free(p);
X509_free(cert);
return issr_str;
}
unsigned char *
htp_sslutil_notbefore_tostr(evhtp_ssl_t * ssl) {
BIO * bio;
X509 * cert;
const ASN1_TIME * time;
size_t len;
unsigned char * time_str;
if (!ssl) {
return NULL;
}
if (!(cert = SSL_get_peer_certificate(ssl))) {
return NULL;
}
if (!(time = X509_get0_notBefore(cert))) {
X509_free(cert);
return NULL;
}
if (!(bio = BIO_new(BIO_s_mem()))) {
X509_free(cert);
return NULL;
}
if (!ASN1_TIME_print(bio, time)) {
BIO_free(bio);
X509_free(cert);
return NULL;
}
if ((len = BIO_pending(bio)) == 0) {
BIO_free(bio);
X509_free(cert);
return NULL;
}
if (!(time_str = calloc(len + 1, 1))) {
return NULL;
}
BIO_read(bio, time_str, len);
BIO_free(bio);
X509_free(cert);
return time_str;
} /* htp_sslutil_notbefore_tostr */
unsigned char *
htp_sslutil_notafter_tostr(evhtp_ssl_t * ssl) {
BIO * bio;
X509 * cert;
const ASN1_TIME * time;
size_t len;
unsigned char * time_str;
if (!ssl) {
return NULL;
}
if (!(cert = SSL_get_peer_certificate(ssl))) {
return NULL;
}
if (!(time = X509_get0_notAfter(cert))) {
X509_free(cert);
return NULL;
}
if (!(bio = BIO_new(BIO_s_mem()))) {
X509_free(cert);
return NULL;
}
if (!ASN1_TIME_print(bio, time)) {
BIO_free(bio);
X509_free(cert);
return NULL;
}
if ((len = BIO_pending(bio)) == 0) {
BIO_free(bio);
X509_free(cert);
return NULL;
}
if (!(time_str = calloc(len + 1, 1))) {
return NULL;
}
BIO_read(bio, time_str, len);
BIO_free(bio);
X509_free(cert);
return time_str;
} /* htp_sslutil_notafter_tostr */
unsigned char *
htp_sslutil_sha1_tostr(evhtp_ssl_t * ssl) {
const EVP_MD * md_alg;
X509 * cert;
unsigned int n;
unsigned char md[EVP_MAX_MD_SIZE];
unsigned char * buf = NULL;
size_t offset;
size_t nsz;
int sz;
int i;
if (!ssl) {
return NULL;
}
md_alg = EVP_sha1();
if (!md_alg) {
return NULL;
}
if (!(cert = SSL_get_peer_certificate(ssl))) {
return NULL;
}
n = 0;
if (!X509_digest(cert, md_alg, md, &n)) {
return NULL;
}
nsz = 3 * n + 1;
buf = (unsigned char *)calloc(nsz, 1);
if (buf) {
offset = 0;
for (i = 0; i < n; i++) {
sz = snprintf((char*)buf + offset, nsz - offset, "%02X%c", md[i], (i + 1 == n) ? 0 : ':');
offset += sz;
if (sz < 0 || offset >= nsz) {
free(buf);
buf = NULL;
break;
}
}
}
X509_free(cert);
return buf;
} /* htp_sslutil_sha1_tostr */
unsigned char *
htp_sslutil_serial_tostr(evhtp_ssl_t * ssl) {
BIO * bio;
X509 * cert;
size_t len;
unsigned char * ser_str;
if (!ssl) {
return NULL;
}
if (!(cert = SSL_get_peer_certificate(ssl))) {
return NULL;
}
if (!(bio = BIO_new(BIO_s_mem()))) {
X509_free(cert);
return NULL;
}
i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert));
if ((len = BIO_pending(bio)) == 0) {
BIO_free(bio);
X509_free(cert);
return NULL;
}
if (!(ser_str = calloc(len + 1, 1))) {
return NULL;
}
BIO_read(bio, ser_str, len);
X509_free(cert);
BIO_free(bio);
return ser_str;
} /* htp_sslutil_serial_tostr */
unsigned char *
htp_sslutil_cipher_tostr(evhtp_ssl_t * ssl) {
const SSL_CIPHER * cipher;
const char * p;
unsigned char * cipher_str;
if (!ssl) {
return NULL;
}
if (!(cipher = SSL_get_current_cipher(ssl))) {
return NULL;
}
if (!(p = SSL_CIPHER_get_name(cipher))) {
return NULL;
}
cipher_str = (unsigned char *)strdup(p);
return cipher_str;
}
unsigned char *
htp_sslutil_cert_tostr(evhtp_ssl_t * ssl) {
X509 * cert;
BIO * bio;
unsigned char * raw_cert_str;
unsigned char * cert_str;
unsigned char * p;
size_t raw_cert_len;
size_t cert_len;
int i;
if (!ssl) {
return NULL;
}
if (!(cert = SSL_get_peer_certificate(ssl))) {
return NULL;
}
if (!(bio = BIO_new(BIO_s_mem()))) {
X509_free(cert);
return NULL;
}
if (!PEM_write_bio_X509(bio, cert)) {
BIO_free(bio);
X509_free(cert);
return NULL;
}
raw_cert_len = BIO_pending(bio);
raw_cert_str = calloc(raw_cert_len + 1, 1);
BIO_read(bio, raw_cert_str, raw_cert_len);
cert_len = raw_cert_len - 1;
for (i = 0; i < raw_cert_len - 1; i++) {
if (raw_cert_str[i] == '\n') {
/*
* \n's will be converted to \r\n\t, so we must reserve
* enough space for that much data.
*/
cert_len += 2;
}
}
/* 2 extra chars, one for possible last char (if not '\n'), and one for NULL terminator */
cert_str = calloc(cert_len + 2, 1);
p = cert_str;
for (i = 0; i < raw_cert_len - 1; i++) {
if (raw_cert_str[i] == '\n') {
*p++ = '\r';
*p++ = '\n';
*p++ = '\t';
} else {
*p++ = raw_cert_str[i];
}
}
/* Don't assume last character is '\n' */
if (raw_cert_str[i] != '\n') {
*p++ = raw_cert_str[i];
}
BIO_free(bio);
X509_free(cert);
free(raw_cert_str);
return cert_str;
} /* htp_sslutil_cert_tostr */
unsigned char *
htp_sslutil_x509_ext_tostr(evhtp_ssl_t * ssl, const char * oid) {
unsigned char * ext_str;
X509 * cert;
ASN1_OBJECT * oid_obj;
int oid_pos;
X509_EXTENSION * ext;
ASN1_OCTET_STRING * octet;
const unsigned char * octet_data;
long xlen;
int xtag;
int xclass;
if (!ssl) {
return NULL;
}
if (!(cert = SSL_get_peer_certificate(ssl))) {
return NULL;
}
if (!(oid_obj = OBJ_txt2obj(oid, 1))) {
X509_free(cert);
return NULL;
}
ext_str = NULL;
oid_pos = X509_get_ext_by_OBJ(cert, oid_obj, -1);
if (!(ext = X509_get_ext(cert, oid_pos))) {
ASN1_OBJECT_free(oid_obj);
X509_free(cert);
return NULL;
}
if (!(octet = X509_EXTENSION_get_data(ext))) {
ASN1_OBJECT_free(oid_obj);
X509_free(cert);
return NULL;
}
octet_data = octet->data;
if (ASN1_get_object(&octet_data, &xlen, &xtag, &xclass, octet->length)) {
ASN1_OBJECT_free(oid_obj);
X509_free(cert);
return NULL;
}
/* We're only supporting string data. Could optionally add support
* for encoded binary data */
if (xlen > 0 && xtag == 0x0C && octet->type == V_ASN1_OCTET_STRING) {
ext_str = (unsigned char *)strndup((const char *)octet_data, xlen);
}
ASN1_OBJECT_free(oid_obj);
X509_free(cert);
return ext_str;
} /* htp_sslutil_x509_ext_tostr */
int
htp_sslutil_verify2opts(const char * opts_str) {
if (!opts_str || !strcasecmp(opts_str, "off")) {
return SSL_VERIFY_NONE;
}
if (!strcasecmp(opts_str, "optional")) {
return SSL_VERIFY_PEER;
}
if (!strcasecmp(opts_str, "on")) {
return SSL_VERIFY_PEER
| SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
}
return -1;
}
int
htp_sslutil_add_xheaders(evhtp_headers_t * hdrs, evhtp_ssl_t * ssl, short flags) {
int i;
if (!hdrs || !ssl) {
return -1;
}
struct {
const char * hdr_str;
short flag;
unsigned char * (* convfn)(evhtp_ssl_t *);
} ssl_x_hdrs_[] = {
{ "X-SSL-Subject", HTP_SSLUTILS_XHDR_SUBJ, htp_sslutil_subject_tostr },
{ "X-SSL-Issuer", HTP_SSLUTILS_XHDR_ISSR, htp_sslutil_issuer_tostr },
{ "X-SSL-Notbefore", HTP_SSLUTILS_XHDR_NBFR, htp_sslutil_notbefore_tostr },
{ "X-SSL-Notafter", HTP_SSLUTILS_XHDR_NAFR, htp_sslutil_notafter_tostr },
{ "X-SSL-Serial", HTP_SSLUTILS_XHDR_SERL, htp_sslutil_serial_tostr },
{ "X-SSL-Cipher", HTP_SSLUTILS_XHDR_CIPH, htp_sslutil_cipher_tostr },
{ "X-SSL-Certificate", HTP_SSLUTILS_XHDR_CERT, htp_sslutil_cert_tostr },
{ "X-SSL-SHA1", HTP_SSLUTILS_XHDR_SHA1, htp_sslutil_sha1_tostr },
{ NULL, 0, NULL }
};
/* remove all of the current x- headers if present */
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Subject"));
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Issuer"));
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Notbefore"));
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Notafter"));
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Serial"));
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Cipher"));
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Certificate"));
if (flags == 0) {
return 0;
}
/* iterate over our ssl_x_hdrs_ struct array, compare the flags,
* and if a xhdr flag is set, run the proper *_tostr function and
* append it to the `hdrs` passed to this function.
*/
for (i = 0; ssl_x_hdrs_[i].hdr_str; i++) {
char * o_str = NULL;
if (flags & ssl_x_hdrs_[i].flag) {
if ((o_str = (char*)(ssl_x_hdrs_[i].convfn)(ssl))) {
evhtp_headers_add_header(
hdrs,
evhtp_header_new(ssl_x_hdrs_[i].hdr_str, o_str, 0, 1));
evhtp_safe_free(o_str, free);
}
}
}
return 0;
} /* htp_sslutil_add_xheaders */
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/TappaT/clixon-libevhtp.git
git@gitee.com:TappaT/clixon-libevhtp.git
TappaT
clixon-libevhtp
clixon-libevhtp
master

搜索帮助