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)
示例#2
0
def _validate_urls(urls, must_use_cache=False, ocsp_response_cache_uri=None):
    ocsp = ocsp_pyasn1.SnowflakeOCSP(
        must_use_cache=must_use_cache,
        ocsp_response_cache_uri=ocsp_response_cache_uri)
    for url in urls:
        connection = _openssl_connect(url)
        ocsp.validate(url, connection)
示例#3
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}"
示例#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_with_bogus_cache_files(tmpdir):
    """
    Attempt to use bogus OCSP response data
    """
    cache_file_name, target_hosts = _store_cache_in_file(tmpdir)

    # reading cache file
    cache_data = {}
    ocsp_asn1crypto.read_ocsp_response_cache_file(cache_file_name, cache_data)
    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
    ocsp_asn1crypto.write_ocsp_response_cache_file(cache_file_name, cache_data)

    # forces to use the bogus cache file but it should raise errors
    ocsp_asn1crypto.OCSP_VALIDATION_CACHE = {}  # reset the memory cache
    ocsp = ocsp_asn1crypto.SnowflakeOCSP(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)
示例#6
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}"
示例#7
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}"
示例#8
0
def test_ocsp():
    """
    OCSP tests using asn1crypto and whatever default caches
    """
    ocsp_asn1crypto.OCSP_VALIDATION_CACHE = {}  # reset the memory cache
    ocsp = ocsp_asn1crypto.SnowflakeOCSP()
    for url in TARGET_HOSTS:
        connection = _openssl_connect(url)
        assert ocsp.validate(url, connection), \
            'Failed to validate: {0}'.format(url)
示例#9
0
def test_ocsp():
    """
    OCSP tests for PyOpenSSL
    """
    ocsp_pyasn1.OCSP_VALIDATION_CACHE = {}  # reset the memory cache
    ocsp = ocsp_pyasn1.SnowflakeOCSP()
    for url in URLS:
        connection = _openssl_connect(url)
        assert ocsp.validate(url, connection), \
            'Failed to validate: {0}'.format(url)
示例#10
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}"
示例#11
0
def test_ocsp_with_invalid_cache_file():
    """
    OCSP tests with an invalid cache file
    """
    ocsp_asn1crypto.OCSP_VALIDATION_CACHE = {}  # reset the memory cache
    ocsp = ocsp_asn1crypto.SnowflakeOCSP(
        ocsp_response_cache_uri="NEVER_EXISTS")
    for url in TARGET_HOSTS[0:1]:
        connection = _openssl_connect(url)
        assert ocsp.validate(url, connection), \
            'Failed to validate: {0}'.format(url)
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)
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']
示例#14
0
def _store_cache_in_file(tmpdir):
    tmp_dir = str(tmpdir.mkdir('ocsp_response_cache'))
    cache_file_name = path.join(tmp_dir, 'cache_file.txt')
    # cache OCSP response
    ocsp_asn1crypto.OCSP_VALIDATION_CACHE = {}  # reset the memory cache
    ocsp = ocsp_asn1crypto.SnowflakeOCSP(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)
    assert path.exists(cache_file_name), "OCSP response cache file"
    return cache_file_name, TARGET_HOSTS
示例#15
0
def dump_ocsp_response(urls, output_filename):
    ocsp = SFOCSP()
    for url in urls:
        if not url.startswith('http'):
            url = 'https://' + url
        parsed_url = urlsplit(url)
        hostname = parsed_url.hostname
        port = parsed_url.port or 443
        connection = _openssl_connect(hostname, port)
        cert_data = ocsp.extract_certificate_chain(connection)
        current_time = int(time.time())
        print("Target URL: {0}".format(url))
        print("Current Time: {0}".format(
            strftime('%Y%m%d%H%M%SZ', gmtime(current_time))))
        for issuer, subject in cert_data:
            cert_id, _ = ocsp.create_ocsp_request(issuer, subject)
            _, _, _, cert_id, ocsp_response_der = \
                ocsp.validate_by_direct_connection(issuer, subject)
            ocsp_response = asn1crypto_ocsp.OCSPResponse.load(ocsp_response_der)
            print(
                "------------------------------------------------------------")
            print("Subject Name: {0}".format(subject.subject.native))
            print("Issuer Name: {0}".format(issuer.subject.native))
            print("OCSP URI: {0}".format(subject.ocsp_urls))
            print("CRL URI: {0}".format(
                subject.crl_distribution_points[0].native))
            print("Issuer Name Hash: {0}".format(subject.issuer.sha1))
            print("Issuer Key Hash: {0}".format(issuer.public_key.sha1))
            print("Serial Number: {0}".format(subject.serial_number))
            print("Response Status: {0}".format(
                ocsp_response['response_status'].native))
            basic_ocsp_response = ocsp_response.basic_ocsp_response
            tbs_response_data = basic_ocsp_response['tbs_response_data']
            print("Responder ID: {0}".format(
                tbs_response_data['responder_id'].name))
            current_time = int(time.time())
            for single_response in tbs_response_data['responses']:
                cert_status = single_response['cert_status'].name
                if cert_status == 'good':
                    dump_good_status(current_time, single_response)
                elif cert_status == 'revoked':
                    dump_revoked_status(single_response)
                else:
                    print("Unknown")
            print('')

        if output_filename:
            SFOCSP.OCSP_CACHE.write_ocsp_response_cache_file(
                ocsp,
                output_filename)
    return SFOCSP.OCSP_CACHE.CACHE
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']
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)
示例#18
0
def test_ocsp_with_file_cache(tmpdir):
    """
    OCSP tests for PyOpenSSL
    """
    tmp_dir = str(tmpdir.mkdir('ocsp_response_cache'))
    cache_file_name = path.join(tmp_dir, 'cache_file.txt')

    ocsp_pyasn1.OCSP_VALIDATION_CACHE = {}  # reset the memory cache
    ocsp = ocsp_pyasn1.SnowflakeOCSP(
        ocsp_response_cache_uri='file://' + cache_file_name)
    for url in URLS:
        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 using asn1crypto and the file cache
    """
    tmp_dir = str(tmpdir.mkdir('ocsp_response_cache'))
    cache_file_name = path.join(tmp_dir, 'cache_file.txt')

    ocsp_asn1crypto.OCSP_VALIDATION_CACHE = {}  # reset the memory cache
    ocsp = ocsp_asn1crypto.SnowflakeOCSP(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)
def _fetch_certs(hostname_file):
    with open(hostname_file) as f:
        hostnames = f.read().split("\n")

    map_serial_to_name = {}
    for h in hostnames:
        if not h:
            continue
        connection = _openssl_connect(h, 443)
        for cert_openssl in connection.get_peer_cert_chain():
            cert_der = dump_certificate(FILETYPE_ASN1, cert_openssl)
            cert = Certificate.load(cert_der)
            map_serial_to_name[cert.serial_number] = cert.subject.native

    return map_serial_to_name
示例#21
0
def _validate_certs_using_ocsp(url, cache_file_name):
    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')
        with ocsp_pyasn1.OCSP_VALIDATION_CACHE_LOCK:
            ocsp_pyasn1.OCSP_VALIDATION_CACHE = {}
    if random.random() < 0.05:
        logger.info('deleting a cache file: %s', cache_file_name)
        os.unlink(cache_file_name)
    connection = _openssl_connect(url)
    ocsp = ocsp_pyasn1.SnowflakeOCSP(
        ocsp_response_cache_uri='file://' + cache_file_name)
    ocsp.validate(url, connection)
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
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)
示例#24
0
def test_invalid_certid_spec_bypass_ssd_fail_open():
    """
    Clean any skeletons of past tests
    """
    _teardown_ssd_test_setup()
    """
    For convenience we overwrite the local
    OCSP Cache to have SSD instead of OCSP 
    responses for all cert id. This reduces
    the incovenience to find which cert id 
    corresponds to which URL
    """
    js_ssd = {}
    priv_key = _get_test_priv_key(1)
    tmp_dir = str(tempfile.gettempdir())
    temp_ocsp_file_path = path.join(tmp_dir, "ocsp_cache_backup.json")
    with codecs.open(OCSP_RESPONSE_CACHE_URI,
                     "r",
                     encoding='utf-8',
                     errors='ignore') as f:
        js = json.load(f)
        for cid, (ts, ocsp_resp) in js.items():
            ssd = _create_cert_spec_ocsp_bypass_token(priv_key, cid, 12)
            js_ssd.update({cid: [ts, b64encode(ssd).decode('ascii')]})
    with codecs.open(temp_ocsp_file_path,
                     "w",
                     encoding='utf-8',
                     errors='ignore') as f_ssd:
        json.dump(js_ssd, f_ssd)
    """
    OCSP Fail Open mode via Environment Variable
    """
    os.environ["SF_OCSP_FAIL_OPEN"] = "true"
    ocsp = _setup_ssd_test(temp_ocsp_file_path)
    hostname = 'sfcsupport.us-east-1.snowflakecomputing.com'

    connection = _openssl_connect(hostname)

    assert ocsp.validate(hostname, connection), \
        "validation should have succeeded with soft fail enabled\n"
    del os.environ["SF_OCSP_FAIL_OPEN"]
    """
    OCSP Fail Open via parameter passed to SnowflakeOCSP constructor
    """
    ocsp = _setup_ssd_test(temp_ocsp_file_path, fail_open=True)
    assert ocsp.validate(hostname, connection), \
        "validation should have succeeded with soft fail enabled\n"
示例#25
0
def test_invalid_certid_spec_bypass_ssd():
    """
    Clean any skeletons of past tests
    """
    _teardown_ssd_test_setup()
    """
    For convenience we overwrite the local
    OCSP Cache to have SSD instead of OCSP 
    responses for all cert id. This reduces
    the incovenience to find which cert id 
    corresponds to which URL
    """
    js_ssd = {}
    priv_key = _get_test_priv_key(1)
    tmp_dir = str(tempfile.gettempdir())
    temp_ocsp_file_path = path.join(tmp_dir, "ocsp_cache_backup.json")
    with codecs.open(OCSP_RESPONSE_CACHE_URI,
                     "r",
                     encoding='utf-8',
                     errors='ignore') as f:
        js = json.load(f)
        for cid, (ts, ocsp_resp) in js.items():
            ssd = _create_cert_spec_ocsp_bypass_token(priv_key, cid, 12)
            js_ssd.update({cid: [ts, b64encode(ssd).decode('ascii')]})
    with codecs.open(temp_ocsp_file_path,
                     "w",
                     encoding='utf-8',
                     errors='ignore') as f_ssd:
        json.dump(js_ssd, f_ssd)
    """
    Setup OCSP instance to use test keys
    for authenticating SSD
    """
    ocsp = _setup_ssd_test(temp_ocsp_file_path)
    hostname = 'sfcsupport.us-east-1.snowflakecomputing.com'

    exception_occured = False

    connection = _openssl_connect(hostname)

    try:
        ocsp.validate(hostname, connection)
    except RevocationCheckError:
        exception_occured = True

    assert exception_occured,\
        "No exception raised for bad Server Side Directive"
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
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']
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()
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']
示例#30
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')
        with ocsp_asn1crypto.OCSP_VALIDATION_CACHE_LOCK:
            ocsp_asn1crypto.OCSP_VALIDATION_CACHE = {}
    if random.random() < 0.05:
        logger.info('deleting a cache file: %s', cache_file_name)
        ocsp_asn1crypto._lock_cache_file(cache_file_name)
        try:
            os.unlink(cache_file_name)
        finally:
            ocsp_asn1crypto._unlock_cache_file(cache_file_name)
    connection = _openssl_connect(url)
    ocsp = ocsp_asn1crypto.SnowflakeOCSP(ocsp_response_cache_uri='file://' +
                                         cache_file_name)
    ocsp.validate(url, connection)