mirror of
https://github.com/sonertari/SSLproxy
synced 2024-11-18 03:25:31 +00:00
Refactored -w/-W and improved docs
This commit is contained in:
parent
11f6742bff
commit
6ec6c56ded
59
main.c
59
main.c
@ -115,10 +115,10 @@ main_usage(void)
|
|||||||
" -k pemfile use CA key (and cert) from pemfile to sign forged certs\n"
|
" -k pemfile use CA key (and cert) from pemfile to sign forged certs\n"
|
||||||
" -C pemfile use CA chain from pemfile (intermediate and root CA certs)\n"
|
" -C pemfile use CA chain from pemfile (intermediate and root CA certs)\n"
|
||||||
" -K pemfile use key from pemfile for leaf certs (default: generate)\n"
|
" -K pemfile use key from pemfile for leaf certs (default: generate)\n"
|
||||||
" -w gendir write generated key/cert pairs to gendir\n"
|
|
||||||
" -W gendir same as -w but also write the original cert\n"
|
|
||||||
" -t certdir use cert+chain+key PEM files from certdir to target all sites\n"
|
" -t certdir use cert+chain+key PEM files from certdir to target all sites\n"
|
||||||
" matching the common names (non-matching: generate if CA)\n"
|
" matching the common names (non-matching: generate if CA)\n"
|
||||||
|
" -w gendir write leaf key and only generated certificates to gendir\n"
|
||||||
|
" -W gendir write leaf key and all certificates to gendir\n"
|
||||||
" -O deny all OCSP requests on all proxyspecs\n"
|
" -O deny all OCSP requests on all proxyspecs\n"
|
||||||
" -P passthrough SSL connections if they cannot be split because of\n"
|
" -P passthrough SSL connections if they cannot be split because of\n"
|
||||||
" client cert auth or no matching cert and no CA (default: drop)\n"
|
" client cert auth or no matching cert and no CA (default: drop)\n"
|
||||||
@ -618,7 +618,7 @@ main(int argc, char *argv[])
|
|||||||
free(rhs);
|
free(rhs);
|
||||||
break;
|
break;
|
||||||
case 'W':
|
case 'W':
|
||||||
opts->writeorig = 1;
|
opts->certgen_writeall = 1;
|
||||||
if (opts->certgendir)
|
if (opts->certgendir)
|
||||||
free(opts->certgendir);
|
free(opts->certgendir);
|
||||||
opts->certgendir = strdup(optarg);
|
opts->certgendir = strdup(optarg);
|
||||||
@ -626,7 +626,7 @@ main(int argc, char *argv[])
|
|||||||
oom_die(argv0);
|
oom_die(argv0);
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
opts->writeorig = 0;
|
opts->certgen_writeall = 0;
|
||||||
if (opts->certgendir)
|
if (opts->certgendir)
|
||||||
free(opts->certgendir);
|
free(opts->certgendir);
|
||||||
opts->certgendir = strdup(optarg);
|
opts->certgendir = strdup(optarg);
|
||||||
@ -669,11 +669,6 @@ main(int argc, char *argv[])
|
|||||||
argv0);
|
argv0);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (opts->certgendir && opts->key) {
|
|
||||||
fprintf(stderr, "%s: -K and -w are mutually exclusive.\n",
|
|
||||||
argv0);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
if (!opts->spec) {
|
if (!opts->spec) {
|
||||||
fprintf(stderr, "%s: no proxyspec specified.\n", argv0);
|
fprintf(stderr, "%s: no proxyspec specified.\n", argv0);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@ -771,27 +766,37 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opts->certgendir) {
|
if (opts->certgendir) {
|
||||||
unsigned char *keyfpr = malloc(SSL_KEY_IDSZ);
|
char *keyid, *keyfn;
|
||||||
if(ssl_key_identifier_sha1(opts->key, keyfpr)) {
|
int prv;
|
||||||
fprintf(stderr, "%s: error generating RSA fingerprint\n", argv0);
|
FILE *keyf;
|
||||||
|
|
||||||
|
keyid = ssl_key_identifier(opts->key, 0);
|
||||||
|
if (!keyid) {
|
||||||
|
fprintf(stderr, "%s: error generating key id\n", argv0);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
char *keyfn;
|
|
||||||
asprintf(&keyfn, "%s/%02X%02X%02X%02X%02X%02X%02X%02X%02X"
|
prv = asprintf(&keyfn, "%s/%s.key", opts->certgendir, keyid);
|
||||||
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X.key",
|
if (prv == -1) {
|
||||||
opts->certgendir,
|
fprintf(stderr, "%s: %s (%i)\n", argv0,
|
||||||
keyfpr[0], keyfpr[1], keyfpr[2], keyfpr[3], keyfpr[4],
|
strerror(errno), errno);
|
||||||
keyfpr[5], keyfpr[6], keyfpr[7], keyfpr[8], keyfpr[9],
|
exit(EXIT_FAILURE);
|
||||||
keyfpr[10], keyfpr[11], keyfpr[12], keyfpr[13], keyfpr[14],
|
|
||||||
keyfpr[15], keyfpr[16], keyfpr[17], keyfpr[18], keyfpr[19]);
|
|
||||||
FILE *keyfd = fopen(keyfn,"w");
|
|
||||||
if (!keyfd) {
|
|
||||||
log_err_printf("Failed to open '%s' for writing: %s\n",
|
|
||||||
keyfn, strerror(errno));
|
|
||||||
} else {
|
|
||||||
PEM_write_PrivateKey(keyfd, opts->key, NULL, 0, 0, NULL, NULL);
|
|
||||||
fclose(keyfd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(keyf = fopen(keyfn, "w"))) {
|
||||||
|
fprintf(stderr, "%s: Failed to open '%s' for writing: "
|
||||||
|
"%s (%i)\n", argv0, keyfn,
|
||||||
|
strerror(errno), errno);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (!PEM_write_PrivateKey(keyf, opts->key, NULL, 0, 0,
|
||||||
|
NULL, NULL)) {
|
||||||
|
fprintf(stderr, "%s: Failed to write key to '%s': "
|
||||||
|
"%s (%i)\n", argv0, keyfn,
|
||||||
|
strerror(errno), errno);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
fclose(keyf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* usage checks after defaults */
|
/* usage checks after defaults */
|
||||||
|
4
opts.h
4
opts.h
@ -80,7 +80,9 @@ typedef struct opts {
|
|||||||
#ifdef HAVE_LOCAL_PROCINFO
|
#ifdef HAVE_LOCAL_PROCINFO
|
||||||
unsigned int lprocinfo : 1;
|
unsigned int lprocinfo : 1;
|
||||||
#endif /* HAVE_LOCAL_PROCINFO */
|
#endif /* HAVE_LOCAL_PROCINFO */
|
||||||
|
unsigned int certgen_writeall: 1;
|
||||||
char *ciphers;
|
char *ciphers;
|
||||||
|
char *certgendir;
|
||||||
char *tgcrtdir;
|
char *tgcrtdir;
|
||||||
char *dropuser;
|
char *dropuser;
|
||||||
char *dropgroup;
|
char *dropgroup;
|
||||||
@ -101,8 +103,6 @@ typedef struct opts {
|
|||||||
char *ecdhcurve;
|
char *ecdhcurve;
|
||||||
#endif /* !OPENSSL_NO_ECDH */
|
#endif /* !OPENSSL_NO_ECDH */
|
||||||
proxyspec_t *spec;
|
proxyspec_t *spec;
|
||||||
char *certgendir;
|
|
||||||
unsigned int writeorig: 1;
|
|
||||||
} opts_t;
|
} opts_t;
|
||||||
|
|
||||||
opts_t *opts_new(void) MALLOC;
|
opts_t *opts_new(void) MALLOC;
|
||||||
|
188
pxyconn.c
188
pxyconn.c
@ -40,6 +40,7 @@
|
|||||||
#include "attrib.h"
|
#include "attrib.h"
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -120,6 +121,7 @@ typedef struct pxy_conn_ctx {
|
|||||||
|
|
||||||
/* status flags */
|
/* status flags */
|
||||||
unsigned int immutable_cert : 1; /* 1 if the cert cannot be changed */
|
unsigned int immutable_cert : 1; /* 1 if the cert cannot be changed */
|
||||||
|
unsigned int generated_cert : 1; /* 1 if we generated a new cert */
|
||||||
unsigned int connected : 1; /* 0 until both ends are connected */
|
unsigned int connected : 1; /* 0 until both ends are connected */
|
||||||
unsigned int seen_req_header : 1; /* 0 until request header complete */
|
unsigned int seen_req_header : 1; /* 0 until request header complete */
|
||||||
unsigned int seen_resp_header : 1; /* 0 until response hdr complete */
|
unsigned int seen_resp_header : 1; /* 0 until response hdr complete */
|
||||||
@ -147,8 +149,10 @@ typedef struct pxy_conn_ctx {
|
|||||||
char *http_status_text;
|
char *http_status_text;
|
||||||
char *http_content_length;
|
char *http_content_length;
|
||||||
|
|
||||||
/* log strings from SSL context */
|
/* log strings related to SSL */
|
||||||
char *ssl_names;
|
char *ssl_names;
|
||||||
|
char *origcrtfpr;
|
||||||
|
char *usedcrtfpr;
|
||||||
|
|
||||||
#ifdef HAVE_LOCAL_PROCINFO
|
#ifdef HAVE_LOCAL_PROCINFO
|
||||||
/* local process information */
|
/* local process information */
|
||||||
@ -167,8 +171,6 @@ typedef struct pxy_conn_ctx {
|
|||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
int af;
|
int af;
|
||||||
X509 *origcrt;
|
X509 *origcrt;
|
||||||
char *origfpr[SSL_X509_FPRSZ*2+1];
|
|
||||||
char *newfpr[SSL_X509_FPRSZ*2+1];
|
|
||||||
|
|
||||||
/* references to event base and configuration */
|
/* references to event base and configuration */
|
||||||
struct event_base *evbase;
|
struct event_base *evbase;
|
||||||
@ -211,9 +213,7 @@ pxy_conn_ctx_new(proxyspec_t *spec, opts_t *opts,
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void NONNULL(1)
|
||||||
pxy_conn_ctx_free(pxy_conn_ctx_t *ctx) NONNULL(1);
|
|
||||||
static void
|
|
||||||
pxy_conn_ctx_free(pxy_conn_ctx_t *ctx)
|
pxy_conn_ctx_free(pxy_conn_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_PROXY
|
#ifdef DEBUG_PROXY
|
||||||
@ -253,6 +253,12 @@ pxy_conn_ctx_free(pxy_conn_ctx_t *ctx)
|
|||||||
if (ctx->ssl_names) {
|
if (ctx->ssl_names) {
|
||||||
free(ctx->ssl_names);
|
free(ctx->ssl_names);
|
||||||
}
|
}
|
||||||
|
if (ctx->origcrtfpr) {
|
||||||
|
free(ctx->origcrtfpr);
|
||||||
|
}
|
||||||
|
if (ctx->usedcrtfpr) {
|
||||||
|
free(ctx->usedcrtfpr);
|
||||||
|
}
|
||||||
#ifdef HAVE_LOCAL_PROCINFO
|
#ifdef HAVE_LOCAL_PROCINFO
|
||||||
if (ctx->lproc.exec_path) {
|
if (ctx->lproc.exec_path) {
|
||||||
free(ctx->lproc.exec_path);
|
free(ctx->lproc.exec_path);
|
||||||
@ -314,17 +320,11 @@ pxy_debug_crt(X509 *crt)
|
|||||||
free(names);
|
free(names);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char fpr[SSL_X509_FPRSZ];
|
char *fpr;
|
||||||
if (ssl_x509_fingerprint_sha1(crt, fpr) == -1) {
|
if (!(fpr = ssl_x509_fingerprint(crt, 1))) {
|
||||||
log_err_printf("Warning: Error generating X509 fingerprint\n");
|
log_err_printf("Warning: Error generating X509 fingerprint\n");
|
||||||
} else {
|
} else {
|
||||||
log_dbg_printf("Fingerprint: " "%02x:%02x:%02x:%02x:"
|
log_dbg_printf("Fingerprint: %s\n", fpr);
|
||||||
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:"
|
|
||||||
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
||||||
fpr[0], fpr[1], fpr[2], fpr[3], fpr[4],
|
|
||||||
fpr[5], fpr[6], fpr[7], fpr[8], fpr[9],
|
|
||||||
fpr[10], fpr[11], fpr[12], fpr[13], fpr[14],
|
|
||||||
fpr[15], fpr[16], fpr[17], fpr[18], fpr[19]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_CERTIFICATE
|
#ifdef DEBUG_CERTIFICATE
|
||||||
@ -375,11 +375,12 @@ pxy_log_connect_nonhttp(pxy_conn_ctx_t *ctx)
|
|||||||
} else {
|
} else {
|
||||||
rv = asprintf(&msg, "ssl %s %s "
|
rv = asprintf(&msg, "ssl %s %s "
|
||||||
"sni:%s names:%s "
|
"sni:%s names:%s "
|
||||||
"sproto:%s:%s dproto:%s:%s"
|
"sproto:%s:%s dproto:%s:%s "
|
||||||
|
"origcrt:%s usedcrt:%s"
|
||||||
#ifdef HAVE_LOCAL_PROCINFO
|
#ifdef HAVE_LOCAL_PROCINFO
|
||||||
" %s"
|
" %s"
|
||||||
#endif /* HAVE_LOCAL_PROCINFO */
|
#endif /* HAVE_LOCAL_PROCINFO */
|
||||||
" %s %s\n",
|
"\n",
|
||||||
STRORDASH(ctx->src_str),
|
STRORDASH(ctx->src_str),
|
||||||
STRORDASH(ctx->dst_str),
|
STRORDASH(ctx->dst_str),
|
||||||
STRORDASH(ctx->sni),
|
STRORDASH(ctx->sni),
|
||||||
@ -387,13 +388,13 @@ pxy_log_connect_nonhttp(pxy_conn_ctx_t *ctx)
|
|||||||
SSL_get_version(ctx->src.ssl),
|
SSL_get_version(ctx->src.ssl),
|
||||||
SSL_get_cipher(ctx->src.ssl),
|
SSL_get_cipher(ctx->src.ssl),
|
||||||
SSL_get_version(ctx->dst.ssl),
|
SSL_get_version(ctx->dst.ssl),
|
||||||
SSL_get_cipher(ctx->dst.ssl)
|
SSL_get_cipher(ctx->dst.ssl),
|
||||||
|
STRORDASH(ctx->origcrtfpr),
|
||||||
|
STRORDASH(ctx->usedcrtfpr)
|
||||||
#ifdef HAVE_LOCAL_PROCINFO
|
#ifdef HAVE_LOCAL_PROCINFO
|
||||||
, lpi
|
, lpi
|
||||||
#endif /* HAVE_LOCAL_PROCINFO */
|
#endif /* HAVE_LOCAL_PROCINFO */
|
||||||
,
|
);
|
||||||
*ctx->origfpr,
|
|
||||||
*ctx->newfpr);
|
|
||||||
}
|
}
|
||||||
if ((rv < 0) || !msg) {
|
if ((rv < 0) || !msg) {
|
||||||
ctx->enomem = 1;
|
ctx->enomem = 1;
|
||||||
@ -455,7 +456,7 @@ pxy_log_connect_http(pxy_conn_ctx_t *ctx)
|
|||||||
#ifdef HAVE_LOCAL_PROCINFO
|
#ifdef HAVE_LOCAL_PROCINFO
|
||||||
" %s"
|
" %s"
|
||||||
#endif /* HAVE_LOCAL_PROCINFO */
|
#endif /* HAVE_LOCAL_PROCINFO */
|
||||||
"%s %s %s\n",
|
"%s\n",
|
||||||
STRORDASH(ctx->src_str),
|
STRORDASH(ctx->src_str),
|
||||||
STRORDASH(ctx->dst_str),
|
STRORDASH(ctx->dst_str),
|
||||||
STRORDASH(ctx->http_host),
|
STRORDASH(ctx->http_host),
|
||||||
@ -466,17 +467,16 @@ pxy_log_connect_http(pxy_conn_ctx_t *ctx)
|
|||||||
#ifdef HAVE_LOCAL_PROCINFO
|
#ifdef HAVE_LOCAL_PROCINFO
|
||||||
lpi,
|
lpi,
|
||||||
#endif /* HAVE_LOCAL_PROCINFO */
|
#endif /* HAVE_LOCAL_PROCINFO */
|
||||||
ctx->ocsp_denied ? " ocsp:denied" : "",
|
ctx->ocsp_denied ? " ocsp:denied" : "");
|
||||||
*ctx->origfpr,
|
|
||||||
*ctx->newfpr);
|
|
||||||
} else {
|
} else {
|
||||||
rv = asprintf(&msg, "https %s %s %s %s %s %s %s "
|
rv = asprintf(&msg, "https %s %s %s %s %s %s %s "
|
||||||
"sni:%s names:%s "
|
"sni:%s names:%s "
|
||||||
"sproto:%s:%s dproto:%s:%s"
|
"sproto:%s:%s dproto:%s:%s "
|
||||||
|
"origcrt:%s usedcrt:%s"
|
||||||
#ifdef HAVE_LOCAL_PROCINFO
|
#ifdef HAVE_LOCAL_PROCINFO
|
||||||
" %s"
|
" %s"
|
||||||
#endif /* HAVE_LOCAL_PROCINFO */
|
#endif /* HAVE_LOCAL_PROCINFO */
|
||||||
"%s %s %s\n",
|
"%s\n",
|
||||||
STRORDASH(ctx->src_str),
|
STRORDASH(ctx->src_str),
|
||||||
STRORDASH(ctx->dst_str),
|
STRORDASH(ctx->dst_str),
|
||||||
STRORDASH(ctx->http_host),
|
STRORDASH(ctx->http_host),
|
||||||
@ -490,12 +490,12 @@ pxy_log_connect_http(pxy_conn_ctx_t *ctx)
|
|||||||
SSL_get_cipher(ctx->src.ssl),
|
SSL_get_cipher(ctx->src.ssl),
|
||||||
SSL_get_version(ctx->dst.ssl),
|
SSL_get_version(ctx->dst.ssl),
|
||||||
SSL_get_cipher(ctx->dst.ssl),
|
SSL_get_cipher(ctx->dst.ssl),
|
||||||
|
STRORDASH(ctx->origcrtfpr),
|
||||||
|
STRORDASH(ctx->usedcrtfpr),
|
||||||
#ifdef HAVE_LOCAL_PROCINFO
|
#ifdef HAVE_LOCAL_PROCINFO
|
||||||
lpi,
|
lpi,
|
||||||
#endif /* HAVE_LOCAL_PROCINFO */
|
#endif /* HAVE_LOCAL_PROCINFO */
|
||||||
ctx->ocsp_denied ? " ocsp:denied" : "",
|
ctx->ocsp_denied ? " ocsp:denied" : "");
|
||||||
*ctx->origfpr,
|
|
||||||
*ctx->newfpr);
|
|
||||||
}
|
}
|
||||||
if ((rv < 0 ) || !msg) {
|
if ((rv < 0 ) || !msg) {
|
||||||
ctx->enomem = 1;
|
ctx->enomem = 1;
|
||||||
@ -732,6 +732,66 @@ pxy_srcsslctx_create(pxy_conn_ctx_t *ctx, X509 *crt, STACK_OF(X509) *chain,
|
|||||||
return sslctx;
|
return sslctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pxy_srccert_write_to_gendir(pxy_conn_ctx_t *ctx, X509 *crt, int is_orig)
|
||||||
|
{
|
||||||
|
char *fn;
|
||||||
|
int rv;
|
||||||
|
struct stat sb;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
if (!ctx->origcrtfpr)
|
||||||
|
return -1;
|
||||||
|
if (is_orig) {
|
||||||
|
rv = asprintf(&fn, "%s/%s.crt", ctx->opts->certgendir,
|
||||||
|
ctx->origcrtfpr);
|
||||||
|
} else {
|
||||||
|
if (!ctx->usedcrtfpr)
|
||||||
|
return -1;
|
||||||
|
rv = asprintf(&fn, "%s/%s-%s.crt", ctx->opts->certgendir,
|
||||||
|
ctx->origcrtfpr, ctx->usedcrtfpr);
|
||||||
|
}
|
||||||
|
if (rv == -1) {
|
||||||
|
ctx->enomem = 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (stat(fn, &sb) == 0) {
|
||||||
|
free(fn);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!(f = fopen(fn, "w"))) {
|
||||||
|
log_err_printf("Failed to open '%s' for writing: %s (%i)\n",
|
||||||
|
fn, strerror(errno), errno);
|
||||||
|
free(fn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!PEM_write_X509(f, crt)) {
|
||||||
|
log_err_printf("Failed to write certificate to '%s'\n", fn);
|
||||||
|
fclose(f);
|
||||||
|
free(fn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
free(fn);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pxy_srccert_write(pxy_conn_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
if (ctx->opts->certgen_writeall || ctx->generated_cert) {
|
||||||
|
if (pxy_srccert_write_to_gendir(ctx,
|
||||||
|
SSL_get_certificate(ctx->src.ssl), 0) == -1) {
|
||||||
|
log_err_printf("Failed to write used certificate\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ctx->opts->certgen_writeall) {
|
||||||
|
if (pxy_srccert_write_to_gendir(ctx, ctx->origcrt, 1) == -1) {
|
||||||
|
log_err_printf("Failed to write orig certificate\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static cert_t *
|
static cert_t *
|
||||||
pxy_srccert_create(pxy_conn_ctx_t *ctx)
|
pxy_srccert_create(pxy_conn_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
@ -804,48 +864,19 @@ pxy_srccert_create(pxy_conn_ctx_t *ctx)
|
|||||||
}
|
}
|
||||||
cert_set_key(cert, ctx->opts->key);
|
cert_set_key(cert, ctx->opts->key);
|
||||||
cert_set_chain(cert, ctx->opts->chain);
|
cert_set_chain(cert, ctx->opts->chain);
|
||||||
|
ctx->generated_cert = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char origfpr[SSL_X509_FPRSZ], newfpr[SSL_X509_FPRSZ];
|
if ((WANT_CONNECT_LOG(ctx) || ctx->opts->certgendir) && ctx->origcrt) {
|
||||||
ssl_x509_fingerprint_sha1(ctx->origcrt, origfpr);
|
ctx->origcrtfpr = ssl_x509_fingerprint(ctx->origcrt, 0);
|
||||||
ssl_x509_fingerprint_sha1(cert->crt, newfpr);
|
if (!ctx->origcrtfpr)
|
||||||
asprintf(ctx->origfpr,"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
|
ctx->enomem = 1;
|
||||||
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
|
}
|
||||||
origfpr[0], origfpr[1], origfpr[2], origfpr[3], origfpr[4],
|
if ((WANT_CONNECT_LOG(ctx) || ctx->opts->certgen_writeall) &&
|
||||||
origfpr[5], origfpr[6], origfpr[7], origfpr[8], origfpr[9],
|
cert && cert->crt) {
|
||||||
origfpr[10], origfpr[11], origfpr[12], origfpr[13], origfpr[14],
|
ctx->usedcrtfpr = ssl_x509_fingerprint(cert->crt, 0);
|
||||||
origfpr[15], origfpr[16], origfpr[17], origfpr[18], origfpr[19]);
|
if (!ctx->usedcrtfpr)
|
||||||
asprintf(ctx->newfpr,"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
|
ctx->enomem = 1;
|
||||||
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
|
|
||||||
newfpr[0], newfpr[1], newfpr[2], newfpr[3], newfpr[4],
|
|
||||||
newfpr[5], newfpr[6], newfpr[7], newfpr[8], newfpr[9],
|
|
||||||
newfpr[10], newfpr[11], newfpr[12], newfpr[13], newfpr[14],
|
|
||||||
newfpr[15], newfpr[16], newfpr[17], newfpr[18], newfpr[19]);
|
|
||||||
|
|
||||||
if (ctx->opts->certgendir) {
|
|
||||||
char *crtfn;
|
|
||||||
asprintf(&crtfn, "%s/%s-%s.crt", ctx->opts->certgendir, *ctx->origfpr, *ctx->newfpr);
|
|
||||||
FILE *crtfd;
|
|
||||||
crtfd = fopen(crtfn, "w");
|
|
||||||
if (crtfd) {
|
|
||||||
PEM_write_X509(crtfd, cert->crt);
|
|
||||||
fclose(crtfd);
|
|
||||||
} else {
|
|
||||||
log_err_printf("Failed to open '%s' for writing: %s\n",
|
|
||||||
crtfn, strerror(errno));
|
|
||||||
}
|
|
||||||
if (ctx->opts->writeorig) {
|
|
||||||
char *origfn;
|
|
||||||
asprintf(&origfn, "%s/%s.crt", ctx->opts->certgendir, *ctx->origfpr);
|
|
||||||
FILE *origfd = fopen(origfn, "w");
|
|
||||||
if (origfd) {
|
|
||||||
PEM_write_X509(origfd, ctx->origcrt);
|
|
||||||
fclose(origfd);
|
|
||||||
} else {
|
|
||||||
log_err_printf("Failed to open '%s' for writing: %s\n",
|
|
||||||
origfn, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cert;
|
return cert;
|
||||||
@ -969,6 +1000,7 @@ pxy_ossl_servername_cb(SSL *ssl, UNUSED int *al, void *arg)
|
|||||||
return SSL_TLSEXT_ERR_NOACK;
|
return SSL_TLSEXT_ERR_NOACK;
|
||||||
}
|
}
|
||||||
cachemgr_fkcrt_set(ctx->origcrt, newcrt);
|
cachemgr_fkcrt_set(ctx->origcrt, newcrt);
|
||||||
|
ctx->generated_cert = 1;
|
||||||
if (OPTS_DEBUG(ctx->opts)) {
|
if (OPTS_DEBUG(ctx->opts)) {
|
||||||
log_dbg_printf("===> Updated forged server "
|
log_dbg_printf("===> Updated forged server "
|
||||||
"certificate:\n");
|
"certificate:\n");
|
||||||
@ -983,6 +1015,16 @@ pxy_ossl_servername_cb(SSL *ssl, UNUSED int *al, void *arg)
|
|||||||
ctx->enomem = 1;
|
ctx->enomem = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (WANT_CONNECT_LOG(ctx) || ctx->opts->certgendir) {
|
||||||
|
if (ctx->usedcrtfpr) {
|
||||||
|
free(ctx->usedcrtfpr);
|
||||||
|
}
|
||||||
|
ctx->usedcrtfpr = ssl_x509_fingerprint(newcrt, 0);
|
||||||
|
if (!ctx->usedcrtfpr) {
|
||||||
|
ctx->enomem = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
newsslctx = pxy_srcsslctx_create(ctx, newcrt, ctx->opts->chain,
|
newsslctx = pxy_srcsslctx_create(ctx, newcrt, ctx->opts->chain,
|
||||||
ctx->opts->key);
|
ctx->opts->key);
|
||||||
if (!newsslctx) {
|
if (!newsslctx) {
|
||||||
@ -1810,6 +1852,12 @@ connected:
|
|||||||
pxy_log_connect_nonhttp(ctx);
|
pxy_log_connect_nonhttp(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* write SSL certificates to gendir */
|
||||||
|
if (this->ssl && (bev == ctx->src.bev) &&
|
||||||
|
ctx->opts->certgendir) {
|
||||||
|
pxy_srccert_write(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (OPTS_DEBUG(ctx->opts)) {
|
if (OPTS_DEBUG(ctx->opts)) {
|
||||||
if (this->ssl) {
|
if (this->ssl) {
|
||||||
/* for SSL, we get two connect events */
|
/* for SSL, we get two connect events */
|
||||||
|
19
sslsplit.1
19
sslsplit.1
@ -181,12 +181,6 @@ no matching certificate in the provided certificate directory.
|
|||||||
Use private key from \fIpemfile\fP for certificates forged on-the-fly.
|
Use private key from \fIpemfile\fP for certificates forged on-the-fly.
|
||||||
If \fB-K\fP is not given, SSLsplit will generate a random 1024-bit RSA key.
|
If \fB-K\fP is not given, SSLsplit will generate a random 1024-bit RSA key.
|
||||||
.TP
|
.TP
|
||||||
.B \-w \fIgendir\fP
|
|
||||||
Write generated keys and certificates to individual files in \fIgendir\fP.
|
|
||||||
.TP
|
|
||||||
.B \-W \fIgendir\fP
|
|
||||||
Same as -w, but also write original certificates
|
|
||||||
.TP
|
|
||||||
.B \-l \fIlogfile\fP
|
.B \-l \fIlogfile\fP
|
||||||
Log connections to \fIlogfile\fP in a single line per connection format,
|
Log connections to \fIlogfile\fP in a single line per connection format,
|
||||||
including addresses and ports and some HTTP and SSL information, if available.
|
including addresses and ports and some HTTP and SSL information, if available.
|
||||||
@ -297,6 +291,19 @@ Mac OS X.
|
|||||||
.B \-V
|
.B \-V
|
||||||
Display version and compiled features information and exit.
|
Display version and compiled features information and exit.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-w \fIgendir\fP
|
||||||
|
Write generated keys and certificates to individual files in \fIgendir\fP.
|
||||||
|
For keys, the key identifier is used as filename, which consists of the SHA-1
|
||||||
|
hash of the ASN.1 bit string of the public key, as referenced by the
|
||||||
|
subjectKeyIdentifier extension in certificates.
|
||||||
|
For certificates, the SHA-1 fingerprints of the original and the used (forged)
|
||||||
|
certificate are combined to form the filename.
|
||||||
|
Note that only newly generated certificates are written to disk.
|
||||||
|
.TP
|
||||||
|
.B \-W \fIgendir\fP
|
||||||
|
Same as \fB-w\fP, but also write original certificates and certificates not
|
||||||
|
newly generated, such as those loaded from \fB-t\fP.
|
||||||
|
.TP
|
||||||
.B \-Z
|
.B \-Z
|
||||||
Disable SSL/TLS compression on all connections. This is useful if your
|
Disable SSL/TLS compression on all connections. This is useful if your
|
||||||
limiting factor is CPU, not network bandwidth.
|
limiting factor is CPU, not network bandwidth.
|
||||||
|
Loading…
Reference in New Issue
Block a user