Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port last integration tests to python #2966

Merged
merged 6 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
just use openssl
  • Loading branch information
hubertdeng123 committed Apr 16, 2024
commit 2673f2592f53ab69ffbb5c2fdf0d9fbe3e86f8a6
304 changes: 125 additions & 179 deletions _integration-test/test_run.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import datetime
import json
import os
import re
import shutil
import subprocess
import time
from functools import lru_cache
Expand All @@ -12,11 +10,6 @@
import pytest
import sentry_sdk
from bs4 import BeautifulSoup
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID

SENTRY_CONFIG_PY = "sentry/sentry.conf.py"
SENTRY_TEST_HOST = os.getenv("SENTRY_TEST_HOST", "http:https://localhost:9000")
Expand Down Expand Up @@ -146,7 +139,7 @@ def test_cleanup_crons_running():


def test_custom_cas():
# Set environment variable
hubertdeng123 marked this conversation as resolved.
Show resolved Hide resolved
# Set environment variables
os.environ["COMPOSE_FILE"] = (
"docker-compose.yml:_integration-test/custom-ca-roots/docker-compose.test.yml"
)
Expand All @@ -155,167 +148,120 @@ def test_custom_cas():
custom_certs_path = "certificates"

# Generate tightly constrained CA
ca_key = rsa.generate_private_key(
public_exponent=65537, key_size=2048, backend=default_backend()
)

ca_name = x509.Name(
[x509.NameAttribute(NameOID.COMMON_NAME, "TEST CA *DO NOT TRUST*")]
)

ca_cert = (
x509.CertificateBuilder()
.subject_name(ca_name)
.issuer_name(ca_name)
.public_key(ca_key.public_key())
.serial_number(x509.random_serial_number())
.not_valid_before(datetime.datetime.utcnow())
.not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=1))
.add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True)
.add_extension(
x509.KeyUsage(
digital_signature=False,
key_encipherment=False,
content_commitment=False,
data_encipherment=False,
key_agreement=False,
key_cert_sign=True,
crl_sign=True,
encipher_only=False,
decipher_only=False,
),
critical=True,
)
.add_extension(
x509.NameConstraints([x509.DNSName("self.test")], None), critical=True
)
.sign(private_key=ca_key, algorithm=hashes.SHA256(), backend=default_backend())
)

ca_key_path = f"{test_nginx_conf_path}/ca.key"
ca_crt_path = f"{test_nginx_conf_path}/ca.crt"

with open(ca_key_path, "wb") as key_file:
key_file.write(
ca_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption(),
)
)

with open(ca_crt_path, "wb") as cert_file:
cert_file.write(ca_cert.public_bytes(serialization.Encoding.PEM))
subprocess.run(
[
"openssl",
"req",
"-x509",
"-new",
"-nodes",
"-newkey",
"rsa:2048",
"-keyout",
ca_key_path,
"-sha256",
"-days",
"1",
"-out",
ca_crt_path,
"-batch",
"-subj",
"/CN=TEST CA *DO NOT TRUST*",
"-addext",
"keyUsage = critical, keyCertSign, cRLSign",
"-addext",
"nameConstraints = critical, permitted;DNS:self.test",
],
check=True,
)

# Create custom certs path and copy ca.crt
os.makedirs(custom_certs_path, exist_ok=True)
shutil.copyfile(ca_crt_path, f"{custom_certs_path}/test-custom-ca-roots.crt")
# Generate server key and certificate

self_test_key_path = os.path.join(test_nginx_conf_path, "self.test.key")
self_test_csr_path = os.path.join(test_nginx_conf_path, "self.test.csr")
self_test_cert_path = os.path.join(test_nginx_conf_path, "self.test.crt")

self_test_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)

self_test_req = (
x509.CertificateSigningRequestBuilder()
.subject_name(
x509.Name(
[
x509.NameAttribute(
NameOID.COMMON_NAME, "Self Signed with CA Test Server"
)
]
)
)
.add_extension(
x509.SubjectAlternativeName([x509.DNSName("self.test")]), critical=False
)
.sign(self_test_key, hashes.SHA256())
subprocess.run(
["cp", ca_crt_path, f"{custom_certs_path}/test-custom-ca-roots.crt"], check=True
)

self_test_cert = (
x509.CertificateBuilder()
.subject_name(
x509.Name(
[
x509.NameAttribute(
NameOID.COMMON_NAME, "Self Signed with CA Test Server"
)
]
)
)
.issuer_name(ca_cert.issuer)
.serial_number(x509.random_serial_number())
.not_valid_before(datetime.datetime.utcnow())
.not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=1))
.public_key(self_test_req.public_key())
.add_extension(
x509.SubjectAlternativeName([x509.DNSName("self.test")]), critical=False
)
.sign(private_key=ca_key, algorithm=hashes.SHA256())
# Generate server certificate
self_test_key_path = f"{test_nginx_conf_path}/self.test.key"
self_test_req_path = f"{test_nginx_conf_path}/self.test.req"
subprocess.run(
[
"openssl",
"req",
"-new",
"-nodes",
"-newkey",
"rsa:2048",
"-keyout",
self_test_key_path,
"-addext",
"subjectAltName=DNS:self.test",
"-out",
self_test_req_path,
"-batch",
"-subj",
"/CN=Self Signed with CA Test Server",
],
check=True,
)

# Save server key, CSR, and certificate
with open(self_test_key_path, "wb") as key_file:
key_file.write(
self_test_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption(),
)
)
with open(self_test_csr_path, "wb") as csr_file:
csr_file.write(self_test_req.public_bytes(serialization.Encoding.PEM))
with open(self_test_cert_path, "wb") as cert_file:
cert_file.write(self_test_cert.public_bytes(serialization.Encoding.PEM))

# Generate server key and certificate for fake.test

fake_test_key_path = os.path.join(test_nginx_conf_path, "fake.test.key")
fake_test_cert_path = os.path.join(test_nginx_conf_path, "fake.test.crt")

fake_test_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)

fake_test_cert = (
x509.CertificateBuilder()
.subject_name(
x509.Name(
[x509.NameAttribute(NameOID.COMMON_NAME, "Self Signed Test Server")]
)
)
.issuer_name(
x509.Name(
[x509.NameAttribute(NameOID.COMMON_NAME, "Self Signed Test Server")]
)
)
.serial_number(x509.random_serial_number())
.not_valid_before(datetime.datetime.utcnow())
.not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=1))
.public_key(fake_test_key.public_key())
.add_extension(
x509.SubjectAlternativeName([x509.DNSName("fake.test")]), critical=False
)
.sign(private_key=fake_test_key, algorithm=hashes.SHA256())
# Create self-signed certificate using the CA
self_test_crt_path = f"{test_nginx_conf_path}/self.test.crt"
subprocess.run(
[
"openssl",
"x509",
"-req",
"-in",
self_test_req_path,
"-CA",
ca_crt_path,
"-CAkey",
ca_key_path,
"-extfile",
'<(printf "subjectAltName=DNS:self.test")',
"-CAcreateserial",
"-out",
self_test_crt_path,
"-days",
"1",
"-sha256",
],
shell=True,
check=True,
)

# Save server key and certificate for fake.test
with open(fake_test_key_path, "wb") as key_file:
key_file.write(
fake_test_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption(),
)
)
with open(fake_test_cert_path, "wb") as cert_file:
cert_file.write(fake_test_cert.public_bytes(serialization.Encoding.PEM))
shutil.copyfile(
"_integration-test/custom-ca-roots/test.py",
"sentry/test-custom-ca-roots.py",
)
# Sanity check that signed certificate passes OpenSSL's validation
subprocess.run(
["openssl", "verify", "-CAfile", ca_crt_path, self_test_crt_path], check=True
)

# Create self-signed certificate with a different subjectAltName
fake_test_key_path = f"{test_nginx_conf_path}/fake.test.key"
fake_test_crt_path = f"{test_nginx_conf_path}/fake.test.crt"
subprocess.run(
[
"openssl",
"req",
"-x509",
"-newkey",
"rsa:2048",
"-nodes",
"-days",
"1",
"-keyout",
fake_test_key_path,
"-out",
fake_test_crt_path,
"-addext",
"subjectAltName=DNS:fake.test",
"-subj",
"/CN=Self Signed Test Server",
],
check=True,
)
subprocess.run(
["docker", "compose", "--ansi", "never", "up", "-d", "fixture-custom-ca-roots"],
check=True,
Expand All @@ -334,28 +280,28 @@ def test_custom_cas():
],
check=True,
)
# subprocess.run(
# [
# "docker",
# "compose",
# "--ansi",
# "never",
# "rm",
# "-s",
# "-f",
# "-v",
# "fixture-custom-ca-roots",
# ],
# check=True,
# )

# # Remove files
# os.remove(f"{custom_certs_path}/test-custom-ca-roots.crt")
# os.remove("sentry/test-custom-ca-roots.py")

# # Unset environment variable
# if "COMPOSE_FILE" in os.environ:
# del os.environ["COMPOSE_FILE"]
subprocess.run(
[
"docker",
"compose",
"--ansi",
"never",
"rm",
"-s",
"-f",
"-v",
"fixture-custom-ca-roots",
],
check=True,
)

# Remove files
os.remove(f"{custom_certs_path}/test-custom-ca-roots.crt")
os.remove("sentry/test-custom-ca-roots.py")

# Unset environment variable
if "COMPOSE_FILE" in os.environ:
del os.environ["COMPOSE_FILE"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I noticed: this test doesn't seem to have any asserts in it? Is there anything we can do to check that our custom CAs are actually the ones used?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It actually does have asserts in it, although it's not very clear. I can put in a comment explaining this in the code, but the asserts come from _integration-test/custom-ca-roots/test.py. The file is copied into the docker volume and executed within the container with the command

subprocess.run(
        [
            "docker",
            "compose",
            "--ansi",
            "never",
            "run",
            "--no-deps",
            "web",
            "python3",
            "/etc/sentry/test-custom-ca-roots.py",
        ],
        check=True,
    )



def test_receive_transaction_events(client_login):
Expand Down
1 change: 0 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
cryptography>=42.0.4
sentry-sdk>=1.39.2
pytest>=8.0.0
pytest-cov>=4.1.0
Expand Down
Loading