# PKI
This material differs from normal cryptography courses in that it describes real-world use cases of cryptographic standards, libraries, and tools.
Cryptography research essentially aims for two fundamental goals:
1. to guide the invention of better cryptographies and
2. to fully understand the limit of prosposed cryptographies.
In daily life, ubiquitus cryptographic infrastructures automatically provide users with good enough security for communication.
How is research transformed into working equipments?
A crude but conceptually acceptible description of the process is as follows.
1. Security experts aware of recent crpytographic research form a commitee.
2. The commitee produces a *standard* describing
- the responsibility and function of each party involved,
- ownership, location, and functions of assets created by parties,
- communication protocols that the paritites observe,
- the crpytographic algorithms used at specific steps of the communication process,
- components that encapsulate all functions described above, and
- the interface requirements of the components.
3. Developers implement libraries that realize components and interface requirements mandated by the *standard*.
Parts of the libraries are binaries that provide a user-friendly interface; these are called tools.
5. Administrators deploy the libraries to various parts of existing computing infrastructure in conformance to the *standard*, creating a favorable cryptographic infrastructure.
6. Users play their roles according to the *standard* and enjoy the service without much hassle.
One of such is [X.509](https://tools.ietf.org/html/rfc5280),
which is used by TLS/SSL.
In fact X.509 is quite general, as it defines a <u>p</u>ublic <u>k</u>ey <u>i</u>nfrastruture ([PKI](https://en.wikipedia.org/wiki/Public_key_infrastructure)).
This model could be used for TLS/SSL, SSH, and application/service authentication.
- [OpenStack wiki on PKI](https://wiki.openstack.org/wiki/PKI)
- [OpenStack docs on dogtag](https://docs.openstack.org/api-guide/key-manager/dogtag_setup.html)
- [SSH certificate](https://smallstep.com/blog/use-ssh-certificates/)
- [Dogtag is the OSS version of RHCS](http://www.ncsa.illinois.edu/People/jbasney/pki/)
## Dogtag
[Dogtag](https://www.dogtagpki.org/wiki/PKI_Main_Page) is a full-featured PKI deployment that uses the [389 directory server](https://www.dogtagpki.org/wiki/PKI_Main_Page) (389ds) as an LDAP backend.
## Openssl
### Key generation
Generate RSA key
```bash
openssl genrsa -out <example.key> <bits>
```
Print private key
```bash
openssl rsa -in <example.key>
```
Print public key
```bash
openssl rsa -in <example.key> -pubout
```
Print textual format of the key
```bash
openssl rsa -in <example.key> -text
```
Print textual format of the key (without private key)
```bash
openssl rsa -in <example.key> -text -noout
```
Generate RSA key encrypt with AES256
```bash
openssl genrsa -aes256 -out <example.key> <bits>
```
Check RSA key
```bash
openssl rsa -check -in <example.key>
```
Add passphrase and encrypt the key with AES256
```bash
openssl rsa -aes256 -in <example.key> -out <encrypted.key>
```
Remove passphrase from the key
```bash
openssl rsa -in <example.key> -out <example.key>
```
### Certificate signing request (CSR)
Create a CSR from scratch (with passphrase)
```bash
openssl req -newkey rsa:<bits> -keyout <example.key > -out <example.csr>
```
Create a CSR from scratch (without passphrase)
```bash
openssl req -nodes -newkey rsa:<bits> -keyout <example.key> -out <example.csr>
```
Provide CSR subject info through the command line
```bash
openssl req [-nodes] -newkey rsa:<bits> -subj "/C=<country>/ST=<state>/L=<Locality>/O=<Organization>/OU=<Organization Unit>/CN=<Common Name>" -keyout <example.key> -out <example.csr>
```
Create a CSR from existing private key.
```bash
openssl req -new -key <example.key> -out <example.csr> -[digest]
```
Create a CSR from existing certificate and private key
```bash
openssl x509 -x509toreq -in cert.pem -out example.csr -signkey example.key
```
Print CSR
```bash
openssl req -in <example.csr>
```
Print CSR in textual format
```bash
openssl req -in <example.csr> -noout -text
```
### X.509 Certificate
Create an X.509 certificate from scratch
```bash
openssl req -x509 [-nodes] -newkey rsa:<bits> -keyout <example.key> -out <example.crt> -days <days>
```
Create a self signed X.509 certificate with existing private key and csr
```bash
openssl x509 -req -in <example.csr> -signkey <example.key> -out <example.crt> -days <days>
```
Create child certificate using root CA's certificate and private key
```bash
openssl x509 -req -in <example.csr> -CA <ca.crt> -CAkey <ca.key> -set_serial <serial> -out <example.crt> -days <days>
openssl x509 -req -in <example.csr> -CA <ca.crt> -CAkey <ca.key> -CAcreateserial -out <example.crt> -days <days>
```
Print X.509 Certificate
```bash
openssl x509 -in <example.csr>
```
Print X.509 Certificate in textual format
```bash
openssl x509 -in <example.csr> -noout -text
```
### Vereification
Verify validity of CSR:
```bash
openssl req -in example.csr -verify
```
Verify that private key matches a certificate and CSR:
```bash
openssl rsa -noout -modulus -in <example.key> | sha256sum
openssl x509 -noout -modulus -in <example.crt> | sha256sum
openssl req -noout -modulus -in <example.csr> | sha256sum
```
Verify Certificate (root certificate & intermediate certificate chain verified)
```bash
openssl verify <example.crt>
```
Verify Certificate (root certificate verified, providing intermediate certificate chain
```bash
openssl verify -untrusted <intermediate-chain.pem> <example.crt>
```
Verify Certificate (providing root CA)
```bash
openssl verify -CAFile <ca.crt> -untrusted intermediate-ca-chain.pem <example.crt>
```
### Hash
Verify digests
```bash
openssl dgst -[hash_function] <input_file>
```
### Connection
Connect to a server using TLS:
```bash
openssl s_client -connect <host>:<port>
openssl s_client -connect -host <host> -port <port>
```
Show certificates when connecting to the server
```bash
openssl s_client -showcerts -host <host> -port <port> < /dev/null
```
Connect to a server and verify its host name
```bash
openssl s_client -verify_hostname <hostname> -connect <host>:<port>
```
Connect to a server with SNI override
```bash
openssl s_client -servername <hostname> -host <host> -port <port>
```
Connect to a server providing cipher suite
```bash
openssl s_client -host <host> -port <port> -cipher <cipher_suite>
```
### Convertion between encoding
Convert certificate between DER and PEM:
```bash
openssl x509 -in <example.pem> -outform der -out example.der
openssl x509 -in <example.der> -inform der -out example.pem
```
## Vault
[HashiCorp Vault](https://www.vaultproject.io/docs) is a PKI-capable secret manager.
We can create a root CA manually, as outlined above, and make Vault an intermediate CA.
The root CA keys can then be saved on a pen-drive in a physical vault.
Here is a recap on creating the root CA:
```bash
openssl genrsa -aes256 -out rootCA.key 4096 # You will be prompted for password.
```
- [Vault -- tutorials](https://learn.hashicorp.com/vault)
- [Vault -- PKI Secrets Engines](https://www.vaultproject.io/docs/secrets/pki)
- [Vault -- Build Your Own CA](https://learn.hashicorp.com/tutorials/vault/pki-engine)
- [Facebook SSH certs](https://engineering.fb.com/security/scalable-and-secure-access-with-ssh/)