Merge branch 'genstore' of https://github.com/psychomario/sslsplit into feature/genstore

pull/13/head
Daniel Roethlisberger 10 years ago
commit 160fd991e0

@ -115,6 +115,8 @@ 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"
" -O deny all OCSP requests on all proxyspecs\n" " -O deny all OCSP requests on all proxyspecs\n"
@ -274,7 +276,7 @@ main(int argc, char *argv[])
} }
while ((ch = getopt(argc, argv, OPT_g OPT_G OPT_Z OPT_i "k:c:C:K:t:" while ((ch = getopt(argc, argv, OPT_g OPT_G OPT_Z OPT_i "k:c:C:K:t:"
"OPs:r:R:e:Eu:m:j:p:l:L:S:F:dDVh")) != -1) { "OPs:r:R:e:Eu:m:j:p:l:L:S:F:dDVhW:w:")) != -1) {
switch (ch) { switch (ch) {
case 'c': case 'c':
if (opts->cacrt) if (opts->cacrt)
@ -615,6 +617,22 @@ main(int argc, char *argv[])
free(lhs); free(lhs);
free(rhs); free(rhs);
break; break;
case 'W':
opts->writeorig = 1;
if (opts->certgendir)
free(opts->certgendir);
opts->certgendir = strdup(optarg);
if (!opts->certgendir)
oom_die(argv0);
break;
case 'w':
opts->writeorig = 0;
if (opts->certgendir)
free(opts->certgendir);
opts->certgendir = strdup(optarg);
if (!opts->certgendir)
oom_die(argv0);
break;
} }
#ifdef HAVE_LOCAL_PROCINFO #ifdef HAVE_LOCAL_PROCINFO
case 'i': case 'i':
@ -651,6 +669,11 @@ 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);
@ -747,6 +770,30 @@ main(int argc, char *argv[])
} }
} }
if (opts->certgendir) {
unsigned char *keyfpr = malloc(SSL_KEY_IDSZ);
if(ssl_key_identifier_sha1(opts->key, keyfpr)) {
fprintf(stderr, "%s: error generating RSA fingerprint\n", argv0);
exit(EXIT_FAILURE);
}
char *keyfn;
asprintf(&keyfn, "%s/%02X%02X%02X%02X%02X%02X%02X%02X%02X"
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X.key",
opts->certgendir,
keyfpr[0], keyfpr[1], keyfpr[2], keyfpr[3], keyfpr[4],
keyfpr[5], keyfpr[6], keyfpr[7], keyfpr[8], keyfpr[9],
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);
}
}
/* usage checks after defaults */ /* usage checks after defaults */
if (opts->dropgroup && !opts->dropuser) { if (opts->dropgroup && !opts->dropuser) {
fprintf(stderr, "%s: -m depends on -u.\n", argv0); fprintf(stderr, "%s: -m depends on -u.\n", argv0);

@ -105,6 +105,9 @@ opts_free(opts_t *opts)
if (opts->contentlog) { if (opts->contentlog) {
free(opts->contentlog); free(opts->contentlog);
} }
if (opts->certgendir) {
free(opts->certgendir);
}
if (opts->contentlog_basedir) { if (opts->contentlog_basedir) {
free(opts->contentlog_basedir); free(opts->contentlog_basedir);
} }

@ -101,6 +101,8 @@ 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;

@ -167,6 +167,8 @@ 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;
@ -377,7 +379,7 @@ pxy_log_connect_nonhttp(pxy_conn_ctx_t *ctx)
#ifdef HAVE_LOCAL_PROCINFO #ifdef HAVE_LOCAL_PROCINFO
" %s" " %s"
#endif /* HAVE_LOCAL_PROCINFO */ #endif /* HAVE_LOCAL_PROCINFO */
"\n", " %s %s\n",
STRORDASH(ctx->src_str), STRORDASH(ctx->src_str),
STRORDASH(ctx->dst_str), STRORDASH(ctx->dst_str),
STRORDASH(ctx->sni), STRORDASH(ctx->sni),
@ -389,7 +391,9 @@ pxy_log_connect_nonhttp(pxy_conn_ctx_t *ctx)
#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;
@ -451,7 +455,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\n", "%s %s %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),
@ -462,7 +466,9 @@ 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 "
@ -470,7 +476,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\n", "%s %s %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),
@ -487,7 +493,9 @@ 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);
} }
if ((rv < 0 ) || !msg) { if ((rv < 0 ) || !msg) {
ctx->enomem = 1; ctx->enomem = 1;
@ -798,6 +806,48 @@ pxy_srccert_create(pxy_conn_ctx_t *ctx)
cert_set_chain(cert, ctx->opts->chain); cert_set_chain(cert, ctx->opts->chain);
} }
unsigned char origfpr[SSL_X509_FPRSZ], newfpr[SSL_X509_FPRSZ];
ssl_x509_fingerprint_sha1(ctx->origcrt, origfpr);
ssl_x509_fingerprint_sha1(cert->crt, newfpr);
asprintf(ctx->origfpr,"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
origfpr[0], origfpr[1], origfpr[2], origfpr[3], origfpr[4],
origfpr[5], origfpr[6], origfpr[7], origfpr[8], origfpr[9],
origfpr[10], origfpr[11], origfpr[12], origfpr[13], origfpr[14],
origfpr[15], origfpr[16], origfpr[17], origfpr[18], origfpr[19]);
asprintf(ctx->newfpr,"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
"%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;
} }

@ -30,15 +30,15 @@ sslsplit \-\- transparent and scalable SSL/TLS interception
.SH SYNOPSIS .SH SYNOPSIS
.na .na
.B sslsplit .B sslsplit
[\fB-kCKOPZdDgGsrReumjplLSFi\fP] \fB-c\fP \fIpem\fP [\fB-kCKwWOPZdDgGsrReumjplLSFi\fP] \fB-c\fP \fIpem\fP
\fIproxyspecs\fP [...] \fIproxyspecs\fP [...]
.br .br
.B sslsplit .B sslsplit
[\fB-kCKOPZdDgGsrReumjplLSFi\fP] \fB-c\fP \fIpem\fP \fB-t\fP \fIdir\fP [\fB-kCKwWOPZdDgGsrReumjplLSFi\fP] \fB-c\fP \fIpem\fP \fB-t\fP \fIdir\fP
\fIproxyspecs\fP [...] \fIproxyspecs\fP [...]
.br .br
.B sslsplit .B sslsplit
[\fB-OPZdDgGsrReumjplLSFi\fP] \fB-t\fP \fIdir\fP [\fB-OPZwWdDgGsrReumjplLSFi\fP] \fB-t\fP \fIdir\fP
\fIproxyspecs\fP [...] \fIproxyspecs\fP [...]
.br .br
.B sslsplit -E .B sslsplit -E
@ -181,6 +181,12 @@ 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.

Loading…
Cancel
Save