Merge branch 'maint-0.4.5' into release-0.4.5
[tor.git] / src / test / test_x509.c
blob94e7db33dee5156d36d184b40d5dd2d176ca54a9
1 /* Copyright (c) 2010-2020, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 #define TOR_X509_PRIVATE
5 #include "orconfig.h"
7 #ifdef _WIN32
8 #include <winsock2.h>
9 #endif
10 #include <math.h>
11 #include <stddef.h>
13 #include "lib/cc/compat_compiler.h"
15 #include "core/or/or.h"
16 #include "lib/log/log.h"
17 #include "app/config/config.h"
18 #include "lib/tls/x509.h"
19 #include "lib/tls/x509_internal.h"
20 #include "app/config/or_state_st.h"
22 #include "test/test.h"
23 #include "test/log_test_helpers.h"
25 #include "tinytest.h"
27 /* A mock replacement for crypto_digest that always fails. */
28 static int
29 mock_failing_digest(char *digest, const char *m, size_t len)
31 (void)digest;
32 (void)m;
33 (void)len;
34 return -1;
37 static void
38 test_x509_cert_new_failing_digest(void *arg)
40 (void)arg;
41 crypto_pk_t *pk1=NULL, *pk2=NULL;
42 tor_x509_cert_impl_t *impl = NULL;
43 tor_x509_cert_t *cert = NULL;
44 pk1 = pk_generate(0);
45 pk2 = pk_generate(1);
47 impl = tor_tls_create_certificate(pk1, pk2, "hello", "world", 86400*100);
48 tt_assert(impl);
49 MOCK(crypto_digest, mock_failing_digest);
51 setup_full_capture_of_logs(LOG_WARN);
52 cert = tor_x509_cert_new(impl);
53 tt_assert(!cert);
54 expect_log_msg_containing("Couldn't wrap encoded X509 certificate");
55 expect_log_msg_containing("unable to compute digests of certificate key");
57 done:
58 crypto_pk_free(pk1);
59 crypto_pk_free(pk2);
60 UNMOCK(crypto_digest);
61 teardown_capture_of_logs();
64 static tor_x509_cert_t *
65 cert_from_der64(const char *der64)
67 size_t der64len = strlen(der64);
68 unsigned char *der = tor_malloc_zero(der64len);
69 int derlen;
70 tor_x509_cert_t *cert = NULL;
72 derlen = base64_decode((char*)der, der64len,
73 der64, der64len);
74 if (derlen >= 0)
75 cert = tor_x509_cert_decode(der, derlen);
76 tor_free(der);
77 return cert;
80 static void
81 test_x509_consume_ec_cert(void *arg)
83 (void)arg;
84 /* This is a small self-signed EC certificate. */
85 const char certificate[] =
86 "MIIBEzCBugIJAIdl5svgOZ0OMAoGCCqGSM49BAMCMBIxEDAOBgNVBAMMB1Rlc3Rp\n"
87 "bmcwHhcNMTgwODIzMTcyMzI1WhcNMTkwODIzMTcyMzI1WjASMRAwDgYDVQQDDAdU\n"
88 "ZXN0aW5nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExMDpnRc0Btic3tIyCKNE\n"
89 "iNY4j4gzcaYzS2sTYRoVK3RAukG29Qg6/c8e8XcnsSquU4fItYxDRbi/3nhYk4CP\n"
90 "GDAKBggqhkjOPQQDAgNIADBFAiA0h1q03C2xlONUgAOonJLrlV1SUtMeKDxNsxsU\n"
91 "+FSPvQIhAM7kY9Tlt0ELmyMnORPp1VJieXn/qhL5VoxGxSedTbny\n";
92 const time_t now = 1535045321; /* when I'm writing this test. */
93 tor_x509_cert_t *cert = cert_from_der64(certificate);
94 crypto_pk_t *key = NULL;
95 tt_assert(cert);
97 key = tor_tls_cert_get_key(cert);
98 tt_ptr_op(NULL, OP_EQ, key); // Can't get an RSA key out of an EC cert.
100 /* It's a self-signed cert -- make sure it signed itself. */
101 tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert, now, 0));
103 /* Make sure we detect its key as non-RSA1024 */
104 setup_capture_of_logs(LOG_INFO);
105 tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert, now, 1));
106 expect_log_msg_containing("Key is not RSA1024");
108 done:
109 tor_x509_cert_free(cert);
110 crypto_pk_free(key);
111 teardown_capture_of_logs();
114 static void
115 test_x509_reject_tiny_keys(void *arg)
117 (void)arg;
118 const char *certificates[] = {
119 /* Self-signed RSA512 */
120 "MIIBXDCCAQYCCQDKikjJYZI5uDANBgkqhkiG9w0BAQsFADA1MRUwEwYDVQQHDAxE\n"
121 "ZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMTgw\n"
122 "ODIzMTczNjQ4WhcNMTkwODIzMTczNjQ4WjA1MRUwEwYDVQQHDAxEZWZhdWx0IENp\n"
123 "dHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwXDANBgkqhkiG9w0BAQEF\n"
124 "AANLADBIAkEAqOvVKzrSpmKOTNqDzBG/iZrUdhCrMRsymFXyIScJcdsyn7jB8RMy\n"
125 "fbHqG8EqB8HHLU/eqt/+zhh2w08Lx3+5QwIDAQABMA0GCSqGSIb3DQEBCwUAA0EA\n"
126 "RSCq0sNbD9uWfcBqF0U4MtfFjU5x+RQQCeBVtAzwC9bggSILKZfB9XUvtGh6vqig\n",
127 /* Self-signed secp112r2 */
128 "MIIBLTCB+QIJAI0LtN9uWxy3MAoGCCqGSM49BAMCMEUxCzAJBgNVBAYTAkFVMRMw\n"
129 "EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0\n"
130 "eSBMdGQwHhcNMTgwODIzMTc0MTQ4WhcNMTkwODIzMTc0MTQ4WjBFMQswCQYDVQQG\n"
131 "EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lk\n"
132 "Z2l0cyBQdHkgTHRkMDIwEAYHKoZIzj0CAQYFK4EEAAcDHgAEf7dFHo7xhCtIcgyo\n"
133 "Px+IDcUUlntZCtar6V4O0zAKBggqhkjOPQQDAgMjADAgAg4yhBJMEmpkNbZU95Zf\n"
134 "uwIOJAan4J1ETxUII1RrGmw=\n"
136 const time_t now = 1535046182;
137 tor_x509_cert_t *cert = NULL;
139 unsigned i;
140 for (i = 0; i < ARRAY_LENGTH(certificates); ++i) {
141 cert = cert_from_der64(certificates[i]);
142 /* It might parse okay, depending on our version of NSS or OpenSSL. */
143 if (cert == NULL)
144 continue;
145 /* But it should not validate. */
146 tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert, now, 0));
147 tor_x509_cert_free(cert);
150 done:
151 tor_x509_cert_free(cert);
154 static void
155 test_x509_expiration(void *arg)
157 (void)arg;
158 /* a 365-day RSA2048 cert, created between 0 and 60 minutes before "now" */
159 const char certificate[] =
160 "MIICzjCCAbYCCQDxIONWIQ9OGDANBgkqhkiG9w0BAQsFADApMQswCQYDVQQGEwJV\n"
161 "UzEaMBgGA1UEAwwRSW50ZXJlc3RpbmcgdGltZXMwHhcNMTgwODIzMTc1NTE4WhcN\n"
162 "MTkwODIzMTc1NTE4WjApMQswCQYDVQQGEwJVUzEaMBgGA1UEAwwRSW50ZXJlc3Rp\n"
163 "bmcgdGltZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0Blz1fBii\n"
164 "OffpFlzMrmfPah/vkPcNrwoyx5YiosbHErYUpqdCtfNb7rbBM5xcac1LmF9kjnOQ\n"
165 "uAw1jsCNE82QHwWMlXOqaZCEJsnttNo0Y7yaSR/ChbGJ54XCp+Lx2acyTeH9cBWU\n"
166 "de8/sKAQ4NqpbEP01pBH4+1mPu2MYWjVWVicUxmw0mJ3cfkJCWUzt0nC4ls8+Itk\n"
167 "7XliKb216Z9uQXu/zD/JGkxAljnFs1jXCX4NyWz46xnJFzXbYCeyQnBz0tUbAvgg\n"
168 "uRdryYtHzD46hd8LTXH6oK2gV64ILAhDnRb1aBjnCXxbex24XoW3hjSrKGTdNsXA\n"
169 "RMWU/8QZaoiBAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFIYDBcbit2kOMrHECZK\n"
170 "ctem40A3s+0ZifzZ2KLhW8dTr/2Zb6DnlqVm2iUOV4cG/o1RAn/HzkQQuWEq+oBG\n"
171 "yOPVHudvCyGs+2ZQWudgAv9xq8N7KtZwJhnn42c2YSoreqRXDQgJqGFatyr+XdR7\n"
172 "gdQapLI4BFbZToeXp49Nl+q9330hKaSmIYmWEZ7R/33R64PU2el7X9/apYEcuZQT\n"
173 "+FjEqcO1lJ8/dTwM/2C1BJZqUeFTAu+ac1M+4//qyJRUUc6xSJLhiens8atWaxwL\n"
174 "eBCT8fCY8oPOwA1eImc/yWWmWXpv8bBWVe8OeLCMKM/OZoIdFqQpqSdcyGoh/kIW\n"
175 "Dws=\n";
176 const time_t now = 1535046996;
178 tor_x509_cert_t *cert = cert_from_der64(certificate);
179 tt_assert(cert);
181 tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert, now, 0));
183 tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert,
184 now-TOR_X509_FUTURE_SLOP, 0));
185 tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert,
186 now+365*86400+TOR_X509_PAST_SLOP - 3600, 0));
188 tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert,
189 now-TOR_X509_FUTURE_SLOP - 3600, 0));
190 tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert,
191 now+365*86400+TOR_X509_FUTURE_SLOP, 0));
193 done:
194 tor_x509_cert_free(cert);
197 #define TEST(name) { #name, test_x509_ ## name, TT_FORK, 0, NULL }
199 struct testcase_t x509_tests[] = {
200 TEST(cert_new_failing_digest),
201 TEST(consume_ec_cert),
202 TEST(reject_tiny_keys),
203 TEST(expiration),
204 END_OF_TESTCASES