Skip to content

Commit

Permalink
Fix MICA creation
Browse files Browse the repository at this point in the history
  • Loading branch information
aguinane committed Aug 16, 2024
1 parent 5d650e4 commit 8407c76
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 23 deletions.
48 changes: 29 additions & 19 deletions sep2tools/cert_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,29 +200,30 @@ def generate_serca(


def generate_mica(
csr_path: Path,
ca_cert_path: Path,
ca_key_path: Path,
key_file: Path,
cert_file: Path | None = None,
org_name: str = "Example Org Name",
country_name: str = "AU",
common_name: str = "IEEE 2030.5 MICA",
policy_oids: list[ObjectIdentifier] = DEFAULT_MICA_POLICIES,
) -> tuple[Path, Path]:
"""Use a CSR and MICA key pair to generate a SEP2 Certificate"""

with open(csr_path, "rb") as fh:
csr_data = fh.read()
csr = x509.load_pem_x509_csr(csr_data)

if not cert_file:
output_dir = key_file.parent
output_dir = csr_path.parent
output_dir.mkdir(exist_ok=True)
if key_file.suffix == "pem":
cert_name = f"{key_file.stem}-mica.pem"
if csr_path.suffix == "pem":
cert_name = f"{csr_path.stem}-mica.pem"
else:
cert_name = f"{key_file.stem}.pem"
cert_name = f"{csr_path.stem}.pem"
cert_file = output_dir / cert_name

with open(key_file, "rb") as fh:
pem_data = fh.read()
key = serialization.load_pem_private_key(pem_data, password=None)

# Load certificate authority
with open(ca_cert_path, "rb") as fh:
ca_pem_data = fh.read()
Expand All @@ -234,20 +235,20 @@ def generate_mica(
valid_from = datetime.now(tz=tz.UTC)
valid_to = INDEF_EXPIRY # as per standard

policies = [x509.PolicyInformation(ANY_POLICY_OID, None)]
policies = [x509.PolicyInformation(oid, None) for oid in policy_oids]

# Define the Subject Name
subject = x509.Name(
[
x509.NameAttribute(NameOID.COUNTRY_NAME, country_name),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, org_name),
x509.NameAttribute(NameOID.COMMON_NAME, "IEEE 2030.5 MICA"),
x509.NameAttribute(NameOID.COMMON_NAME, common_name),
x509.NameAttribute(NameOID.SERIAL_NUMBER, "1"),
]
)

# Generate a Subject Key Identifier (SKI)
ski = key.public_key().public_bytes(
ski = csr.public_key().public_bytes(
encoding=serialization.Encoding.DER,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
Expand All @@ -256,11 +257,14 @@ def generate_mica(
ski_digest.update(ski)
ski_value = ski_digest.finalize()

issuer_name = ca_cert.subject
iname = x509.Name(issuer_name)

cert = (
x509.CertificateBuilder()
.subject_name(subject)
.issuer_name(subject)
.public_key(key.public_key())
.issuer_name(iname)
.public_key(csr.public_key())
.serial_number(x509.random_serial_number())
.not_valid_before(valid_from)
.not_valid_after(valid_to)
Expand Down Expand Up @@ -321,7 +325,7 @@ def generate_device_certificate(
cert_file: Path | None = None,
policy_oids: list[ObjectIdentifier] = DEFAULT_DEV_POLICIES,
valid_to: datetime | None = None,
subject_name: str = "",
common_name: str = "",
) -> Path:
"""Use a CSR and Signing Certificate key pair to generate a SEP2 Certificate"""

Expand Down Expand Up @@ -359,16 +363,22 @@ def generate_device_certificate(
encoder.leave()
hw_module_name = encoder.output()

# SubjectName should be blank
if subject_name:
# Define the Subject Name
if common_name:
log.warning("Specifying a SubjectName is a deviation from SEP2")
sname = x509.Name(subject_name)
subject = x509.Name(
[
x509.NameAttribute(NameOID.COMMON_NAME, common_name),
]
)
else:
subject = x509.Name("")

issuer_name = ca_cert.subject
iname = x509.Name(issuer_name)
cert = (
x509.CertificateBuilder()
.subject_name(sname)
.subject_name(subject)
.issuer_name(iname)
.public_key(csr.public_key())
.serial_number(x509.random_serial_number())
Expand Down
12 changes: 8 additions & 4 deletions sep2tools/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,18 @@ def create_key(key_file: Optional[Path] = None, verbose: bool = False) -> None:


@app.command()
def create_serca(verbose: bool = False, output_dir: Path = DEFAULT_DIR) -> None:
def create_serca(
org_name: str = "Smart Energy",
verbose: bool = False,
output_dir: Path = DEFAULT_DIR,
) -> None:
log_level = "DEBUG" if verbose else "INFO"
logging.basicConfig(level=log_level, format=LOG_FORMAT)

output_dir.mkdir(exist_ok=True)
key_file = output_dir / "serca.key"
key, csr = generate_key(key_file, generate_csr=False)
generate_serca(key)
generate_serca(key, org_name=org_name)


@app.command()
Expand All @@ -83,8 +87,8 @@ def create_mica(

output_dir.mkdir(exist_ok=True)
key_file = output_dir / "mica.key"
key, csr = generate_key(key_file, generate_csr=False)
generate_mica(ca_cert, ca_key, key)
key, csr = generate_key(key_file, generate_csr=True)
generate_mica(csr, ca_cert, ca_key, org_name=org_name)


@app.command()
Expand Down

0 comments on commit 8407c76

Please sign in to comment.