Skip to content

Commit

Permalink
Add integration tests and experimental workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
dkirov-dd committed Dec 23, 2024
1 parent 3e3e51a commit 23d2930
Show file tree
Hide file tree
Showing 2 changed files with 290 additions and 0 deletions.
222 changes: 222 additions & 0 deletions .github/workflows/experimental.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
name: Test FIPS experimental

on:
workflow_dispatch:
inputs:
zip_url:
required: true
type: string
default: 'https://agent-ints-python-build-sandbox.s3.eu-north-1.amazonaws.com/python-windows-combined-v3.12.6-openssl-3.0.15-openssl-3.0.9-amd64.zip'
pull_request:
path:
- datadog_checks_base/datadog_checks/**
schedule:
- cron: '0 0,8,16 * * *'

defaults:
run:
shell: bash

jobs:
test:
strategy:
matrix:
include:
- platform: "Windows"
runner: "windows-2022"
zip_url: "https://agent-ints-python-build-sandbox.s3.eu-north-1.amazonaws.com/python-windows-combined-v3.12.6-openssl-3.0.15-openssl-3.0.9-amd64.zip"
- platform: "Linux"
runner: "ubuntu-22.04"
zip_url: ""
name: FIPS test on ${{ matrix.platform }}
runs-on: ${{ matrix.runner }}

env:
FORCE_COLOR: "1"
DEBIAN_FRONTEND: "noninteractive"
OPENSSL_FIPS: "1"
PYTHON_VERSION: "3.12"
OPENSSL_VERSION: "3.0.15"
FIPS_MODULE_VERSION: "3.0.9"

steps:

- uses: actions/checkout@v4

- name: Install System Dependencies
if: runner.os == 'Linux'
run: |
sudo apt update
sudo apt install -y --no-install-recommends \
wget \
build-essential \
gcc \
make \
perl \
libc6-dev
- name: Build FIPS Module
if: runner.os == 'Linux'
run: |
wget https://www.openssl.org/source/openssl-${{ env.FIPS_MODULE_VERSION }}.tar.gz \
&& tar -xvzf openssl-${{ env.FIPS_MODULE_VERSION }}.tar.gz \
&& cd openssl-${{ env.FIPS_MODULE_VERSION }} \
&& ./Configure enable-fips \
&& make \
&& sudo make install
- name: Build OpenSSL
if: runner.os == 'Linux'
run: |
wget https://www.openssl.org/source/openssl-${{ env.OPENSSL_VERSION }}.tar.gz \
&& tar -xvzf openssl-${{ env.OPENSSL_VERSION }}.tar.gz \
&& cd openssl-${{ env.OPENSSL_VERSION }} \
&& ./Configure enable-fips \
&& make \
&& sudo make install
- name: Build Python from Source with Custom OpenSSL
if: runner.os == 'Linux'
run: |
# Install dependencies for building Python
sudo apt-get update && sudo apt-get install -y \
build-essential \
zlib1g-dev \
libffi-dev \
libssl-dev \
libncurses5-dev \
libsqlite3-dev \
libreadline-dev \
libbz2-dev \
liblzma-dev \
tk-dev \
uuid-dev \
libgdbm-dev \
wget
# Download and extract Python source
wget https://www.python.org/ftp/python/${{ env.PYTHON_VERSION }}/Python-${{ env.PYTHON_VERSION }}.tgz
tar -xvzf Python-${{ env.PYTHON_VERSION }}.tgz -C python_dir
cd python_dir
# Configure and build Python with custom OpenSSL
./configure --enable-optimizations --with-openssl=$(pwd)/../openssl-${{ env.OPENSSL_VERSION }}
make -j$(nproc)
sudo make altinstall
- name: Download python-windows-combined
if: runner.os == 'Windows'
shell: powershell
run: |
Invoke-WebRequest -Uri ${{ inputs.zip_url || matrix.zip_url }} -OutFile 'python_combined.zip'
- name: Unzip python_combined.zip
if: runner.os == 'Windows'
shell: powershell
run: |
Expand-Archive -Path python_combined.zip -DestinationPath .\python_dir
- name: Run fipsintall.exe
if: runner.os == 'Windows'
working-directory: .\python_dir
shell: powershell
run: |
.\openssl.exe fipsinstall -module .\ossl-modules\fips.dll -out fipsmodule.cnf
- name: Configure OpenSSL for FIPS
if: runner.os == 'Windows'
working-directory: .\python_dir
shell: powershell
run: |
# Create openssl.cnf to enable FIPS mode
$OpenSSLConf = @"
config_diagnostics = 1
openssl_conf = openssl_init
.include fipsmodule.cnf
[openssl_init]
providers = provider_sect
alg_section = algorithm_sect
[provider_sect]
fips = fips_sect
base = base_sect
[base_sect]
activate = 1
[algorithm_sect]
default_properties = fips=yes
"@
$OpenSSLConf | Set-Content -Path ".\openssl.cnf"
- name: Verify OpenSSL
if: runner.os == 'Windows'
working-directory: .\python_dir
shell: powershell
run: |
.\openssl.exe version -a
.\openssl.exe list -providers
- name: Verify OpenSSL with FIPS ENV vars
if: runner.os == 'Windows'
working-directory: .\python_dir
shell: powershell
run: |
$env:OPENSSL_MODULES = ".\ossl-modules"
$env:OPENSSL_CONF = ".\openssl.cnf"
.\openssl.exe list -providers
- name: Add Python to PATH
run: |
if [[ "$RUNNER_OS" == "Windows" ]]; then
echo "PATH=$(pwd)\python_dir;$(pwd)\python_dir\Scripts;$PATH" >> $GITHUB_ENV
else
echo "PATH=$(pwd)/python_dir:$PATH" >> $GITHUB_ENV
fi
- name: Install pip
run: |
python -m ensurepip
- name: Restore cache
uses: actions/cache/restore@v4
with:
path: ${{ runner.os == 'Windows' && '~\AppData\Local\pip\Cache' || '~/.cache/pip' }}
key: >-
${{ format(
'v01-python-{0}-{1}-{2}-{3}',
env.pythonLocation,
hashFiles('datadog_checks_base/pyproject.toml'),
hashFiles('datadog_checks_dev/pyproject.toml'),
hashFiles('ddev/pyproject.toml')
)}}
restore-keys: |-
v01-python-${{ env.pythonLocation }}
- name: Install ddev from local folder
run: |
python -m pip install -e ./datadog_checks_dev[cli]
python -m pip install -e ./ddev
- name: Configure ddev
run: |
ddev config set repos.core .
ddev config set repo core
- name: Test
if: runner.os == 'Windows'
shell: powershell
run: |
$env:PATH_TO_OPENSSL_CONF = "$(pwd)\openssl.cnf"
$env:PATH_TO_OPENSSL_MODULES = "$(pwd)\ossl-modules"
$env:OPENSSL_CONF = "$(pwd)\openssl.cnf"
$env:OPENSSL_MODULES = "$(pwd)\ossl-modules"
.\python_dir\openssl.exe list -providers
.\python_dir\openssl.exe md5
ddev datadog_checks_base -m fips_off
ddev datadog_checks_base -m fips_on
python -c "import ssl; ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT).set_ciphers('MD5')"
which python
68 changes: 68 additions & 0 deletions datadog_checks_base/tests/test_fips.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# (C) Datadog, Inc. 2024-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
from typing import Any # noqa: F401

import os
import pytest

from datadog_checks.base.utils.fips import enable_fips

PATH_TO_OPENSSL_CONF = os.getenv("PATH_TO_OPENSSL_CONF")
PATH_TO_OPENSSL_MODULES = os.getenv("PATH_TO_OPENSSL_MODULES")


@pytest.fixture(scope="function")
def clean_environment(monkeypatch):
monkeypatch.setenv("GOFIPS", "0")
monkeypatch.setenv("OPENSSL_CONF", "")
monkeypatch.setenv("OPENSSL_MODULES", "")
yield


@pytest.mark.fips_off
def test_ssl_md5_before_fips(clean_environment):
"""
MD5 cipher should be available through ssl before enabling FIPS mode.
"""
import ssl

ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.set_ciphers("MD5")
assert True


@pytest.mark.fips_off
def test_cryptography_md5_before_fips(clean_environment):
"""
MD5 cipher should be available through cryptography before enabling FIPS mode.
"""
from cryptography.hazmat.primitives import hashes

assert hashes.Hash(hashes.MD5())


@pytest.mark.fips_on
def test_ssl_md5_after_fips(clean_environment):
"""
MD5 cipher should not be available through ssl after enabling FIPS mode.
"""
import ssl

enable_fips(path_to_openssl_conf=PATH_TO_OPENSSL_CONF, path_to_openssl_modules=PATH_TO_OPENSSL_MODULES)
with pytest.raises(ssl.SSLError, match='No cipher can be selected.'):
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.set_ciphers("MD5")


@pytest.mark.fips_on
def test_cryptography_md5_after_fips(clean_environment):
"""
MD5 cipher should not be available through cryptography after enabling FIPS mode.
"""
from cryptography.exceptions import InternalError
from cryptography.hazmat.primitives import hashes

enable_fips(path_to_openssl_conf=PATH_TO_OPENSSL_CONF, path_to_openssl_modules=PATH_TO_OPENSSL_MODULES)
with pytest.raises(InternalError, match='Unknown OpenSSL error.'):
hashes.Hash(hashes.MD5())

0 comments on commit 23d2930

Please sign in to comment.