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

[gnmi] add test to use gnmi certificate after 2038 year problem #15770

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
84 changes: 7 additions & 77 deletions tests/gnmi/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

from tests.common.helpers.assertions import pytest_require as pyrequire
from tests.common.helpers.dut_utils import check_container_state
from tests.gnmi.helper import gnmi_container, apply_cert_config, recover_cert_config, create_ext_conf
from tests.gnmi.helper import GNMI_SERVER_START_WAIT_TIME
from tests.gnmi.helper import gnmi_container, apply_cert_config, recover_cert_config, GNMI_SERVER_START_WAIT_TIME, \
prepare_root_cert, prepare_server_cert, prepare_client_cert, copy_certificate_to_dut, copy_certificate_to_ptf
from tests.common.gu_utils import create_checkpoint, rollback

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -46,82 +46,12 @@ def setup_gnmi_server(duthosts, rand_one_dut_hostname, localhost, ptfhost):
check_container_state(duthost, gnmi_container(duthost), should_be_running=True),
"Test was not supported on devices which do not support GNMI!")

# Create Root key
local_command = "openssl genrsa -out gnmiCA.key 2048"
localhost.shell(local_command)

# Create Root cert
local_command = "openssl req \
-x509 \
-new \
-nodes \
-key gnmiCA.key \
-sha256 \
-days 1825 \
-subj '/CN=test.gnmi.sonic' \
-out gnmiCA.pem"
localhost.shell(local_command)

# Create server key
local_command = "openssl genrsa -out gnmiserver.key 2048"
localhost.shell(local_command)

# Create server CSR
local_command = "openssl req \
-new \
-key gnmiserver.key \
-subj '/CN=test.server.gnmi.sonic' \
-out gnmiserver.csr"
localhost.shell(local_command)

# Sign server certificate
create_ext_conf(duthost.mgmt_ip, "extfile.cnf")
local_command = "openssl x509 \
-req \
-in gnmiserver.csr \
-CA gnmiCA.pem \
-CAkey gnmiCA.key \
-CAcreateserial \
-out gnmiserver.crt \
-days 825 \
-sha256 \
-extensions req_ext -extfile extfile.cnf"
localhost.shell(local_command)

# Create client key
local_command = "openssl genrsa -out gnmiclient.key 2048"
localhost.shell(local_command)

# Create client CSR
local_command = "openssl req \
-new \
-key gnmiclient.key \
-subj '/CN=test.client.gnmi.sonic' \
-out gnmiclient.csr"
localhost.shell(local_command)

# Sign client certificate
local_command = "openssl x509 \
-req \
-in gnmiclient.csr \
-CA gnmiCA.pem \
-CAkey gnmiCA.key \
-CAcreateserial \
-out gnmiclient.crt \
-days 825 \
-sha256"
localhost.shell(local_command)
prepare_root_cert(localhost)
prepare_server_cert(duthost, localhost)
prepare_client_cert(localhost)

# Copy CA certificate, server certificate and client certificate over to the DUT
duthost.copy(src='gnmiCA.pem', dest='/etc/sonic/telemetry/')
duthost.copy(src='gnmiserver.crt', dest='/etc/sonic/telemetry/')
duthost.copy(src='gnmiserver.key', dest='/etc/sonic/telemetry/')
duthost.copy(src='gnmiclient.crt', dest='/etc/sonic/telemetry/')
duthost.copy(src='gnmiclient.key', dest='/etc/sonic/telemetry/')
# Copy CA certificate and client certificate over to the PTF
ptfhost.copy(src='gnmiCA.pem', dest='/root/')
ptfhost.copy(src='gnmiclient.crt', dest='/root/')
ptfhost.copy(src='gnmiclient.key', dest='/root/')
copy_certificate_to_dut(duthost)
copy_certificate_to_ptf(ptfhost)

create_checkpoint(duthost, SETUP_ENV_CP)
apply_cert_config(duthost)
Expand Down
129 changes: 129 additions & 0 deletions tests/gnmi/helper.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import time
import logging
import pytest
import re
from datetime import datetime
from tests.common.utilities import wait_until
from tests.common.helpers.gnmi_utils import GNMIEnvironment

Expand Down Expand Up @@ -406,3 +408,130 @@ def gnoi_request(duthost, localhost, rpc, request_json_data):
return -1, output['stderr']
else:
return 0, output['stdout']


def cert_date_on_dut(duthost):
cmd = "openssl x509 -in /etc/sonic/telemetry/gnmiCA.pem -text"
output = duthost.shell(cmd, module_ignore_errors=True)
not_after_line = re.search(r"Not After\s*:\s*(.*)", output['stdout'])
if not_after_line:
not_after_date_str = not_after_line.group(1).strip()
# Convert the date string to a datetime object
expiry_date = datetime.strptime(not_after_date_str, "%b %d %H:%M:%S %Y GMT")
# comparison date is January 20, 2038, after the 2038 problem
after_2038_problem_date = datetime(2038, 1, 20)

if expiry_date < after_2038_problem_date:
raise Exception("The expiry date {} is not after 2038 problem date".format(expiry_date))
else:
logger.info("The expiry date {} is after January 20, 2038.".format(expiry_date))
else:
raise Exception("The 'Not After' line with expiry date was not found")


def prepare_root_cert(localhost, days="1825"):
create_root_key(localhost)
create_root_cert(localhost, days)


def create_root_key(localhost):
local_command = "openssl genrsa -out gnmiCA.key 2048"
localhost.shell(local_command)


def create_root_cert(localhost, days):
local_command = "openssl req \
-x509 \
-new \
-nodes \
-key gnmiCA.key \
-sha256 \
-days {} \
-subj '/CN=test.gnmi.sonic' \
-out gnmiCA.pem".format(days)
localhost.shell(local_command)


def prepare_server_cert(duthost, localhost, days="825"):
create_server_key(localhost)
create_server_csr(localhost)
sign_server_certificate(duthost, localhost, days)


def create_server_key(localhost):
local_command = "openssl genrsa -out gnmiserver.key 2048"
localhost.shell(local_command)


def create_server_csr(localhost):
local_command = "openssl req \
-new \
-key gnmiserver.key \
-subj '/CN=test.server.gnmi.sonic' \
-out gnmiserver.csr"
localhost.shell(local_command)


def sign_server_certificate(duthost, localhost, days):
create_ext_conf(duthost.mgmt_ip, "extfile.cnf")
local_command = "openssl x509 \
-req \
-in gnmiserver.csr \
-CA gnmiCA.pem \
-CAkey gnmiCA.key \
-CAcreateserial \
-out gnmiserver.crt \
-days {} \
-sha256 \
-extensions req_ext \
-extfile extfile.cnf".format(days)
localhost.shell(local_command)


def prepare_client_cert(localhost, days="825"):
create_client_key(localhost)
create_client_csr(localhost)
sign_client_certificate(localhost, days)


def create_client_key(localhost):
local_command = "openssl genrsa -out gnmiclient.key 2048"
localhost.shell(local_command)


def create_client_csr(localhost):
local_command = "openssl req \
-new \
-key gnmiclient.key \
-subj '/CN=test.client.gnmi.sonic' \
-out gnmiclient.csr"
localhost.shell(local_command)


def sign_client_certificate(localhost, days):
local_command = "openssl x509 \
-req \
-in gnmiclient.csr \
-CA gnmiCA.pem \
-CAkey gnmiCA.key \
-CAcreateserial \
-out gnmiclient.crt \
-days {} \
-sha256".format(days)
localhost.shell(local_command)


def copy_certificate_to_dut(duthost):
# Copy CA certificate, server certificate and client certificate over to the DUT
duthost.copy(src='gnmiCA.pem', dest='/etc/sonic/telemetry/')
duthost.copy(src='gnmiserver.crt', dest='/etc/sonic/telemetry/')
duthost.copy(src='gnmiserver.key', dest='/etc/sonic/telemetry/')
duthost.copy(src='gnmiclient.crt', dest='/etc/sonic/telemetry/')
duthost.copy(src='gnmiclient.key', dest='/etc/sonic/telemetry/')


def copy_certificate_to_ptf(ptfhost):
# Copy CA certificate and client certificate over to the PTF
ptfhost.copy(src='gnmiCA.pem', dest='/root/')
ptfhost.copy(src='gnmiclient.crt', dest='/root/')
ptfhost.copy(src='gnmiclient.key', dest='/root/')
38 changes: 38 additions & 0 deletions tests/gnmi/test_gnmi_2038.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import pytest
import logging

from .helper import gnmi_capabilities, prepare_root_cert, prepare_server_cert, prepare_client_cert, \
copy_certificate_to_dut, copy_certificate_to_ptf, apply_cert_config, cert_date_on_dut

logger = logging.getLogger(__name__)
SETUP_ENV_CP = "test_setup_checkpoint"

pytestmark = [
pytest.mark.topology('any'),
pytest.mark.disable_loganalyzer
]


def test_gnmi_capabilities(duthosts, rand_one_dut_hostname, localhost, ptfhost):
'''
Verify certificate after 2038 year problem
'''
duthost = duthosts[rand_one_dut_hostname]

prepare_root_cert(localhost, days="4850")
prepare_server_cert(duthost, localhost, days="4810")
prepare_client_cert(localhost, days="4810")

copy_certificate_to_dut(duthost)
copy_certificate_to_ptf(ptfhost)

apply_cert_config(duthost)

# Verify certificate date on DUT
cert_date_on_dut(duthost)

# Verify GNMI capabilities to validate functionality
ret, msg = gnmi_capabilities(duthost, localhost)
assert ret == 0, msg
assert "sonic-db" in msg, msg
assert "JSON_IETF" in msg, msg
Loading