Skip to content

Commit

Permalink
epoch
Browse files Browse the repository at this point in the history
  • Loading branch information
Tero Mononen committed May 11, 2024
0 parents commit d9528ec
Show file tree
Hide file tree
Showing 13 changed files with 1,028 additions and 0 deletions.
Empty file added LICENSE
Empty file.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
all:
python -m build
107 changes: 107 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# CA tool

This is not a ready project; more like a gist showing how to do certain things

## Purpose

- Provides user interface for
- keypair generation for CA and certificate user
- issuing certificates based on requests,
- listing various object, and
- revocation/CRL generation.

- Keeps track on issues and revoked certificates.
- Implements secret sharing for CA keys using SSSS if available

- Requires OpenSSL 3.x

## Examples

### Install

~~~
$ pip install nanoCA-1.0.0-py3-none-any.whl
$ alias CA="python -m nanoCA"
~~~

### Setup

this is done once; second time will fail without altering system state
~~~
$ CA init
~~~

## Create Top Level CA

This creates the top level CA (selfsigned) with default RSA:8k key. For the key we enable 2 / 20 secret sharing. The key generator makes the key and CSR that can be certified with `issue` command.

After Issuing the CA certificate we'll create a CRL that can be published.

~~~
$ CA keygen --shares 2 20 root-ca
$ CA issue \
--subject /DC=SSH/DC=NET/CN=root-ca \
--altname DNS=root-ca.ssh.net --altname [email protected] \
--usage TOP --name root-ca \
root-ca /tmp/nqx/certificates/root-ca.csr /tmp/root-ca.crt
$ CA crl
--shares 2 --validity 182
root-ca /tmp/crl-top-without-revoked-certs.crl
~~~

## Create Intermediate (Sub) CA

Create a key pair for the sub-CA. This key is passphrase protected - the user will be prompted for the password instead of shares.
This also demonstrates mixed key type hierarchy.

As the Root CA uses secret sharing, we'll need to provide number of secrets it uses (XXX: we should store this by side of the key instead)

~~~
$ CA keygen --keytype ED448 --name sub-ca
$ CA issue
--shares 2
--subject /DC=SSH/DC=NET/CN=sub-ca/
--altname DNS=sub-ca.ssh.net --altname [email protected]
--usage INTERMEDIATE --name sub-ca
root-ca /tmp/nqx/certificates/sub-ca.csr /tmp/sub-ca.crt
$ CA crl
--validity 91
sub-ca /tmp/crl-sub-without-revoked-certs.crl
~~~

## Create a LEAF certificate

First create key pair and CSR on some device, then transmit the req.pem to the CA. The CA check that request is from legit source, creates a certificate and registers issuance. The resulting certifiate leaf.crt can then be sent to the requestor.

~~~
$ openssl req -new -subj '/CN=Node 1/' -noenc -out leaf.pem
$ CA issue
--subject /DC=devices/DC=SSH/DC=NET/CN=Leaf Device One/
--altname DNS=leaf1.devices.ssh.net --altname [email protected] --altname IP=1.2.3.4
sub-ca
/tmp/leaf.pem /tmp/leaf.crt
~~~

Subject Alternative Names can be of types
* DNS; DNS names for hosts
* IP; IP address for hosts
* EMAIL; E-mail address for user
* UPN; creates Microsoft OID'ed OtherName SAN for User Principal Names

## Revoke certificate

Revoke leaf certificate issued above. This can be done either using the CA stored certificate, or by serial number.

~~~
$ CA list --type cert 'Leaf Device One'
Status Serial Path Subject
V 123123 afcc77c8-2d2b-4957-8306-0c0ae571ff13.crt /DC=devices/DC=SSH/DC=NET/CN=Leaf Device One/
$ CA revoke sub-ca $certsdir/afcc77c8-2d2b-4957-8306-0c0ae571ff13.crt
or
$ CA revoke --serial 123123 sub-ca
$ CA crl sub-ca /tmp/crl-sub-with-revoked-certs.crl
~~~
6 changes: 6 additions & 0 deletions make-debian
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
VERSION=$(git rev-parse --short HEAD)

fpm --output-type deb --input-type python --python-pypi file://`pwd`/dist \
--prefix /usr/sbin --name nanoca --version $VERSION \
--description 'Rather minimalistic Certificate Authority' \
--package nanoCA-2.2.6.deb nanoCA-1.0.0
23 changes: 23 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[project]
name = "nanoCA"
version = "1.0.0"
authors = [
{ name="Tero Mononen", email="[email protected]" },
]
description = "Nano CA with Secret Sharing"
readme = "README.md"
requires-python = ">=3.7"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]

[project.urls]
"Homepage" = "https://www.ssh.com/"
"Bug Tracker" = "https://support.ssh.com"

[build-system]
requires = [
"setuptools", "click"
]
2 changes: 2 additions & 0 deletions src/.flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
max-line-length = 131
105 changes: 105 additions & 0 deletions src/nanoCA.egg-info/PKG-INFO
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
Metadata-Version: 2.1
Name: nanoCA
Version: 1.0.0
Summary: Nano CA with Secret Sharing
Author-email: Tero Mononen <[email protected]>
Project-URL: Homepage, https://www.ssh.com/
Project-URL: Bug Tracker, https://support.ssh.com
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE

# CA tool

## Purpose

- keeps track on issues and revoked certificates.
- implments secret sharing for CA keys
- provides user interface for keypair generation, issuing certificates based on requests, listing various object, and revocation/CRL generation.

## Examples

### Install
~~~
$ pip install nanoCA-1.0.0-py3-none-any.whl
$ alias CA="python -m nanoCA"
~~~

### Setup

this is done once; second time will fail without altering system state
~~~
$ CA init
~~~

## Create Top Level CA

This creates the top level CA (selfsigned) with default RSA:8k key. For the key we enable 2 / 20 secret sharing. The key generator makes the key and CSR that can be certified with `issue` command.

After Issuing the CA certificate we'll create a CRL that can be published.

~~~
$ CA keygen --shares 2 20 --name root-ca
$ CA issue \
--subject /DC=SSH/DC=NET/CN=root-ca \
--altname DNS=root-ca.ssh.net --altname [email protected] \
--usage TOP --name root-ca \
root-ca /tmp/nqx/certificates/root-ca.csr /tmp/root-ca.crt
$ CA crl
--shares 2 --validity 182
root-ca /tmp/crl-top-without-revoked-certs.crl
~~~

## Create Intermediate (Sub) CA

Create a key pair for the sub-CA. This key is passphrase protected - the user will be prompted for the password instead of shares.
This also demonstrates mixed key type hierarchy.

As the Root CA uses secret sharing, we'll need to provide number of secrets it uses (XXX: we should store this by side of the key instead)

~~~
$ CA keygen --keytype ED448 --name sub-ca
$ CA issue
--shares 2
--subject /DC=SSH/DC=NET/CN=sub-ca/
--altname DNS=sub-ca.ssh.net --altname [email protected]
--usage INTERMEDIATE --name sub-ca
root-ca /tmp/nqx/certificates/sub-ca.csr /tmp/sub-ca.crt
$ CA crl
--validity 91
sub-ca /tmp/crl-sub-without-revoked-certs.crl
~~~

## Create a LEAF certificate

First create key pair and CSR on some device, then transmit the req.pem to the CA. The CA check that request is from legit source, creates a certificate and registers issuance. The resulting certifiate leaf.crt can then be sent to the requestor.

~~~
$ openssl req -new -subj '/CN=Node 1/' -noenc -out leaf.pem

$ CA issue
--subject /DC=devices/DC=SSH/DC=NET/CN=Leaf Device One/
--altname DNS=leaf1.devices.ssh.net --altname [email protected] --altname IP=1.2.3.4
sub-ca
/tmp/leaf.pem /tmp/leaf.crt
~~~

## Revoke certificate

Revoke leaf certificate issued above. This can be done either using the CA stored certificate, or by serial number.

~~~
$ CA list --type cert 'Leaf Device One'
Status Serial Path Subject
V 123123 afcc77c8-2d2b-4957-8306-0c0ae571ff13.crt /DC=devices/DC=SSH/DC=NET/CN=Leaf Device One/

$ CA revoke sub-ca $certsdir/afcc77c8-2d2b-4957-8306-0c0ae571ff13.crt

or

$ CA revoke --serial 123123 sub-ca
$ CA crl sub-ca /tmp/crl-sub-with-revoked-certs.crl
~~~
9 changes: 9 additions & 0 deletions src/nanoCA.egg-info/SOURCES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
LICENSE
README.md
pyproject.toml
src/nanoCA/__main__.py
src/nanoCA/ca.py
src/nanoCA.egg-info/PKG-INFO
src/nanoCA.egg-info/SOURCES.txt
src/nanoCA.egg-info/dependency_links.txt
src/nanoCA.egg-info/top_level.txt
1 change: 1 addition & 0 deletions src/nanoCA.egg-info/dependency_links.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions src/nanoCA.egg-info/top_level.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nanoCA
Empty file added src/nanoCA/__init__,py
Empty file.
4 changes: 4 additions & 0 deletions src/nanoCA/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .ca import main

if __name__ == '__main__':
main()
Loading

0 comments on commit d9528ec

Please sign in to comment.