Programming certificate store

Programming certificate store

Neuko provides an abstract class of CertificateStore to make it flexible for developer to choose on how to save and retrieve certificates from the device.

CertificateStore is a class that defines on how the Neuko SDK module saves and retrieves the following certificates:

  • Provisioning certificates
  • Perpetual certificates

Each of the certificate types consists of 3 types of files:

  • Root CA file.
  • Chain certificate file.
  • Private key file.

For illustration, let’s assume that all Provisioning Certificates is stored in /secured/certificates/provisioning directory while Perpetual Certificates will be stored in /secured/certificates/perpetual.

Info

Downloaded certificates from Neuko Web application have the following filename format:

  • Root CA – ProvisioningRootCA.pem
  • Chain certificate – account_idproject_idschema_id-provisioning-certificate.pem.crt
  • Private Key – account_idproject_idschema_id-provisioning-private.pem.crt
import { DeviceIdentifier, CertificateStore } from "@neukolabs/device-sdk-js";
import { readFileSync, writeFileSync } from 'fs';
import path from 'path';

class deviceCertificateStore extends CertificateStore {
    readonly SECURED_DIR   = "./secured/certificates/";
    readonly PROVISION_DIR = "provisioning";
    readonly PERPETUAL_DIR = "perpetual";

    public getBootstrapCertificateAuthority(deviceIdentifier: DeviceIdentifier): Promise<string | Buffer> | string | Buffer {
        // the path is ./secured/certificates/provisioning/ProvisioningRootCA.pem
        const filePath = path.join(this.SECURED_DIR, this.PROVISIONING_DIR, "ProvisioningRootCA.pem");
        return readFileSync(filePath);
    }

    public getBootstrapChainCertificate(deviceIdentifier: DeviceIdentifier): Promise<string | Buffer> | string | Buffer {
        // the path is ./secured/certificates/provisioning/acc_someid-prj_someid-sch_someid-provisioning-certificate.pem.crt
        const filePath = path.join(this.SECURED_DIR, this.PROVISIONING_DIR, [deviceIdentifier.accountId, deviceIdentifier.projectId, deviceIdentifier.deviceSchemaId, "provisioning-certificate.pem.crt"].join("-"));
        return readFileSync(filePath);
    }

    public getBootstrapPrivateKey(deviceIdentifier: DeviceIdentifier): Promise<string | Buffer> | string | Buffer {
        // the path is ./secured/certificates/provisioning/acc_someid-prj_someid-sch_someid-provisioning-private.pem.crt
        const filePath = path.join(this.SECURED_DIR, this.PROVISIONING_DIR, [deviceIdentifier.accountId, deviceIdentifier.projectId, deviceIdentifier.deviceSchemaId, "provisioning-private.pem.crt"].join("-"));
        return readFileSync(filePath);
    }

    public getPerpetualCertificateAuthority(deviceIdentifier: DeviceIdentifier): Promise<string | Buffer> | string | Buffer {
        // the path is ./secured/certificates/perpetual/ProvisioningRootCA.pem
        const filePath = path.join(this.SECURED_DIR, this.PERPETUAL_DIR, "ProvisioningRootCA.pem");
        return readFileSync(filePath);
    }

    public getPerpetualChainCertificate(deviceIdentifier: DeviceIdentifier): Promise<string | Buffer> | string | Buffer {
        // the path is ./secured/certificates/perpetual/acc_someid-prj_someid-sch_someid-certificate.pem.crt
        const filePath = path.join(this.SECURED_DIR, this.PERPETUAL_DIR, [deviceIdentifier.accountId, deviceIdentifier.projectId, deviceIdentifier.deviceSchemaId, "certificate.pem.crt"].join("-"));
        return readFileSync(filePath);
    }

    public getPerpetualPrivateKey(deviceIdentifier: DeviceIdentifier): Promise<string | Buffer> | string | Buffer {
        // the path is ./secured/certificates/perpetual/acc_someid-prj_someid-sch_someid-private.pem.crt
        const filePath = path.join(this.SECURED_DIR, this.PERPETUAL_DIR, [deviceIdentifier.accountId, deviceIdentifier.projectId, deviceIdentifier.deviceSchemaId, "private.pem.crt"].join("-"));
        return readFileSync(filePath);
    }

    public savePerpetualCertificateAuthority(deviceIdentifier: DeviceIdentifier, certificate: Promise<string | Buffer> | string | Buffer): Promise<void> | void {
        const filePath = path.join(this.SECURED_DIR, this.PERPETUAL_DIR, "ProvisioningRootCA.pem");
        writeFileSync(filePath, certificate as string | Buffer);
    }

    public savePerpetualChainCertificate(deviceIdentifier: DeviceIdentifier, certificate: Promise<string | Buffer> | string | Buffer): Promise<void> | void {
        const filePath = path.join(this.SECURED_DIR, this.PERPETUAL_DIR, [deviceIdentifier.accountId, deviceIdentifier.projectId, deviceIdentifier.deviceSchemaId, "certificate.pem.crt"].join("-"));
        writeFileSync(filePath, certificate as string | Buffer);
    }

    public savePerpetualPrivateKey(deviceIdentifier: DeviceIdentifier, certificate: Promise<string | Buffer> | string | Buffer): Promise<void> | void {
        const filePath = path.join(this.SECURED_DIR, this.PERPETUAL_DIR, [deviceIdentifier.accountId, deviceIdentifier.projectId, deviceIdentifier.deviceSchemaId, "private.pem.crt"].join("-"));
        writeFileSync(filePath, certificate as string | Buffer);
    }
}

 

import os
from neuko.device.model import DeviceIdentifier
from neuko.connection.certificateStore import CertificateStore

class EdgeGatewayCertificateStore(CertificateStore):

    PROVISION_DIR = '/opt/secured/cetificates/bootstrap'
    PERPETUAL_DIR = '/opt/secured/cetificates/perpetual'

    async def getBootstrapCertificateAuthority(self, deviceIdentifier: DeviceIdentifier) -> str:
        return os.path.join(self.PROVISION_DIR, 'ProvisioningRootCA.pem')

    async def getBootstrapChainCertificate(self, deviceIdentifier: DeviceIdentifier) -> str:
        return os.path.join(self.PROVISION_DIR, f'{deviceIdentifier.accountId}-{deviceIdentifer.projectId}-{deviceIdentifier.deviceSchemaId}-provisioning-certificate.pem.crt')

    async def getBootstrapPrivateKey(self, deviceIdentifier: DeviceIdentifier) -> str:
        return os.path.join(self.PROVISION_DIR, f'{deviceIdentifier.accountId}-{deviceIdentifer.projectId}-{deviceIdentifier.deviceSchemaId}-provisioning-private.pem.crt')

    async def getPerpetualCertificateAuthority(self, deviceIdentifier: DeviceIdentifier) -> str:
        return os.path.join(self.PERPETUAL_DIR, 'ProvisioningRootCA.pem')

    async def getPerpetualChainCertificate(self, deviceIdentifier: DeviceIdentifier) -> str:
        return os.path.join(self.PERPETUAL_DIR, f'{deviceIdentifier.accountId}-{deviceIdentifer.projectId}-{deviceIdentifier.deviceSchemaId}-certificate.pem.crt')


    async def getPerpetualPrivateKey(self, deviceIdentifier: DeviceIdentifier) -> str:
        return os.path.join(self.PERPETUAL_DIR, f'{deviceIdentifier.accountId}-{deviceIdentifer.projectId}-{deviceIdentifier.deviceSchemaId}-private.pem.crt')

    async def savePerpetualCertificateAuthority(self, deviceIdentifier: DeviceIdentifier, certificate: str) -> None:
        filePath = os.path.join(self.PERPETUAL_DIR, 'ProvisioningRootCA.pem')
        fd = open(filePath, mode="w")
        fd.write(certificate)
        fd.close()

    async def savePerpetualChainCertificate(self, deviceIdentifier: DeviceIdentifier, certificate: str) -> None:
        filePath = os.path.join(self.PERPETUAL_DIR, f'{deviceIdentifier.accountId}-{deviceIdentifer.projectId}-{deviceIdentifier.deviceSchemaId}-certificate.pem.crt')
        fd = open(filePath, mode="w")
        fd.write(certificate)
        fd.close()

    async def savePerpetualPrivateKey(self, deviceIdentifier: DeviceIdentifier, certificate: str) -> None:
        filePath = os.path.join(self.PERPETUAL_DIR, f'{deviceIdentifier.accountId}-{deviceIdentifer.projectId}-{deviceIdentifier.deviceSchemaId}-private.pem.crt')
        fd = open(filePath, mode="w")
        fd.write(certificate)
        fd.close()

 

Scroll to Top