Skip to content

iOS SCEP enrollment fails: “Couldn’t create certificate signing request” (smallstep CA + NGINX) #2399

@ismailunsall

Description

@ismailunsall

SCEP Enrollment Setup & Issue Summary (DevOps Write‑Up)

Network / Context

  • The local smallstep CA and the iOS device under test are on the same network.
  • Hostname resolution is configured via /etc/hosts and dnsmasq. The iOS device resolves the domain to the local IP (same subnet).
  • I can download the CA and SCEP configuration profiles over HTTPS (even when TLS verification is not enforced).

Docker Compose Environment

services:
step-ca:
image: smallstep/step-ca:0.28.4
container_name: step-ca
restart: unless-stopped
environment:
DOCKER_STEPCA_INIT_NAME: "Lab Root CA"
DOCKER_STEPCA_INIT_DNS_NAMES: "step-ca,localhost"
DOCKER_STEPCA_INIT_SSH: "false"
DOCKER_STEPCA_INIT_ACME: "false"
DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT: "false"
volumes:
- ./step:/home/step
ports:
- "8080:8080"
healthcheck:
test: ["CMD-SHELL", "wget -qO- --no-check-certificate https://localhost:8080/health || exit 1"]
interval: 10s
timeout: 5s
retries: 6
start_period: 15s

nginx:
image: nginx:1.27-alpine
container_name: step-edge
depends_on:
- step-ca
restart: unless-stopped
ports:
- "9001:9001" # HTTPS for iOS
- "9000:9000" # optional HTTP for local testing
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./edge:/etc/nginx/ssl:ro
- ./out:/usr/share/nginx/html/profiles:ro

What the System Does

  • Runs step-ca in Docker and copies the Root/Intermediate certificates from the container into the out/ directory.
  • Edge TLS: generates edge/tls.key (RSA‑2048) + a CSR; signs it with step-ca (admin) → produces edge/tls.crt and edge/tls.fullchain.crt.
  • Creates/updates a SCEP provisioner with:
    • challenge (hex)
    • caps: SCEPStandard, POSTPKIOperation, SHA‑256, Renewal
    • minimum RSA key size 2048
    • encryption‑algorithm‑identifier = 2
    • X.509 template: clientAuth, KeyUsage: sign+enc
      → restarts step-ca and verifies health
  • Generates profiles:
    • ca.mobileconfig (Root + Intermediate, base64‑embedded)
    • scep.mobileconfig (URL: https://<EDGE_HOST>:/scep/<SCEP_NAME>, RSA‑2048, Usage=5, Challenge)
    • combined profile (CA + SCEP) anchoring via PayloadCertificateAnchorUUID to the Root/Intermediate
  • Profile signing: if needed, issues a short‑lived “Profile Signer” leaf (24h) with step ca certificate; signs all .mobileconfig files via OpenSSL SMIME/DER (nodetach) using signer.crt/key/chain.
  • Starts nginx: serves signed profiles from /profiles/; proxies /scep/ requests to step-ca:8080.
  • Verifies the TLS chain and prints ready URLs.
  • Versions (from compose): step-ca 0.28.4, nginx 1.27‑alpine (CLI logs note 0.28.7).

iOS Installation Order

  1. Install the CA‑only profile first.
    • The CA profile downloads; even if iOS shows “Not Verified,” proceed.
    • Then enable trust: Settings → General → About → Certificate Trust Settings → enable Full Trust for “Lab Root CA”.
  2. Download and install the SCEP configuration profile afterwards.

Observed Error

  • When installing the SCEP enrollment profile (enroll-profile.signed.mobileconfig) or the all‑in‑one profile, iOS shows:
    “Couldn’t create certificate signing request”
  • The SCEP profile does not install on the iOS device.

Question

Given this local smallstep CA setup (same network, host resolved via /etc/hosts and dnsmasq, CA/SCEP configs retrievable over HTTPS), how can I successfully install the SCEP profile on the iOS mobile device? What am I missing or doing incorrectly that causes the “Couldn’t create certificate signing request” error?

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions