Search documentation of macula

# macula_cert (macula v4.4.9)

View Source

Macula Self-Sovereign Certificate System

Provides Ed25519 DID-anchored certificate generation and verification. Unlike traditional PKI, these certificates do not require external CAs.

Certificate hierarchy: - Realm certificates are self-signed (root of trust for a namespace) - Instance certificates are signed by the realm certificate

Example usage:

Generate realm keypair and certificate: {PubKey, PrivKey} = macula_cert:generate_keypair(), {ok, RealmCert} = macula_cert:generate_realm_cert(DID, PubKey, PrivKey).

Generate instance certificate signed by realm: {InstPub, InstPriv} = macula_cert:generate_keypair(), {ok, InstCert} = macula_cert:generate_instance_cert(InstanceDID, InstPub, RealmCert, PrivKey).

Verify certificate chain: ok = macula_cert:verify_cert(InstCert, RealmCert).

# Summary

## Types

macula_cert/0
macula_cert_request/0

## Functions

canonical_form(Cert)

Generate canonical form for signing/verification The canonical form excludes the signature field and is deterministic.

cn_to_did(CN)

Convert common name to DID format Example: "app.io.example" becomes "did:macula:io.example.app"

decode(Binary)

Decode certificate from binary format

did_to_cn(DID)

Convert DID to common name format Example: "did:macula:io.example.app" becomes "app.io.example"

encode(Cert)

Encode certificate to binary format Uses term_to_binary for now; can switch to CBOR/JSON for interop.

extract_realm_did(InstanceDID)

Extract realm DID from an instance DID Example: "did:macula:io.example.app.node01" becomes "did:macula:io.example"

from_map(Map)

Convert map to certificate record

generate_instance_cert(InstanceDID, InstancePubKey, RealmCert, RealmPrivKey)

Generate an instance certificate signed by a realm certificate The instance DID must be under the realm's namespace.

generate_instance_cert(InstanceDID, InstancePubKey, RealmCert, RealmPrivKey, ValidityDays)

Generate an instance certificate with custom validity

generate_keypair()

Generate a new Ed25519 keypair Returns {PublicKey, PrivateKey} as raw binaries.

generate_realm_cert(RealmDID, PublicKey, PrivateKey)

Generate a self-signed realm certificate Realm certificates are the root of trust for a namespace.

generate_realm_cert(RealmDID, PublicKey, PrivateKey, ValidityDays)

Generate a self-signed realm certificate with custom validity

generate_serial()

Generate a random certificate serial number

is_expired(Cert)

Check if a certificate is expired

is_valid_now(Cert)

Check if a certificate is currently valid (within validity period)

sign_cert_request(Request, RealmCert, RealmPrivKey)

Sign a certificate request Used when processing CSRs from remote instances.

to_map(Cert)

Convert certificate record to map

verify_cert(InstanceCert, IssuerCert)

Verify an instance certificate against its issuer (realm) certificate

verify_self_signed(Cert)

Verify a self-signed (realm) certificate

# Types

# macula_cert/0

    -type macula_cert() ::
              #macula_cert{subject_did :: binary(),
                           subject_cn :: binary(),
                           issuer_did :: binary(),
                           issuer_cn :: binary(),
                           not_before :: non_neg_integer(),
                           not_after :: non_neg_integer(),
                           public_key :: binary(),
                           signature :: binary(),
                           serial :: binary(),
                           version :: pos_integer(),
                           extensions :: map()}.

# macula_cert_request/0

    -type macula_cert_request() ::
              #macula_cert_request{subject_did :: binary(),
                                   subject_cn :: binary(),
                                   public_key :: binary(),
                                   validity_days :: pos_integer()}.

# Functions

# canonical_form(Cert)

    -spec canonical_form(Cert :: macula_cert()) -> binary().

Generate canonical form for signing/verification The canonical form excludes the signature field and is deterministic.

# cn_to_did(CN)

    -spec cn_to_did(CN :: binary()) -> binary().

Convert common name to DID format Example: "app.io.example" becomes "did:macula:io.example.app"

# decode(Binary)

    -spec decode(Binary :: binary()) -> {ok, macula_cert()} | {error, term()}.

Decode certificate from binary format

# did_to_cn(DID)

    -spec did_to_cn(DID :: binary()) -> binary().

Convert DID to common name format Example: "did:macula:io.example.app" becomes "app.io.example"

# encode(Cert)

    -spec encode(Cert :: macula_cert()) -> binary().

Encode certificate to binary format Uses term_to_binary for now; can switch to CBOR/JSON for interop.

# extract_realm_did(InstanceDID)

    -spec extract_realm_did(InstanceDID :: binary()) -> binary().

Extract realm DID from an instance DID Example: "did:macula:io.example.app.node01" becomes "did:macula:io.example"

# from_map(Map)

    -spec from_map(Map :: map()) -> {ok, macula_cert()} | {error, term()}.

Convert map to certificate record

# generate_instance_cert(InstanceDID, InstancePubKey, RealmCert, RealmPrivKey)

    -spec generate_instance_cert(InstanceDID :: binary(),
                                 InstancePubKey :: binary(),
                                 RealmCert :: macula_cert(),
                                 RealmPrivKey :: binary()) ->
                                    {ok, macula_cert()} | {error, term()}.

Generate an instance certificate signed by a realm certificate The instance DID must be under the realm's namespace.

# generate_instance_cert(InstanceDID, InstancePubKey, RealmCert, RealmPrivKey, ValidityDays)

    -spec generate_instance_cert(InstanceDID :: binary(),
                                 InstancePubKey :: binary(),
                                 RealmCert :: macula_cert(),
                                 RealmPrivKey :: binary(),
                                 ValidityDays :: pos_integer()) ->
                                    {ok, macula_cert()} | {error, term()}.

Generate an instance certificate with custom validity

# generate_keypair()

    -spec generate_keypair() -> {PublicKey :: binary(), PrivateKey :: binary()}.

Generate a new Ed25519 keypair Returns {PublicKey, PrivateKey} as raw binaries.

# generate_realm_cert(RealmDID, PublicKey, PrivateKey)

    -spec generate_realm_cert(RealmDID :: binary(), PublicKey :: binary(), PrivateKey :: binary()) ->
                                 {ok, macula_cert()} | {error, term()}.

Generate a self-signed realm certificate Realm certificates are the root of trust for a namespace.

# generate_realm_cert(RealmDID, PublicKey, PrivateKey, ValidityDays)

    -spec generate_realm_cert(RealmDID :: binary(),
                              PublicKey :: binary(),
                              PrivateKey :: binary(),
                              ValidityDays :: pos_integer()) ->
                                 {ok, macula_cert()} | {error, term()}.

Generate a self-signed realm certificate with custom validity

# generate_serial()

    -spec generate_serial() -> binary().

Generate a random certificate serial number

# is_expired(Cert)

    -spec is_expired(Cert :: macula_cert()) -> boolean().

Check if a certificate is expired

# is_valid_now(Cert)

    -spec is_valid_now(Cert :: macula_cert()) -> boolean().

Check if a certificate is currently valid (within validity period)

# sign_cert_request(Request, RealmCert, RealmPrivKey)

    -spec sign_cert_request(Request :: macula_cert_request(),
                            RealmCert :: macula_cert(),
                            RealmPrivKey :: binary()) ->
                               {ok, macula_cert()} | {error, term()}.

Sign a certificate request Used when processing CSRs from remote instances.

# to_map(Cert)

    -spec to_map(Cert :: macula_cert()) -> map().

Convert certificate record to map

# verify_cert(InstanceCert, IssuerCert)

    -spec verify_cert(InstanceCert :: macula_cert(), IssuerCert :: macula_cert()) -> ok | {error, term()}.

Verify an instance certificate against its issuer (realm) certificate

# verify_self_signed(Cert)

    -spec verify_self_signed(Cert :: macula_cert()) -> ok | {error, term()}.

Verify a self-signed (realm) certificate