Certificate Manager Guide

Configure TLS/SSL certificates for secure BMC communication.

Table of Contents

  1. Overview
  2. Setup & Configuration
    1. Build-Time Configuration
    2. Certificate Locations
  3. Managing Certificates
    1. View Current Certificate
    2. Generate Self-Signed Certificate
    3. Replace Certificate via Redfish
    4. Add CA Certificate
  4. Deep Dive
    1. X.509 Certificate Chain Validation
    2. Certificate Storage and File Format
    3. CSR Generation Process
    4. Service Restart Integration
    5. Source Code Reference
  5. References

Overview

phosphor-certificate-manager manages X.509 certificates for HTTPS, LDAP, and other secure services on OpenBMC.

---
title: Certificate Manager Architecture
---
flowchart TB
    subgraph certmgr["phosphor-certificate-manager"]
        direction LR
        https["HTTPS Certs<br/>(/etc/ssl/certs/https/)"]
        ldapcert["LDAP Certs<br/>(/etc/ssl/certs/ldap/)"]
        authority["Authority Certs<br/>(Trusted CAs)"]
        csr["CSR Generation<br/>(Signing Req)"]
    end

    subgraph consumers["Certificate Consumers"]
        direction LR
        bmcweb["bmcweb<br/>(HTTPS server)"]
        ldapclient["LDAP Client<br/>(secure auth)"]
    end

    certmgr --> consumers
ASCII-art version (for comparison)
+-------------------------------------------------------------------+
|                Certificate Manager Architecture                   |
+-------------------------------------------------------------------+
|                                                                   |
|  +------------------------------------------------------------+   |
|  |             phosphor-certificate-manager                   |   |
|  |                                                            |   |
|  |   +------------------+  +------------------+               |   |
|  |   | HTTPS Certs      |  | LDAP Certs       |               |   |
|  |   | (/etc/ssl/certs/ |  | (/etc/ssl/certs/ |               |   |
|  |   |  https/)         |  |  ldap/)          |               |   |
|  |   +------------------+  +------------------+               |   |
|  |                                                            |   |
|  |   +------------------+  +------------------+               |   |
|  |   | Authority Certs  |  | CSR Generation   |               |   |
|  |   | (Trusted CAs)    |  | (Signing Req)    |               |   |
|  |   +------------------+  +------------------+               |   |
|  |                                                            |   |
|  +----------------------------+-------------------------------+   |
|                               |                                   |
|           +-------------------+-------------------+               |
|           |                                       |               |
|           v                                       v               |
|  +------------------+                   +------------------+      |
|  |     bmcweb       |                   |   LDAP Client    |      |
|  |  (HTTPS server)  |                   |  (secure auth)   |      |
|  +------------------+                   +------------------+      |
|                                                                   |
+-------------------------------------------------------------------+

Setup & Configuration

Build-Time Configuration

# Include certificate manager
IMAGE_INSTALL:append = " phosphor-certificate-manager"

Certificate Locations

Type Path Description
HTTPS Server /etc/ssl/certs/https/server.pem Web server certificate
HTTPS CA /etc/ssl/certs/https/authority/ Trusted CA certificates
LDAP Client /etc/ssl/certs/ldap/ LDAP client certificates

Managing Certificates

View Current Certificate

# Via Redfish
curl -k -u root:0penBmc \
    https://localhost/redfish/v1/CertificateService/CertificateLocations

# View certificate details
openssl x509 -in /etc/ssl/certs/https/server.pem -text -noout

Generate Self-Signed Certificate

# Generate on BMC
openssl req -x509 -newkey rsa:2048 \
    -keyout /etc/ssl/private/server.pem \
    -out /etc/ssl/certs/https/server.pem \
    -days 365 -nodes \
    -subj "/CN=openbmc/O=MyOrg"

# Restart bmcweb
systemctl restart bmcweb

Replace Certificate via Redfish

# Replace HTTPS certificate
curl -k -u root:0penBmc -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "CertificateType": "PEM",
        "CertificateString": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
    }' \
    https://localhost/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates

# Generate CSR
curl -k -u root:0penBmc -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "CommonName": "bmc.example.com",
        "Organization": "MyOrg",
        "Country": "US"
    }' \
    https://localhost/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR

Add CA Certificate

# Add trusted CA
curl -k -u root:0penBmc -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "CertificateType": "PEM",
        "CertificateString": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
    }' \
    https://localhost/redfish/v1/Managers/bmc/Truststore/Certificates

Deep Dive

Advanced implementation details for certificate management developers.

X.509 Certificate Chain Validation

┌────────────────────────────────────────────────────────────────────────────┐
│                    Certificate Chain Validation Flow                       │
├────────────────────────────────────────────────────────────────────────────┤
│                                                                            │
│  INCOMING CERTIFICATE CHAIN                                                │
│  ──────────────────────────                                                │
│                                                                            │
│  ┌─────────────────────┐                                                   │
│  │   Leaf Certificate  │  Subject: CN=bmc.example.com                      │
│  │   (Server Cert)     │  Issuer: CN=Intermediate CA                       │
│  │                     │  Key Usage: Digital Signature, Key Encipherment   │
│  │                     │  Ext Key Usage: TLS Web Server Authentication     │
│  └──────────┬──────────┘                                                   │
│             │ Signed by                                                    │
│             v                                                              │
│  ┌─────────────────────┐                                                   │
│  │ Intermediate CA     │  Subject: CN=Intermediate CA                      │
│  │ Certificate         │  Issuer: CN=Root CA                               │
│  │                     │  Basic Constraints: CA:TRUE, pathLen:0            │
│  │                     │  Key Usage: Certificate Sign, CRL Sign            │
│  └──────────┬──────────┘                                                   │
│             │ Signed by                                                    │
│             v                                                              │
│  ┌─────────────────────┐                                                   │
│  │   Root CA           │  Subject: CN=Root CA (self-signed)                │
│  │   Certificate       │  Issuer: CN=Root CA                               │
│  │   (Trust Anchor)    │  Basic Constraints: CA:TRUE                       │
│  └─────────────────────┘                                                   │
│                                                                            │
│  VALIDATION STEPS (OpenSSL in phosphor-certificate-manager):               │
│  ──────────────────────────────────────────────────────────                │
│                                                                            │
│  1. PARSE CERTIFICATE CHAIN                                                │
│     ┌─────────────────────────────────────────────────────────────────┐    │
│     │ PEM_read_bio_X509() for each certificate in chain               │    │
│     │ Build X509_STORE with trusted root CAs from /etc/ssl/certs/     │    │
│     └─────────────────────────────────────────────────────────────────┘    │
│                                                                            │
│  2. VERIFY CERTIFICATE SIGNATURES                                          │
│     ┌─────────────────────────────────────────────────────────────────┐    │
│     │ X509_verify(leaf_cert, intermediate_pubkey) == 1                │    │
│     │ X509_verify(intermediate_cert, root_pubkey) == 1                │    │
│     │ X509_verify(root_cert, root_pubkey) == 1 (self-signed)          │    │
│     └─────────────────────────────────────────────────────────────────┘    │
│                                                                            │
│  3. CHECK VALIDITY PERIOD                                                  │
│     ┌─────────────────────────────────────────────────────────────────┐    │
│     │ X509_cmp_current_time(X509_get_notBefore(cert)) <= 0            │    │
│     │ X509_cmp_current_time(X509_get_notAfter(cert)) >= 0             │    │
│     │                                                                 │    │
│     │ notBefore ──────────── NOW ──────────── notAfter                │    │
│     │     ✓                   │                   ✓                   │    │
│     └─────────────────────────────────────────────────────────────────┘    │
│                                                                            │
│  4. VERIFY KEY USAGE & EXTENDED KEY USAGE                                  │
│     ┌─────────────────────────────────────────────────────────────────┐    │
│     │ For HTTPS server certificate:                                   │    │
│     │   - digitalSignature bit must be set                            │    │
│     │   - keyEncipherment bit must be set (RSA) OR                    │    │
│     │   - keyAgreement bit must be set (ECDH)                         │    │
│     │   - extKeyUsage: id-kp-serverAuth (1.3.6.1.5.5.7.3.1)           │    │
│     │                                                                 │    │
│     │ For LDAP client certificate:                                    │    │
│     │   - extKeyUsage: id-kp-clientAuth (1.3.6.1.5.5.7.3.2)           │    │
│     └─────────────────────────────────────────────────────────────────┘    │
│                                                                            │
│  5. BUILD TRUST CHAIN TO ROOT                                              │
│     ┌─────────────────────────────────────────────────────────────────┐    │
│     │ X509_STORE_CTX_init(ctx, store, leaf_cert, intermediates)       │    │
│     │ X509_verify_cert(ctx)                                           │    │
│     │                                                                 │    │
│     │ Result: X509_V_OK (0) or error code                             │    │
│     └─────────────────────────────────────────────────────────────────┘    │
│                                                                            │
└────────────────────────────────────────────────────────────────────────────┘

Certificate Storage and File Format

┌────────────────────────────────────────────────────────────────────────────┐
│                    Certificate Storage Architecture                        │
├────────────────────────────────────────────────────────────────────────────┤
│                                                                            │
│  /etc/ssl/                                                                 │
│  ├── certs/                                                                │
│  │   ├── https/                                                            │
│  │   │   ├── server.pem          ← HTTPS server cert + private key         │
│  │   │   └── authority/          ← Trusted CA certs for client auth        │
│  │   │       ├── ca1.pem                                                   │
│  │   │       └── ca2.pem                                                   │
│  │   └── ldap/                                                             │
│  │       └── client.pem          ← LDAP client certificate                 │
│  └── private/                                                              │
│      └── server.pem              ← Private key (mode 0600)                 │
│                                                                            │
│  COMBINED PEM FILE FORMAT (server.pem):                                    │
│  ─────────────────────────────────────                                     │
│                                                                            │
│  -----BEGIN PRIVATE KEY-----                                               │
│  MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC...                    │
│  ... (Base64 encoded private key) ...                                      │
│  -----END PRIVATE KEY-----                                                 │
│  -----BEGIN CERTIFICATE-----                                               │
│  MIIDXTCCAkWgAwIBAgIJAJC1HiIAZAiUMA0GCSqGSIb3Qq...                         │
│  ... (Base64 encoded server certificate) ...                               │
│  -----END CERTIFICATE-----                                                 │
│  -----BEGIN CERTIFICATE-----                                               │
│  MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSj...                             │
│  ... (Base64 encoded intermediate CA - optional) ...                       │
│  -----END CERTIFICATE-----                                                 │
│                                                                            │
│  D-BUS OBJECT STRUCTURE:                                                   │
│  ─────────────────────                                                     │
│                                                                            │
│  /xyz/openbmc_project/certs                                                │
│  ├── server                                                                │
│  │   └── https                                                             │
│  │       └── 1                   ← Certificate object                      │
│  │           ├── xyz.openbmc_project.Certs.Certificate                     │
│  │           │   ├── CertificateString (PEM)                               │
│  │           │   ├── Subject                                               │
│  │           │   ├── Issuer                                                │
│  │           │   ├── ValidNotBefore                                        │
│  │           │   └── ValidNotAfter                                         │
│  │           └── xyz.openbmc_project.Object.Delete                         │
│  └── authority                                                             │
│      └── truststore                                                        │
│          ├── 1                   ← CA certificate 1                        │
│          └── 2                   ← CA certificate 2                        │
│                                                                            │
└────────────────────────────────────────────────────────────────────────────┘

CSR Generation Process

┌────────────────────────────────────────────────────────────────────────────┐
│                   Certificate Signing Request (CSR) Flow                   │
├────────────────────────────────────────────────────────────────────────────┤
│                                                                            │
│  REDFISH CSR REQUEST                                                       │
│  ───────────────────                                                       │
│  POST /redfish/v1/CertificateService/Actions/                              │
│       CertificateService.GenerateCSR                                       │
│  {                                                                         │
│      "CommonName": "bmc.example.com",                                      │
│      "Organization": "ACME Corp",                                          │
│      "OrganizationalUnit": "IT",                                           │
│      "City": "San Francisco",                                              │
│      "State": "CA",                                                        │
│      "Country": "US",                                                      │
│      "AlternativeNames": ["bmc", "192.168.1.100"],                         │
│      "KeyPairAlgorithm": "EC",                                             │
│      "KeyCurveId": "secp384r1"                                             │
│  }                                                                         │
│                                                                            │
│  CSR GENERATION STEPS:                                                     │
│  ────────────────────                                                      │
│                                                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  1. Generate Key Pair                                               │   │
│  │     ────────────────────                                            │   │
│  │     // For EC key (recommended)                                     │   │
│  │     EVP_PKEY* pkey = EVP_EC_gen("secp384r1");                       │   │
│  │                                                                     │   │
│  │     // For RSA key                                                  │   │
│  │     EVP_PKEY* pkey = EVP_RSA_gen(2048);                             │   │
│  └────────────────────────────────────────────────────────────────────-┘   │
│                                                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  2. Create CSR Structure                                            │   │
│  │     ─────────────────────                                           │   │
│  │     X509_REQ* req = X509_REQ_new();                                 │   │
│  │     X509_REQ_set_pubkey(req, pkey);                                 │   │
│  │     X509_REQ_set_version(req, 0);  // Version 1                     │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  3. Set Subject Distinguished Name                                  │   │
│  │     ────────────────────────────                                    │   │
│  │     X509_NAME* name = X509_REQ_get_subject_name(req);               │   │
│  │     X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,            │   │
│  │                                "bmc.example.com", -1, -1, 0);       │   │
│  │     X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,             │   │
│  │                                "ACME Corp", -1, -1, 0);             │   │
│  │     // ... additional fields                                        │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  4. Add Subject Alternative Names (SAN) Extension                   │   │
│  │     ──────────────────────────────────────────                      │   │
│  │     STACK_OF(X509_EXTENSION)* exts = sk_X509_EXTENSION_new_null();  │   │
│  │     X509_EXTENSION* san_ext = X509V3_EXT_conf_nid(                  │   │
│  │         NULL, NULL, NID_subject_alt_name,                           │   │
│  │         "DNS:bmc,DNS:bmc.example.com,IP:192.168.1.100");            │   │
│  │     sk_X509_EXTENSION_push(exts, san_ext);                          │   │
│  │     X509_REQ_add_extensions(req, exts);                             │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  5. Sign CSR with Private Key                                       │   │
│  │     ──────────────────────────                                      │   │
│  │     X509_REQ_sign(req, pkey, EVP_sha384());                         │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  6. Output PEM-encoded CSR                                          │   │
│  │     ─────────────────────                                           │   │
│  │     -----BEGIN CERTIFICATE REQUEST-----                             │   │
│  │     MIICpDCCAYwCAQAwXzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNB...         │   │
│  │     ... (Base64 encoded CSR) ...                                    │   │
│  │     -----END CERTIFICATE REQUEST-----                               │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                            │
│  7. Store private key in /etc/ssl/private/ (mode 0600)                     │
│  8. Return CSR to administrator for CA signing                             │
│  9. After signing, install certificate via Replace action                  │
│                                                                            │
└────────────────────────────────────────────────────────────────────────────┘

Service Restart Integration

┌────────────────────────────────────────────────────────────────────────────┐
│              Certificate Installation Service Integration                  │
├────────────────────────────────────────────────────────────────────────────┤
│                                                                            │
│  Certificate Installed                                                     │
│         │                                                                  │
│         v                                                                  │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  phosphor-certificate-manager                                       │   │
│  │                                                                     │   │
│  │  1. Write certificate to filesystem                                 │   │
│  │     install(cert_pem, "/etc/ssl/certs/https/server.pem")            │   │
│  │                                                                     │   │
│  │  2. Set proper permissions                                          │   │
│  │     chmod 0644 server.pem (cert)                                    │   │
│  │     chmod 0600 private key                                          │   │
│  │                                                                     │   │
│  │  3. Notify dependent services via D-Bus                             │   │
│  │     Certificate.Install signal                                      │   │
│  └────────────────────────────────────────────────────────────────────-┘   │
│         │                                                                  │
│         v                                                                  │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  Service Restart Mechanism                                          │   │
│  │                                                                     │   │
│  │  Option 1: systemd unit dependency (phosphor-certificate-manager)   │   │
│  │    [Unit]                                                           │   │
│  │    PropagatesReloadTo=bmcweb.service                                │   │
│  │                                                                     │   │
│  │  Option 2: Direct service restart                                   │   │
│  │    sd_bus_call_method(                                              │   │
│  │        bus, "org.freedesktop.systemd1",                             │   │
│  │        "/org/freedesktop/systemd1",                                 │   │
│  │        "org.freedesktop.systemd1.Manager",                          │   │
│  │        "RestartUnit", "bmcweb.service", "replace"                   │   │
│  │    );                                                               │   │
│  │                                                                     │   │
│  │  Option 3: Service watches certificate file                         │   │
│  │    inotify_add_watch(fd, "/etc/ssl/certs/https/", IN_MODIFY)        │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│         │                                                                  │
│         v                                                                  │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  bmcweb SSL Context Reload                                          │   │
│  │                                                                     │   │
│  │  SSL_CTX_use_certificate_chain_file(ctx, "/etc/ssl/.../server.pem") │   │
│  │  SSL_CTX_use_PrivateKey_file(ctx, "/etc/ssl/.../server.pem")        │   │
│  │                                                                     │   │
│  │  New connections use new certificate                                │   │
│  │  Existing connections continue with old cert until closed           │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                            │
└────────────────────────────────────────────────────────────────────────────┘

Source Code Reference

Key implementation files in phosphor-certificate-manager:

File Description
certificate.cpp Certificate class with X.509 parsing and validation
certs_manager.cpp Main certificate manager handling install/replace/delete
csr.cpp CSR generation using OpenSSL
argument.cpp CLI argument parsing for certificate types
watch.cpp Filesystem watcher for certificate changes

References


Tested on: OpenBMC master, QEMU romulus


Back to top

OpenBMC Guide Tutorial is not affiliated with the OpenBMC project. Content is provided for educational purposes.

This site uses Just the Docs, a documentation theme for Jekyll.