Skip to main content

GridAPPSD Certificate Store

Python Tests PyPI version License Code style: black

A flexible and secure X.509 certificate generator and store for IEEE 2030.5 smart grid devices, IoT applications, and general TLS/HTTPS requirements.

Features

  • Complete Certificate Generation: Create CAs, device certificates, and self-signed certificates
  • IEEE 2030.5 Support: Designed with IEEE 2030.5-2018 standard in mind for smart grid communications
  • Certificate Store: Persistent storage and retrieval of certificates with lookup capabilities
  • Device Identity: LFDI/SFDI calculation and extraction for IEEE 2030.5 device identification
  • Access Control: Client registry with granular access control for secure device communications
  • Multiple Key Types: Support for both RSA and Elliptic Curve cryptography
  • Flexible Subject Alternative Names: Create certificates with URIs, DNS names, IP addresses, or email addresses
  • TLS 1.2+ Compliance: Generate certificates that meet security requirements for modern TLS
  • Certificate Persistence: Easily save and load certificates and private keys
  • Web Server Certificates: Specialized method for generating HTTPS server certificates

Installation

# Install from PyPI
pip install gridappsd-certificate-store

# Or with Poetry
poetry add gridappsd-certificate-store

Quick Start

Certificate Generation

from gridappsd_certs import DeviceCertificateGenerator

# Initialize the generator
cert_gen = DeviceCertificateGenerator(key_type='rsa', key_size=2048)

# Create a CA certificate
ca_attrs = {
    'common_name': 'GridAPPSD Root CA',
    'organization': 'GridAPPSD',
    'country': 'US',
    'organizational_unit': 'Security'
}

ca_cert, ca_key = cert_gen.create_ca_certificate(ca_attrs, valid_days=3652)

# Create a device certificate for IEEE 2030.5
device_attrs = {
    'common_name': 'Smart Meter 101',
    'organization': 'GridAPPSD',
    'country': 'US',
    'organizational_unit': 'Smart Meters',
    'serial_number': 'SM101-12345'
}

device_cert, device_key = cert_gen.create_device_certificate(
    device_attrs,
    ca_cert,
    ca_key,
    device_id="11111111-2222-3333-4444-555555555555"
)

# Save certificates and keys
cert_gen.save_certificate(ca_cert, 'ca_cert.pem')
cert_gen.save_private_key(ca_key, 'ca_key.pem', password='secure-password')
cert_gen.save_certificate(device_cert, 'device_cert.pem')
cert_gen.save_private_key(device_key, 'device_key.pem')

Certificate Store

from gridappsd_certs import (
    CertificateStore,
    calculate_lfdi_from_certificate,
    calculate_sfdi_from_lfdi
)

# Create a certificate store with persistent storage
store = CertificateStore(storage_path="/path/to/cert/store")

# Add certificates to the store
ca_fingerprint = store.add_certificate(ca_cert, ca_key, alias="Root CA")
device_fingerprint = store.add_certificate(device_cert, device_key, alias="Device 101")

# Look up certificates by various attributes
cert_by_fingerprint = store.get_certificate_by_fingerprint(device_fingerprint)
certs_by_common_name = store.get_certificate_by_common_name("Smart Meter 101")

# Get IEEE 2030.5 identifiers
lfdi = calculate_lfdi_from_certificate(device_cert)
sfdi = calculate_sfdi_from_lfdi(lfdi)
print(f"Device LFDI: {lfdi}")
print(f"Device SFDI: {sfdi}")

# Get private key for a certificate
device_key = store.get_private_key(device_fingerprint)

Client Registry with Access Control

from gridappsd_certs import (
    ClientRegistry,
    ClientProfile,
    AccessControl,
    extract_identity_from_certificate
)

# Create a certificate store and registry
cert_store = CertificateStore(storage_path="/path/to/certs")
registry = ClientRegistry(cert_store=cert_store)

# Create access control rules
acl = AccessControl()
acl.add_rule("/dcap", "GET", allow=True) # Allow access to device capability
acl.add_rule("/edev/*", "GET", allow=True) # Allow read access to end devices
acl.add_rule("/drp/*", "*", allow=True) # Allow all methods on demand response

# Create a client profile
client_profile = ClientProfile(
    client_id="device-101",
    acl=acl
)

# Add client to registry with its certificate
registry.add_client("device-101", certificate=device_cert, profile=client_profile)

# Later, authenticate a client with its certificate
client = registry.get_client_by_certificate(device_cert)
if client:
    # Check if client can access a resource
    if client.can_access("/drp/1/dre", "GET"):
        print("Access granted to demand response events")
    else:
        print("Access denied")

# Save registry for persistence
registry.save("/path/to/registry.json")

IEEE 2030.5 Integration

The library is designed with IEEE 2030.5-2018 standard in mind, which requires:

  • TLS 1.2 with AES-CCM mode of operation
  • X.509 certificates for mutual authentication
  • Device identification via LFDI/SFDI and UUID in Subject Alternative Name
# Extract IEEE 2030.5 device information from certificate
from gridappsd_certs import extract_device_information_from_certificate

device_info = extract_device_information_from_certificate(device_cert)
print(f"LFDI: {device_info['lfdi']}")
print(f"SFDI: {device_info['sfdi']}")
print(f"Device ID: {device_info['device_id']}")

Certificate Validation

from gridappsd_certs import CertificateValidator

# Create validator with trusted CA certificates
validator = CertificateValidator(trust_store=[ca_cert])

# Validate a device certificate
result = validator.validate(device_cert)
if result.valid:
    print("Certificate is valid")
else:
    print(f"Certificate validation failed: {', '.join(result.errors)}")

Certificate Attributes

The following attributes can be included in certificate subject information:

Dictionary Key Description
common_name The common name (CN) for the certificate
country Two-letter country code (e.g., 'US')
state State or province name
locality City or locality name
organization Organization name
organizational_unit Department or unit within organization
email Email address
serial_number Serial number (useful for device identification)

Development

# Clone the repository
git clone https://github.com/GRIDAPPSD/gridappsd-certificate-store.git
cd gridappsd-certificate-store

# Install dependencies with Poetry
poetry install

# Run tests
poetry run pytest

# Run tests with coverage
poetry run pytest --cov=gridappsd_certs

# Format code
poetry run black gridappsd_certs

Metadata

Release files for gridappsd-certificate-store 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gridappsd-certificate-store 0.3.0
File Size Uploaded Provenance Actions
gridappsd_certificate_store-0.3.0.tar.gz 18.9 kB With provenance Details for gridappsd_certificate_store-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for gridappsd-certificate-store 0.3.0
File Interpreter ABI Platform Actions
gridappsd_certificate_store-0.3.0-py3-none-any.whl Python 3 none any Details for gridappsd_certificate_store-0.3.0-py3-none-any.whl

Total release size: 40.7 kB

Release files / gridappsd_certificate_store-0.3.0.tar.gz

Download URL gridappsd_certificate_store-0.3.0.tar.gz
Size 18.9 kB
Tags Source
SHA-256 checksum
How to use checksums
eb616c55c8be9a2b600a9e6e8ab15003a6105fbd5c3c9431b73af061f51c23a6
BLAKE2b-256 checksum
How to use checksums
2e712fe25c5dd2d17d484e7d1b91ef6c6373f9e5021a91cb7896e1af19e5356f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 16, 2025.

Transparency log

Release files / gridappsd_certificate_store-0.3.0-py3-none-any.whl

Download URL gridappsd_certificate_store-0.3.0-py3-none-any.whl
Size 21.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b56a2453606bba8876dff94791085286e103153bff5a13857ab5e349bcb3c578
BLAKE2b-256 checksum
How to use checksums
06806f52d0cc1fc1233fcb1da517a4696d0dd0ce91deec37fe44f93f92ee4960
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 16, 2025.

Transparency log

Security for gridappsd-certificate-store 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for gridappsd_certificate_store-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 16, 2025.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page