Caramel is a CA Registry Manager
Clone or download
teyrow Merge pull request #48 from ModioAB/fix-backdated-timestamp
Adjust "not before" rather than setting it
Latest commit 7cd87d9 Dec 13, 2018
Type Name Latest commit message Commit time
Failed to load latest commit information.
caramel Adjust "not before" rather than setting it Dec 11, 2018
doc Add Affero GPLv3 License & Cleanout before release Jan 8, 2015
fcgi-utils WSGI example script for deployment in fcgi-utils May 8, 2016
request-certificate request-cert: Work around systems that _forbid_ utf8 requests Oct 9, 2015
tests Bundle signing key + cert into a class Aug 13, 2015
.gitignore ignore python 3 byte compile caches Oct 22, 2013
CHANGES.txt Bump to v1.7.0 Sep 14, 2018
LICENSE Add Affero GPLv3 License & Cleanout before release Jan 8, 2015 Unaltered pyramid project with sqlalchemy scaffold Sep 23, 2013 README updates and fixes Jan 15, 2015 Add config for Oct 9, 2015
caramel-ER.dia Update ER diagram to match implementation. Dec 17, 2013 Add Affero GPLv3 License & Cleanout before release Jan 8, 2015
caramel-refresh.conf caramel-refresh: batch-refreshing based on existing csr setups. Jan 2, 2015 caramel-refresh: batch-refreshing based on existing csr setups. Jan 2, 2015 Fix deployment permissions to be non stupid Aug 8, 2014
development.ini Add Affero GPLv3 License & Cleanout before release Jan 8, 2015 deploy script fixes (pip /etc) Apr 25, 2017
pre-commit-checks Documentation of pre-commit hooks Nov 28, 2013
production.ini Add Affero GPLv3 License & Cleanout before release Jan 8, 2015
setup.cfg Unaltered pyramid project with sqlalchemy scaffold Sep 23, 2013 Release v 1.8.0 Nov 5, 2018

Caramel README

What is Caramel?

Caramel is a certificate management system that makes it easy to use client certificates in web applications, mobile applications, embedded use and other places. It solves the certificate signing and certificate management headache, while attempting to be easy to deploy, maintain and use in a secure manner.

Caramel makes it easier (it's never completely easy) to run your own certificate authority and manage and maintain keys and signing periods.

Caramel focuses on reliably and continuously updating short-lived certificates where clients (and embedded devices) continue to "phone home" and fetch updated certificates. This means that we do not have to provide OCSP and CRL endpoints to handle compromised certificates, but only have to stop updating the certificate. This also means that expired certificates should be considered broken.

How does Caramel work?

Caramel is a REST-ful web application that accepts certificate signing requests (CSR) from anyone, stores them, and possibly returns a signed certificate.

A client pushes its certificate signing request (CSR) to the public web application. The web application validates the CSR, and stores it in a database.

A backend (administration) web application talks to the same database (preferably from inside an intranet or other secure place), and lets you view signing requests, and sign them.

The certificates are signed with a short lifetime (3 days), and client scripts are supposed to regularly contact the public web service and download a freshly signed certificate. Root (Certificate Authority) keys only live on the "administration" part, and should preferably be kept on a non-public machine.

What should I take special care about?

No identity validation is performed by the application, this is left as an exercise for the reader.

Your signing keys are stored on the administration machine.

If a client doesn't regularly download its public certificate, it will time out and become "stale", thus preventing future connections.

Example usage

We install the administration interface and database on an internal machine (intranet) and put the public application on our software update service. We use the unique identifier for each client (its machine-ID or mac-address) as the identifier, and manually match these when initially signing requests.

Since the CSR doesn't change with time, it is re-signed every 15 days, and in the client startup sequence, the client will download a refreshed certificate from the caramel server.

Example implementation of a client (in shell-script, using OpenSSL) is included. The example includes:

  • Generating a key
  • Generating a signing request
  • Uploading a signing request
  • Fetching a valid certificate
  • Updating a valid certificate

Security trade-offs

We have made a conscious decision to have signing keys living (unencrypted, for now) on the administration server. This is a usability trade-off in order to make it possible to smoothly use signing keys.

We set strict limits on what kinds of crypto, strings and other things are allowed in a CSR.

We are doing our very best to not build crypto. OpenSSL is used wherever possible, and we try to not implement our own algorithms for fear of doing it wrongly.

Maintaining your certificates

In a server environment with several certificates you usually end up rotating/refreshing them in a cron job. Included is a tool called that will parse a config file, and automatically refresh all certificates matching. This requires the original CSR and certificate to be in place. See request-certificate for a tool to generate your own certificates.

caramel-refresh is intended to be run in a cron job on servers (or clients). Please make sure you run the job as the correct user, so permissions aren't a problem afterwards.

Getting Started

cd <directory containing this file>
$venv/bin/python develop
$venv/bin/caramel_initialize_db development.ini
$venv/bin/caramel_ca development.ini
$venv/bin/pserve development.ini

Running Tests

cd <directory containing this file>
$venv/bin/python develop
$venv/bin/python -m unittest discover

Running Tests with Nose

cd <directory containing this file>
$venv/bin/python develop
$venv/bin/pip install nose

Installing the Commit Hook

We use commit-hooks to run test-cases in a clean virtualenv before each commit. This is to ensure a certain level of quality and code standards, and to prevent missing dependencies in Running these tests at each commit can be expensive as it involves going to the network and downloading every package from scratch. This is not a concern for our development environment, but may be a problem for others.

Install the hooks with the following commands:

cd <directory containing this file>
ln -rs pre-commit-checks .git/hooks/pre-commit

Please note the "-r" flag to ln, as it makes sure the relative link keeps the correct path.

For the pre-commit hook to work, you need to have flake8 available. Either install flake8 via:

pip install flake8

Or point git config hooks.flake8 to the flake8 executable:

git config hooks.flake8 /path/to/flake8

Dependencies needed from the operating system

  • libffi-devel (on RHEL/CentOS)
  • openssl, openssl-devel
  • gcc

Making sure you have VirtualEnv

To use the commit hook you need virtualenv available. If you do not have virtualenv in your path, please point to it with:

git config hooks.virtualenv /path/to/virtualenv

In order to run the python3 interpreter instead of the normal python2 interpreter, you should configure the hook as this:

git config hooks.virtualenv /usr/bin/virtualenv -p /usr/bin/python3


We have chosen the GNU Affero GPL v3 license for the project. We see no need for others to keep modification to this software a secret, and we welcome outside providers. Just because the code is GPLv3, doesn't prevent you from keeping your keys & certificates private.

For the organizations using this, there should be no additional gain to be had from keeping the source code secret, and if you think there is any such gain, please contact us.