|
@@ -0,0 +1,204 @@
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+#define TOR_X509_PRIVATE
|
|
|
|
+#include "orconfig.h"
|
|
|
|
+
|
|
|
|
+#ifdef _WIN32
|
|
|
|
+#include <winsock2.h>
|
|
|
|
+#endif
|
|
|
|
+#include <math.h>
|
|
|
|
+#include <stddef.h>
|
|
|
|
+
|
|
|
|
+#include "lib/cc/compat_compiler.h"
|
|
|
|
+
|
|
|
|
+#include "core/or/or.h"
|
|
|
|
+#include "lib/log/log.h"
|
|
|
|
+#include "app/config/config.h"
|
|
|
|
+#include "lib/tls/x509.h"
|
|
|
|
+#include "lib/tls/x509_internal.h"
|
|
|
|
+#include "app/config/or_state_st.h"
|
|
|
|
+
|
|
|
|
+#include "test/test.h"
|
|
|
|
+#include "test/log_test_helpers.h"
|
|
|
|
+
|
|
|
|
+#include "tinytest.h"
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
+mock_failing_digest(char *digest, const char *m, size_t len)
|
|
|
|
+{
|
|
|
|
+ (void)digest;
|
|
|
|
+ (void)m;
|
|
|
|
+ (void)len;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+test_x509_cert_new_failing_digest(void *arg)
|
|
|
|
+{
|
|
|
|
+ (void)arg;
|
|
|
|
+ crypto_pk_t *pk1=NULL, *pk2=NULL;
|
|
|
|
+ tor_x509_cert_impl_t *impl = NULL;
|
|
|
|
+ tor_x509_cert_t *cert = NULL;
|
|
|
|
+ pk1 = pk_generate(0);
|
|
|
|
+ pk2 = pk_generate(1);
|
|
|
|
+
|
|
|
|
+ impl = tor_tls_create_certificate(pk1, pk2, "hello", "world", 86400*100);
|
|
|
|
+ tt_assert(impl);
|
|
|
|
+ MOCK(crypto_digest, mock_failing_digest);
|
|
|
|
+
|
|
|
|
+ setup_full_capture_of_logs(LOG_WARN);
|
|
|
|
+ cert = tor_x509_cert_new(impl);
|
|
|
|
+ tt_assert(!cert);
|
|
|
|
+ expect_log_msg_containing("Couldn't wrap encoded X509 certificate");
|
|
|
|
+ expect_log_msg_containing("unable to compute digests of certificate key");
|
|
|
|
+
|
|
|
|
+ done:
|
|
|
|
+ crypto_pk_free(pk1);
|
|
|
|
+ crypto_pk_free(pk2);
|
|
|
|
+ if (impl)
|
|
|
|
+ tor_x509_cert_impl_free_(impl);
|
|
|
|
+ UNMOCK(crypto_digest);
|
|
|
|
+ teardown_capture_of_logs();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static tor_x509_cert_t *
|
|
|
|
+cert_from_der64(const char *der64)
|
|
|
|
+{
|
|
|
|
+ size_t der64len = strlen(der64);
|
|
|
|
+ unsigned char *der = tor_malloc_zero(der64len);
|
|
|
|
+ int derlen;
|
|
|
|
+ tor_x509_cert_t *cert = NULL;
|
|
|
|
+
|
|
|
|
+ derlen = base64_decode((char*)der, der64len,
|
|
|
|
+ der64, der64len);
|
|
|
|
+ if (derlen >= 0)
|
|
|
|
+ cert = tor_x509_cert_decode(der, derlen);
|
|
|
|
+ tor_free(der);
|
|
|
|
+ return cert;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+test_x509_consume_ec_cert(void *arg)
|
|
|
|
+{
|
|
|
|
+ (void)arg;
|
|
|
|
+
|
|
|
|
+ const char certificate[] =
|
|
|
|
+ "MIIBEzCBugIJAIdl5svgOZ0OMAoGCCqGSM49BAMCMBIxEDAOBgNVBAMMB1Rlc3Rp\n"
|
|
|
|
+ "bmcwHhcNMTgwODIzMTcyMzI1WhcNMTkwODIzMTcyMzI1WjASMRAwDgYDVQQDDAdU\n"
|
|
|
|
+ "ZXN0aW5nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExMDpnRc0Btic3tIyCKNE\n"
|
|
|
|
+ "iNY4j4gzcaYzS2sTYRoVK3RAukG29Qg6/c8e8XcnsSquU4fItYxDRbi/3nhYk4CP\n"
|
|
|
|
+ "GDAKBggqhkjOPQQDAgNIADBFAiA0h1q03C2xlONUgAOonJLrlV1SUtMeKDxNsxsU\n"
|
|
|
|
+ "+FSPvQIhAM7kY9Tlt0ELmyMnORPp1VJieXn/qhL5VoxGxSedTbny\n";
|
|
|
|
+ const time_t now = 1535045321;
|
|
|
|
+ tor_x509_cert_t *cert = cert_from_der64(certificate);
|
|
|
|
+ tt_assert(cert);
|
|
|
|
+
|
|
|
|
+ tt_ptr_op(NULL, OP_EQ, tor_tls_cert_get_key(cert));
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert, now, 0));
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ setup_capture_of_logs(LOG_INFO);
|
|
|
|
+ tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert, now, 1));
|
|
|
|
+ expect_log_msg_containing("Key is not RSA1024");
|
|
|
|
+
|
|
|
|
+ done:
|
|
|
|
+ tor_x509_cert_free(cert);
|
|
|
|
+ teardown_capture_of_logs();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+test_x509_reject_tiny_keys(void *arg)
|
|
|
|
+{
|
|
|
|
+ (void)arg;
|
|
|
|
+ const char *certificates[] = {
|
|
|
|
+
|
|
|
|
+ "MIIBXDCCAQYCCQDKikjJYZI5uDANBgkqhkiG9w0BAQsFADA1MRUwEwYDVQQHDAxE\n"
|
|
|
|
+ "ZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMTgw\n"
|
|
|
|
+ "ODIzMTczNjQ4WhcNMTkwODIzMTczNjQ4WjA1MRUwEwYDVQQHDAxEZWZhdWx0IENp\n"
|
|
|
|
+ "dHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwXDANBgkqhkiG9w0BAQEF\n"
|
|
|
|
+ "AANLADBIAkEAqOvVKzrSpmKOTNqDzBG/iZrUdhCrMRsymFXyIScJcdsyn7jB8RMy\n"
|
|
|
|
+ "fbHqG8EqB8HHLU/eqt/+zhh2w08Lx3+5QwIDAQABMA0GCSqGSIb3DQEBCwUAA0EA\n"
|
|
|
|
+ "RSCq0sNbD9uWfcBqF0U4MtfFjU5x+RQQCeBVtAzwC9bggSILKZfB9XUvtGh6vqig\n",
|
|
|
|
+
|
|
|
|
+ "MIIBLTCB+QIJAI0LtN9uWxy3MAoGCCqGSM49BAMCMEUxCzAJBgNVBAYTAkFVMRMw\n"
|
|
|
|
+ "EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0\n"
|
|
|
|
+ "eSBMdGQwHhcNMTgwODIzMTc0MTQ4WhcNMTkwODIzMTc0MTQ4WjBFMQswCQYDVQQG\n"
|
|
|
|
+ "EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lk\n"
|
|
|
|
+ "Z2l0cyBQdHkgTHRkMDIwEAYHKoZIzj0CAQYFK4EEAAcDHgAEf7dFHo7xhCtIcgyo\n"
|
|
|
|
+ "Px+IDcUUlntZCtar6V4O0zAKBggqhkjOPQQDAgMjADAgAg4yhBJMEmpkNbZU95Zf\n"
|
|
|
|
+ "uwIOJAan4J1ETxUII1RrGmw=\n"
|
|
|
|
+ };
|
|
|
|
+ const time_t now = 1535046182;
|
|
|
|
+ tor_x509_cert_t *cert = NULL;
|
|
|
|
+
|
|
|
|
+ unsigned i;
|
|
|
|
+ for (i = 0; i < ARRAY_LENGTH(certificates); ++i) {
|
|
|
|
+ cert = cert_from_der64(certificates[i]);
|
|
|
|
+
|
|
|
|
+ if (cert == NULL)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert, now, 0));
|
|
|
|
+ tor_x509_cert_free(cert);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ done:
|
|
|
|
+ tor_x509_cert_free(cert);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+test_x509_expiration(void *arg)
|
|
|
|
+{
|
|
|
|
+ (void)arg;
|
|
|
|
+
|
|
|
|
+ const char certificate[] =
|
|
|
|
+ "MIICzjCCAbYCCQDxIONWIQ9OGDANBgkqhkiG9w0BAQsFADApMQswCQYDVQQGEwJV\n"
|
|
|
|
+ "UzEaMBgGA1UEAwwRSW50ZXJlc3RpbmcgdGltZXMwHhcNMTgwODIzMTc1NTE4WhcN\n"
|
|
|
|
+ "MTkwODIzMTc1NTE4WjApMQswCQYDVQQGEwJVUzEaMBgGA1UEAwwRSW50ZXJlc3Rp\n"
|
|
|
|
+ "bmcgdGltZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0Blz1fBii\n"
|
|
|
|
+ "OffpFlzMrmfPah/vkPcNrwoyx5YiosbHErYUpqdCtfNb7rbBM5xcac1LmF9kjnOQ\n"
|
|
|
|
+ "uAw1jsCNE82QHwWMlXOqaZCEJsnttNo0Y7yaSR/ChbGJ54XCp+Lx2acyTeH9cBWU\n"
|
|
|
|
+ "de8/sKAQ4NqpbEP01pBH4+1mPu2MYWjVWVicUxmw0mJ3cfkJCWUzt0nC4ls8+Itk\n"
|
|
|
|
+ "7XliKb216Z9uQXu/zD/JGkxAljnFs1jXCX4NyWz46xnJFzXbYCeyQnBz0tUbAvgg\n"
|
|
|
|
+ "uRdryYtHzD46hd8LTXH6oK2gV64ILAhDnRb1aBjnCXxbex24XoW3hjSrKGTdNsXA\n"
|
|
|
|
+ "RMWU/8QZaoiBAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFIYDBcbit2kOMrHECZK\n"
|
|
|
|
+ "ctem40A3s+0ZifzZ2KLhW8dTr/2Zb6DnlqVm2iUOV4cG/o1RAn/HzkQQuWEq+oBG\n"
|
|
|
|
+ "yOPVHudvCyGs+2ZQWudgAv9xq8N7KtZwJhnn42c2YSoreqRXDQgJqGFatyr+XdR7\n"
|
|
|
|
+ "gdQapLI4BFbZToeXp49Nl+q9330hKaSmIYmWEZ7R/33R64PU2el7X9/apYEcuZQT\n"
|
|
|
|
+ "+FjEqcO1lJ8/dTwM/2C1BJZqUeFTAu+ac1M+4//qyJRUUc6xSJLhiens8atWaxwL\n"
|
|
|
|
+ "eBCT8fCY8oPOwA1eImc/yWWmWXpv8bBWVe8OeLCMKM/OZoIdFqQpqSdcyGoh/kIW\n"
|
|
|
|
+ "Dws=\n";
|
|
|
|
+ const time_t now = 1535046996;
|
|
|
|
+
|
|
|
|
+ tor_x509_cert_t *cert = cert_from_der64(certificate);
|
|
|
|
+ tt_assert(cert);
|
|
|
|
+
|
|
|
|
+ tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert, now, 0));
|
|
|
|
+
|
|
|
|
+ tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert,
|
|
|
|
+ now-TOR_X509_FUTURE_SLOP, 0));
|
|
|
|
+ tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert,
|
|
|
|
+ now+365*86400+TOR_X509_PAST_SLOP - 3600, 0));
|
|
|
|
+
|
|
|
|
+ tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert,
|
|
|
|
+ now-TOR_X509_FUTURE_SLOP - 3600, 0));
|
|
|
|
+ tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert,
|
|
|
|
+ now+365*86400+TOR_X509_FUTURE_SLOP, 0));
|
|
|
|
+
|
|
|
|
+ done:
|
|
|
|
+ tor_x509_cert_free(cert);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define TEST(name) { #name, test_x509_ ## name, TT_FORK, 0, NULL }
|
|
|
|
+
|
|
|
|
+struct testcase_t x509_tests[] = {
|
|
|
|
+ TEST(cert_new_failing_digest),
|
|
|
|
+ TEST(consume_ec_cert),
|
|
|
|
+ TEST(reject_tiny_keys),
|
|
|
|
+ TEST(expiration),
|
|
|
|
+ END_OF_TESTCASES
|
|
|
|
+};
|