2 * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 * We need access to the deprecated low level HMAC APIs for legacy purposes
12 * when the deprecated calls are not hidden
14 #ifndef OPENSSL_NO_DEPRECATED_3_0
15 # define OPENSSL_SUPPRESS_DEPRECATED
18 #include <openssl/ssl.h>
19 #include "internal/nelem.h"
20 #include "helpers/ssltestlib.h"
22 #include "../ssl/ssl_local.h"
24 #undef OSSL_NO_USABLE_TLS1_3
25 #if defined(OPENSSL_NO_TLS1_3) \
26 || (defined(OPENSSL_NO_EC) && defined(OPENSSL_NO_DH))
28 * If we don't have ec or dh then there are no built-in groups that are usable
31 # define OSSL_NO_USABLE_TLS1_3
34 #if !defined(OSSL_NO_USEABLE_TLS1_3)
36 static char *certsdir
= NULL
;
37 static char *cert
= NULL
;
38 static char *privkey
= NULL
;
40 static int client_cert_cb(SSL
*ssl
, X509
**x509
, EVP_PKEY
**pkey
)
47 /* Check that SSL_get0_peer_certificate() returns something sensible */
48 if (!TEST_ptr(SSL_get0_peer_certificate(ssl
)))
51 in
= BIO_new_file(cert
, "r");
55 if (!TEST_ptr(xcert
= X509_new_ex(NULL
, NULL
))
56 || !TEST_ptr(PEM_read_bio_X509(in
, &xcert
, NULL
, NULL
))
57 || !TEST_ptr(priv_in
= BIO_new_file(privkey
, "r"))
58 || !TEST_ptr(privpkey
= PEM_read_bio_PrivateKey_ex(priv_in
, NULL
,
76 static int verify_cb(int preverify_ok
, X509_STORE_CTX
*x509_ctx
)
82 * Test 0 = app pre-compresses certificate in SSL
83 * Test 1 = app pre-compresses certificate in SSL_CTX
84 * Test 2 = app pre-compresses certificate in SSL_CTX, client authentication
85 * Test 3 = app pre-compresses certificate in SSL_CTX, but it's unused due to prefs
87 /* Compression helper */
88 static int ssl_comp_cert(SSL
*ssl
, int alg
)
90 unsigned char *comp_data
= NULL
;
95 if (!TEST_size_t_gt(comp_len
= SSL_get1_compressed_cert(ssl
, alg
, &comp_data
, &orig_len
), 0))
98 if (!TEST_true(SSL_set1_compressed_cert(ssl
, alg
, comp_data
, comp_len
, orig_len
)))
103 OPENSSL_free(comp_data
);
107 static void cert_comp_info_cb(const SSL
*s
, int where
, int ret
)
109 int *seen
= (int*)SSL_get_app_data(s
);
111 if (SSL_is_server(s
)) {
112 /* TLS_ST_SR_COMP_CERT */
113 if (!strcmp(SSL_state_string(s
), "TRCCC") && seen
!= NULL
)
116 /* TLS_ST_CR_COMP_CERT */
117 if (!strcmp(SSL_state_string(s
), "TRSCC") && seen
!= NULL
)
122 static int test_ssl_cert_comp(int test
)
124 SSL_CTX
*cctx
= NULL
, *sctx
= NULL
;
125 SSL
*clientssl
= NULL
, *serverssl
= NULL
;
127 int expected_client
= TLSEXT_comp_cert_none
;
128 int expected_server
= TLSEXT_comp_cert_none
;
131 /* reverse default order */
132 int server_pref
[] = { TLSEXT_comp_cert_zstd
, TLSEXT_comp_cert_zlib
, TLSEXT_comp_cert_brotli
};
134 int client_pref
[] = { TLSEXT_comp_cert_brotli
, TLSEXT_comp_cert_zlib
, TLSEXT_comp_cert_zstd
};
136 /* one of these *must* be defined! */
137 #ifndef OPENSSL_NO_BROTLI
138 expected_server
= TLSEXT_comp_cert_brotli
;
139 expected_client
= TLSEXT_comp_cert_brotli
;
141 #ifndef OPENSSL_NO_ZLIB
142 expected_server
= TLSEXT_comp_cert_zlib
;
143 if (expected_client
== TLSEXT_comp_cert_none
)
144 expected_client
= TLSEXT_comp_cert_zlib
;
146 #ifndef OPENSSL_NO_ZSTD
147 expected_server
= TLSEXT_comp_cert_zstd
;
148 if (expected_client
== TLSEXT_comp_cert_none
)
149 expected_client
= TLSEXT_comp_cert_zstd
;
152 * If there's only one comp algorithm, pref won't do much
153 * Coverity can get confused in this case, and consider test == 3
156 if (test
== 3 && expected_client
== expected_server
) {
157 TEST_info("Only one compression algorithm configured");
161 if (!TEST_true(create_ssl_ctx_pair(NULL
, TLS_server_method(),
164 &sctx
, &cctx
, cert
, privkey
)))
167 /* coverity[deadcode] */
168 server_pref
[0] = expected_server
;
169 server_pref
[1] = expected_client
;
170 if (!TEST_true(SSL_CTX_set1_cert_comp_preference(sctx
, server_pref
, 2)))
172 client_pref
[0] = expected_client
;
173 if (!TEST_true(SSL_CTX_set1_cert_comp_preference(cctx
, client_pref
, 1)))
176 if (!TEST_true(SSL_CTX_set1_cert_comp_preference(sctx
, server_pref
, OSSL_NELEM(server_pref
))))
178 if (!TEST_true(SSL_CTX_set1_cert_comp_preference(cctx
, client_pref
, OSSL_NELEM(client_pref
))))
182 /* Use callbacks from test_client_cert_cb() */
183 SSL_CTX_set_client_cert_cb(cctx
, client_cert_cb
);
184 SSL_CTX_set_verify(sctx
, SSL_VERIFY_PEER
| SSL_VERIFY_FAIL_IF_NO_PEER_CERT
, verify_cb
);
187 if (test
== 1 || test
== 2 || test
== 3) {
188 if (!TEST_true(SSL_CTX_compress_certs(sctx
, expected_server
)))
192 if (!TEST_true(create_ssl_objects(sctx
, cctx
, &serverssl
, &clientssl
,
196 if (!TEST_true(SSL_set_app_data(clientssl
, &client_seen
)))
198 if (!TEST_true(SSL_set_app_data(serverssl
, &server_seen
)))
200 SSL_set_info_callback(clientssl
, cert_comp_info_cb
);
201 SSL_set_info_callback(serverssl
, cert_comp_info_cb
);
204 if (!TEST_int_eq(ssl_comp_cert(serverssl
, expected_server
), expected_server
))
208 if (!TEST_true(create_ssl_connection(serverssl
, clientssl
, SSL_ERROR_NONE
)))
211 /* coverity[deadcode] */
212 SSL_CONNECTION
*sc
= SSL_CONNECTION_FROM_SSL(serverssl
);
214 /* expect that the pre-compressed cert won't be used */
215 if (!TEST_int_eq(sc
->cert
->key
->cert_comp_used
, 0))
218 if (!TEST_false(*(int*)SSL_get_app_data(clientssl
)))
221 SSL_CONNECTION
*sc
= SSL_CONNECTION_FROM_SSL(serverssl
);
223 if (!TEST_int_gt(sc
->cert
->key
->cert_comp_used
, 0))
226 if (!TEST_true(*(int*)SSL_get_app_data(clientssl
)))
231 /* Only for client auth */
232 if (!TEST_true(*(int*)SSL_get_app_data(serverssl
)))
248 OPT_TEST_DECLARE_USAGE("certdir\n")
250 int setup_tests(void)
252 #if !defined(OSSL_NO_USEABLE_TLS1_3)
253 if (!test_skip_common_options()) {
254 TEST_error("Error parsing test options\n");
258 if (!TEST_ptr(certsdir
= test_get_argument(0)))
261 cert
= test_mk_file_path(certsdir
, "servercert.pem");
265 privkey
= test_mk_file_path(certsdir
, "serverkey.pem");
269 ADD_ALL_TESTS(test_ssl_cert_comp
, 4);
274 OPENSSL_free(privkey
);
281 void cleanup_tests(void)
283 #if !defined(OSSL_NO_USEABLE_TLS1_3)
285 OPENSSL_free(privkey
);