test_x509.c (6945B)
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 mock_failing_digest(char *digest, const char *m, size_t len) 30 { 31 (void)digest; 32 (void)m; 33 (void)len; 34 return -1; 35 } 36 37 static void 38 test_x509_cert_new_failing_digest(void *arg) 39 { 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); 46 47 impl = tor_tls_create_certificate(pk1, pk2, "hello", "world", 86400*100); 48 tt_assert(impl); 49 MOCK(crypto_digest, mock_failing_digest); 50 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"); 56 57 done: 58 crypto_pk_free(pk1); 59 crypto_pk_free(pk2); 60 UNMOCK(crypto_digest); 61 teardown_capture_of_logs(); 62 } 63 64 static tor_x509_cert_t * 65 cert_from_der64(const char *der64) 66 { 67 size_t der64len = strlen(der64); 68 unsigned char *der = tor_malloc_zero(der64len); 69 int derlen; 70 tor_x509_cert_t *cert = NULL; 71 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; 78 } 79 80 static void 81 test_x509_consume_ec_cert(void *arg) 82 { 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); 96 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. 99 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)); 102 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"); 107 108 done: 109 tor_x509_cert_free(cert); 110 crypto_pk_free(key); 111 teardown_capture_of_logs(); 112 } 113 114 static void 115 test_x509_reject_tiny_keys(void *arg) 116 { 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" 135 }; 136 const time_t now = 1535046182; 137 tor_x509_cert_t *cert = NULL; 138 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); 148 } 149 150 done: 151 tor_x509_cert_free(cert); 152 } 153 154 static void 155 test_x509_expiration(void *arg) 156 { 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; 177 178 tor_x509_cert_t *cert = cert_from_der64(certificate); 179 tt_assert(cert); 180 181 tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert, now, 0)); 182 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)); 187 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)); 192 193 done: 194 tor_x509_cert_free(cert); 195 } 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 };