Skip to content

Commit

Permalink
Merge PR #563
Browse files Browse the repository at this point in the history
  • Loading branch information
elibon99 committed Aug 9, 2023
2 parents cd192be + 3ef0b0c commit eba606a
Show file tree
Hide file tree
Showing 7 changed files with 1,862 additions and 1 deletion.
286 changes: 286 additions & 0 deletions tests/device/cli/test_hsmauth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
# -*- coding: utf-8 -*-
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec

from yubikit.management import CAPABILITY
from .. import condition

import pytest
import re
import os
import tempfile

DEFAULT_MANAGEMENT_KEY = "00000000000000000000000000000000"
NON_DEFAULT_MANAGEMENT_KEY = "11111111111111111111111111111111"


def generate_pem_eccp256_keypair():
pk = ec.generate_private_key(ec.SECP256R1(), default_backend())
return (
pk.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption(),
),
pk.public_key().public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
),
)


@pytest.fixture()
def eccp256_keypair():
tmp = tempfile.NamedTemporaryFile(delete=False)
private_key, public_key = generate_pem_eccp256_keypair()
tmp.write(private_key)
tmp.close()
yield tmp.name, public_key
os.remove(tmp.name)


@pytest.fixture()
def tmp_file():
tmp = tempfile.NamedTemporaryFile(delete=False)
yield tmp
tmp.close()
os.remove(tmp.name)


@pytest.fixture(autouse=True)
@condition.capability(CAPABILITY.OATH)
@condition.min_version(5, 4, 3)
def preconditions(ykman_cli):
ykman_cli("hsmauth", "reset", "-f")


class TestOATH:
def test_hsmauth_info(self, ykman_cli):
output = ykman_cli("hsmauth", "info").output
assert "version:" in output

def test_hsmauth_reset(self, ykman_cli):
output = ykman_cli("hsmauth", "reset", "-f").output
assert (
"Success! All YubiHSM Auth data have been cleared from the YubiKey."
in output
)


class TestCredentials:
def test_import_credential_symmetric(self, ykman_cli):
ykman_cli(
"hsmauth",
"credentials",
"symmetric",
"test-name-sym",
"-c",
"123456",
"-E",
os.urandom(16).hex(),
"-M",
os.urandom(16).hex(),
"-m",
DEFAULT_MANAGEMENT_KEY,
)
creds = ykman_cli("hsmauth", "credentials", "list").output
assert "test-name-sym" in creds

def test_import_credential_symmetric_generate(self, ykman_cli):
output = ykman_cli(
"hsmauth",
"credentials",
"symmetric",
"test-name-sym-gen",
"-c",
"123456",
"-g",
"-m",
DEFAULT_MANAGEMENT_KEY,
).output

assert "Generated ENC and MAC keys" in output

def test_import_credential_symmetric_derived(self, ykman_cli):
ykman_cli(
"hsmauth",
"credentials",
"derive",
"test-name-sym-derived",
"-c",
"123456",
"-d",
"password",
)
creds = ykman_cli("hsmauth", "credentials", "list").output
assert "test-name-sym-derived" in creds

@condition.min_version(5, 6)
def test_import_credential_asymmetric(self, ykman_cli):
pair = generate_pem_eccp256_keypair()
ykman_cli(
"hsmauth",
"credentials",
"import",
"test-name-asym",
"-c",
"123456",
"-m",
DEFAULT_MANAGEMENT_KEY,
"-",
input=pair[0],
)
creds = ykman_cli("hsmauth", "credentials", "list").output
assert "test-name-asym" in creds

public_key_exported = ykman_cli(
"hsmauth", "credentials", "export", "test-name-asym", "-"
).stdout_bytes
assert pair[1] == public_key_exported

@condition.min_version(5, 6)
def test_generate_credential_asymmetric(self, ykman_cli):
ykman_cli(
"hsmauth",
"credentials",
"generate",
"test-name-asym-generated",
"-c",
"123456",
"-m",
DEFAULT_MANAGEMENT_KEY,
)

creds = ykman_cli("hsmauth", "credentials", "list").output
assert "test-name-asym-generated" in creds

def test_import_credential_touch_required(self, ykman_cli):
ykman_cli(
"hsmauth",
"credentials",
"derive",
"test-name-touch",
"-c",
"123456",
"-d",
"password",
"-t",
)

creds = ykman_cli("hsmauth", "credentials", "list").output
assert "On" in creds
assert "test-name-touch" in creds

@condition.min_version(5, 6)
def test_export_public_key_to_file(self, ykman_cli, eccp256_keypair, tmp_file):
private_key_file, public_key = eccp256_keypair
ykman_cli(
"hsmauth",
"credentials",
"import",
"test-name-asym",
"-c",
"123456",
"-m",
DEFAULT_MANAGEMENT_KEY,
private_key_file,
)

ykman_cli(
"hsmauth",
"credentials",
"export",
"test-name-asym",
tmp_file.name,
)

public_key_from_file = tmp_file.read()
assert public_key_from_file == public_key

@condition.min_version(5, 6)
def test_export_public_key_symmetric_credential(self, ykman_cli):
ykman_cli(
"hsmauth",
"credentials",
"derive",
"test-name-sym",
"-c",
"123456",
"-d",
"password",
"-m",
DEFAULT_MANAGEMENT_KEY,
)

with pytest.raises(SystemExit):
ykman_cli("hsmauth", "credentials", "export", "test-name-sym")

def test_delete_credential(self, ykman_cli):
ykman_cli(
"hsmauth",
"credentials",
"derive",
"delete-me",
"-c",
"123456",
"-d",
"password",
"-m",
DEFAULT_MANAGEMENT_KEY,
)
old_creds = ykman_cli("hsmauth", "credentials", "list").output
assert "delete-me" in old_creds
ykman_cli("hsmauth", "credentials", "delete", "delete-me", "-f")
new_creds = ykman_cli("hsmauth", "credentials", "list").output
assert "delete-me" not in new_creds


class TestManagementKey:
def test_change_management_key(self, ykman_cli):
ykman_cli(
"hsmauth",
"access",
"change-management-key",
"-m",
DEFAULT_MANAGEMENT_KEY,
"-n",
NON_DEFAULT_MANAGEMENT_KEY,
)

with pytest.raises(SystemExit):
# Should fail - wrong current key
ykman_cli(
"hsmauth",
"access",
"change-management-key",
"-m",
DEFAULT_MANAGEMENT_KEY,
"-n",
DEFAULT_MANAGEMENT_KEY,
)

# Should succeed
ykman_cli(
"hsmauth",
"access",
"change-management-key",
"-m",
NON_DEFAULT_MANAGEMENT_KEY,
"-n",
DEFAULT_MANAGEMENT_KEY,
)

def test_change_management_key_generate(self, ykman_cli):
output = ykman_cli(
"hsmauth",
"access",
"change-management-key",
"-m",
DEFAULT_MANAGEMENT_KEY,
"-g",
).output

assert re.match(
r"^Generated management key: [a-f0-9]{16}", output, re.MULTILINE
)
Loading

0 comments on commit eba606a

Please sign in to comment.