summaryrefslogtreecommitdiffstats
path: root/reg-tests/ssl/set_ssl_cafile.vtc
blob: 3881a42273d61db8403f5fa1e2d47664885d9b36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#REGTEST_TYPE=devel

# This reg-test uses the "set ssl ca-file" command to update a CA file over the CLI.
# It also tests the "abort ssl ca-file" and "show ssl ca-file" commands.
#
# It is based on two CA certificates, set_cafile_interCA1.crt and set_cafile_interCA2.crt,
# and a client certificate that was signed with set_cafile_interCA1.crt (set_cafile_client.pem)
# and a server certificate that was signed with set_cafile_interCA2.crt (set_cafile_server.pem).
# The CA files used by the client and the server will be updated through the CLI until a
# proper connection can be established between them.
#
# It requires socat to upload the certificate
#
# If this test does not work anymore:
# - Check that you have socat

varnishtest "Test the 'set ssl ca-file' feature of the CLI"
feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'"
feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)' && !ssllib_name_startswith(wolfSSL)'"
feature cmd "command -v socat"
feature ignore_unknown_macro

server s1 -repeat 4 {
  rxreq
  txresp
} -start

haproxy h1 -conf {
    global
        tune.ssl.default-dh-param 2048
        tune.ssl.capture-buffer-size 1
        stats socket "${tmpdir}/h1/stats" level admin

    defaults
        mode http
        option httplog
	retries 0
        log stderr local0 debug err
        option logasap
        timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
        timeout client  "${HAPROXY_TEST_TIMEOUT-5s}"
        timeout server  "${HAPROXY_TEST_TIMEOUT-5s}"

    listen clear-lst
        bind "fd@${clearlst}"
       # dummy bind used to test a change when the same crt is used as server and bind
        bind "fd@${foobarlst}" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA1.crt verify none
        server s1 "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA1.crt verify none

    listen clear-verified-lst
        bind "fd@${clearverifiedlst}"
        server s1 "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA1.crt verify required

    listen ssl-lst
        # crt: certificate of the server
        # ca-file: CA used for client authentication request
        bind "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_server.pem ca-verify-file ${testdir}/set_cafile_rootCA.crt ca-file ${testdir}/set_cafile_interCA2.crt verify required crt-ignore-err all
        http-response add-header X-SSL-Client-Verify %[ssl_c_verify]
        server s1 ${s1_addr}:${s1_port}
} -start


# Test the "show ssl ca-file" command
haproxy h1 -cli {
    send "show ssl ca-file"
    expect ~ ".*${testdir}/set_cafile_interCA1.crt - 1 certificate.*"
    send "show ssl ca-file"
    expect ~ ".*${testdir}/set_cafile_interCA2.crt - 1 certificate.*"

    send "show ssl ca-file ${testdir}/set_cafile_interCA2.crt"
    expect ~ ".*SHA1 FingerPrint: 3D3D1D10AD74A8135F05A818E10E5FA91433954D"
}


# This first connection should fail because the client's certificate was signed with the
# set_cafile_interCA1.crt certificate which is not known by the backend.
client c1 -connect ${h1_clearlst_sock} {
    txreq
    rxresp
    expect resp.status == 200
    # unable to verify the client certificate
    expect resp.http.X-SSL-Client-Verify ~ "20|21"
} -run

# Set a new ca-file without committing it and check that the new ca-file is not taken into account
shell {
    printf "set ssl ca-file ${testdir}/set_cafile_interCA2.crt <<\n$(cat ${testdir}/set_cafile_interCA1.crt)\n\n" | socat "${tmpdir}/h1/stats" -
}

# Test the "show ssl ca-file" command
# The transaction should be mentioned in the list
haproxy h1 -cli {
    send "show ssl ca-file"
    expect ~ "\\*${testdir}/set_cafile_interCA2.crt - 1 certificate.*"

# The original CA file did not change
    send "show ssl ca-file ${testdir}/set_cafile_interCA2.crt"
    expect ~ ".*SHA1 FingerPrint: 3D3D1D10AD74A8135F05A818E10E5FA91433954D"

# Only the current transaction displays a new certificate
    send "show ssl ca-file *${testdir}/set_cafile_interCA2.crt"
    expect ~ ".*SHA1 FingerPrint: 4FFF535278883264693CEA72C4FAD13F995D0098"
}

# This connection should still fail for the same reasons as previously
client c1 -connect ${h1_clearlst_sock} {
    txreq
    rxresp
    expect resp.status == 200
    # unable to verify the client certificate
    expect resp.http.X-SSL-Client-Verify ~ "20|21"
} -run

haproxy h1 -cli {
    send "abort ssl ca-file ${testdir}/set_cafile_interCA2.crt"
    expect ~ "Transaction aborted for certificate '${testdir}/set_cafile_interCA2.crt'!"
    send "commit ssl ca-file ${testdir}/set_cafile_interCA2.crt"
    expect ~ "No ongoing transaction!"
}


# Update the bind line's ca-file in order to accept the client certificate
shell {
    printf "set ssl ca-file ${testdir}/set_cafile_interCA2.crt <<\n$(cat ${testdir}/set_cafile_interCA1.crt)\n$(cat ${testdir}/set_cafile_rootCA.crt)\n\n" | socat "${tmpdir}/h1/stats" -
    echo "commit ssl ca-file ${testdir}/set_cafile_interCA2.crt" | socat "${tmpdir}/h1/stats" -
}


# The backend's certificate can't be verified by the frontend because it was signed with
# the set_cafile_interCA2.crt certificate.
client c1 -connect ${h1_clearverifiedlst_sock} {
    txreq
    rxresp
    expect resp.status == 503
} -run


# Update the server line's ca-file. The server certificate should now be accepted by
# the frontend. We replace the single CA by a list of CAs that includes the correct one.
shell {
    printf "set ssl ca-file ${testdir}/set_cafile_interCA1.crt <<\n$(cat ${testdir}/set_cafile_interCA1.crt)\n\n" | socat "${tmpdir}/h1/stats" -
    printf "add ssl ca-file ${testdir}/set_cafile_interCA1.crt <<\n$(cat ${testdir}/set_cafile_interCA2.crt)\n\n" | socat "${tmpdir}/h1/stats" -
    printf "add ssl ca-file ${testdir}/set_cafile_interCA1.crt <<\n$(cat ${testdir}/set_cafile_rootCA.crt)\n\n" | socat "${tmpdir}/h1/stats" -
    echo "commit ssl ca-file ${testdir}/set_cafile_interCA1.crt" | socat "${tmpdir}/h1/stats" -
}

# Test the "show ssl ca-file" with a certificate index
haproxy h1 -cli {
    send "show ssl ca-file"
    expect ~ ".*${testdir}/set_cafile_interCA1.crt - 3 certificate.*"

    send "show ssl ca-file ${testdir}/set_cafile_interCA1.crt:1"
    expect ~ ".*SHA1 FingerPrint: 4FFF535278883264693CEA72C4FAD13F995D0098"

    send "show ssl ca-file ${testdir}/set_cafile_interCA1.crt:2"
    expect !~ ".*SHA1 FingerPrint: 4FFF535278883264693CEA72C4FAD13F995D0098"
    send "show ssl ca-file ${testdir}/set_cafile_interCA1.crt:2"
    expect ~ ".*SHA1 FingerPrint: 3D3D1D10AD74A8135F05A818E10E5FA91433954D"
}

client c1 -connect ${h1_clearverifiedlst_sock} {
    txreq
    rxresp
    expect resp.status == 200
    # there should be no error on the backend side but one on the frontend side
    expect resp.http.X-SSL-Client-Verify == 0
} -run