cert_comp_test.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  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
  8. */
  9. /*
  10. * We need access to the deprecated low level HMAC APIs for legacy purposes
  11. * when the deprecated calls are not hidden
  12. */
  13. #ifndef OPENSSL_NO_DEPRECATED_3_0
  14. # define OPENSSL_SUPPRESS_DEPRECATED
  15. #endif
  16. #include <openssl/ssl.h>
  17. #include "internal/nelem.h"
  18. #include "helpers/ssltestlib.h"
  19. #include "testutil.h"
  20. #include "../ssl/ssl_local.h"
  21. #undef OSSL_NO_USABLE_TLS1_3
  22. #if defined(OPENSSL_NO_TLS1_3) \
  23. || (defined(OPENSSL_NO_EC) && defined(OPENSSL_NO_DH))
  24. /*
  25. * If we don't have ec or dh then there are no built-in groups that are usable
  26. * with TLSv1.3
  27. */
  28. # define OSSL_NO_USABLE_TLS1_3
  29. #endif
  30. #if !defined(OSSL_NO_USEABLE_TLS1_3)
  31. static char *certsdir = NULL;
  32. static char *cert = NULL;
  33. static char *privkey = NULL;
  34. static int client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
  35. {
  36. X509 *xcert;
  37. EVP_PKEY *privpkey;
  38. BIO *in = NULL;
  39. BIO *priv_in = NULL;
  40. /* Check that SSL_get0_peer_certificate() returns something sensible */
  41. if (!TEST_ptr(SSL_get0_peer_certificate(ssl)))
  42. return 0;
  43. in = BIO_new_file(cert, "r");
  44. if (!TEST_ptr(in))
  45. return 0;
  46. if (!TEST_ptr(xcert = X509_new_ex(NULL, NULL))
  47. || !TEST_ptr(PEM_read_bio_X509(in, &xcert, NULL, NULL))
  48. || !TEST_ptr(priv_in = BIO_new_file(privkey, "r"))
  49. || !TEST_ptr(privpkey = PEM_read_bio_PrivateKey_ex(priv_in, NULL,
  50. NULL, NULL,
  51. NULL, NULL)))
  52. goto err;
  53. *x509 = xcert;
  54. *pkey = privpkey;
  55. BIO_free(in);
  56. BIO_free(priv_in);
  57. return 1;
  58. err:
  59. X509_free(xcert);
  60. BIO_free(in);
  61. BIO_free(priv_in);
  62. return 0;
  63. }
  64. static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
  65. {
  66. return 1;
  67. }
  68. /*
  69. * Test 0 = app pre-compresses certificate in SSL
  70. * Test 1 = app pre-compresses certificate in SSL_CTX
  71. * Test 2 = app pre-compresses certificate in SSL_CTX, client authentication
  72. * Test 3 = app pre-compresses certificate in SSL_CTX, but it's unused due to prefs
  73. */
  74. /* Compression helper */
  75. static int ssl_comp_cert(SSL *ssl, int alg)
  76. {
  77. unsigned char *comp_data = NULL;
  78. size_t comp_len = 0;
  79. size_t orig_len = 0;
  80. int retval = 0;
  81. if (!TEST_size_t_gt(comp_len = SSL_get1_compressed_cert(ssl, alg, &comp_data, &orig_len), 0))
  82. goto err;
  83. if (!TEST_true(SSL_set1_compressed_cert(ssl, alg, comp_data, comp_len, orig_len)))
  84. goto err;
  85. retval = alg;
  86. err:
  87. OPENSSL_free(comp_data);
  88. return retval;
  89. }
  90. static void cert_comp_info_cb(const SSL *s, int where, int ret)
  91. {
  92. int *seen = (int*)SSL_get_app_data(s);
  93. if (SSL_is_server(s)) {
  94. /* TLS_ST_SR_COMP_CERT */
  95. if (!strcmp(SSL_state_string(s), "TRCCC") && seen != NULL)
  96. *seen = 1;
  97. } else {
  98. /* TLS_ST_CR_COMP_CERT */
  99. if (!strcmp(SSL_state_string(s), "TRSCC") && seen != NULL)
  100. *seen = 1;
  101. }
  102. }
  103. static int test_ssl_cert_comp(int test)
  104. {
  105. SSL_CTX *cctx = NULL, *sctx = NULL;
  106. SSL *clientssl = NULL, *serverssl = NULL;
  107. int testresult = 0;
  108. int expected_client = TLSEXT_comp_cert_none;
  109. int expected_server = TLSEXT_comp_cert_none;
  110. int client_seen = 0;
  111. int server_seen = 0;
  112. /* reverse default order */
  113. int server_pref[] = { TLSEXT_comp_cert_zstd, TLSEXT_comp_cert_zlib, TLSEXT_comp_cert_brotli };
  114. /* default order */
  115. int client_pref[] = { TLSEXT_comp_cert_brotli, TLSEXT_comp_cert_zlib, TLSEXT_comp_cert_zstd };
  116. /* one of these *must* be defined! */
  117. #ifndef OPENSSL_NO_BROTLI
  118. expected_server = TLSEXT_comp_cert_brotli;
  119. expected_client = TLSEXT_comp_cert_brotli;
  120. #endif
  121. #ifndef OPENSSL_NO_ZLIB
  122. expected_server = TLSEXT_comp_cert_zlib;
  123. if (expected_client == TLSEXT_comp_cert_none)
  124. expected_client = TLSEXT_comp_cert_zlib;
  125. #endif
  126. #ifndef OPENSSL_NO_ZSTD
  127. expected_server = TLSEXT_comp_cert_zstd;
  128. if (expected_client == TLSEXT_comp_cert_none)
  129. expected_client = TLSEXT_comp_cert_zstd;
  130. #endif
  131. /*
  132. * If there's only one comp algorithm, pref won't do much
  133. * Coverity can get confused in this case, and consider test == 3
  134. * to be DEADCODE
  135. */
  136. if (test == 3 && expected_client == expected_server) {
  137. TEST_info("Only one compression algorithm configured");
  138. return 1;
  139. }
  140. if (!TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(),
  141. TLS_client_method(),
  142. TLS1_3_VERSION, 0,
  143. &sctx, &cctx, cert, privkey)))
  144. goto end;
  145. if (test == 3) {
  146. /* coverity[deadcode] */
  147. server_pref[0] = expected_server;
  148. server_pref[1] = expected_client;
  149. if (!TEST_true(SSL_CTX_set1_cert_comp_preference(sctx, server_pref, 2)))
  150. goto end;
  151. client_pref[0] = expected_client;
  152. if (!TEST_true(SSL_CTX_set1_cert_comp_preference(cctx, client_pref, 1)))
  153. goto end;
  154. } else {
  155. if (!TEST_true(SSL_CTX_set1_cert_comp_preference(sctx, server_pref, OSSL_NELEM(server_pref))))
  156. goto end;
  157. if (!TEST_true(SSL_CTX_set1_cert_comp_preference(cctx, client_pref, OSSL_NELEM(client_pref))))
  158. goto end;
  159. }
  160. if (test == 2) {
  161. /* Use callbacks from test_client_cert_cb() */
  162. SSL_CTX_set_client_cert_cb(cctx, client_cert_cb);
  163. SSL_CTX_set_verify(sctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
  164. }
  165. if (test == 1 || test== 2 || test == 3) {
  166. if (!TEST_true(SSL_CTX_compress_certs(sctx, expected_server)))
  167. goto end;
  168. }
  169. if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
  170. NULL, NULL)))
  171. goto end;
  172. if (!TEST_true(SSL_set_app_data(clientssl, &client_seen)))
  173. goto end;
  174. if (!TEST_true(SSL_set_app_data(serverssl, &server_seen)))
  175. goto end;
  176. SSL_set_info_callback(clientssl, cert_comp_info_cb);
  177. SSL_set_info_callback(serverssl, cert_comp_info_cb);
  178. if (test == 0) {
  179. if (!TEST_int_eq(ssl_comp_cert(serverssl, expected_server), expected_server))
  180. goto end;
  181. }
  182. if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
  183. goto end;
  184. if (test == 3) {
  185. /* coverity[deadcode] */
  186. SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(serverssl);
  187. /* expect that the pre-compressed cert won't be used */
  188. if (!TEST_int_eq(sc->cert->key->cert_comp_used, 0))
  189. goto end;
  190. if (!TEST_false(*(int*)SSL_get_app_data(clientssl)))
  191. goto end;
  192. } else {
  193. SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(serverssl);
  194. if (!TEST_int_gt(sc->cert->key->cert_comp_used, 0))
  195. goto end;
  196. if (!TEST_true(*(int*)SSL_get_app_data(clientssl)))
  197. goto end;
  198. }
  199. if (test == 2) {
  200. /* Only for client auth */
  201. if (!TEST_true(*(int*)SSL_get_app_data(serverssl)))
  202. goto end;
  203. }
  204. testresult = 1;
  205. end:
  206. SSL_free(serverssl);
  207. SSL_free(clientssl);
  208. SSL_CTX_free(sctx);
  209. SSL_CTX_free(cctx);
  210. return testresult;
  211. }
  212. #endif
  213. OPT_TEST_DECLARE_USAGE("certdir\n")
  214. int setup_tests(void)
  215. {
  216. #if !defined(OSSL_NO_USEABLE_TLS1_3)
  217. if (!test_skip_common_options()) {
  218. TEST_error("Error parsing test options\n");
  219. return 0;
  220. }
  221. if (!TEST_ptr(certsdir = test_get_argument(0)))
  222. return 0;
  223. cert = test_mk_file_path(certsdir, "servercert.pem");
  224. if (cert == NULL)
  225. goto err;
  226. privkey = test_mk_file_path(certsdir, "serverkey.pem");
  227. if (privkey == NULL)
  228. goto err;
  229. ADD_ALL_TESTS(test_ssl_cert_comp, 4);
  230. return 1;
  231. err:
  232. OPENSSL_free(cert);
  233. OPENSSL_free(privkey);
  234. return 0;
  235. #else
  236. return 1;
  237. #endif
  238. }
  239. void cleanup_tests(void)
  240. {
  241. #if !defined(OSSL_NO_USEABLE_TLS1_3)
  242. OPENSSL_free(cert);
  243. OPENSSL_free(privkey);
  244. #endif
  245. }