x509

package
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 22, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

README ΒΆ

pkg/attest/x509

Local Certificate Authority for ephemeral X.509 certificates.

Status: πŸ§ͺ Experimental

Generates short-lived certificates for Git signing and authentication.

What It Does

Creates self-signed X.509 certificates with 5-minute lifetimes:

flowchart TD
    subgraph "Certificate Generation"
        Master[Master Key] --> CA[Local CA]
        CA --> Ephemeral[Generate Ephemeral Key]
        Ephemeral --> Cert[Create X.509 Certificate]

        Cert --> Fields[Certificate Fields:<br/>βœ“ 5-minute validity<br/>βœ“ Code signing extensions<br/>βœ“ Subject: did:key:signet<br/>βœ“ SKID/AKID]

        Fields --> Output[Ephemeral Cert + Key]
    end

    style Master fill:#ff9999
    style Output fill:#99ff99

Files

  • localca.go - Certificate generation logic

Certificate Structure

// What gets created:
Certificate {
    Version:      3 (X.509 v3)
    SerialNumber: Random 128-bit
    Subject:      CN=did:key:signet, O=Signet
    Issuer:       CN=did:key:signet, O=Signet  // Self-signed
    NotBefore:    Now
    NotAfter:     Now + 5 minutes
    KeyUsage:     DigitalSignature
    ExtKeyUsage:  CodeSigning

    // Key identifiers for chain validation
    SubjectKeyId:   SHA-1(ephemeralPublicKey)
    AuthorityKeyId: SHA-1(masterPublicKey)
}

Usage Example

ca := NewLocalCA(masterPrivateKey)
cert, ephemeralKey, err := ca.CreateEphemeralCertificate(purpose)

// Use the cert for signing
signature := sign(ephemeralKey, data)

// Zero the ephemeral key after use
zeroKey(ephemeralKey)

Security Notes

⚠️ Not for Production PKI:

  • Self-signed certificates only
  • No certificate revocation support
  • No OCSP or CRL
  • Suitable for development and Git signing

Why 5 Minutes?

  • Long enough for a Git commit operation
  • Short enough to limit exposure if compromised
  • No need for revocation infrastructure
  • Forces regular key rotation

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

View Source
var OIDSignetCapabilities = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 99999, 1, 3}

OIDSignetCapabilities is the OID for the signet capability attestation extension. Arc: 1.3.6.1.4.1.99999.1.3 (next after .1=subject, .2=issuance time).

Functions ΒΆ

func EncodeDIDAsSubject ΒΆ

func EncodeDIDAsSubject(did string) pkix.Name

EncodeDIDAsSubject encodes a DID as an X.509 subject

func GenerateSerialNumber ΒΆ

func GenerateSerialNumber() (*big.Int, error)

GenerateSerialNumber generates a random serial number for a certificate

func MarshalCapabilities ΒΆ

func MarshalCapabilities(capabilities []string) ([]byte, error)

MarshalCapabilities encodes capability URIs as ASN.1 SEQUENCE OF UTF8String.

Interop contract (must match TypeScript @peculiar/x509 implementation):

DER encoding: SEQUENCE { UTF8String, UTF8String, ... }
ASN.1 tags:   SEQUENCE = 0x30, UTF8String = 0x0C
Empty list:   SEQUENCE {} = 0x30 0x00

Example: ["urn:signet:cap:sign:artifact"] encodes as:

30 1E 0C 1C 75 72 6E 3A 73 69 67 6E 65 74 3A 63
61 70 3A 73 69 67 6E 3A 61 72 74 69 66 61 63 74

TypeScript equivalent (asn1js):

new asn1js.Sequence({
  value: caps.map(c => new asn1js.Utf8String({ value: c }))
}).toBER(false)

func ParseCapabilities ΒΆ

func ParseCapabilities(cert *x509.Certificate) ([]string, error)

ParseCapabilities extracts capability URIs from a certificate's signet capability extension. Returns nil, nil if the extension is not present.

func UnmarshalCapabilities ΒΆ

func UnmarshalCapabilities(data []byte) ([]string, error)

UnmarshalCapabilities decodes ASN.1 SEQUENCE OF UTF8String back to strings. This is the inverse of MarshalCapabilities and validates the interop contract.

Types ΒΆ

type LocalCA ΒΆ

type LocalCA struct {
	// contains filtered or unexported fields
}

LocalCA provides the logic to issue self-signed, short-lived X.509 certificates from a master key for the MVP. The certificate's subject will be the issuer's DID.

func NewLocalCA ΒΆ

func NewLocalCA(masterKey crypto.Signer, issuerDID string) *LocalCA

NewLocalCA creates a new Local CA with the given master key and DID

func (*LocalCA) CreateCACertificateTemplate ΒΆ

func (ca *LocalCA) CreateCACertificateTemplate() *x509.Certificate

CreateCACertificateTemplate creates a template for the CA (master key) certificate

func (*LocalCA) CreateCertificateTemplate ΒΆ

func (ca *LocalCA) CreateCertificateTemplate(validityDuration time.Duration) *x509.Certificate

CreateCertificateTemplate creates a basic X.509 certificate template for an ephemeral certificate

func (*LocalCA) IssueBridgeCertificate ΒΆ

func (ca *LocalCA) IssueBridgeCertificate(
	ephemeralPubKey crypto.PublicKey,
	capabilities []string,
	validity time.Duration,
) (*x509.Certificate, []byte, error)

IssueBridgeCertificate creates an intermediate CA certificate that embeds capability URIs as an X.509 extension. The bridge cert is IsCA:true with MaxPathLen:0, allowing it to issue ephemeral end-entity certs but not further intermediates.

The capabilities are encoded as ASN.1 SEQUENCE OF UTF8String under OID 1.3.6.1.4.1.99999.1.3.

func (*LocalCA) IssueCertificateForSigner ΒΆ

func (ca *LocalCA) IssueCertificateForSigner(signer crypto.Signer, validityDuration time.Duration) (*x509.Certificate, []byte, error)

IssueCertificateForSigner creates an X.509 certificate for code signing for a provided crypto.Signer with the specified validity duration. The certificate is issued by the master key (CA) for the signer's public key.

This method is designed to work with any crypto.Signer implementation, including hardware-backed signers (PKCS#11, HSM) where the private key never leaves the secure hardware.

Returns the certificate and DER bytes. The caller is responsible for managing the lifecycle of the provided signer.

func (*LocalCA) IssueClientCertificate ΒΆ

func (ca *LocalCA) IssueClientCertificate(template *x509.Certificate, devicePublicKey ed25519.PublicKey) (*x509.Certificate, error)

IssueClientCertificate creates a client identity certificate signed by the master key for the provided device public key

func (*LocalCA) IssueCodeSigningCertWithParent ΒΆ

func (ca *LocalCA) IssueCodeSigningCertWithParent(parentCert *x509.Certificate, validityDuration time.Duration) (*x509.Certificate, []byte, *keys.SecurePrivateKey, error)

IssueCodeSigningCertWithParent creates an ephemeral code-signing certificate signed by ca.masterKey, using parentCert as the issuer template. This enables cert chains like: root CA β†’ bridge cert β†’ ephemeral cert. The parentCert's Subject becomes the ephemeral cert's Issuer, ensuring correct X.509 chain validation.

func (*LocalCA) IssueCodeSigningCertificateSecure ΒΆ

func (ca *LocalCA) IssueCodeSigningCertificateSecure(validityDuration time.Duration) (*x509.Certificate, []byte, *keys.SecurePrivateKey, error)

IssueCodeSigningCertificateSecure creates an X.509 certificate for code signing with the specified validity duration. The certificate is issued by the master key (CA) for an ephemeral key. Returns the certificate, DER bytes, and a secure wrapper for the ephemeral private key.

The returned SecurePrivateKey automatically manages memory cleanup. Callers MUST call Destroy() when done, typically with defer:

cert, der, secKey, err := ca.IssueCodeSigningCertificateSecure(duration)
if err != nil { return err }
defer secKey.Destroy()

func (*LocalCA) IssueEphemeralCertificate ΒΆ

func (ca *LocalCA) IssueEphemeralCertificate(publicKey crypto.PublicKey, validityDuration time.Duration) (*x509.Certificate, []byte, error)

IssueEphemeralCertificate creates a self-signed ephemeral certificate with the given public key and validity duration

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL