do you have your patches on github fork ? (I could not find your fork) вс, 5 июл. 2020 г. в 15:13, Gersner <[email protected]>:
> > > On Sun, Jul 5, 2020 at 12:28 PM Илья Шипицин <[email protected]> wrote: > >> does it clearly applies to current master ? either gmail scrambled patch >> or it is not. >> can you try please ? >> > Exporting the eml and running 'git am' it works cleanly. > > I've reproduced the exact same output when copy-pasting from gmail. It > seems gmail converts the tabs to spaces and this fails the patch (Not sure > why). > Running patch with '-l' will resolve this, but it's probably safer to run > git am on the email. > > >> >> $ patch -p1 < 1.patch >> patching file doc/configuration.txt >> patching file include/haproxy/listener-t.h >> Hunk #1 FAILED at 163. >> 1 out of 1 hunk FAILED -- saving rejects to file >> include/haproxy/listener-t.h.rej >> patching file src/cfgparse-ssl.c >> Hunk #1 succeeded at 538 with fuzz 1. >> Hunk #2 FAILED at 1720. >> 1 out of 2 hunks FAILED -- saving rejects to file src/cfgparse-ssl.c.rej >> patching file src/ssl_sock.c >> Hunk #1 FAILED at 1750. >> Hunk #2 FAILED at 1864. >> Hunk #3 FAILED at 1912. >> Hunk #4 FAILED at 1943. >> Hunk #5 FAILED at 1970. >> Hunk #6 FAILED at 4823. >> Hunk #7 FAILED at 4843. >> 7 out of 7 hunks FAILED -- saving rejects to file src/ssl_sock.c.rej >> >> вс, 5 июл. 2020 г. в 11:46, <[email protected]>: >> >>> From: Shimi Gersner <[email protected]> >>> >>> haproxy supports generating SSL certificates based on SNI using a >>> provided >>> CA signing certificate. Because CA certificates may be signed by multiple >>> CAs, in some scenarios, it is neccesary for the server to attach the >>> trust chain >>> in addition to the generated certificate. >>> >>> The following patch adds the ability to optionally serve all public >>> certificates provided in the `ca-sign-file` PEM file. >>> Certificate loading was ported to use `ca_sign_use_chain` structure, >>> instead of directly reading public/private keys. >>> --- >>> doc/configuration.txt | 8 +++ >>> include/haproxy/listener-t.h | 4 +- >>> src/cfgparse-ssl.c | 13 +++++ >>> src/ssl_sock.c | 98 ++++++++++++++++++++---------------- >>> 4 files changed, 78 insertions(+), 45 deletions(-) >>> >>> diff --git a/doc/configuration.txt b/doc/configuration.txt >>> index 6d472134e..1d3878bc1 100644 >>> --- a/doc/configuration.txt >>> +++ b/doc/configuration.txt >>> @@ -12158,6 +12158,14 @@ ca-sign-pass <passphrase> >>> the dynamic generation of certificates is enabled. See >>> 'generate-certificates' for details. >>> >>> +ca-sign-use-chain >>> + This setting is only available when support for OpenSSL was built in. >>> It is >>> + the CA private key passphrase. This setting is optional and used only >>> when >>> + the dynamic generation of certificates is enabled. See >>> + 'generate-certificates' for details. >>> + Enabling this flag will attach all public certificates encoded in >>> `ca-sign-file` >>> + to the served certificate to the client, enabling trust. >>> + >>> ca-verify-file <cafile> >>> This setting designates a PEM file from which to load CA certificates >>> used to >>> verify client's certificate. It designates CA certificates which must >>> not be >>> diff --git a/include/haproxy/listener-t.h b/include/haproxy/listener-t.h >>> index 224e32513..38ca2839f 100644 >>> --- a/include/haproxy/listener-t.h >>> +++ b/include/haproxy/listener-t.h >>> @@ -163,8 +163,8 @@ struct bind_conf { >>> char *ca_sign_file; /* CAFile used to generate and sign >>> server certificates */ >>> char *ca_sign_pass; /* CAKey passphrase */ >>> >>> - X509 *ca_sign_cert; /* CA certificate referenced by >>> ca_file */ >>> - EVP_PKEY *ca_sign_pkey; /* CA private key referenced by >>> ca_key */ >>> + int ca_sign_use_chain; /* Optionally attached the >>> certificate chain to the served certificate */ >>> + struct cert_key_and_chain * ca_sign_ckch; /* CA and >>> possible certificate chain for ca generation */ >>> #endif >>> struct proxy *frontend; /* the frontend all these listeners >>> belong to, or NULL */ >>> const struct mux_proto_list *mux_proto; /* the mux to use for >>> all incoming connections (specified by the "proto" keyword) */ >>> diff --git a/src/cfgparse-ssl.c b/src/cfgparse-ssl.c >>> index 144cef882..270c857f9 100644 >>> --- a/src/cfgparse-ssl.c >>> +++ b/src/cfgparse-ssl.c >>> @@ -538,6 +538,18 @@ static int bind_parse_ca_sign_file(char **args, int >>> cur_arg, struct proxy *px, s >>> return 0; >>> } >>> >>> +/* parse the "ca-sign-use-chain" bind keyword */ >>> +static int bind_parse_ca_sign_use_chain(char **args, int cur_arg, >>> struct proxy *px, struct bind_conf *conf, char **err) >>> +{ >>> +#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined >>> SSL_NO_GENERATE_CERTIFICATES && defined SSL_CTX_set1_chain) >>> + conf->ca_sign_use_chain = 1; >>> +#else >>> + memprintf(err, "%sthis version of openssl cannot attach >>> certificate chain for SSL certificate generation.\n", >>> + err && *err ? *err : ""); >>> +#endif >>> + return 0; >>> +} >>> + >>> /* parse the "ca-sign-pass" bind keyword */ >>> static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct >>> proxy *px, struct bind_conf *conf, char **err) >>> { >>> @@ -1708,6 +1720,7 @@ static struct bind_kw_list bind_kws = { "SSL", { >>> }, { >>> { "ca-ignore-err", bind_parse_ignore_err, 1 }, >>> /* set error IDs to ignore on verify depth > 0 */ >>> { "ca-sign-file", bind_parse_ca_sign_file, 1 }, >>> /* set CAFile used to generate and sign server certs */ >>> { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, >>> /* set CAKey passphrase */ >>> + { "ca-sign-use-chain", bind_parse_ca_sign_use_chain, 1 }, >>> /* enable attaching ca chain to generated certificate */ >>> { "ciphers", bind_parse_ciphers, 1 }, >>> /* set SSL cipher suite */ >>> #if (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L) >>> { "ciphersuites", bind_parse_ciphersuites, 1 }, >>> /* set TLS 1.3 cipher suite */ >>> diff --git a/src/ssl_sock.c b/src/ssl_sock.c >>> index a32db1a28..54829eb98 100644 >>> --- a/src/ssl_sock.c >>> +++ b/src/ssl_sock.c >>> @@ -1750,8 +1750,8 @@ static int ssl_sock_advertise_alpn_protos(SSL *s, >>> const unsigned char **out, >>> static SSL_CTX * >>> ssl_sock_do_create_cert(const char *servername, struct bind_conf >>> *bind_conf, SSL *ssl) >>> { >>> - X509 *cacert = bind_conf->ca_sign_cert; >>> - EVP_PKEY *capkey = bind_conf->ca_sign_pkey; >>> + X509 *cacert = bind_conf->ca_sign_ckch->cert; >>> + EVP_PKEY *capkey = bind_conf->ca_sign_ckch->key; >>> SSL_CTX *ssl_ctx = NULL; >>> X509 *newcrt = NULL; >>> EVP_PKEY *pkey = NULL; >>> @@ -1864,6 +1864,16 @@ ssl_sock_do_create_cert(const char *servername, >>> struct bind_conf *bind_conf, SSL >>> if (!SSL_CTX_check_private_key(ssl_ctx)) >>> goto mkcert_error; >>> >>> + /* Assign chain if any */ >>> + if (bind_conf->ca_sign_use_chain && >>> bind_conf->ca_sign_ckch->chain) { >>> + if (!SSL_CTX_set1_chain(ssl_ctx, >>> bind_conf->ca_sign_ckch->chain)) { >>> + goto mkcert_error; >>> + } >>> + if (!SSL_CTX_add1_chain_cert(ssl_ctx, >>> bind_conf->ca_sign_ckch->cert)) { >>> + goto mkcert_error; >>> + } >>> + } >>> + >>> if (newcrt) X509_free(newcrt); >>> >>> #ifndef OPENSSL_NO_DH >>> @@ -1912,7 +1922,7 @@ ssl_sock_assign_generated_cert(unsigned int key, >>> struct bind_conf *bind_conf, SS >>> >>> if (ssl_ctx_lru_tree) { >>> HA_RWLOCK_WRLOCK(SSL_GEN_CERTS_LOCK, >>> &ssl_ctx_lru_rwlock); >>> - lru = lru64_lookup(key, ssl_ctx_lru_tree, >>> bind_conf->ca_sign_cert, 0); >>> + lru = lru64_lookup(key, ssl_ctx_lru_tree, >>> bind_conf->ca_sign_ckch->cert, 0); >>> if (lru && lru->domain) { >>> if (ssl) >>> SSL_set_SSL_CTX(ssl, (SSL_CTX >>> *)lru->data); >>> @@ -1943,14 +1953,14 @@ ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, >>> unsigned int key, struct bind_conf >>> >>> if (ssl_ctx_lru_tree) { >>> HA_RWLOCK_WRLOCK(SSL_GEN_CERTS_LOCK, >>> &ssl_ctx_lru_rwlock); >>> - lru = lru64_get(key, ssl_ctx_lru_tree, >>> bind_conf->ca_sign_cert, 0); >>> + lru = lru64_get(key, ssl_ctx_lru_tree, >>> bind_conf->ca_sign_ckch->cert, 0); >>> if (!lru) { >>> HA_RWLOCK_WRUNLOCK(SSL_GEN_CERTS_LOCK, >>> &ssl_ctx_lru_rwlock); >>> return -1; >>> } >>> if (lru->domain && lru->data) >>> lru->free((SSL_CTX *)lru->data); >>> - lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, >>> (void (*)(void *))SSL_CTX_free); >>> + lru64_commit(lru, ssl_ctx, >>> bind_conf->ca_sign_ckch->cert, 0, (void (*)(void *))SSL_CTX_free); >>> HA_RWLOCK_WRUNLOCK(SSL_GEN_CERTS_LOCK, >>> &ssl_ctx_lru_rwlock); >>> return 0; >>> } >>> @@ -1970,7 +1980,7 @@ ssl_sock_generated_cert_key(const void *data, >>> size_t len) >>> static int >>> ssl_sock_generate_certificate(const char *servername, struct bind_conf >>> *bind_conf, SSL *ssl) >>> { >>> - X509 *cacert = bind_conf->ca_sign_cert; >>> + X509 *cacert = bind_conf->ca_sign_ckch->cert; >>> SSL_CTX *ssl_ctx = NULL; >>> struct lru64 *lru = NULL; >>> unsigned int key; >>> @@ -4823,13 +4833,12 @@ int >>> ssl_sock_load_ca(struct bind_conf *bind_conf) >>> { >>> struct proxy *px = bind_conf->frontend; >>> - FILE *fp; >>> - X509 *cacert = NULL; >>> - EVP_PKEY *capkey = NULL; >>> - int err = 0; >>> + struct cert_key_and_chain *ckch = NULL; >>> + int ret = 0; >>> + char *err = NULL; >>> >>> if (!bind_conf->generate_certs) >>> - return err; >>> + return ret; >>> >>> #if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined >>> SSL_NO_GENERATE_CERTIFICATES) >>> if (global_ssl.ctx_cache) { >>> @@ -4843,52 +4852,55 @@ ssl_sock_load_ca(struct bind_conf *bind_conf) >>> ha_alert("Proxy '%s': cannot enable certificate >>> generation, " >>> "no CA certificate File configured at >>> [%s:%d].\n", >>> px->id, bind_conf->file, bind_conf->line); >>> - goto load_error; >>> + goto failed; >>> } >>> >>> - /* read in the CA certificate */ >>> - if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) { >>> - ha_alert("Proxy '%s': Failed to read CA certificate file >>> '%s' at [%s:%d].\n", >>> - px->id, bind_conf->ca_sign_file, >>> bind_conf->file, bind_conf->line); >>> - goto load_error; >>> + /* Allocate cert structure */ >>> + ckch = calloc(1, sizeof(struct cert_key_and_chain)); >>> + if (!ckch) { >>> + ha_alert("Proxy '%s': Failed to read CA certificate file >>> '%s' at [%s:%d]. Chain allocation failure\n", >>> + px->id, bind_conf->ca_sign_file, >>> bind_conf->file, bind_conf->line); >>> } >>> - if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) { >>> - ha_alert("Proxy '%s': Failed to read CA certificate file >>> '%s' at [%s:%d].\n", >>> - px->id, bind_conf->ca_sign_file, >>> bind_conf->file, bind_conf->line); >>> - goto read_error; >>> + >>> + /* Try to parse file */ >>> + if (ssl_sock_load_files_into_ckch(bind_conf->ca_sign_file, ckch, >>> &err)) { >>> + ha_alert("Proxy '%s': Failed to read CA certificate file >>> '%s' at [%s:%d]. Chain loading failed: %s\n", >>> + px->id, bind_conf->ca_sign_file, >>> bind_conf->file, bind_conf->line, err); >>> + if (err) free(err); >>> + goto failed; >>> } >>> - rewind(fp); >>> - if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, >>> bind_conf->ca_sign_pass))) { >>> - ha_alert("Proxy '%s': Failed to read CA private key file >>> '%s' at [%s:%d].\n", >>> - px->id, bind_conf->ca_sign_file, >>> bind_conf->file, bind_conf->line); >>> - goto read_error; >>> + >>> + /* Fail if missing cert or pkey */ >>> + if ((!ckch->cert) || (!ckch->key)) { >>> + ha_alert("Proxy '%s': Failed to read CA certificate file >>> '%s' at [%s:%d]. Chain missing certificate or private key\n", >>> + px->id, bind_conf->ca_sign_file, >>> bind_conf->file, bind_conf->line); >>> + goto failed; >>> } >>> >>> - fclose (fp); >>> - bind_conf->ca_sign_cert = cacert; >>> - bind_conf->ca_sign_pkey = capkey; >>> - return err; >>> + /* Final assignment to bind */ >>> + bind_conf->ca_sign_ckch = ckch; >>> + return ret; >>> + >>> + failed: >>> + if (ckch) { >>> + ssl_sock_free_cert_key_and_chain_contents(ckch); >>> + free(ckch); >>> + } >>> >>> - read_error: >>> - fclose (fp); >>> - if (capkey) EVP_PKEY_free(capkey); >>> - if (cacert) X509_free(cacert); >>> - load_error: >>> bind_conf->generate_certs = 0; >>> - err++; >>> - return err; >>> + ret++; >>> + return ret; >>> } >>> >>> /* Release CA cert and private key used to generate certificated */ >>> void >>> ssl_sock_free_ca(struct bind_conf *bind_conf) >>> { >>> - if (bind_conf->ca_sign_pkey) >>> - EVP_PKEY_free(bind_conf->ca_sign_pkey); >>> - if (bind_conf->ca_sign_cert) >>> - X509_free(bind_conf->ca_sign_cert); >>> - bind_conf->ca_sign_pkey = NULL; >>> - bind_conf->ca_sign_cert = NULL; >>> + if (bind_conf->ca_sign_ckch) { >>> + >>> ssl_sock_free_cert_key_and_chain_contents(bind_conf->ca_sign_ckch); >>> + free(bind_conf->ca_sign_ckch); >>> + bind_conf->ca_sign_ckch = NULL; >>> + } >>> } >>> >>> /* >>> -- >>> 2.27.0 >>> >>> >>>

