diff --git a/main.c b/main.c index 617047f..b0cbccb 100644 --- a/main.c +++ b/main.c @@ -275,7 +275,7 @@ main(int argc, char *argv[]) } 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) { + "k:c:C:K:t:OPs:r:R:e:Eu:m:j:p:l:L:S:F:dDVhX:")) != -1) { switch (ch) { case 'c': if (opts->cacrt) @@ -519,6 +519,13 @@ main(int argc, char *argv[]) opts->contentlog_isdir = 0; opts->contentlog_isspec = 1; break; + case 'X': + if (opts->certgendir) + free(opts->certgendir); + opts->certgendir = strdup(optarg); + if (!opts->certgendir) + oom_die(argv0); + break; #ifdef HAVE_LOCAL_PROCINFO case 'i': opts->lprocinfo = 1; diff --git a/opts.h b/opts.h index abbf5e8..6098b83 100644 --- a/opts.h +++ b/opts.h @@ -100,6 +100,7 @@ typedef struct opts { char *ecdhcurve; #endif /* !OPENSSL_NO_ECDH */ proxyspec_t *spec; + char *certgendir; } opts_t; opts_t *opts_new(void) MALLOC; diff --git a/pxyconn.c b/pxyconn.c index 3cefc66..8c643d5 100644 --- a/pxyconn.c +++ b/pxyconn.c @@ -702,6 +702,40 @@ pxy_srcsslctx_create(pxy_conn_ctx_t *ctx, X509 *crt, STACK_OF(X509) *chain, SSL_CTX_add_extra_chain_cert(sslctx, c); } + if (ctx->opts->certgendir) { + unsigned char origfpr[SSL_X509_FPRSZ], newfpr[SSL_X509_FPRSZ]; + char origfprstr[SSL_X509_FPRSZ*2], newfprstr[SSL_X509_FPRSZ*2]; + ssl_x509_fingerprint_sha1(ctx->origcrt, origfpr); + ssl_x509_fingerprint_sha1(crt, newfpr); + sprintf(origfprstr,"%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]); + sprintf(newfprstr,"%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]); + char *keyfn = malloc(strlen(ctx->opts->certgendir)+1+SSL_X509_FPRSZ*4+1+4); + char *crtfn = malloc(strlen(ctx->opts->certgendir)+1+SSL_X509_FPRSZ*4+1+4); + sprintf(keyfn, "%s/%s-%s.key", ctx->opts->certgendir, origfprstr, newfprstr); + sprintf(crtfn, "%s/%s-%s.crt", ctx->opts->certgendir, origfprstr, newfprstr); + FILE *keyfd, *crtfd; + keyfd = fopen(keyfn, "w"); + crtfd = fopen(crtfn, "w"); + if (keyfd) { + PEM_write_PrivateKey(keyfd, key, NULL, 0, 0, NULL, NULL); + fclose(keyfd); + } + if (crtfd) { + PEM_write_X509(crtfd, crt); + fclose(crtfd); + } + } + #ifdef DEBUG_SESSION_CACHE if (OPTS_DEBUG(ctx->opts)) { int mode = SSL_CTX_get_session_cache_mode(sslctx);