コード例 #1
0
def test_ocsp_with_outdated_cache(tmpdir):
    """
    Attempt to use outdated OCSP response cache file
    """
    cache_file_name, target_hosts = _store_cache_in_file(tmpdir)

    ocsp = SFOCSP(ocsp_response_cache_uri='file://' + cache_file_name)

    # reading cache file
    OCSPCache.read_ocsp_response_cache_file(ocsp, cache_file_name)
    cache_data = OCSPCache.CACHE
    assert cache_data, "more than one cache entries should be stored."

    # setting outdated data
    current_time = int(time.time())
    for k, v in cache_data.items():
        cache_data[k] = (current_time - 48 * 60 * 60, v[1])

    # write back the cache file
    OCSPCache.CACHE = cache_data
    OCSPCache.write_ocsp_response_cache_file(ocsp, cache_file_name)

    # forces to use the bogus cache file but it should raise errors
    SnowflakeOCSP.clear_cache()  # reset the memory cache
    SFOCSP(ocsp_response_cache_uri='file://' + cache_file_name)
    assert SnowflakeOCSP.cache_size() == 0, \
        'must be empty. outdated cache should not be loaded'
コード例 #2
0
def test_ocsp_cache_merge(tmpdir):
    """Merges two OCSP response cache files."""
    previous_folder = tmpdir.mkdir('previous')
    previous_cache_filename, _ = _store_cache_in_file(
        previous_folder, target_hosts=TARGET_HOSTS[0:3])

    current_folder = tmpdir.mkdir('current')
    current_cache_filename, _ = _store_cache_in_file(
        current_folder, target_hosts=TARGET_HOSTS[4:])

    latest_folder = tmpdir.mkdir('latest')
    latest_cache_filename = path.join(str(latest_folder), 'cache_file.txt')

    SnowflakeOCSP.clear_cache()  # reset the memory cache
    ocsp = SFOCSP()
    OCSPCache.merge_cache(ocsp, previous_cache_filename,
                          current_cache_filename, latest_cache_filename)

    with codecs.open(previous_cache_filename) as f:
        prev = json.load(f)
    with codecs.open(current_cache_filename) as f:
        curr = json.load(f)
    with codecs.open(latest_cache_filename) as f:
        latest = json.load(f)

    assert len(latest) > len(prev)
    assert len(latest) > len(curr)
コード例 #3
0
def test_ocsp_cache_merge(tmpdir):
    """
    Merge two OCSP response cache files
    """
    previous_cache_filename = path.join(str(tmpdir), 'cache_file1.txt')
    _store_cache_in_file(tmpdir,
                         target_hosts=TARGET_HOSTS[0:3],
                         filename=previous_cache_filename)

    current_cache_filename = path.join(str(tmpdir), 'cache_file2.txt')
    _store_cache_in_file(tmpdir,
                         target_hosts=TARGET_HOSTS[4:],
                         filename=current_cache_filename)

    latest_cache_filename = path.join(str(tmpdir), 'cache_file.txt')

    SnowflakeOCSP.clear_cache()  # reset the memory cache
    ocsp = SFOCSP()
    OCSPCache.merge_cache(ocsp, previous_cache_filename,
                          current_cache_filename, latest_cache_filename)

    with codecs.open(previous_cache_filename) as f:
        prev = json.load(f)
    with codecs.open(current_cache_filename) as f:
        curr = json.load(f)
    with codecs.open(latest_cache_filename) as f:
        latest = json.load(f)

    assert len(latest) > len(prev)
    assert len(latest) > len(curr)
コード例 #4
0
def test_ocsp_with_invalid_cache_file():
    """OCSP tests with an invalid cache file."""
    SnowflakeOCSP.clear_cache()  # reset the memory cache
    ocsp = SFOCSP(ocsp_response_cache_uri="NEVER_EXISTS")
    for url in TARGET_HOSTS[0:1]:
        connection = _openssl_connect(url)
        assert ocsp.validate(url, connection), f"Failed to validate: {url}"
コード例 #5
0
def test_ocsp_cache_merge(tmpdir):
    """
    Merges two OCSP response cache files.

    First create the entire cache for all hosts.
    Split the created cache into two caches
    Merge the two caches.
    This is to prevent us from doing multiple cache
    creations as the results are not predictable
    due to OCSP responder shenanigans
    """
    cache_folder = tmpdir.mkdir("caches")
    cache_filename, _ = _store_cache_in_file(
        cache_folder,
        target_hosts=TARGET_HOSTS)

    previous_folder = tmpdir.mkdir('previous')
    previous_cache_filename = path.join(str(previous_folder), 'ocsp_response_cache.json')

    current_folder = tmpdir.mkdir('current')
    current_cache_filename = path.join(str(current_folder), 'ocsp_response_cache.json')

    prev_cache = {}
    current_cache = {}
    with codecs.open(cache_filename) as cf:
        orig_cache = json.load(cf)
        counter = 0
        for certid, arr in orig_cache.items():
            if counter < 1:
                prev_cache.update({certid: arr})
            else:
                current_cache.update({certid: arr})
            counter += 1

    with open(previous_cache_filename, 'w') as prev_cache_fp:
        json.dump(prev_cache, prev_cache_fp)

    with open(current_cache_filename, 'w') as curr_cache_fp:
        json.dump(current_cache, curr_cache_fp)

    latest_folder = tmpdir.mkdir('latest')
    latest_cache_filename = path.join(str(latest_folder), 'cache_file.txt')

    SnowflakeOCSP.clear_cache()  # reset the memory cache
    ocsp = SFOCSP()
    OCSPCache.merge_cache(
        ocsp,
        previous_cache_filename,
        current_cache_filename,
        latest_cache_filename)

    with codecs.open(previous_cache_filename) as f:
        prev = json.load(f)
    with codecs.open(current_cache_filename) as f:
        curr = json.load(f)
    with codecs.open(latest_cache_filename) as f:
        latest = json.load(f)

    assert len(latest) > len(prev)
    assert len(latest) > len(curr)
コード例 #6
0
def test_ocsp_wo_cache_server():
    """OCSP Tests with Cache Server Disabled."""
    SnowflakeOCSP.clear_cache()
    ocsp = SFOCSP(use_ocsp_cache_server=False)
    for url in TARGET_HOSTS:
        connection = _openssl_connect(url)
        assert ocsp.validate(url, connection), f"Failed to validate: {url}"
コード例 #7
0
def test_ocsp_with_bogus_cache_files(tmpdir):
    """
    Attempt to use bogus OCSP response data
    """

    cache_file_name, target_hosts = _store_cache_in_file(tmpdir)

    ocsp = SFOCSP(ocsp_response_cache_uri='file://' + cache_file_name)
    OCSPCache.read_ocsp_response_cache_file(ocsp, cache_file_name)
    cache_data = OCSPCache.CACHE
    assert cache_data, "more than one cache entries should be stored."

    # setting bogus data
    current_time = int(time.time())
    for k, v in cache_data.items():
        cache_data[k] = (current_time, b'bogus')

    # write back the cache file
    OCSPCache.CACHE = cache_data
    OCSPCache.write_ocsp_response_cache_file(ocsp, cache_file_name)

    # forces to use the bogus cache file but it should raise errors
    SnowflakeOCSP.clear_cache()
    ocsp = SFOCSP(ocsp_response_cache_uri='file://' + cache_file_name)
    for hostname in target_hosts:
        connection = _openssl_connect(hostname)
        assert ocsp.validate(hostname, connection), \
            'Failed to validate: {0}'.format(hostname)
コード例 #8
0
def test_ocsp_by_post_method():
    """OCSP tests."""
    # reset the memory cache
    SnowflakeOCSP.clear_cache()
    ocsp = SFOCSP(use_post_method=True)
    for url in TARGET_HOSTS:
        connection = _openssl_connect(url)
        assert ocsp.validate(url, connection), f"Failed to validate: {url}"
コード例 #9
0
def test_ocsp():
    """OCSP tests."""
    # reset the memory cache
    SnowflakeOCSP.clear_cache()
    ocsp = SFOCSP()
    for url in TARGET_HOSTS:
        connection = _openssl_connect(url, timeout=5)
        assert ocsp.validate(url, connection), f"Failed to validate: {url}"
コード例 #10
0
def _setup_ssd_test(temp_ocsp_file):

    os.environ['SF_OCSP_ACTIVATE_SSD'] = 'True'
    SnowflakeOCSP.clear_cache()
    ocsp = SFOCSP(ocsp_response_cache_uri='file://' + temp_ocsp_file)
    ocsp.SSD.update_pub_key("dep1", 0.1, _get_test_pub_key(1))

    return ocsp
コード例 #11
0
def test_concurrent_ocsp_requests(tmpdir):
    """Run OCSP revocation checks in parallel. The memory and file caches are deleted randomly."""
    cache_file_name = path.join(str(tmpdir), 'cache_file.txt')
    SnowflakeOCSP.clear_cache()  # reset the memory cache

    target_hosts = TARGET_HOSTS * 5
    pool = ThreadPoolExecutor(len(target_hosts))
    for hostname in target_hosts:
        pool.submit(_validate_certs_using_ocsp, hostname, cache_file_name)
    pool.shutdown()
コード例 #12
0
def _setup_ssd_test(temp_ocsp_file):

    #ssd_local = SFSsd()
    #ssd_local.update_pub_key("dep1", 0.1, _get_test_pub_key(1))

    SnowflakeOCSP.clear_cache()
    ocsp = SFOCSP(ocsp_response_cache_uri='file://' + temp_ocsp_file)
    ocsp.SSD.update_pub_key("dep1", 0.1, _get_test_pub_key(1))

    return ocsp
コード例 #13
0
def test_ocsp_revoked_certificate():
    """Tests revoked certificate."""
    revoked_cert = path.join(THIS_DIR, "../data", "cert_tests", "revoked_certs.pem")

    SnowflakeOCSP.clear_cache()  # reset the memory cache
    ocsp = SFOCSP()

    with pytest.raises(OperationalError) as ex:
        ocsp.validate_certfile(revoked_cert)
    assert ex.value.errno == ex.value.errno == ER_OCSP_RESPONSE_CERT_STATUS_REVOKED
コード例 #14
0
def test_ocsp_revoked_certificate():
    """Tests revoked certificate."""
    revoked_cert = path.join(THIS_DIR, 'data', 'cert_tests',
                             'revoked_certs.pem')

    SnowflakeOCSP.clear_cache()  # reset the memory cache
    ocsp = SFOCSP()

    with pytest.raises(OperationalError) as ex:
        ocsp.validate_certfile(revoked_cert)
    assert ex.value.errno == ex.value.errno == ER_SERVER_CERTIFICATE_REVOKED
コード例 #15
0
def test_ocsp_with_file_cache(tmpdir):
    """OCSP tests and the cache server and file."""
    tmp_dir = str(tmpdir.mkdir("ocsp_response_cache"))
    cache_file_name = path.join(tmp_dir, "cache_file.txt")

    # reset the memory cache
    SnowflakeOCSP.clear_cache()
    ocsp = SFOCSP(ocsp_response_cache_uri="file://" + cache_file_name)
    for url in TARGET_HOSTS:
        connection = _openssl_connect(url)
        assert ocsp.validate(url, connection), f"Failed to validate: {url}"
コード例 #16
0
def test_ocsp_incomplete_chain():
    """Tests incomplete chained certificate."""
    incomplete_chain_cert = path.join(THIS_DIR, 'data', 'cert_tests',
                                      'incomplete-chain.pem')

    SnowflakeOCSP.clear_cache()  # reset the memory cache
    ocsp = SFOCSP()

    with pytest.raises(OperationalError) as ex:
        ocsp.validate_certfile(incomplete_chain_cert)
    assert 'CA certificate is NOT found' in ex.value.msg
コード例 #17
0
def test_ocsp_single_endpoint():
    environ['SF_OCSP_ACTIVATE_NEW_ENDPOINT'] = 'True'
    SnowflakeOCSP.clear_cache()
    ocsp = SFOCSP()
    ocsp.OCSP_CACHE_SERVER.NEW_DEFAULT_CACHE_SERVER_BASE_URL = \
        "https://snowflake.preprod2.us-west-2-dev.external-zone.snowflakecomputing.com:8085/ocsp/"
    connection = _openssl_connect("snowflake.okta.com")
    assert ocsp.validate("snowflake.okta.com", connection), \
        'Failed to validate: {0}'.format("snowflake.okta.com")

    del environ['SF_OCSP_ACTIVATE_NEW_ENDPOINT']
コード例 #18
0
def test_ocsp():
    """
    OCSP tests
    """
    # reset the memory cache
    SnowflakeOCSP.clear_cache()
    ocsp = SFOCSP()
    for url in TARGET_HOSTS:
        connection = _openssl_connect(url)
        assert ocsp.validate(url, connection), \
            'Failed to validate: {0}'.format(url)
コード例 #19
0
def test_ocsp_with_file_cache(tmpdir):
    """
    OCSP tests and the cache server and file
    """
    tmp_dir = str(tmpdir.mkdir('ocsp_response_cache'))
    cache_file_name = path.join(tmp_dir, 'cache_file.txt')

    # reset the memory cache
    SnowflakeOCSP.clear_cache()
    ocsp = SFOCSP(ocsp_response_cache_uri='file://' + cache_file_name)
    for url in TARGET_HOSTS:
        connection = _openssl_connect(url)
        assert ocsp.validate(url, connection), \
            'Failed to validate: {0}'.format(url)
コード例 #20
0
def test_ocsp_bad_validity():
    SnowflakeOCSP.clear_cache()

    environ["SF_OCSP_TEST_MODE"] = "true"
    environ["SF_TEST_OCSP_FORCE_BAD_RESPONSE_VALIDITY"] = "true"

    OCSPCache.del_cache_file()

    ocsp = SFOCSP(use_ocsp_cache_server=False)
    connection = _openssl_connect("snowflake.okta.com")

    assert ocsp.validate("snowflake.okta.com", connection), "Connection should have passed with fail open"
    del environ['SF_OCSP_TEST_MODE']
    del environ['SF_TEST_OCSP_FORCE_BAD_RESPONSE_VALIDITY']
コード例 #21
0
def _store_cache_in_file(tmpdir, target_hosts=None, filename=None):
    if target_hosts is None:
        target_hosts = TARGET_HOSTS
    if filename is None:
        filename = path.join(str(tmpdir), 'cache_file.txt')

    # cache OCSP response
    SnowflakeOCSP.clear_cache()
    ocsp = SFOCSP(ocsp_response_cache_uri='file://' + filename,
                  use_ocsp_cache_server=False)
    for hostname in target_hosts:
        connection = _openssl_connect(hostname)
        assert ocsp.validate(hostname, connection), \
            'Failed to validate: {0}'.format(hostname)
    assert path.exists(filename), "OCSP response cache file"
    return filename, target_hosts
コード例 #22
0
def _validate_certs_using_ocsp(url, cache_file_name):
    """Validate OCSP response. Deleting memory cache and file cache randomly."""
    logger = logging.getLogger('test')
    import time
    import random
    time.sleep(random.randint(0, 3))
    if random.random() < 0.2:
        logger.info('clearing up cache: OCSP_VALIDATION_CACHE')
        SnowflakeOCSP.clear_cache()
    if random.random() < 0.05:
        logger.info('deleting a cache file: %s', cache_file_name)
        SnowflakeOCSP.delete_cache_file()

    connection = _openssl_connect(url)
    ocsp = SFOCSP(ocsp_response_cache_uri='file://' + cache_file_name)
    ocsp.validate(url, connection)
コード例 #23
0
def _store_cache_in_file(tmpdir, target_hosts=None):
    if target_hosts is None:
        target_hosts = TARGET_HOSTS
    os.environ['SF_OCSP_RESPONSE_CACHE_DIR'] = str(tmpdir)
    OCSPCache.reset_cache_dir()
    filename = path.join(str(tmpdir), 'ocsp_response_cache.json')

    # cache OCSP response
    SnowflakeOCSP.clear_cache()
    ocsp = SFOCSP(ocsp_response_cache_uri='file://' + filename,
                  use_ocsp_cache_server=False)
    for hostname in target_hosts:
        connection = _openssl_connect(hostname)
        assert ocsp.validate(hostname, connection), \
            'Failed to validate: {}'.format(hostname)
    assert path.exists(filename), "OCSP response cache file"
    return filename, target_hosts
コード例 #24
0
def test_concurrent_ocsp_requests(tmpdir):
    """
    Run OCSP revocation checks in parallel. The memory and file caches are
    deleted randomly.
    """
    from multiprocessing.pool import ThreadPool

    cache_file_name = path.join(str(tmpdir), 'cache_file.txt')
    SnowflakeOCSP.clear_cache()  # reset the memory cache

    target_hosts = TARGET_HOSTS * 5
    pool = ThreadPool(len(target_hosts))
    for hostname in target_hosts:
        pool.apply_async(_validate_certs_using_ocsp,
                         [hostname, cache_file_name])
    pool.close()
    pool.join()
コード例 #25
0
def test_ocsp_fail_open_w_single_endpoint():
    SnowflakeOCSP.clear_cache()

    OCSPCache.del_cache_file()

    environ["SF_OCSP_TEST_MODE"] = "true"
    environ["SF_TEST_OCSP_URL"] = "http://httpbin.org/delay/10"
    environ["SF_TEST_CA_OCSP_RESPONDER_CONNECTION_TIMEOUT"] = "5"

    ocsp = SFOCSP(use_ocsp_cache_server=False)
    connection = _openssl_connect("snowflake.okta.com")

    try:
        assert ocsp.validate("snowflake.okta.com", connection), \
            'Failed to validate: {0}'.format("snowflake.okta.com")
    finally:
        del environ['SF_OCSP_TEST_MODE']
        del environ['SF_TEST_OCSP_URL']
        del environ['SF_TEST_CA_OCSP_RESPONDER_CONNECTION_TIMEOUT']
コード例 #26
0
def test_ocsp_wo_cache_file():
    """
    OCSP tests without File cache.
    NOTE: Use /etc as a readonly directory such that no cache file is used.
    """
    # reset the memory cache
    SnowflakeOCSP.clear_cache()
    OCSPCache.del_cache_file()
    environ['SF_OCSP_RESPONSE_CACHE_DIR'] = '/etc'
    OCSPCache.reset_cache_dir()

    try:
        ocsp = SFOCSP()
        for url in TARGET_HOSTS:
            connection = _openssl_connect(url)
            assert ocsp.validate(url, connection), \
                'Failed to validate: {0}'.format(url)
    finally:
        del environ['SF_OCSP_RESPONSE_CACHE_DIR']
        OCSPCache.reset_cache_dir()
コード例 #27
0
def test_ocsp_fail_close_w_single_endpoint():
    SnowflakeOCSP.clear_cache()

    environ["SF_OCSP_TEST_MODE"] = "true"
    environ["SF_TEST_OCSP_URL"] = "http://httpbin.org/delay/10"
    environ["SF_TEST_CA_OCSP_RESPONDER_CONNECTION_TIMEOUT"] = "5"

    OCSPCache.del_cache_file()

    ocsp = SFOCSP(use_ocsp_cache_server=False, use_fail_open=False)
    connection = _openssl_connect("snowflake.okta.com")

    with pytest.raises(RevocationCheckError) as ex:
        ocsp.validate("snowflake.okta.com", connection)

    try:
        assert ex.value.errno == ER_INVALID_OCSP_RESPONSE_CODE, "Connection should have failed"
    finally:
        del environ['SF_OCSP_TEST_MODE']
        del environ['SF_TEST_OCSP_URL']
        del environ['SF_TEST_CA_OCSP_RESPONDER_CONNECTION_TIMEOUT']