Skip to content

yiyuanzhong/scep

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SCEP

Inspired by micromdm/scep, I want a simple SCEP service lightweight enough for embedded environment to issue and renew certificates for my in-house devices. While the issuance process must still be done in a trusted environment (physically present and connected to a specific network), the renewal shall be automatic and remote.

Background

While it does have a lot of use cases in enterprise environments, it's not strictly necessary for home users to deal with certificates unless you're a paranoid to deploy certificate based authentication / authorization (like EAP-TLS secured home Wi-Fi or VPN for Starbucks). You can issue the certificate for the first time with a super long key length with insane validity then forget about it, knowing that doing so is still much more secure than passwords (yes I did that), but with automatic enrollment a more reasonable key length can be used to accelerate the computation since short validity can be used, and you don't have to remember which one expires when.

But

Simple Certificate Enrollment Protocol (SCEP) is a widely adopted PKI component that allows (semi-)automatic certificate enrollments. There're modern alternatives like Certificate Enrollment Protocol (CEP) but SCEP is still the most supported solution. However it's not comprehensive in many ways. SCEP is built on top of well defined industry standard (CMS/PKCS7) adding some loose workflows and minor requirements, but never narrows down the flexibilities in CMS/PKCS7 enough which has caused major interoperative issues. Meanwhile for home users, at least me, it's impossible to always track the devices and secure the enrollment process so the renewal has to go through Internet which is a uncontrolled environment.

The design

  • A service with minimal dependencies so I can run it in an embedded container.
  • Certain degree of configurability to interoperate with multiple clients.
  • A dynamic challenge password is intruduced to automate the initial issuance.
  • (TODO) A valid certificate is required to renew the certificates so it's secure over Internet.
    • I somehow lost some of my last development which supports renewals, I have no choice but to write down what I have in this version. *

Quick start

You start by getting the signing CA certificate and key, this can be a self-signed root CA or an intermediate CA (which you should have the full chain ready). Only one signing CA is supported, you can however launch multiple instances since it's quite lightweighted.

Other than specifying validity on the command line, issued certificates can have customized extensions by supplying a configure file containing key=value pairs similar to OpenSSL configure syntax.

An automated authorization can be configured so that the SCEP client must present a challenge password, which is generated based on a secret passphrase and the subject as a pre-authorization. This challenge password is expired 7 days after generation.

To start with you can just invoke the server by: ./scep -p 8080 -c signing.pem -k signing.key

It will start a http server listening on port 8080, URL is ignored so any request like http://<your IP>:8080/ or http://<your IP>:8080/abc/def/123 will invoke the service. Since no password is configured the server will sign any SCEP requests, good for testing.

To automatically authorize a certificate, you configure the password by -C ./scep -p 8080 -c signing.pem -k signing.key -C very-strong-password

With a password set, the client must present a challenge string generated by -S ./scep -C the-same-very-strong-password -S the-subject

The subject is encoded in slash delimited key value pairs, for example ./scep -C 8rROG5qV -S /C=US/O=github/CN=client28369

A 80 bytes challenge string is generated and is valid for 7 days.

In a real world scenario you will want to protect the server by running it behind a TLS reverse proxy, since SCEP doesn't specify where the challenge password should be present, inside the protected payload and/or the plaintext encapsule. In real world macOS will expose the challenge password in plaintext thus any MITM can impersonate the user, and the reason is probably that Apple products do not validate CA certificate at all, thus MITM is always possible with or without a challenge. By default the server will reject the request if it sees challenge password exposed in plaintext, you can allow such requests by passing -E.

The extensions are to be defined in a plaintext file, which you should start with the absolute minimum

basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature
extendedKeyUsage=clientAuth

Then specify the file by -e ./scep -p 8080 -c signing.pem -k signing.key -e extensions.cnf

Releases

No releases published

Packages

No packages published