On 14.05.2015 16:01, Joel Sing wrote:
On Thursday 14 May 2015, Michal Lesniewski wrote:
On 14.05.2015 15:02, Joel Sing wrote:
On Thursday 14 May 2015, Michal Lesniewski wrote:
Hello,

I'm trying to configure OpenBSD 5.7 httpd with tls with
intermediate/chain certificate without no success.

my httpd.conf:

server "default" {
           listen on 10.11.0.200 tls port 443

           tls {
                   certificate "/etc/ssl/server-unified.pem"
                   key "/etc/ssl/private/server.key"
           }

           root "/htdocs/default"
}

types {
           include "/usr/share/misc/mime.types"
}



My certificate is intermediate/chain certificate. That mean I need to
supply "next level" certificate that is between my certificate and CA.

I made that chain certificate concatenating PEM format files with
corresponding certs (all certs Signature Algorithm:
sha256WithRSAEncryption)

cat server.pem sub.class2.server.ca.pem ca-sha2.pem >
/etc/ssl/server-unified.pem

server-unified.pem looks like:

-----BEGIN CERTIFICATE-----
(Primary SSL certificate: server.pem)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(Intermediate certificate: sub.class2.server.ca.pem)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(Root certificate: ca-sha2.pem)
-----END CERTIFICATE-----

Certificate and key installed in default locations:

# ls -alh /etc/ssl/private/server.key
-r--------  1 root  wheel   6.2K May 13 19:40
/etc/ssl/private/server.key # ls -alh /etc/ssl/server.pem
-rw-r--r--  1 root  wheel   3.3K May 13 19:41 /etc/ssl/server.pem
# ls -alh /etc/ssl/server-unified.pem
-rw-r--r--  1 root  wheel   8.0K May 14 13:53
/etc/ssl/server-unified.pem


I try to test using openssl s_client:

michal@michal-MSQ87TN:~$ openssl s_client -connect 10.11.0.200:443
CONNECTED(00000003)
GET / HTTP/1.0



httpd log:


# httpd -dvvvvvvvvvv
startup
server_tls_load_keypair: using certificate /etc/ssl/server-unified.pem
server_tls_load_keypair: using private key /etc/ssl/private/server.key
socket_rlimit: max open files 1024
socket_rlimit: max open files 1024
server_privinit: adding server default
server_privinit: adding server default
socket_rlimit: max open files 1024
server_launch: running server default
server_launch: running server default
server_launch: running server default

there is no "server_tls_init"
nothing apears when started openssl s_client command
This smells very much like the same problem that has been mentioned on
the list earlier - with a 6KB private key and a 8KB bundle, you're almost
certainly hitting the 16K limit for a single imsg. Unfortunately there
were missing return value checks which means that this fails silently. If
you can try httpd from -current you will likely see an error instead of a
silent failure. Otherwise you can try removing one of the certificates
from the bundle in order to reduce the size and see if it then
reports "server_tls_init" and starts working.
tested on -current:

# httpd -dvvvvvvvvvvvvv
startup
server_tls_load_keypair: using certificate /etc/ssl/server-unified.pem
server_tls_load_keypair: using private key /etc/ssl/private/server.key
socket_rlimit: max open files 1024
server_privinit: adding server default
server_privinit: adding server default
config_setserver: failed to compose IMSG_CFG_SERVER imsg for `default':
Result too large
fatal: send server: Result too large
socket_rlimit: max open files 1024
logger exiting, pid 4965
socket_rlimit: max open files 1024
server exiting, pid 10727
server exiting, pid 32594
server exiting, pid 5337

Above situation occurs when I have server cert + intermediate + ca and
only server cert + intermediate in server-chain.pem.
httpd starts only when I supply only my server cert to it.
Is there any solution to run httpd with such big private key?
Try this (albeit only tested a little beyond compilation...)

Index: config.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/config.c,v
retrieving revision 1.37
diff -u -p -r1.37 config.c
--- config.c    11 Apr 2015 14:52:49 -0000      1.37
+++ config.c    14 May 2015 13:58:57 -0000
@@ -193,14 +193,6 @@ config_setserver(struct httpd *env, stru
                        iov[c].iov_base = srv->srv_conf.return_uri;
                        iov[c++].iov_len = srv->srv_conf.return_uri_len;
                }
-               if (srv->srv_conf.tls_cert_len != 0) {
-                       iov[c].iov_base = srv->srv_conf.tls_cert;
-                       iov[c++].iov_len = srv->srv_conf.tls_cert_len;
-               }
-               if (srv->srv_conf.tls_key_len != 0) {
-                       iov[c].iov_base = srv->srv_conf.tls_key;
-                       iov[c++].iov_len = srv->srv_conf.tls_key_len;
-               }
if (id == PROC_SERVER &&
                    (srv->srv_conf.flags & SRVFLAG_LOCATION) == 0) {
@@ -220,6 +212,9 @@ config_setserver(struct httpd *env, stru
                                        return (-1);
                                }
                        }
+
+                       /* Configure TLS if necessary. */
+                       config_settls(env, srv);
                } else {
                        if (proc_composev_imsg(ps, id, -1, IMSG_CFG_SERVER, -1,
                            iov, c) != 0) {
@@ -235,6 +230,72 @@ config_setserver(struct httpd *env, stru
  }
int
+config_settls(struct httpd *env, struct server *srv)
+{
+       struct privsep          *ps = env->sc_ps;
+       struct tls_config        tls;
+       struct iovec             iov[2];
+       size_t                   c;
+
+       if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0)
+               return (0);
+
+       log_debug("%s: configuring TLS for %s", __func__, srv->srv_conf.name);
+
+       if (srv->srv_conf.tls_cert_len != 0) {
+               DPRINTF("%s: sending TLS cert \"%s[%u]\" to %s fd %d", __func__,
+                   srv->srv_conf.name, srv->srv_conf.id,
+                   ps->ps_title[PROC_SERVER], srv->srv_s);
+
+               memset(&tls, 0, sizeof(tls));
+               tls.id = srv->srv_conf.id;
+               tls.port = srv->srv_conf.port;
+               memcpy(&tls.ss, &srv->srv_conf.ss, sizeof(tls.ss));
+               tls.tls_cert_len = srv->srv_conf.tls_cert_len;
+
+               c = 0;
+               iov[c].iov_base = &tls;
+               iov[c++].iov_len = sizeof(tls);
+               iov[c].iov_base = srv->srv_conf.tls_cert;
+               iov[c++].iov_len = srv->srv_conf.tls_cert_len;
+
+               if (proc_composev_imsg(ps, PROC_SERVER, -1, IMSG_CFG_TLS, -1,
+                   iov, c) != 0) {
+                       log_warn("%s: failed to compose IMSG_CFG_TLS imsg for "
+                           "`%s'", __func__, srv->srv_conf.name);
+                       return (-1);
+               }
+       }
+
+       if (srv->srv_conf.tls_key_len != 0) {
+               DPRINTF("%s: sending TLS key \"%s[%u]\" to %s fd %d", __func__,
+                   srv->srv_conf.name, srv->srv_conf.id,
+                   ps->ps_title[PROC_SERVER], srv->srv_s);
+
+               memset(&tls, 0, sizeof(tls));
+               tls.id = srv->srv_conf.id;
+               tls.port = srv->srv_conf.port;
+               memcpy(&tls.ss, &srv->srv_conf.ss, sizeof(tls.ss));
+               tls.tls_key_len = srv->srv_conf.tls_key_len;
+
+               c = 0;
+               iov[c].iov_base = &tls;
+               iov[c++].iov_len = sizeof(tls);
+               iov[c].iov_base = srv->srv_conf.tls_key;
+               iov[c++].iov_len = srv->srv_conf.tls_key_len;
+
+               if (proc_composev_imsg(ps, PROC_SERVER, -1, IMSG_CFG_TLS, -1,
+                   iov, c) != 0) {
+                       log_warn("%s: failed to compose IMSG_CFG_TLS imsg for "
+                           "`%s'", __func__, srv->srv_conf.name);
+                       return (-1);
+               }
+       }
+
+       return (0);
+}
+
+int
  config_getserver_auth(struct httpd *env, struct server_config *srv_conf)
  {
        struct privsep          *ps = env->sc_ps;
@@ -422,9 +483,7 @@ config_getserver(struct httpd *env, stru
        /* Reset these variables to avoid free'ing invalid pointers */
        serverconfig_reset(&srv_conf);
- if ((IMSG_DATA_SIZE(imsg) - s) <
-           (srv_conf.tls_cert_len + srv_conf.tls_key_len +
-           srv_conf.return_uri_len)) {
+       if ((IMSG_DATA_SIZE(imsg) - s) < (size_t)srv_conf.return_uri_len) {
                log_debug("%s: invalid message length", __func__);
                goto fail;
        }
@@ -475,17 +534,64 @@ config_getserver(struct httpd *env, stru
                        goto fail;
                s += srv->srv_conf.return_uri_len;
        }
-       if (srv->srv_conf.tls_cert_len != 0) {
+
+       return (0);
+
+ fail:
+       if (imsg->fd != -1)
+               close(imsg->fd);
+       if (srv != NULL)
+               free(srv->srv_conf.return_uri);
+       free(srv);
+
+       return (-1);
+}
+
+int
+config_gettls(struct httpd *env, struct imsg *imsg)
+{
+#ifdef DEBUG
+       struct privsep          *ps = env->sc_ps;
+#endif
+       struct server           *srv = NULL;
+       struct tls_config        tls_conf;
+       u_int8_t                *p = imsg->data;
+       size_t                   s;
+
+       IMSG_SIZE_CHECK(imsg, &tls_conf);
+       memcpy(&tls_conf, p, sizeof(tls_conf));
+       s = sizeof(tls_conf);
+
+       if ((IMSG_DATA_SIZE(imsg) - s) <
+           (tls_conf.tls_cert_len + tls_conf.tls_key_len)) {
+               log_debug("%s: invalid message length", __func__);
+               goto fail;
+       }
+
+       /* Find server with matching listening socket. */
+       if ((srv = server_byaddr((struct sockaddr *)
+           &tls_conf.ss, tls_conf.port)) == NULL) {
+               log_debug("%s: server not found", __func__);
+               goto fail;
+       }
+
+       DPRINTF("%s: %s %d TLS configuration \"%s[%u]\"", __func__,
+           ps->ps_title[privsep_process], ps->ps_instance,
+           srv->srv_conf.name, srv->srv_conf.id);
+
+       if (tls_conf.tls_cert_len != 0) {
+               srv->srv_conf.tls_cert_len = tls_conf.tls_cert_len;
                if ((srv->srv_conf.tls_cert = get_data(p + s,
-                   srv->srv_conf.tls_cert_len)) == NULL)
+                   tls_conf.tls_cert_len)) == NULL)
                        goto fail;
-               s += srv->srv_conf.tls_cert_len;
+               s += tls_conf.tls_cert_len;
        }
-       if (srv->srv_conf.tls_key_len != 0) {
+       if (tls_conf.tls_key_len != 0) {
+               srv->srv_conf.tls_key_len = tls_conf.tls_key_len;
                if ((srv->srv_conf.tls_key = get_data(p + s,
-                   srv->srv_conf.tls_key_len)) == NULL)
+                   tls_conf.tls_key_len)) == NULL)
                        goto fail;
-               s += srv->srv_conf.tls_key_len;
+               s += tls_conf.tls_key_len;
        }
return (0);
@@ -493,11 +599,6 @@ config_getserver(struct httpd *env, stru
   fail:
        if (imsg->fd != -1)
                close(imsg->fd);
-       if (srv != NULL) {
-               free(srv->srv_conf.tls_cert);
-               free(srv->srv_conf.tls_key);
-       }
-       free(srv);
return (-1);
  }
Index: httpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v
retrieving revision 1.82
diff -u -p -r1.82 httpd.h
--- httpd.h     15 Mar 2015 22:08:45 -0000      1.82
+++ httpd.h     14 May 2015 13:58:57 -0000
@@ -199,6 +199,7 @@ enum imsg_type {
        IMSG_CTL_START,
        IMSG_CTL_REOPEN,
        IMSG_CFG_SERVER,
+       IMSG_CFG_TLS,
        IMSG_CFG_MEDIA,
        IMSG_CFG_AUTH,
        IMSG_CFG_DONE,
@@ -436,6 +437,18 @@ struct server_config {
  };
  TAILQ_HEAD(serverhosts, server_config);
+struct tls_config {
+       u_int32_t                id;
+
+       in_port_t                port;
+       struct sockaddr_storage  ss;
+
+       u_int8_t                *tls_cert;
+       size_t                   tls_cert_len;
+       u_int8_t                *tls_key;
+       size_t                   tls_key_len;
+};
+
  struct server {
        TAILQ_ENTRY(server)      srv_entry;
        struct server_config     srv_conf;
@@ -674,7 +687,9 @@ int  config_setreset(struct httpd *, u_i
  int    config_getreset(struct httpd *, struct imsg *);
  int    config_getcfg(struct httpd *, struct imsg *);
  int    config_setserver(struct httpd *, struct server *);
+int     config_settls(struct httpd *, struct server *);
  int    config_getserver(struct httpd *, struct imsg *);
+int     config_gettls(struct httpd *, struct imsg *);
  int    config_setmedia(struct httpd *, struct media_type *);
  int    config_getmedia(struct httpd *, struct imsg *);
  int    config_setauth(struct httpd *, struct auth *);
Index: server.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server.c,v
retrieving revision 1.63
diff -u -p -r1.63 server.c
--- server.c    23 Apr 2015 16:59:28 -0000      1.63
+++ server.c    14 May 2015 13:58:57 -0000
@@ -1118,6 +1118,9 @@ server_dispatch_parent(int fd, struct pr
        case IMSG_CFG_SERVER:
                config_getserver(env, imsg);
                break;
+       case IMSG_CFG_TLS:
+               config_gettls(env, imsg);
+               break;
        case IMSG_CFG_DONE:
                config_getcfg(env, imsg);
                break;


Thank you Joel!

This patch resolves this problem. There is full chain received by browser (and sent by httpd).
I also moved source to 5.7-release and compiled - works fine.

michal@michal-MSQ87TN:~$ openssl s_client -connect 10.11.0.200:443
CONNECTED(00000003)
depth=2 C = IL, O = StartCom Ltd., OU = Secure Digital Certificate Signing, CN = StartCom Certification Authority
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
 0 s:/C=PL/ST=Mazowieckie/L=Warszawa/O=XXX/CN=XXX/emailAddress=XXX
i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 2 Primary Intermediate Server CA 1 s:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 2 Primary Intermediate Server CA i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority 2 s:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
(Primary SSL certificate: server.pem)
-----END CERTIFICATE-----
subject=/C=PL/ST=Mazowieckie/L=Warszawa/O=XXX/CN=XXX/emailAddress=XXX
issuer=/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 2 Primary Intermediate Server CA
---
No client certificate CA names sent
---
SSL handshake has read 7458 bytes and written 511 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 8192 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: A0E092B9E0E87D690895CC867668900781C6C210BC8759A21D229A995079368F
    Session-ID-ctx:
Master-Key: E2A995E0041ACEEB54770724C0B82059C12264C3361A1BDE6480AE5DAE4DD805CD34B8830DD6511400B77E997B77C56D
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - a5 79 ac c4 25 60 d7 43-36 66 9b db 52 2c 0e ae .y..%`.C6f..R,..
    0010 - 00 ea 6d 98 ad 3c e0 ec-43 fe 1c 92 5a 51 7e e2 ..m..<..C...ZQ~.
    0020 - f5 02 87 06 52 fa b7 29-ae 2e 45 dd e9 42 59 86 ....R..)..E..BY.
    0030 - 74 62 68 b0 69 ba 65 55-07 88 9d 67 1d b9 81 1e tbh.i.eU...g....
    0040 - 2d 71 ea 72 0e b5 34 0b-07 cf da ef a1 d2 5d 59 -q.r..4.......]Y
    0050 - e6 09 27 d1 a5 fc 2e 51-32 19 3b 2e ee d8 38 03 ..'....Q2.;...8.
    0060 - ab ac 15 54 2a d4 1c 16-9b 8f f0 50 77 08 df af ...T*......Pw...
    0070 - 74 51 ae 7f 59 5a 3b 79-78 78 5c d0 dc e8 e0 1c tQ..YZ;yxx\.....
    0080 - e0 03 d5 91 f8 92 6d 8a-61 66 ee bb d5 31 9c 62 ......m.af...1.b
    0090 - 3d 47 c2 94 b5 0e b5 99-c8 2c c7 77 cb b0 ab 23 =G.......,.w...#
    00a0 - f0 2e 5c 7a 3a 68 30 a6-7e 03 8c 23 7e 7c 2a 48 ..\z:h0.~..#~|*H
    00b0 - 9a 81 94 6c fc 25 9c 18-b6 84 3c 78 21 f6 e0 ae ...l.%....<x!...

    Start Time: 1431617780
    Timeout   : 300 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
---
DONE



# httpd -dvvvvvvvvvvvvv
startup
socket_rlimit: max open files 1024
server_tls_load_keypair: using certificate /etc/ssl/server-unified.pem
server_tls_load_keypair: using private key /etc/ssl/private/server.key
server_privinit: adding server default
server_privinit: adding server default
config_settls: configuring TLS for default
socket_rlimit: max open files 1024
socket_rlimit: max open files 1024
server_launch: running server default
server_tls_init: setting up TLS for default
server_launch: running server default
server_tls_init: setting up TLS for default
server_launch: running server default
server_launch: running server default
server_launch: running server default
server_tls_init: setting up TLS for default
server_launch: running server default
default 10.11.0.100 - - [14/May/2015:18:04:16 +0200] "GET / HTTP/1.1" 200 7
^Clogger exiting, pid 21624
server exiting, pid 27906
server exiting, pid 4429
server exiting, pid 17735
parent terminating, pid 19215

Reply via email to