Line data Source code
1 : /* Copyright (c) 2010-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : #define TOR_X509_PRIVATE
5 : #include "orconfig.h"
6 :
7 : #ifdef _WIN32
8 : #include <winsock2.h>
9 : #endif
10 : #include <math.h>
11 : #include <stddef.h>
12 :
13 : #include "lib/cc/compat_compiler.h"
14 :
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"
21 :
22 : #include "test/test.h"
23 : #include "test/log_test_helpers.h"
24 :
25 : #include "tinytest.h"
26 :
27 : /* A mock replacement for crypto_digest that always fails. */
28 : static int
29 2 : mock_failing_digest(char *digest, const char *m, size_t len)
30 : {
31 2 : (void)digest;
32 2 : (void)m;
33 2 : (void)len;
34 2 : return -1;
35 : }
36 :
37 : static void
38 1 : test_x509_cert_new_failing_digest(void *arg)
39 : {
40 1 : (void)arg;
41 1 : crypto_pk_t *pk1=NULL, *pk2=NULL;
42 1 : tor_x509_cert_impl_t *impl = NULL;
43 1 : tor_x509_cert_t *cert = NULL;
44 1 : pk1 = pk_generate(0);
45 1 : pk2 = pk_generate(1);
46 :
47 1 : impl = tor_tls_create_certificate(pk1, pk2, "hello", "world", 86400*100);
48 1 : tt_assert(impl);
49 1 : MOCK(crypto_digest, mock_failing_digest);
50 :
51 1 : setup_full_capture_of_logs(LOG_WARN);
52 1 : cert = tor_x509_cert_new(impl);
53 1 : tt_assert(!cert);
54 1 : expect_log_msg_containing("Couldn't wrap encoded X509 certificate");
55 1 : expect_log_msg_containing("unable to compute digests of certificate key");
56 :
57 1 : done:
58 1 : crypto_pk_free(pk1);
59 1 : crypto_pk_free(pk2);
60 1 : UNMOCK(crypto_digest);
61 1 : teardown_capture_of_logs();
62 1 : }
63 :
64 : static tor_x509_cert_t *
65 4 : cert_from_der64(const char *der64)
66 : {
67 4 : size_t der64len = strlen(der64);
68 4 : unsigned char *der = tor_malloc_zero(der64len);
69 4 : int derlen;
70 4 : tor_x509_cert_t *cert = NULL;
71 :
72 4 : derlen = base64_decode((char*)der, der64len,
73 : der64, der64len);
74 4 : if (derlen >= 0)
75 4 : cert = tor_x509_cert_decode(der, derlen);
76 4 : tor_free(der);
77 4 : return cert;
78 : }
79 :
80 : static void
81 1 : test_x509_consume_ec_cert(void *arg)
82 : {
83 1 : (void)arg;
84 : /* This is a small self-signed EC certificate. */
85 1 : 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 1 : const time_t now = 1535045321; /* when I'm writing this test. */
93 1 : tor_x509_cert_t *cert = cert_from_der64(certificate);
94 1 : crypto_pk_t *key = NULL;
95 1 : tt_assert(cert);
96 :
97 1 : key = tor_tls_cert_get_key(cert);
98 1 : tt_ptr_op(NULL, OP_EQ, key); // Can't get an RSA key out of an EC cert.
99 :
100 : /* It's a self-signed cert -- make sure it signed itself. */
101 1 : tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert, now, 0));
102 :
103 : /* Make sure we detect its key as non-RSA1024 */
104 1 : setup_capture_of_logs(LOG_INFO);
105 1 : tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert, now, 1));
106 1 : expect_log_msg_containing("Key is not RSA1024");
107 :
108 1 : done:
109 1 : tor_x509_cert_free(cert);
110 1 : crypto_pk_free(key);
111 1 : teardown_capture_of_logs();
112 1 : }
113 :
114 : static void
115 1 : test_x509_reject_tiny_keys(void *arg)
116 : {
117 1 : (void)arg;
118 1 : 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"
135 : };
136 1 : const time_t now = 1535046182;
137 1 : tor_x509_cert_t *cert = NULL;
138 :
139 1 : unsigned i;
140 3 : for (i = 0; i < ARRAY_LENGTH(certificates); ++i) {
141 2 : cert = cert_from_der64(certificates[i]);
142 : /* It might parse okay, depending on our version of NSS or OpenSSL. */
143 2 : if (cert == NULL)
144 1 : continue;
145 : /* But it should not validate. */
146 1 : tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert, now, 0));
147 2 : tor_x509_cert_free(cert);
148 : }
149 :
150 1 : done:
151 1 : tor_x509_cert_free(cert);
152 1 : }
153 :
154 : static void
155 1 : test_x509_expiration(void *arg)
156 : {
157 1 : (void)arg;
158 : /* a 365-day RSA2048 cert, created between 0 and 60 minutes before "now" */
159 1 : 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 1 : const time_t now = 1535046996;
177 :
178 1 : tor_x509_cert_t *cert = cert_from_der64(certificate);
179 1 : tt_assert(cert);
180 :
181 1 : tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert, now, 0));
182 :
183 1 : tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert,
184 : now-TOR_X509_FUTURE_SLOP, 0));
185 1 : tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert,
186 : now+365*86400+TOR_X509_PAST_SLOP - 3600, 0));
187 :
188 1 : tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert,
189 : now-TOR_X509_FUTURE_SLOP - 3600, 0));
190 1 : tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert,
191 : now+365*86400+TOR_X509_FUTURE_SLOP, 0));
192 :
193 1 : done:
194 1 : tor_x509_cert_free(cert);
195 1 : }
196 :
197 : #define TEST(name) { #name, test_x509_ ## name, TT_FORK, 0, NULL }
198 :
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
205 : };
|