feat(commands): enhance crypto generation capabilities (#2842)
This expands the functionality of the certificates and rsa commands and merges them into one command called cypto which can either use the cert or pair subcommands to generate certificates or key-pairs respectively. The rsa, ecdsa, and ed25519 subcommands exist for both the cert and pair commands. A new --ca-path argument for the cert subcommand allows Authelia to sign other certs with CA certs. Co-authored-by: Amir Zarrinkafsh <nightah@me.com>pull/3604/head
parent
0b5f92d9eb
commit
fcac438637
|
@ -42,11 +42,11 @@ openssl rsa -in private.pem -outform PEM -pubout -out public.pem
|
||||||
The __Authelia__ docker container or CLI binary can be used to generate a RSA 4096 bit keypair:
|
The __Authelia__ docker container or CLI binary can be used to generate a RSA 4096 bit keypair:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -u "$(id -u):$(id -g)" -v "$(pwd)":/keys authelia/authelia:latest authelia rsa generate --dir /keys
|
docker run -u "$(id -u):$(id -g)" -v "$(pwd)":/keys authelia/authelia:latest authelia crypto pair rsa generate --bits 4096 --directory /keys
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
authelia rsa generate --dir /path/to/keys
|
authelia crypto pair rsa generate --directory /path/to/keys
|
||||||
```
|
```
|
||||||
|
|
||||||
## Generating an RSA Self-Signed Certificate
|
## Generating an RSA Self-Signed Certificate
|
||||||
|
@ -69,9 +69,9 @@ The __Authelia__ docker container or binary can be used to generate a RSA 4096 b
|
||||||
domain `example.com`:
|
domain `example.com`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -u "$(id -u):$(id -g)" -v "$(pwd)":/keys authelia/authelia authelia certificates generate --host example.com --dir /keys
|
docker run -u "$(id -u):$(id -g)" -v "$(pwd)":/keys authelia/authelia authelia crypto certificate rsa generate --common-name example.com --directory /keys
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
authelia certificates generate --host example.com --dir /path/to/keys
|
authelia crypto certificate rsa generate --common-name example.com --directory /path/to/keys
|
||||||
```
|
```
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "CLI"
|
title: "CLI"
|
||||||
description: ""
|
description: ""
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
weight: 300
|
weight: 300
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-gen"
|
title: "authelia-gen"
|
||||||
description: ""
|
description: ""
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-06-03T10:57:43+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-gen"
|
title: "authelia-gen"
|
||||||
description: "Reference for the authelia-gen command."
|
description: "Reference for the authelia-gen command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-06-03T10:57:43+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -28,4 +28,4 @@ Authelia's generator tooling
|
||||||
* [authelia-gen code](authelia-gen_code.md) - Generate code
|
* [authelia-gen code](authelia-gen_code.md) - Generate code
|
||||||
* [authelia-gen docs](authelia-gen_docs.md) - Generate docs
|
* [authelia-gen docs](authelia-gen_docs.md) - Generate docs
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-gen all"
|
title: "authelia-gen all"
|
||||||
description: "Reference for the authelia-gen all command."
|
description: "Reference for the authelia-gen all command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-06-03T10:57:43+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -30,4 +30,4 @@ authelia-gen all [flags]
|
||||||
|
|
||||||
* [authelia-gen](authelia-gen.md) - Authelia's generator tooling
|
* [authelia-gen](authelia-gen.md) - Authelia's generator tooling
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-gen code"
|
title: "authelia-gen code"
|
||||||
description: "Reference for the authelia-gen code command."
|
description: "Reference for the authelia-gen code command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-06-03T10:57:43+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -31,4 +31,4 @@ authelia-gen code [flags]
|
||||||
* [authelia-gen](authelia-gen.md) - Authelia's generator tooling
|
* [authelia-gen](authelia-gen.md) - Authelia's generator tooling
|
||||||
* [authelia-gen code keys](authelia-gen_code_keys.md) - Generate the list of valid configuration keys
|
* [authelia-gen code keys](authelia-gen_code_keys.md) - Generate the list of valid configuration keys
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-gen code keys"
|
title: "authelia-gen code keys"
|
||||||
description: "Reference for the authelia-gen code keys command."
|
description: "Reference for the authelia-gen code keys command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-06-03T10:57:43+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -32,4 +32,4 @@ authelia-gen code keys [flags]
|
||||||
|
|
||||||
* [authelia-gen code](authelia-gen_code.md) - Generate code
|
* [authelia-gen code](authelia-gen_code.md) - Generate code
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-gen docs"
|
title: "authelia-gen docs"
|
||||||
description: "Reference for the authelia-gen docs command."
|
description: "Reference for the authelia-gen docs command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-06-03T10:57:43+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -33,4 +33,4 @@ authelia-gen docs [flags]
|
||||||
* [authelia-gen docs cli](authelia-gen_docs_cli.md) - Generate CLI docs
|
* [authelia-gen docs cli](authelia-gen_docs_cli.md) - Generate CLI docs
|
||||||
* [authelia-gen docs date](authelia-gen_docs_date.md) - Generate doc dates
|
* [authelia-gen docs date](authelia-gen_docs_date.md) - Generate doc dates
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-gen docs cli"
|
title: "authelia-gen docs cli"
|
||||||
description: "Reference for the authelia-gen docs cli command."
|
description: "Reference for the authelia-gen docs cli command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-06-03T10:57:43+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -37,4 +37,4 @@ authelia-gen docs cli [flags]
|
||||||
|
|
||||||
* [authelia-gen docs](authelia-gen_docs.md) - Generate docs
|
* [authelia-gen docs](authelia-gen_docs.md) - Generate docs
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-gen docs time"
|
title: "authelia-gen docs time"
|
||||||
description: "Reference for the authelia-gen docs time command."
|
description: "Reference for the authelia-gen docs time command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-06-03T11:17:29+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts"
|
title: "authelia-scripts"
|
||||||
description: ""
|
description: ""
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts"
|
title: "authelia-scripts"
|
||||||
description: "Reference for the authelia-scripts command."
|
description: "Reference for the authelia-scripts command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -49,4 +49,4 @@ authelia-scripts help
|
||||||
* [authelia-scripts unittest](authelia-scripts_unittest.md) - Run unit tests
|
* [authelia-scripts unittest](authelia-scripts_unittest.md) - Run unit tests
|
||||||
* [authelia-scripts xflags](authelia-scripts_xflags.md) - Generate X LDFlags for building Authelia
|
* [authelia-scripts xflags](authelia-scripts_xflags.md) - Generate X LDFlags for building Authelia
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts bootstrap"
|
title: "authelia-scripts bootstrap"
|
||||||
description: "Reference for the authelia-scripts bootstrap command."
|
description: "Reference for the authelia-scripts bootstrap command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -47,4 +47,4 @@ authelia-scripts bootstrap
|
||||||
|
|
||||||
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts build"
|
title: "authelia-scripts build"
|
||||||
description: "Reference for the authelia-scripts build command."
|
description: "Reference for the authelia-scripts build command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -47,4 +47,4 @@ authelia-scripts build
|
||||||
|
|
||||||
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts certificates"
|
title: "authelia-scripts certificates"
|
||||||
description: "Reference for the authelia-scripts certificates command."
|
description: "Reference for the authelia-scripts certificates command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
lastmod: 2022-06-03T11:17:29+10:00
|
lastmod: 2022-06-03T11:17:29+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts certificates generate"
|
title: "authelia-scripts certificates generate"
|
||||||
description: "Reference for the authelia-scripts certificates generate command."
|
description: "Reference for the authelia-scripts certificates generate command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
lastmod: 2022-06-03T11:17:29+10:00
|
lastmod: 2022-06-03T11:17:29+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts ci"
|
title: "authelia-scripts ci"
|
||||||
description: "Reference for the authelia-scripts ci command."
|
description: "Reference for the authelia-scripts ci command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -47,4 +47,4 @@ authelia-scripts ci
|
||||||
|
|
||||||
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts clean"
|
title: "authelia-scripts clean"
|
||||||
description: "Reference for the authelia-scripts clean command."
|
description: "Reference for the authelia-scripts clean command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -47,4 +47,4 @@ authelia-scripts clean
|
||||||
|
|
||||||
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts docker"
|
title: "authelia-scripts docker"
|
||||||
description: "Reference for the authelia-scripts docker command."
|
description: "Reference for the authelia-scripts docker command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -49,4 +49,4 @@ authelia-scripts docker
|
||||||
* [authelia-scripts docker build](authelia-scripts_docker_build.md) - Build the docker image of Authelia
|
* [authelia-scripts docker build](authelia-scripts_docker_build.md) - Build the docker image of Authelia
|
||||||
* [authelia-scripts docker push-manifest](authelia-scripts_docker_push-manifest.md) - Push Authelia docker manifest to the Docker registries
|
* [authelia-scripts docker push-manifest](authelia-scripts_docker_push-manifest.md) - Push Authelia docker manifest to the Docker registries
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts docker build"
|
title: "authelia-scripts docker build"
|
||||||
description: "Reference for the authelia-scripts docker build command."
|
description: "Reference for the authelia-scripts docker build command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -48,4 +48,4 @@ authelia-scripts docker build
|
||||||
|
|
||||||
* [authelia-scripts docker](authelia-scripts_docker.md) - Commands related to building and publishing docker image
|
* [authelia-scripts docker](authelia-scripts_docker.md) - Commands related to building and publishing docker image
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts docker push-manifest"
|
title: "authelia-scripts docker push-manifest"
|
||||||
description: "Reference for the authelia-scripts docker push-manifest command."
|
description: "Reference for the authelia-scripts docker push-manifest command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -47,4 +47,4 @@ authelia-scripts docker push-manifest
|
||||||
|
|
||||||
* [authelia-scripts docker](authelia-scripts_docker.md) - Commands related to building and publishing docker image
|
* [authelia-scripts docker](authelia-scripts_docker.md) - Commands related to building and publishing docker image
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts hash-password"
|
title: "authelia-scripts hash-password"
|
||||||
description: "Reference for the authelia-scripts hash-password command."
|
description: "Reference for the authelia-scripts hash-password command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
lastmod: 2022-06-03T11:17:29+10:00
|
lastmod: 2022-06-03T11:17:29+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts rsa"
|
title: "authelia-scripts rsa"
|
||||||
description: "Reference for the authelia-scripts rsa command."
|
description: "Reference for the authelia-scripts rsa command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
lastmod: 2022-06-03T11:17:29+10:00
|
lastmod: 2022-06-03T11:17:29+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts rsa generate"
|
title: "authelia-scripts rsa generate"
|
||||||
description: "Reference for the authelia-scripts rsa generate command."
|
description: "Reference for the authelia-scripts rsa generate command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
lastmod: 2022-06-03T11:17:29+10:00
|
lastmod: 2022-06-03T11:17:29+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts serve"
|
title: "authelia-scripts serve"
|
||||||
description: "Reference for the authelia-scripts serve command."
|
description: "Reference for the authelia-scripts serve command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -47,4 +47,4 @@ authelia-scripts serve test.yml
|
||||||
|
|
||||||
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts suites"
|
title: "authelia-scripts suites"
|
||||||
description: "Reference for the authelia-scripts suites command."
|
description: "Reference for the authelia-scripts suites command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -51,4 +51,4 @@ authelia-scripts suites
|
||||||
* [authelia-scripts suites teardown](authelia-scripts_suites_teardown.md) - Teardown a test suite environment
|
* [authelia-scripts suites teardown](authelia-scripts_suites_teardown.md) - Teardown a test suite environment
|
||||||
* [authelia-scripts suites test](authelia-scripts_suites_test.md) - Run a test suite
|
* [authelia-scripts suites test](authelia-scripts_suites_test.md) - Run a test suite
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts suites list"
|
title: "authelia-scripts suites list"
|
||||||
description: "Reference for the authelia-scripts suites list command."
|
description: "Reference for the authelia-scripts suites list command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -49,4 +49,4 @@ authelia-scripts suites list
|
||||||
|
|
||||||
* [authelia-scripts suites](authelia-scripts_suites.md) - Commands related to suites management
|
* [authelia-scripts suites](authelia-scripts_suites.md) - Commands related to suites management
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts suites setup"
|
title: "authelia-scripts suites setup"
|
||||||
description: "Reference for the authelia-scripts suites setup command."
|
description: "Reference for the authelia-scripts suites setup command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -49,4 +49,4 @@ authelia-scripts suites setup Standalone
|
||||||
|
|
||||||
* [authelia-scripts suites](authelia-scripts_suites.md) - Commands related to suites management
|
* [authelia-scripts suites](authelia-scripts_suites.md) - Commands related to suites management
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts suites teardown"
|
title: "authelia-scripts suites teardown"
|
||||||
description: "Reference for the authelia-scripts suites teardown command."
|
description: "Reference for the authelia-scripts suites teardown command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -49,4 +49,4 @@ authelia-scripts suites setup Standalone
|
||||||
|
|
||||||
* [authelia-scripts suites](authelia-scripts_suites.md) - Commands related to suites management
|
* [authelia-scripts suites](authelia-scripts_suites.md) - Commands related to suites management
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts suites test"
|
title: "authelia-scripts suites test"
|
||||||
description: "Reference for the authelia-scripts suites test command."
|
description: "Reference for the authelia-scripts suites test command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -52,4 +52,4 @@ authelia-scripts suites test Standalone
|
||||||
|
|
||||||
* [authelia-scripts suites](authelia-scripts_suites.md) - Commands related to suites management
|
* [authelia-scripts suites](authelia-scripts_suites.md) - Commands related to suites management
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts unittest"
|
title: "authelia-scripts unittest"
|
||||||
description: "Reference for the authelia-scripts unittest command."
|
description: "Reference for the authelia-scripts unittest command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -47,4 +47,4 @@ authelia-scripts unittest
|
||||||
|
|
||||||
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia-scripts xflags"
|
title: "authelia-scripts xflags"
|
||||||
description: "Reference for the authelia-scripts xflags command."
|
description: "Reference for the authelia-scripts xflags command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -49,4 +49,4 @@ authelia-scripts xflags
|
||||||
|
|
||||||
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
* [authelia-scripts](authelia-scripts.md) - A utility used in the Authelia development process.
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia"
|
title: "authelia"
|
||||||
description: ""
|
description: ""
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia"
|
title: "authelia"
|
||||||
description: "Reference for the authelia command."
|
description: "Reference for the authelia command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -24,7 +24,7 @@ An open-source authentication and authorization server providing
|
||||||
two-factor authentication and single sign-on (SSO) for your
|
two-factor authentication and single sign-on (SSO) for your
|
||||||
applications via a web portal.
|
applications via a web portal.
|
||||||
|
|
||||||
Documentation is available at: https://www.authelia.com/docs
|
Documentation is available at: https://www.authelia.com/
|
||||||
|
|
||||||
```
|
```
|
||||||
authelia [flags]
|
authelia [flags]
|
||||||
|
@ -49,10 +49,9 @@ authelia --config /etc/authelia/config/
|
||||||
|
|
||||||
* [authelia access-control](authelia_access-control.md) - Helpers for the access control system
|
* [authelia access-control](authelia_access-control.md) - Helpers for the access control system
|
||||||
* [authelia build-info](authelia_build-info.md) - Show the build information of Authelia
|
* [authelia build-info](authelia_build-info.md) - Show the build information of Authelia
|
||||||
* [authelia certificates](authelia_certificates.md) - Commands related to certificate generation
|
* [authelia crypto](authelia_crypto.md) - Perform cryptographic operations
|
||||||
* [authelia hash-password](authelia_hash-password.md) - Hash a password to be used in file-based users database.
|
* [authelia hash-password](authelia_hash-password.md) - Hash a password to be used in file-based users database
|
||||||
* [authelia rsa](authelia_rsa.md) - Commands related to rsa keypair generation
|
|
||||||
* [authelia storage](authelia_storage.md) - Manage the Authelia storage
|
* [authelia storage](authelia_storage.md) - Manage the Authelia storage
|
||||||
* [authelia validate-config](authelia_validate-config.md) - Check a configuration against the internal configuration validation mechanisms
|
* [authelia validate-config](authelia_validate-config.md) - Check a configuration against the internal configuration validation mechanisms
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia access-control"
|
title: "authelia access-control"
|
||||||
description: "Reference for the authelia access-control command."
|
description: "Reference for the authelia access-control command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -37,4 +37,4 @@ authelia access-control --help
|
||||||
* [authelia](authelia.md) - authelia untagged-unknown-dirty (master, unknown)
|
* [authelia](authelia.md) - authelia untagged-unknown-dirty (master, unknown)
|
||||||
* [authelia access-control check-policy](authelia_access-control_check-policy.md) - Checks a request against the access control rules to determine what policy would be applied
|
* [authelia access-control check-policy](authelia_access-control_check-policy.md) - Checks a request against the access control rules to determine what policy would be applied
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia access-control check-policy"
|
title: "authelia access-control check-policy"
|
||||||
description: "Reference for the authelia access-control check-policy command."
|
description: "Reference for the authelia access-control check-policy command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -53,7 +53,7 @@ authelia access-control check-policy --config config.yml --url https://example.c
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-c, --config strings configuration files to load (default [config.yml])
|
-c, --config strings configuration files to load (default [configuration.yml])
|
||||||
--groups strings the groups of the subject
|
--groups strings the groups of the subject
|
||||||
-h, --help help for check-policy
|
-h, --help help for check-policy
|
||||||
--ip string the ip of the subject
|
--ip string the ip of the subject
|
||||||
|
@ -67,4 +67,4 @@ authelia access-control check-policy --config config.yml --url https://example.c
|
||||||
|
|
||||||
* [authelia access-control](authelia_access-control.md) - Helpers for the access control system
|
* [authelia access-control](authelia_access-control.md) - Helpers for the access control system
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia build-info"
|
title: "authelia build-info"
|
||||||
description: "Reference for the authelia build-info command."
|
description: "Reference for the authelia build-info command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -49,4 +49,4 @@ authelia build-info
|
||||||
|
|
||||||
* [authelia](authelia.md) - authelia untagged-unknown-dirty (master, unknown)
|
* [authelia](authelia.md) - authelia untagged-unknown-dirty (master, unknown)
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
title: "authelia certificates"
|
|
||||||
description: "Reference for the authelia certificates command."
|
|
||||||
lead: ""
|
|
||||||
date: 2022-05-31T11:13:56+10:00
|
|
||||||
draft: false
|
|
||||||
images: []
|
|
||||||
menu:
|
|
||||||
reference:
|
|
||||||
parent: "cli-authelia"
|
|
||||||
weight: 330
|
|
||||||
toc: true
|
|
||||||
---
|
|
||||||
|
|
||||||
## authelia certificates
|
|
||||||
|
|
||||||
Commands related to certificate generation
|
|
||||||
|
|
||||||
### Synopsis
|
|
||||||
|
|
||||||
Commands related to certificate generation.
|
|
||||||
|
|
||||||
This subcommand allows preforming X509 certificate tasks.
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
```
|
|
||||||
authelia certificates --help
|
|
||||||
```
|
|
||||||
|
|
||||||
### Options
|
|
||||||
|
|
||||||
```
|
|
||||||
-h, --help help for certificates
|
|
||||||
--host strings Comma-separated hostnames and IPs to generate a certificate for
|
|
||||||
```
|
|
||||||
|
|
||||||
### SEE ALSO
|
|
||||||
|
|
||||||
* [authelia](authelia.md) - authelia untagged-unknown-dirty (master, unknown)
|
|
||||||
* [authelia certificates generate](authelia_certificates_generate.md) - Generate a self-signed certificate
|
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
|
|
@ -1,59 +0,0 @@
|
||||||
---
|
|
||||||
title: "authelia certificates generate"
|
|
||||||
description: "Reference for the authelia certificates generate command."
|
|
||||||
lead: ""
|
|
||||||
date: 2022-05-31T11:13:56+10:00
|
|
||||||
draft: false
|
|
||||||
images: []
|
|
||||||
menu:
|
|
||||||
reference:
|
|
||||||
parent: "cli-authelia"
|
|
||||||
weight: 330
|
|
||||||
toc: true
|
|
||||||
---
|
|
||||||
|
|
||||||
## authelia certificates generate
|
|
||||||
|
|
||||||
Generate a self-signed certificate
|
|
||||||
|
|
||||||
### Synopsis
|
|
||||||
|
|
||||||
Generate a self-signed certificate.
|
|
||||||
|
|
||||||
This subcommand allows generating self-signed certificates.
|
|
||||||
|
|
||||||
```
|
|
||||||
authelia certificates generate [flags]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
```
|
|
||||||
authelia certificates generate
|
|
||||||
authelia certificates generate --dir ./out
|
|
||||||
```
|
|
||||||
|
|
||||||
### Options
|
|
||||||
|
|
||||||
```
|
|
||||||
--ca Whether this cert should be its own Certificate Authority
|
|
||||||
--dir string Target directory where the certificate and keys will be stored
|
|
||||||
--duration duration Duration that certificate is valid for (default 8760h0m0s)
|
|
||||||
--ecdsa-curve string ECDSA curve to use to generate a key. Valid values are P224, P256 (recommended), P384, P521
|
|
||||||
--ed25519 Generate an Ed25519 key
|
|
||||||
-h, --help help for generate
|
|
||||||
--rsa-bits int Size of RSA key to generate. Ignored if --ecdsa-curve is set (default 2048)
|
|
||||||
--start-date string Creation date formatted as Jan 1 15:04:05 2011
|
|
||||||
```
|
|
||||||
|
|
||||||
### Options inherited from parent commands
|
|
||||||
|
|
||||||
```
|
|
||||||
--host strings Comma-separated hostnames and IPs to generate a certificate for
|
|
||||||
```
|
|
||||||
|
|
||||||
### SEE ALSO
|
|
||||||
|
|
||||||
* [authelia certificates](authelia_certificates.md) - Commands related to certificate generation
|
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto"
|
||||||
|
description: "Reference for the authelia crypto command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto
|
||||||
|
|
||||||
|
Perform cryptographic operations
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Perform cryptographic operations.
|
||||||
|
|
||||||
|
This subcommand allows preforming cryptographic certificate, key pair, etc tasks.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help help for crypto
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia](authelia.md) - authelia untagged-unknown-dirty (master, unknown)
|
||||||
|
* [authelia crypto certificate](authelia_crypto_certificate.md) - Perform certificate cryptographic operations
|
||||||
|
* [authelia crypto pair](authelia_crypto_pair.md) - Perform key pair cryptographic operations
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,44 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto certificate"
|
||||||
|
description: "Reference for the authelia crypto certificate command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto certificate
|
||||||
|
|
||||||
|
Perform certificate cryptographic operations
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Perform certificate cryptographic operations.
|
||||||
|
|
||||||
|
This subcommand allows preforming certificate cryptographic tasks.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help help for certificate
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto](authelia_crypto.md) - Perform cryptographic operations
|
||||||
|
* [authelia crypto certificate ecdsa](authelia_crypto_certificate_ecdsa.md) - Perform ECDSA certificate cryptographic operations
|
||||||
|
* [authelia crypto certificate ed25519](authelia_crypto_certificate_ed25519.md) - Perform Ed25519 certificate cryptographic operations
|
||||||
|
* [authelia crypto certificate rsa](authelia_crypto_certificate_rsa.md) - Perform RSA certificate cryptographic operations
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,43 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto certificate ecdsa"
|
||||||
|
description: "Reference for the authelia crypto certificate ecdsa command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto certificate ecdsa
|
||||||
|
|
||||||
|
Perform ECDSA certificate cryptographic operations
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Perform ECDSA certificate cryptographic operations.
|
||||||
|
|
||||||
|
This subcommand allows preforming ECDSA certificate cryptographic tasks.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate ecdsa --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help help for ecdsa
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto certificate](authelia_crypto_certificate.md) - Perform certificate cryptographic operations
|
||||||
|
* [authelia crypto certificate ecdsa generate](authelia_crypto_certificate_ecdsa_generate.md) - Generate an ECDSA private key and certificate
|
||||||
|
* [authelia crypto certificate ecdsa request](authelia_crypto_certificate_ecdsa_request.md) - Generate an ECDSA private key and certificate signing request
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto certificate ecdsa generate"
|
||||||
|
description: "Reference for the authelia crypto certificate ecdsa generate command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto certificate ecdsa generate
|
||||||
|
|
||||||
|
Generate an ECDSA private key and certificate
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Generate an ECDSA private key and certificate.
|
||||||
|
|
||||||
|
This subcommand allows generating an ECDSA private key and certificate.
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate ecdsa generate [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate ecdsa generate --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
--ca create the certificate as a certificate authority certificate
|
||||||
|
-c, --common-name string certificate common name
|
||||||
|
--country strings certificate country
|
||||||
|
-b, --curve string Sets the elliptic curve which can be P224, P256, P384, or P521 (default "P256")
|
||||||
|
-d, --directory string directory where the generated keys, certificates, etc will be stored
|
||||||
|
--duration duration duration of time the certificate is valid for (default 8760h0m0s)
|
||||||
|
--extended-usage strings specify the extended usage types of the certificate
|
||||||
|
--file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt")
|
||||||
|
--file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem")
|
||||||
|
--file.certificate string name of the file to export the certificate data to (default "public.crt")
|
||||||
|
--file.private-key string name of the file to export the private key data to (default "private.pem")
|
||||||
|
-h, --help help for generate
|
||||||
|
-l, --locality strings certificate locality
|
||||||
|
--not-before string earliest date and time the certificate is considered valid formatted as Jan 2 15:04:05 2006 (default is now)
|
||||||
|
-o, --organization strings certificate organization (default [Authelia])
|
||||||
|
--organizational-unit strings certificate organizational unit
|
||||||
|
--path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed
|
||||||
|
-p, --postcode strings certificate postcode
|
||||||
|
--province strings certificate province
|
||||||
|
--sans strings subject alternative names
|
||||||
|
--signature string signature algorithm for the certificate (default "SHA256")
|
||||||
|
-s, --street-address strings certificate street address
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto certificate ecdsa](authelia_crypto_certificate_ecdsa.md) - Perform ECDSA certificate cryptographic operations
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto certificate ecdsa request"
|
||||||
|
description: "Reference for the authelia crypto certificate ecdsa request command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto certificate ecdsa request
|
||||||
|
|
||||||
|
Generate an ECDSA private key and certificate signing request
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Generate an ECDSA private key and certificate signing request.
|
||||||
|
|
||||||
|
This subcommand allows generating an ECDSA private key and certificate signing request.
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate ecdsa request [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate ecdsa request --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-c, --common-name string certificate common name
|
||||||
|
--country strings certificate country
|
||||||
|
-b, --curve string Sets the elliptic curve which can be P224, P256, P384, or P521 (default "P256")
|
||||||
|
-d, --directory string directory where the generated keys, certificates, etc will be stored
|
||||||
|
--duration duration duration of time the certificate is valid for (default 8760h0m0s)
|
||||||
|
--file.csr string name of the file to export the certificate request data to (default "request.csr")
|
||||||
|
--file.private-key string name of the file to export the private key data to (default "private.pem")
|
||||||
|
-h, --help help for request
|
||||||
|
-l, --locality strings certificate locality
|
||||||
|
--not-before string earliest date and time the certificate is considered valid formatted as Jan 2 15:04:05 2006 (default is now)
|
||||||
|
-o, --organization strings certificate organization (default [Authelia])
|
||||||
|
--organizational-unit strings certificate organizational unit
|
||||||
|
-p, --postcode strings certificate postcode
|
||||||
|
--province strings certificate province
|
||||||
|
--sans strings subject alternative names
|
||||||
|
--signature string signature algorithm for the certificate (default "SHA256")
|
||||||
|
-s, --street-address strings certificate street address
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto certificate ecdsa](authelia_crypto_certificate_ecdsa.md) - Perform ECDSA certificate cryptographic operations
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,43 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto certificate ed25519"
|
||||||
|
description: "Reference for the authelia crypto certificate ed25519 command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto certificate ed25519
|
||||||
|
|
||||||
|
Perform Ed25519 certificate cryptographic operations
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Perform Ed25519 certificate cryptographic operations.
|
||||||
|
|
||||||
|
This subcommand allows preforming Ed25519 certificate cryptographic tasks.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate ed25519 --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help help for ed25519
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto certificate](authelia_crypto_certificate.md) - Perform certificate cryptographic operations
|
||||||
|
* [authelia crypto certificate ed25519 generate](authelia_crypto_certificate_ed25519_generate.md) - Generate an Ed25519 private key and certificate
|
||||||
|
* [authelia crypto certificate ed25519 request](authelia_crypto_certificate_ed25519_request.md) - Generate an Ed25519 private key and certificate signing request
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,65 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto certificate ed25519 generate"
|
||||||
|
description: "Reference for the authelia crypto certificate ed25519 generate command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto certificate ed25519 generate
|
||||||
|
|
||||||
|
Generate an Ed25519 private key and certificate
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Generate an Ed25519 private key and certificate.
|
||||||
|
|
||||||
|
This subcommand allows generating an Ed25519 private key and certificate.
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate ed25519 generate [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate ed25519 request --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
--ca create the certificate as a certificate authority certificate
|
||||||
|
-c, --common-name string certificate common name
|
||||||
|
--country strings certificate country
|
||||||
|
-d, --directory string directory where the generated keys, certificates, etc will be stored
|
||||||
|
--duration duration duration of time the certificate is valid for (default 8760h0m0s)
|
||||||
|
--extended-usage strings specify the extended usage types of the certificate
|
||||||
|
--file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt")
|
||||||
|
--file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem")
|
||||||
|
--file.certificate string name of the file to export the certificate data to (default "public.crt")
|
||||||
|
--file.private-key string name of the file to export the private key data to (default "private.pem")
|
||||||
|
-h, --help help for generate
|
||||||
|
-l, --locality strings certificate locality
|
||||||
|
--not-before string earliest date and time the certificate is considered valid formatted as Jan 2 15:04:05 2006 (default is now)
|
||||||
|
-o, --organization strings certificate organization (default [Authelia])
|
||||||
|
--organizational-unit strings certificate organizational unit
|
||||||
|
--path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed
|
||||||
|
-p, --postcode strings certificate postcode
|
||||||
|
--province strings certificate province
|
||||||
|
--sans strings subject alternative names
|
||||||
|
--signature string signature algorithm for the certificate (default "SHA256")
|
||||||
|
-s, --street-address strings certificate street address
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto certificate ed25519](authelia_crypto_certificate_ed25519.md) - Perform Ed25519 certificate cryptographic operations
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,60 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto certificate ed25519 request"
|
||||||
|
description: "Reference for the authelia crypto certificate ed25519 request command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto certificate ed25519 request
|
||||||
|
|
||||||
|
Generate an Ed25519 private key and certificate signing request
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Generate an Ed25519 private key and certificate signing request.
|
||||||
|
|
||||||
|
This subcommand allows generating an Ed25519 private key and certificate signing request.
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate ed25519 request [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate ed25519 request --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-c, --common-name string certificate common name
|
||||||
|
--country strings certificate country
|
||||||
|
-d, --directory string directory where the generated keys, certificates, etc will be stored
|
||||||
|
--duration duration duration of time the certificate is valid for (default 8760h0m0s)
|
||||||
|
--file.csr string name of the file to export the certificate request data to (default "request.csr")
|
||||||
|
--file.private-key string name of the file to export the private key data to (default "private.pem")
|
||||||
|
-h, --help help for request
|
||||||
|
-l, --locality strings certificate locality
|
||||||
|
--not-before string earliest date and time the certificate is considered valid formatted as Jan 2 15:04:05 2006 (default is now)
|
||||||
|
-o, --organization strings certificate organization (default [Authelia])
|
||||||
|
--organizational-unit strings certificate organizational unit
|
||||||
|
-p, --postcode strings certificate postcode
|
||||||
|
--province strings certificate province
|
||||||
|
--sans strings subject alternative names
|
||||||
|
--signature string signature algorithm for the certificate (default "SHA256")
|
||||||
|
-s, --street-address strings certificate street address
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto certificate ed25519](authelia_crypto_certificate_ed25519.md) - Perform Ed25519 certificate cryptographic operations
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,43 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto certificate rsa"
|
||||||
|
description: "Reference for the authelia crypto certificate rsa command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto certificate rsa
|
||||||
|
|
||||||
|
Perform RSA certificate cryptographic operations
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Perform RSA certificate cryptographic operations.
|
||||||
|
|
||||||
|
This subcommand allows preforming RSA certificate cryptographic tasks.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate rsa --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help help for rsa
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto certificate](authelia_crypto_certificate.md) - Perform certificate cryptographic operations
|
||||||
|
* [authelia crypto certificate rsa generate](authelia_crypto_certificate_rsa_generate.md) - Generate an RSA private key and certificate
|
||||||
|
* [authelia crypto certificate rsa request](authelia_crypto_certificate_rsa_request.md) - Generate an RSA private key and certificate signing request
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto certificate rsa generate"
|
||||||
|
description: "Reference for the authelia crypto certificate rsa generate command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto certificate rsa generate
|
||||||
|
|
||||||
|
Generate an RSA private key and certificate
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Generate an RSA private key and certificate.
|
||||||
|
|
||||||
|
This subcommand allows generating an RSA private key and certificate.
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate rsa generate [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate rsa generate --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-b, --bits int number of RSA bits for the certificate (default 2048)
|
||||||
|
--ca create the certificate as a certificate authority certificate
|
||||||
|
-c, --common-name string certificate common name
|
||||||
|
--country strings certificate country
|
||||||
|
-d, --directory string directory where the generated keys, certificates, etc will be stored
|
||||||
|
--duration duration duration of time the certificate is valid for (default 8760h0m0s)
|
||||||
|
--extended-usage strings specify the extended usage types of the certificate
|
||||||
|
--file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt")
|
||||||
|
--file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem")
|
||||||
|
--file.certificate string name of the file to export the certificate data to (default "public.crt")
|
||||||
|
--file.private-key string name of the file to export the private key data to (default "private.pem")
|
||||||
|
-h, --help help for generate
|
||||||
|
-l, --locality strings certificate locality
|
||||||
|
--not-before string earliest date and time the certificate is considered valid formatted as Jan 2 15:04:05 2006 (default is now)
|
||||||
|
-o, --organization strings certificate organization (default [Authelia])
|
||||||
|
--organizational-unit strings certificate organizational unit
|
||||||
|
--path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed
|
||||||
|
-p, --postcode strings certificate postcode
|
||||||
|
--province strings certificate province
|
||||||
|
--sans strings subject alternative names
|
||||||
|
--signature string signature algorithm for the certificate (default "SHA256")
|
||||||
|
-s, --street-address strings certificate street address
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto certificate rsa](authelia_crypto_certificate_rsa.md) - Perform RSA certificate cryptographic operations
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto certificate rsa request"
|
||||||
|
description: "Reference for the authelia crypto certificate rsa request command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto certificate rsa request
|
||||||
|
|
||||||
|
Generate an RSA private key and certificate signing request
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Generate an RSA private key and certificate signing request.
|
||||||
|
|
||||||
|
This subcommand allows generating an RSA private key and certificate signing request.
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate rsa request [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto certificate rsa request --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-b, --bits int number of RSA bits for the certificate (default 2048)
|
||||||
|
-c, --common-name string certificate common name
|
||||||
|
--country strings certificate country
|
||||||
|
-d, --directory string directory where the generated keys, certificates, etc will be stored
|
||||||
|
--duration duration duration of time the certificate is valid for (default 8760h0m0s)
|
||||||
|
--file.csr string name of the file to export the certificate request data to (default "request.csr")
|
||||||
|
--file.private-key string name of the file to export the private key data to (default "private.pem")
|
||||||
|
-h, --help help for request
|
||||||
|
-l, --locality strings certificate locality
|
||||||
|
--not-before string earliest date and time the certificate is considered valid formatted as Jan 2 15:04:05 2006 (default is now)
|
||||||
|
-o, --organization strings certificate organization (default [Authelia])
|
||||||
|
--organizational-unit strings certificate organizational unit
|
||||||
|
-p, --postcode strings certificate postcode
|
||||||
|
--province strings certificate province
|
||||||
|
--sans strings subject alternative names
|
||||||
|
--signature string signature algorithm for the certificate (default "SHA256")
|
||||||
|
-s, --street-address strings certificate street address
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto certificate rsa](authelia_crypto_certificate_rsa.md) - Perform RSA certificate cryptographic operations
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,44 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto pair"
|
||||||
|
description: "Reference for the authelia crypto pair command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto pair
|
||||||
|
|
||||||
|
Perform key pair cryptographic operations
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Perform key pair cryptographic operations.
|
||||||
|
|
||||||
|
This subcommand allows preforming key pair cryptographic tasks.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help help for pair
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto](authelia_crypto.md) - Perform cryptographic operations
|
||||||
|
* [authelia crypto pair ecdsa](authelia_crypto_pair_ecdsa.md) - Perform ECDSA key pair cryptographic operations
|
||||||
|
* [authelia crypto pair ed25519](authelia_crypto_pair_ed25519.md) - Perform Ed25519 key pair cryptographic operations
|
||||||
|
* [authelia crypto pair rsa](authelia_crypto_pair_rsa.md) - Perform RSA key pair cryptographic operations
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto pair ecdsa"
|
||||||
|
description: "Reference for the authelia crypto pair ecdsa command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto pair ecdsa
|
||||||
|
|
||||||
|
Perform ECDSA key pair cryptographic operations
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Perform ECDSA key pair cryptographic operations.
|
||||||
|
|
||||||
|
This subcommand allows preforming ECDSA key pair cryptographic tasks.
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair ecdsa [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair ecdsa --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help help for ecdsa
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto pair](authelia_crypto_pair.md) - Perform key pair cryptographic operations
|
||||||
|
* [authelia crypto pair ecdsa generate](authelia_crypto_pair_ecdsa_generate.md) - Generate a cryptographic ECDSA key pair
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,50 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto pair ecdsa generate"
|
||||||
|
description: "Reference for the authelia crypto pair ecdsa generate command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto pair ecdsa generate
|
||||||
|
|
||||||
|
Generate a cryptographic ECDSA key pair
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Generate a cryptographic ECDSA key pair.
|
||||||
|
|
||||||
|
This subcommand allows generating an ECDSA key pair.
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair ecdsa generate [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair ecdsa generate --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-b, --curve string Sets the elliptic curve which can be P224, P256, P384, or P521 (default "P256")
|
||||||
|
-d, --directory string directory where the generated keys, certificates, etc will be stored
|
||||||
|
--file.private-key string name of the file to export the private key data to (default "private.pem")
|
||||||
|
--file.public-key string name of the file to export the public key data to (default "public.pem")
|
||||||
|
-h, --help help for generate
|
||||||
|
--pkcs8 force PKCS #8 ASN.1 format
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto pair ecdsa](authelia_crypto_pair_ecdsa.md) - Perform ECDSA key pair cryptographic operations
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto pair ed25519"
|
||||||
|
description: "Reference for the authelia crypto pair ed25519 command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto pair ed25519
|
||||||
|
|
||||||
|
Perform Ed25519 key pair cryptographic operations
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Perform Ed25519 key pair cryptographic operations.
|
||||||
|
|
||||||
|
This subcommand allows preforming Ed25519 key pair cryptographic tasks.
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair ed25519 [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair ed25519 --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help help for ed25519
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto pair](authelia_crypto_pair.md) - Perform key pair cryptographic operations
|
||||||
|
* [authelia crypto pair ed25519 generate](authelia_crypto_pair_ed25519_generate.md) - Generate a cryptographic Ed25519 key pair
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,49 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto pair ed25519 generate"
|
||||||
|
description: "Reference for the authelia crypto pair ed25519 generate command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto pair ed25519 generate
|
||||||
|
|
||||||
|
Generate a cryptographic Ed25519 key pair
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Generate a cryptographic Ed25519 key pair.
|
||||||
|
|
||||||
|
This subcommand allows generating an Ed25519 key pair.
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair ed25519 generate [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair ed25519 generate --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-d, --directory string directory where the generated keys, certificates, etc will be stored
|
||||||
|
--file.private-key string name of the file to export the private key data to (default "private.pem")
|
||||||
|
--file.public-key string name of the file to export the public key data to (default "public.pem")
|
||||||
|
-h, --help help for generate
|
||||||
|
--pkcs8 force PKCS #8 ASN.1 format
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto pair ed25519](authelia_crypto_pair_ed25519.md) - Perform Ed25519 key pair cryptographic operations
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto pair rsa"
|
||||||
|
description: "Reference for the authelia crypto pair rsa command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto pair rsa
|
||||||
|
|
||||||
|
Perform RSA key pair cryptographic operations
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Perform RSA key pair cryptographic operations.
|
||||||
|
|
||||||
|
This subcommand allows preforming RSA key pair cryptographic tasks.
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair rsa [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair rsa --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help help for rsa
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto pair](authelia_crypto_pair.md) - Perform key pair cryptographic operations
|
||||||
|
* [authelia crypto pair rsa generate](authelia_crypto_pair_rsa_generate.md) - Generate a cryptographic RSA key pair
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -0,0 +1,50 @@
|
||||||
|
---
|
||||||
|
title: "authelia crypto pair rsa generate"
|
||||||
|
description: "Reference for the authelia crypto pair rsa generate command."
|
||||||
|
lead: ""
|
||||||
|
date: 2022-06-27T12:16:00+10:00
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli-authelia"
|
||||||
|
weight: 330
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## authelia crypto pair rsa generate
|
||||||
|
|
||||||
|
Generate a cryptographic RSA key pair
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
Generate a cryptographic RSA key pair.
|
||||||
|
|
||||||
|
This subcommand allows generating an RSA key pair.
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair rsa generate [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
authelia crypto pair rsa generate --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-b, --bits int number of RSA bits for the certificate (default 2048)
|
||||||
|
-d, --directory string directory where the generated keys, certificates, etc will be stored
|
||||||
|
--file.private-key string name of the file to export the private key data to (default "private.pem")
|
||||||
|
--file.public-key string name of the file to export the public key data to (default "public.pem")
|
||||||
|
-h, --help help for generate
|
||||||
|
--pkcs8 force PKCS #8 ASN.1 format
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [authelia crypto pair rsa](authelia_crypto_pair_rsa.md) - Perform RSA key pair cryptographic operations
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia hash-password"
|
title: "authelia hash-password"
|
||||||
description: "Reference for the authelia hash-password command."
|
description: "Reference for the authelia hash-password command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -14,7 +14,7 @@ toc: true
|
||||||
|
|
||||||
## authelia hash-password
|
## authelia hash-password
|
||||||
|
|
||||||
Hash a password to be used in file-based users database.
|
Hash a password to be used in file-based users database
|
||||||
|
|
||||||
### Synopsis
|
### Synopsis
|
||||||
|
|
||||||
|
@ -53,4 +53,4 @@ authelia hash-password --key-length=64 -- 'mypass'
|
||||||
|
|
||||||
* [authelia](authelia.md) - authelia untagged-unknown-dirty (master, unknown)
|
* [authelia](authelia.md) - authelia untagged-unknown-dirty (master, unknown)
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
---
|
|
||||||
title: "authelia rsa"
|
|
||||||
description: "Reference for the authelia rsa command."
|
|
||||||
lead: ""
|
|
||||||
date: 2022-05-31T11:13:56+10:00
|
|
||||||
draft: false
|
|
||||||
images: []
|
|
||||||
menu:
|
|
||||||
reference:
|
|
||||||
parent: "cli-authelia"
|
|
||||||
weight: 330
|
|
||||||
toc: true
|
|
||||||
---
|
|
||||||
|
|
||||||
## authelia rsa
|
|
||||||
|
|
||||||
Commands related to rsa keypair generation
|
|
||||||
|
|
||||||
### Synopsis
|
|
||||||
|
|
||||||
Commands related to rsa keypair generation.
|
|
||||||
|
|
||||||
This subcommand allows performing RSA keypair tasks.
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
```
|
|
||||||
authelia rsa --help
|
|
||||||
```
|
|
||||||
|
|
||||||
### Options
|
|
||||||
|
|
||||||
```
|
|
||||||
-h, --help help for rsa
|
|
||||||
```
|
|
||||||
|
|
||||||
### SEE ALSO
|
|
||||||
|
|
||||||
* [authelia](authelia.md) - authelia untagged-unknown-dirty (master, unknown)
|
|
||||||
* [authelia rsa generate](authelia_rsa_generate.md) - Generate a RSA keypair
|
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
|
|
@ -1,48 +0,0 @@
|
||||||
---
|
|
||||||
title: "authelia rsa generate"
|
|
||||||
description: "Reference for the authelia rsa generate command."
|
|
||||||
lead: ""
|
|
||||||
date: 2022-05-31T11:13:56+10:00
|
|
||||||
draft: false
|
|
||||||
images: []
|
|
||||||
menu:
|
|
||||||
reference:
|
|
||||||
parent: "cli-authelia"
|
|
||||||
weight: 330
|
|
||||||
toc: true
|
|
||||||
---
|
|
||||||
|
|
||||||
## authelia rsa generate
|
|
||||||
|
|
||||||
Generate a RSA keypair
|
|
||||||
|
|
||||||
### Synopsis
|
|
||||||
|
|
||||||
Generate a RSA keypair.
|
|
||||||
|
|
||||||
This subcommand allows generating an RSA keypair.
|
|
||||||
|
|
||||||
```
|
|
||||||
authelia rsa generate [flags]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
```
|
|
||||||
authelia rsa generate
|
|
||||||
authelia rsa generate --dir ./out
|
|
||||||
```
|
|
||||||
|
|
||||||
### Options
|
|
||||||
|
|
||||||
```
|
|
||||||
-d, --dir string Target directory where the keypair will be stored
|
|
||||||
-h, --help help for generate
|
|
||||||
-b, --key-size int Sets the key size in bits (default 2048)
|
|
||||||
```
|
|
||||||
|
|
||||||
### SEE ALSO
|
|
||||||
|
|
||||||
* [authelia rsa](authelia_rsa.md) - Commands related to rsa keypair generation
|
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage"
|
title: "authelia storage"
|
||||||
description: "Reference for the authelia storage command."
|
description: "Reference for the authelia storage command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -62,4 +62,4 @@ authelia storage --help
|
||||||
* [authelia storage schema-info](authelia_storage_schema-info.md) - Show the storage information
|
* [authelia storage schema-info](authelia_storage_schema-info.md) - Show the storage information
|
||||||
* [authelia storage user](authelia_storage_user.md) - Manages user settings
|
* [authelia storage user](authelia_storage_user.md) - Manages user settings
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage encryption"
|
title: "authelia storage encryption"
|
||||||
description: "Reference for the authelia storage encryption command."
|
description: "Reference for the authelia storage encryption command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -63,4 +63,4 @@ authelia storage encryption --help
|
||||||
* [authelia storage encryption change-key](authelia_storage_encryption_change-key.md) - Changes the encryption key
|
* [authelia storage encryption change-key](authelia_storage_encryption_change-key.md) - Changes the encryption key
|
||||||
* [authelia storage encryption check](authelia_storage_encryption_check.md) - Checks the encryption key against the database data
|
* [authelia storage encryption check](authelia_storage_encryption_check.md) - Checks the encryption key against the database data
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage encryption change-key"
|
title: "authelia storage encryption change-key"
|
||||||
description: "Reference for the authelia storage encryption change-key command."
|
description: "Reference for the authelia storage encryption change-key command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -67,4 +67,4 @@ authelia storage encryption change-key --encryption-key b3453fde-ecc2-4a1f-9422-
|
||||||
|
|
||||||
* [authelia storage encryption](authelia_storage_encryption.md) - Manage storage encryption
|
* [authelia storage encryption](authelia_storage_encryption.md) - Manage storage encryption
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage encryption check"
|
title: "authelia storage encryption check"
|
||||||
description: "Reference for the authelia storage encryption check command."
|
description: "Reference for the authelia storage encryption check command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -69,4 +69,4 @@ authelia storage encryption check --verbose --encryption-key b3453fde-ecc2-4a1f-
|
||||||
|
|
||||||
* [authelia storage encryption](authelia_storage_encryption.md) - Manage storage encryption
|
* [authelia storage encryption](authelia_storage_encryption.md) - Manage storage encryption
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage migrate"
|
title: "authelia storage migrate"
|
||||||
description: "Reference for the authelia storage migrate command."
|
description: "Reference for the authelia storage migrate command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -66,4 +66,4 @@ authelia storage migrate --help
|
||||||
* [authelia storage migrate list-up](authelia_storage_migrate_list-up.md) - List the up migrations available
|
* [authelia storage migrate list-up](authelia_storage_migrate_list-up.md) - List the up migrations available
|
||||||
* [authelia storage migrate up](authelia_storage_migrate_up.md) - Perform a migration up
|
* [authelia storage migrate up](authelia_storage_migrate_up.md) - Perform a migration up
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage migrate down"
|
title: "authelia storage migrate down"
|
||||||
description: "Reference for the authelia storage migrate down command."
|
description: "Reference for the authelia storage migrate down command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -71,4 +71,4 @@ authelia storage migrate down --target 20 --encryption-key b3453fde-ecc2-4a1f-94
|
||||||
|
|
||||||
* [authelia storage migrate](authelia_storage_migrate.md) - Perform or list migrations
|
* [authelia storage migrate](authelia_storage_migrate.md) - Perform or list migrations
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage migrate history"
|
title: "authelia storage migrate history"
|
||||||
description: "Reference for the authelia storage migrate history command."
|
description: "Reference for the authelia storage migrate history command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -67,4 +67,4 @@ authelia storage migrate history --encryption-key b3453fde-ecc2-4a1f-9422-2707dd
|
||||||
|
|
||||||
* [authelia storage migrate](authelia_storage_migrate.md) - Perform or list migrations
|
* [authelia storage migrate](authelia_storage_migrate.md) - Perform or list migrations
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage migrate list-down"
|
title: "authelia storage migrate list-down"
|
||||||
description: "Reference for the authelia storage migrate list-down command."
|
description: "Reference for the authelia storage migrate list-down command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -68,4 +68,4 @@ authelia storage migrate list-down --encryption-key b3453fde-ecc2-4a1f-9422-2707
|
||||||
|
|
||||||
* [authelia storage migrate](authelia_storage_migrate.md) - Perform or list migrations
|
* [authelia storage migrate](authelia_storage_migrate.md) - Perform or list migrations
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage migrate list-up"
|
title: "authelia storage migrate list-up"
|
||||||
description: "Reference for the authelia storage migrate list-up command."
|
description: "Reference for the authelia storage migrate list-up command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -68,4 +68,4 @@ authelia storage migrate list-up --encryption-key b3453fde-ecc2-4a1f-9422-2707dd
|
||||||
|
|
||||||
* [authelia storage migrate](authelia_storage_migrate.md) - Perform or list migrations
|
* [authelia storage migrate](authelia_storage_migrate.md) - Perform or list migrations
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage migrate up"
|
title: "authelia storage migrate up"
|
||||||
description: "Reference for the authelia storage migrate up command."
|
description: "Reference for the authelia storage migrate up command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -70,4 +70,4 @@ authelia storage migrate up --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed49
|
||||||
|
|
||||||
* [authelia storage migrate](authelia_storage_migrate.md) - Perform or list migrations
|
* [authelia storage migrate](authelia_storage_migrate.md) - Perform or list migrations
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage schema-info"
|
title: "authelia storage schema-info"
|
||||||
description: "Reference for the authelia storage schema-info command."
|
description: "Reference for the authelia storage schema-info command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -67,4 +67,4 @@ authelia storage schema-info --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed4
|
||||||
|
|
||||||
* [authelia storage](authelia_storage.md) - Manage the Authelia storage
|
* [authelia storage](authelia_storage.md) - Manage the Authelia storage
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage user"
|
title: "authelia storage user"
|
||||||
description: "Reference for the authelia storage user command."
|
description: "Reference for the authelia storage user command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -63,4 +63,4 @@ authelia storage user --help
|
||||||
* [authelia storage user identifiers](authelia_storage_user_identifiers.md) - Manage user opaque identifiers
|
* [authelia storage user identifiers](authelia_storage_user_identifiers.md) - Manage user opaque identifiers
|
||||||
* [authelia storage user totp](authelia_storage_user_totp.md) - Manage TOTP configurations
|
* [authelia storage user totp](authelia_storage_user_totp.md) - Manage TOTP configurations
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage user identifiers"
|
title: "authelia storage user identifiers"
|
||||||
description: "Reference for the authelia storage user identifiers command."
|
description: "Reference for the authelia storage user identifiers command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -65,4 +65,4 @@ authelia storage user identifiers --help
|
||||||
* [authelia storage user identifiers generate](authelia_storage_user_identifiers_generate.md) - Generate opaque identifiers in bulk
|
* [authelia storage user identifiers generate](authelia_storage_user_identifiers_generate.md) - Generate opaque identifiers in bulk
|
||||||
* [authelia storage user identifiers import](authelia_storage_user_identifiers_import.md) - Import the identifiers from a YAML file
|
* [authelia storage user identifiers import](authelia_storage_user_identifiers_import.md) - Import the identifiers from a YAML file
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage user identifiers add"
|
title: "authelia storage user identifiers add"
|
||||||
description: "Reference for the authelia storage user identifiers add command."
|
description: "Reference for the authelia storage user identifiers add command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -70,4 +70,4 @@ authelia storage user identifiers add john --identifier f0919359-9d15-4e15-bcba-
|
||||||
|
|
||||||
* [authelia storage user identifiers](authelia_storage_user_identifiers.md) - Manage user opaque identifiers
|
* [authelia storage user identifiers](authelia_storage_user_identifiers.md) - Manage user opaque identifiers
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage user identifiers export"
|
title: "authelia storage user identifiers export"
|
||||||
description: "Reference for the authelia storage user identifiers export command."
|
description: "Reference for the authelia storage user identifiers export command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -69,4 +69,4 @@ authelia storage user identifiers export --file export.yaml --encryption-key b34
|
||||||
|
|
||||||
* [authelia storage user identifiers](authelia_storage_user_identifiers.md) - Manage user opaque identifiers
|
* [authelia storage user identifiers](authelia_storage_user_identifiers.md) - Manage user opaque identifiers
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage user identifiers generate"
|
title: "authelia storage user identifiers generate"
|
||||||
description: "Reference for the authelia storage user identifiers generate command."
|
description: "Reference for the authelia storage user identifiers generate command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -72,4 +72,4 @@ authelia storage user identifiers generate --users john,mary --services openid -
|
||||||
|
|
||||||
* [authelia storage user identifiers](authelia_storage_user_identifiers.md) - Manage user opaque identifiers
|
* [authelia storage user identifiers](authelia_storage_user_identifiers.md) - Manage user opaque identifiers
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage user identifiers import"
|
title: "authelia storage user identifiers import"
|
||||||
description: "Reference for the authelia storage user identifiers import command."
|
description: "Reference for the authelia storage user identifiers import command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -72,4 +72,4 @@ authelia storage user identifiers import --file export.yaml --encryption-key b34
|
||||||
|
|
||||||
* [authelia storage user identifiers](authelia_storage_user_identifiers.md) - Manage user opaque identifiers
|
* [authelia storage user identifiers](authelia_storage_user_identifiers.md) - Manage user opaque identifiers
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage user totp"
|
title: "authelia storage user totp"
|
||||||
description: "Reference for the authelia storage user totp command."
|
description: "Reference for the authelia storage user totp command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -64,4 +64,4 @@ authelia storage user totp --help
|
||||||
* [authelia storage user totp export](authelia_storage_user_totp_export.md) - Perform exports of the TOTP configurations
|
* [authelia storage user totp export](authelia_storage_user_totp_export.md) - Perform exports of the TOTP configurations
|
||||||
* [authelia storage user totp generate](authelia_storage_user_totp_generate.md) - Generate a TOTP configuration for a user
|
* [authelia storage user totp generate](authelia_storage_user_totp_generate.md) - Generate a TOTP configuration for a user
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage user totp delete"
|
title: "authelia storage user totp delete"
|
||||||
description: "Reference for the authelia storage user totp delete command."
|
description: "Reference for the authelia storage user totp delete command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -67,4 +67,4 @@ authelia storage user totp delete john --encryption-key b3453fde-ecc2-4a1f-9422-
|
||||||
|
|
||||||
* [authelia storage user totp](authelia_storage_user_totp.md) - Manage TOTP configurations
|
* [authelia storage user totp](authelia_storage_user_totp.md) - Manage TOTP configurations
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage user totp export"
|
title: "authelia storage user totp export"
|
||||||
description: "Reference for the authelia storage user totp export command."
|
description: "Reference for the authelia storage user totp export command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -70,4 +70,4 @@ authelia storage user totp export --format png --dir ./totp-qr --encryption-key
|
||||||
|
|
||||||
* [authelia storage user totp](authelia_storage_user_totp.md) - Manage TOTP configurations
|
* [authelia storage user totp](authelia_storage_user_totp.md) - Manage TOTP configurations
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia storage user totp generate"
|
title: "authelia storage user totp generate"
|
||||||
description: "Reference for the authelia storage user totp generate command."
|
description: "Reference for the authelia storage user totp generate command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -79,4 +79,4 @@ authelia storage user totp generate john --algorithm SHA512 --config config.yml
|
||||||
|
|
||||||
* [authelia storage user totp](authelia_storage_user_totp.md) - Manage TOTP configurations
|
* [authelia storage user totp](authelia_storage_user_totp.md) - Manage TOTP configurations
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "authelia validate-config"
|
title: "authelia validate-config"
|
||||||
description: "Reference for the authelia validate-config command."
|
description: "Reference for the authelia validate-config command."
|
||||||
lead: ""
|
lead: ""
|
||||||
date: 2022-05-31T11:13:56+10:00
|
date: 2022-06-15T17:51:47+10:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
@ -45,4 +45,4 @@ authelia validate-config --config config.yml
|
||||||
|
|
||||||
* [authelia](authelia.md) - authelia untagged-unknown-dirty (master, unknown)
|
* [authelia](authelia.md) - authelia untagged-unknown-dirty (master, unknown)
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 13-Jun-2022
|
###### Auto generated by spf13/cobra on 27-Jun-2022
|
||||||
|
|
|
@ -60,7 +60,7 @@ if [[ $MODIFIED == "false" ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Generating SSL certificate for *.$DOMAIN"
|
echo "Generating SSL certificate for *.$DOMAIN"
|
||||||
sudo docker run -a stdout -v $PWD/traefik/certs:/tmp/certs authelia/authelia authelia certificates generate --host *.$DOMAIN --dir /tmp/certs/ > /dev/null
|
sudo docker run -a stdout -v $PWD/traefik/certs:/tmp/certs authelia/authelia authelia crypto certificate rsa generate --common-name="*.${DOMAIN}" --directory=/tmp/certs/ > /dev/null
|
||||||
|
|
||||||
if [[ $DOMAIN != "example.com" ]]; then
|
if [[ $DOMAIN != "example.com" ]]; then
|
||||||
if [[ $(uname) == "Darwin" ]]; then
|
if [[ $(uname) == "Darwin" ]]; then
|
||||||
|
|
|
@ -1,169 +0,0 @@
|
||||||
package commands
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/elliptic"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func newCertificatesCmd() (cmd *cobra.Command) {
|
|
||||||
cmd = &cobra.Command{
|
|
||||||
Use: "certificates",
|
|
||||||
Short: cmdAutheliaCertificatesShort,
|
|
||||||
Long: cmdAutheliaCertificatesLong,
|
|
||||||
Example: cmdAutheliaCertificatesExample,
|
|
||||||
Args: cobra.NoArgs,
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.PersistentFlags().StringSlice("host", []string{}, "Comma-separated hostnames and IPs to generate a certificate for")
|
|
||||||
|
|
||||||
err := cmd.MarkPersistentFlagRequired("host")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.AddCommand(newCertificatesGenerateCmd())
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func newCertificatesGenerateCmd() (cmd *cobra.Command) {
|
|
||||||
cmd = &cobra.Command{
|
|
||||||
Use: "generate",
|
|
||||||
Short: cmdAutheliaCertificatesGenerateShort,
|
|
||||||
Long: cmdAutheliaCertificatesGenerateLong,
|
|
||||||
Example: cmdAutheliaCertificatesGenerateExample,
|
|
||||||
Args: cobra.NoArgs,
|
|
||||||
Run: cmdCertificatesGenerateRun,
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Flags().String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011")
|
|
||||||
cmd.Flags().Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for")
|
|
||||||
cmd.Flags().Bool("ca", false, "Whether this cert should be its own Certificate Authority")
|
|
||||||
cmd.Flags().Int("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set")
|
|
||||||
cmd.Flags().String("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256 (recommended), P384, P521")
|
|
||||||
cmd.Flags().Bool("ed25519", false, "Generate an Ed25519 key")
|
|
||||||
cmd.Flags().String("dir", "", "Target directory where the certificate and keys will be stored")
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func cmdCertificatesGenerateRun(cmd *cobra.Command, _ []string) {
|
|
||||||
// implementation retrieved from https://golang.org/src/crypto/tls/generate_cert.go
|
|
||||||
ecdsaCurve, err := cmd.Flags().GetString("ecdsa-curve")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to parse ecdsa-curve flag: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
ed25519Key, err := cmd.Flags().GetBool("ed25519")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to parse ed25519 flag: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
rsaBits, err := cmd.Flags().GetInt("rsa-bits")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to parse rsa-bits flag: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
hosts, err := cmd.Flags().GetStringSlice("host")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to parse host flag: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
validFrom, err := cmd.Flags().GetString("start-date")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to parse start-date flag: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
validFor, err := cmd.Flags().GetDuration("duration")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to parse duration flag: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
isCA, err := cmd.Flags().GetBool("ca")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to parse ca flag: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
certificateTargetDirectory, err := cmd.Flags().GetString("dir")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to parse dir flag: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmdCertificatesGenerateRunExtended(hosts, ecdsaCurve, validFrom, certificateTargetDirectory, ed25519Key, isCA, rsaBits, validFor)
|
|
||||||
}
|
|
||||||
|
|
||||||
func cmdCertificatesGenerateRunExtended(hosts []string, ecdsaCurve, validFrom, certificateTargetDirectory string, ed25519Key, isCA bool, rsaBits int, validFor time.Duration) {
|
|
||||||
certPath := filepath.Join(certificateTargetDirectory, "cert.pem")
|
|
||||||
keyPath := filepath.Join(certificateTargetDirectory, "key.pem")
|
|
||||||
|
|
||||||
var (
|
|
||||||
notBefore time.Time
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
switch len(validFrom) {
|
|
||||||
case 0:
|
|
||||||
notBefore = time.Now()
|
|
||||||
default:
|
|
||||||
notBefore, err = time.Parse("Jan 2 15:04:05 2006", validFrom)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to parse start date: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var privateKeyBuilder utils.PrivateKeyBuilder
|
|
||||||
|
|
||||||
switch ecdsaCurve {
|
|
||||||
case "":
|
|
||||||
if ed25519Key {
|
|
||||||
privateKeyBuilder = utils.Ed25519KeyBuilder{}
|
|
||||||
} else {
|
|
||||||
privateKeyBuilder = utils.RSAKeyBuilder{}.WithKeySize(rsaBits)
|
|
||||||
}
|
|
||||||
case "P224":
|
|
||||||
privateKeyBuilder = utils.ECDSAKeyBuilder{}.WithCurve(elliptic.P224())
|
|
||||||
case "P256":
|
|
||||||
privateKeyBuilder = utils.ECDSAKeyBuilder{}.WithCurve(elliptic.P256())
|
|
||||||
case "P384":
|
|
||||||
privateKeyBuilder = utils.ECDSAKeyBuilder{}.WithCurve(elliptic.P384())
|
|
||||||
case "P521":
|
|
||||||
privateKeyBuilder = utils.ECDSAKeyBuilder{}.WithCurve(elliptic.P521())
|
|
||||||
default:
|
|
||||||
log.Fatalf("Failed to generate private key: unrecognized elliptic curve: \"%s\"", ecdsaCurve)
|
|
||||||
}
|
|
||||||
|
|
||||||
certBytes, keyBytes, err := utils.GenerateCertificate(privateKeyBuilder, hosts, notBefore, validFor, isCA)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.WriteFile(certPath, certBytes, 0600)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to write %s for writing: %v", certPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Certificate written to %s\n", certPath)
|
|
||||||
|
|
||||||
err = os.WriteFile(keyPath, keyBytes, 0600)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to write %s for writing: %v", certPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Private Key written to %s\n", keyPath)
|
|
||||||
}
|
|
|
@ -302,41 +302,85 @@ prior to deploying it.`
|
||||||
cmdAutheliaValidateConfigExample = `authelia validate-config
|
cmdAutheliaValidateConfigExample = `authelia validate-config
|
||||||
authelia validate-config --config config.yml`
|
authelia validate-config --config config.yml`
|
||||||
|
|
||||||
cmdAutheliaCertificatesShort = "Commands related to certificate generation"
|
cmdAutheliaCryptoShort = "Perform cryptographic operations"
|
||||||
|
|
||||||
cmdAutheliaCertificatesLong = `Commands related to certificate generation.
|
cmdAutheliaCryptoLong = `Perform cryptographic operations.
|
||||||
|
|
||||||
This subcommand allows preforming X509 certificate tasks.`
|
This subcommand allows preforming cryptographic certificate, key pair, etc tasks.`
|
||||||
|
|
||||||
cmdAutheliaCertificatesExample = `authelia certificates --help`
|
cmdAutheliaCryptoExample = `authelia crypto --help`
|
||||||
|
|
||||||
cmdAutheliaCertificatesGenerateShort = "Generate a self-signed certificate"
|
cmdAutheliaCryptoCertificateShort = "Perform certificate cryptographic operations"
|
||||||
|
|
||||||
cmdAutheliaCertificatesGenerateLong = `Generate a self-signed certificate.
|
cmdAutheliaCryptoCertificateLong = `Perform certificate cryptographic operations.
|
||||||
|
|
||||||
This subcommand allows generating self-signed certificates.`
|
This subcommand allows preforming certificate cryptographic tasks.`
|
||||||
|
|
||||||
cmdAutheliaCertificatesGenerateExample = `authelia certificates generate
|
cmdAutheliaCryptoCertificateExample = `authelia crypto certificate --help`
|
||||||
authelia certificates generate --dir ./out`
|
|
||||||
|
|
||||||
cmdAutheliaRSAShort = "Commands related to rsa keypair generation"
|
fmtCmdAutheliaCryptoCertificateSubShort = "Perform %s certificate cryptographic operations"
|
||||||
|
|
||||||
cmdAutheliaRSALong = `Commands related to rsa keypair generation.
|
fmtCmdAutheliaCryptoCertificateSubLong = `Perform %s certificate cryptographic operations.
|
||||||
|
|
||||||
This subcommand allows performing RSA keypair tasks.`
|
This subcommand allows preforming %s certificate cryptographic tasks.`
|
||||||
|
|
||||||
cmdAutheliaRSAExample = `authelia rsa --help`
|
cmdAutheliaCryptoCertificateRSAExample = `authelia crypto certificate rsa --help`
|
||||||
|
|
||||||
cmdAutheliaRSAGenerateShort = "Generate a RSA keypair"
|
cmdAutheliaCryptoCertificateECDSAExample = `authelia crypto certificate ecdsa --help`
|
||||||
|
|
||||||
cmdAutheliaRSAGenerateLong = `Generate a RSA keypair.
|
cmdAutheliaCryptoCertificateEd25519Example = `authelia crypto certificate ed25519 --help`
|
||||||
|
|
||||||
This subcommand allows generating an RSA keypair.`
|
fmtCmdAutheliaCryptoCertificateGenerateRequestShort = "Generate an %s private key and %s"
|
||||||
|
|
||||||
cmdAutheliaRSAGenerateExample = `authelia rsa generate
|
fmtCmdAutheliaCryptoCertificateGenerateRequestLong = `Generate an %s private key and %s.
|
||||||
authelia rsa generate --dir ./out`
|
|
||||||
|
|
||||||
cmdAutheliaHashPasswordShort = "Hash a password to be used in file-based users database."
|
This subcommand allows generating an %s private key and %s.`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoCertificateRSAGenerateExample = `authelia crypto certificate rsa generate --help`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoCertificateECDSAGenerateExample = `authelia crypto certificate ecdsa generate --help`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoCertificateEd25519GenerateExample = `authelia crypto certificate ed25519 request --help`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoCertificateRSARequestExample = `authelia crypto certificate rsa request --help`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoCertificateECDSARequestExample = `authelia crypto certificate ecdsa request --help`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoCertificateEd25519RequestExample = `authelia crypto certificate ed25519 request --help`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoPairShort = "Perform key pair cryptographic operations"
|
||||||
|
|
||||||
|
cmdAutheliaCryptoPairLong = `Perform key pair cryptographic operations.
|
||||||
|
|
||||||
|
This subcommand allows preforming key pair cryptographic tasks.`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoPairExample = `authelia crypto pair --help`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoPairSubShort = "Perform %s key pair cryptographic operations"
|
||||||
|
|
||||||
|
cmdAutheliaCryptoPairSubLong = `Perform %s key pair cryptographic operations.
|
||||||
|
|
||||||
|
This subcommand allows preforming %s key pair cryptographic tasks.`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoPairRSAExample = `authelia crypto pair rsa --help`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoPairECDSAExample = `authelia crypto pair ecdsa --help`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoPairEd25519Example = `authelia crypto pair ed25519 --help`
|
||||||
|
|
||||||
|
fmtCmdAutheliaCryptoPairGenerateShort = "Generate a cryptographic %s key pair"
|
||||||
|
|
||||||
|
fmtCmdAutheliaCryptoPairGenerateLong = `Generate a cryptographic %s key pair.
|
||||||
|
|
||||||
|
This subcommand allows generating an %s key pair.`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoPairRSAGenerateExample = `authelia crypto pair rsa generate --help`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoPairECDSAGenerateExample = `authelia crypto pair ecdsa generate --help`
|
||||||
|
|
||||||
|
cmdAutheliaCryptoPairEd25519GenerateExample = `authelia crypto pair ed25519 generate --help`
|
||||||
|
|
||||||
|
cmdAutheliaHashPasswordShort = "Hash a password to be used in file-based users database"
|
||||||
|
|
||||||
cmdAutheliaHashPasswordLong = `Hash a password to be used in file-based users database.`
|
cmdAutheliaHashPasswordLong = `Hash a password to be used in file-based users database.`
|
||||||
|
|
||||||
|
@ -364,6 +408,59 @@ var (
|
||||||
validStorageTOTPExportFormats = []string{storageTOTPExportFormatCSV, storageTOTPExportFormatURI, storageTOTPExportFormatPNG}
|
validStorageTOTPExportFormats = []string{storageTOTPExportFormatCSV, storageTOTPExportFormatURI, storageTOTPExportFormatPNG}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
timeLayoutCertificateNotBefore = "Jan 2 15:04:05 2006"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
cmdFlagNameDirectory = "directory"
|
||||||
|
|
||||||
|
cmdFlagNamePathCA = "path.ca"
|
||||||
|
|
||||||
|
cmdFlagNameFilePrivateKey = "file.private-key"
|
||||||
|
cmdFlagNameFilePublicKey = "file.public-key"
|
||||||
|
cmdFlagNameFileCertificate = "file.certificate"
|
||||||
|
cmdFlagNameFileCAPrivateKey = "file.ca-private-key"
|
||||||
|
cmdFlagNameFileCACertificate = "file.ca-certificate"
|
||||||
|
cmdFlagNameFileCSR = "file.csr"
|
||||||
|
|
||||||
|
cmdFlagNameExtendedUsage = "extended-usage"
|
||||||
|
cmdFlagNameSignature = "signature"
|
||||||
|
cmdFlagNameCA = "ca"
|
||||||
|
cmdFlagNameSANs = "sans"
|
||||||
|
|
||||||
|
cmdFlagNameCommonName = "common-name"
|
||||||
|
cmdFlagNameOrganization = "organization"
|
||||||
|
cmdFlagNameOrganizationalUnit = "organizational-unit"
|
||||||
|
cmdFlagNameCountry = "country"
|
||||||
|
cmdFlagNameProvince = "province"
|
||||||
|
cmdFlagNameLocality = "locality"
|
||||||
|
cmdFlagNameStreetAddress = "street-address"
|
||||||
|
cmdFlagNamePostcode = "postcode"
|
||||||
|
|
||||||
|
cmdFlagNameNotBefore = "not-before"
|
||||||
|
cmdFlagNameDuration = "duration"
|
||||||
|
|
||||||
|
cmdFlagNamePKCS8 = "pkcs8"
|
||||||
|
cmdFlagNameBits = "bits"
|
||||||
|
cmdFlagNameCurve = "curve"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
cmdUseCertificate = "certificate"
|
||||||
|
cmdUseGenerate = "generate"
|
||||||
|
cmdUseRequest = "request"
|
||||||
|
cmdUsePair = "pair"
|
||||||
|
cmdUseRSA = "rsa"
|
||||||
|
cmdUseECDSA = "ecdsa"
|
||||||
|
cmdUseEd25519 = "ed25519"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
cryptoCertPubCertOut = "certificate"
|
||||||
|
cryptoCertCSROut = "certificate signing request"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errNoStorageProvider = errors.New("no storage provider configured")
|
errNoStorageProvider = errors.New("no storage provider configured")
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,451 @@
|
||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newCryptoCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "crypto",
|
||||||
|
Short: cmdAutheliaCryptoShort,
|
||||||
|
Long: cmdAutheliaCryptoLong,
|
||||||
|
Example: cmdAutheliaCryptoExample,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(
|
||||||
|
newCryptoCertificateCmd(),
|
||||||
|
newCryptoPairCmd(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCryptoCertificateCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: cmdUseCertificate,
|
||||||
|
Short: cmdAutheliaCryptoCertificateShort,
|
||||||
|
Long: cmdAutheliaCryptoCertificateLong,
|
||||||
|
Example: cmdAutheliaCryptoCertificateExample,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(
|
||||||
|
newCryptoCertificateSubCmd(cmdUseRSA),
|
||||||
|
newCryptoCertificateSubCmd(cmdUseECDSA),
|
||||||
|
newCryptoCertificateSubCmd(cmdUseEd25519),
|
||||||
|
)
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCryptoCertificateSubCmd(use string) (cmd *cobra.Command) {
|
||||||
|
var (
|
||||||
|
example, useFmt string
|
||||||
|
)
|
||||||
|
|
||||||
|
useFmt = fmtCryptoUse(use)
|
||||||
|
|
||||||
|
switch use {
|
||||||
|
case cmdUseRSA:
|
||||||
|
example = cmdAutheliaCryptoCertificateRSAExample
|
||||||
|
case cmdUseECDSA:
|
||||||
|
example = cmdAutheliaCryptoCertificateECDSAExample
|
||||||
|
case cmdUseEd25519:
|
||||||
|
example = cmdAutheliaCryptoCertificateEd25519Example
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: use,
|
||||||
|
Short: fmt.Sprintf(fmtCmdAutheliaCryptoCertificateSubShort, useFmt),
|
||||||
|
Long: fmt.Sprintf(fmtCmdAutheliaCryptoCertificateSubLong, useFmt, useFmt),
|
||||||
|
Example: example,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(newCryptoGenerateCmd(cmdUseCertificate, use), newCryptoCertificateRequestCmd(use))
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCryptoCertificateRequestCmd(algorithm string) (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: cmdUseRequest,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
RunE: cryptoCertificateRequestRunE,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdFlagsCryptoPrivateKey(cmd)
|
||||||
|
cmdFlagsCryptoCertificateCommon(cmd)
|
||||||
|
cmdFlagsCryptoCertificateRequest(cmd)
|
||||||
|
|
||||||
|
algorithmFmt := fmtCryptoUse(algorithm)
|
||||||
|
|
||||||
|
cmd.Short = fmt.Sprintf(fmtCmdAutheliaCryptoCertificateGenerateRequestShort, algorithmFmt, cryptoCertCSROut)
|
||||||
|
cmd.Long = fmt.Sprintf(fmtCmdAutheliaCryptoCertificateGenerateRequestLong, algorithmFmt, cryptoCertCSROut, algorithmFmt, cryptoCertCSROut)
|
||||||
|
|
||||||
|
switch algorithm {
|
||||||
|
case cmdUseRSA:
|
||||||
|
cmd.Example = cmdAutheliaCryptoCertificateRSARequestExample
|
||||||
|
|
||||||
|
cmdFlagsCryptoPrivateKeyRSA(cmd)
|
||||||
|
case cmdUseECDSA:
|
||||||
|
cmd.Example = cmdAutheliaCryptoCertificateECDSARequestExample
|
||||||
|
|
||||||
|
cmdFlagsCryptoPrivateKeyECDSA(cmd)
|
||||||
|
case cmdUseEd25519:
|
||||||
|
cmd.Example = cmdAutheliaCryptoCertificateEd25519RequestExample
|
||||||
|
|
||||||
|
cmdFlagsCryptoPrivateKeyEd25519(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCryptoPairCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: cmdUsePair,
|
||||||
|
Short: cmdAutheliaCryptoPairShort,
|
||||||
|
Long: cmdAutheliaCryptoPairLong,
|
||||||
|
Example: cmdAutheliaCryptoPairExample,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(
|
||||||
|
newCryptoPairSubCmd(cmdUseRSA),
|
||||||
|
newCryptoPairSubCmd(cmdUseECDSA),
|
||||||
|
newCryptoPairSubCmd(cmdUseEd25519),
|
||||||
|
)
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCryptoPairSubCmd(use string) (cmd *cobra.Command) {
|
||||||
|
var (
|
||||||
|
example, useFmt string
|
||||||
|
)
|
||||||
|
|
||||||
|
useFmt = fmtCryptoUse(use)
|
||||||
|
|
||||||
|
switch use {
|
||||||
|
case cmdUseRSA:
|
||||||
|
example = cmdAutheliaCryptoPairRSAExample
|
||||||
|
case cmdUseECDSA:
|
||||||
|
example = cmdAutheliaCryptoPairECDSAExample
|
||||||
|
case cmdUseEd25519:
|
||||||
|
example = cmdAutheliaCryptoPairEd25519Example
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: use,
|
||||||
|
Short: fmt.Sprintf(cmdAutheliaCryptoPairSubShort, useFmt),
|
||||||
|
Long: fmt.Sprintf(cmdAutheliaCryptoPairSubLong, useFmt, useFmt),
|
||||||
|
Example: example,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
RunE: cryptoGenerateRunE,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(newCryptoGenerateCmd(cmdUsePair, use))
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCryptoGenerateCmd(category, algorithm string) (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: cmdUseGenerate,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
RunE: cryptoGenerateRunE,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdFlagsCryptoPrivateKey(cmd)
|
||||||
|
|
||||||
|
algorithmFmt := fmtCryptoUse(algorithm)
|
||||||
|
|
||||||
|
switch category {
|
||||||
|
case cmdUseCertificate:
|
||||||
|
cmdFlagsCryptoCertificateCommon(cmd)
|
||||||
|
cmdFlagsCryptoCertificateGenerate(cmd)
|
||||||
|
|
||||||
|
cmd.Short = fmt.Sprintf(fmtCmdAutheliaCryptoCertificateGenerateRequestShort, algorithmFmt, cryptoCertPubCertOut)
|
||||||
|
cmd.Long = fmt.Sprintf(fmtCmdAutheliaCryptoCertificateGenerateRequestLong, algorithmFmt, cryptoCertPubCertOut, algorithmFmt, cryptoCertPubCertOut)
|
||||||
|
|
||||||
|
switch algorithm {
|
||||||
|
case cmdUseRSA:
|
||||||
|
cmd.Example = cmdAutheliaCryptoCertificateRSAGenerateExample
|
||||||
|
|
||||||
|
cmdFlagsCryptoPrivateKeyRSA(cmd)
|
||||||
|
case cmdUseECDSA:
|
||||||
|
cmd.Example = cmdAutheliaCryptoCertificateECDSAGenerateExample
|
||||||
|
|
||||||
|
cmdFlagsCryptoPrivateKeyECDSA(cmd)
|
||||||
|
case cmdUseEd25519:
|
||||||
|
cmd.Example = cmdAutheliaCryptoCertificateEd25519GenerateExample
|
||||||
|
|
||||||
|
cmdFlagsCryptoPrivateKeyEd25519(cmd)
|
||||||
|
}
|
||||||
|
case cmdUsePair:
|
||||||
|
cmdFlagsCryptoPairGenerate(cmd)
|
||||||
|
|
||||||
|
cmd.Short = fmt.Sprintf(fmtCmdAutheliaCryptoPairGenerateShort, algorithmFmt)
|
||||||
|
cmd.Long = fmt.Sprintf(fmtCmdAutheliaCryptoPairGenerateLong, algorithmFmt, algorithmFmt)
|
||||||
|
|
||||||
|
switch algorithm {
|
||||||
|
case cmdUseRSA:
|
||||||
|
cmd.Example = cmdAutheliaCryptoPairRSAGenerateExample
|
||||||
|
|
||||||
|
cmdFlagsCryptoPrivateKeyRSA(cmd)
|
||||||
|
case cmdUseECDSA:
|
||||||
|
cmd.Example = cmdAutheliaCryptoPairECDSAGenerateExample
|
||||||
|
|
||||||
|
cmdFlagsCryptoPrivateKeyECDSA(cmd)
|
||||||
|
case cmdUseEd25519:
|
||||||
|
cmd.Example = cmdAutheliaCryptoPairEd25519GenerateExample
|
||||||
|
|
||||||
|
cmdFlagsCryptoPrivateKeyEd25519(cmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoGenerateRunE(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
var (
|
||||||
|
privateKey interface{}
|
||||||
|
)
|
||||||
|
|
||||||
|
if privateKey, err = cryptoGenPrivateKeyFromCmd(cmd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.Parent().Parent().Use == cmdUseCertificate {
|
||||||
|
return cryptoCertificateGenerateRunE(cmd, args, privateKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cryptoPairGenerateRunE(cmd, args, privateKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoCertificateRequestRunE(cmd *cobra.Command, _ []string) (err error) {
|
||||||
|
var (
|
||||||
|
privateKey interface{}
|
||||||
|
)
|
||||||
|
|
||||||
|
if privateKey, err = cryptoGenPrivateKeyFromCmd(cmd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
template *x509.CertificateRequest
|
||||||
|
csr []byte
|
||||||
|
privateKeyPath, csrPath string
|
||||||
|
)
|
||||||
|
|
||||||
|
if template, err = cryptoGetCSRFromCmd(cmd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b := strings.Builder{}
|
||||||
|
|
||||||
|
b.WriteString("Generating Certificate Request\n\n")
|
||||||
|
|
||||||
|
b.WriteString("Subject:\n")
|
||||||
|
b.WriteString(fmt.Sprintf("\tCommon Name: %s, Organization: %s, Organizational Unit: %s\n", template.Subject.CommonName, template.Subject.Organization, template.Subject.OrganizationalUnit))
|
||||||
|
b.WriteString(fmt.Sprintf("\tCountry: %v, Province: %v, Street Address: %v, Postal Code: %v, Locality: %v\n\n", template.Subject.Country, template.Subject.Province, template.Subject.StreetAddress, template.Subject.PostalCode, template.Subject.Locality))
|
||||||
|
|
||||||
|
b.WriteString("Properties:\n")
|
||||||
|
|
||||||
|
b.WriteString(fmt.Sprintf("\tSignature Algorithm: %s, Public Key Algorithm: %s", template.SignatureAlgorithm, template.PublicKeyAlgorithm))
|
||||||
|
|
||||||
|
switch k := privateKey.(type) {
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
b.WriteString(fmt.Sprintf(", Bits: %d", k.N.BitLen()))
|
||||||
|
case *ecdsa.PrivateKey:
|
||||||
|
b.WriteString(fmt.Sprintf(", Elliptic Curve: %s", k.Curve.Params().Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
b.WriteString(fmt.Sprintf("\n\tSubject Alternative Names: %s\n\n", strings.Join(cryptoSANsToString(template.DNSNames, template.IPAddresses), ", ")))
|
||||||
|
|
||||||
|
if privateKeyPath, csrPath, err = cryptoGetWritePathsFromCmd(cmd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b.WriteString("Output Paths:\n")
|
||||||
|
b.WriteString(fmt.Sprintf("\tPrivate Key: %s\n", privateKeyPath))
|
||||||
|
b.WriteString(fmt.Sprintf("\tCertificate Request: %s\n\n", csrPath))
|
||||||
|
|
||||||
|
fmt.Print(b.String())
|
||||||
|
|
||||||
|
b.Reset()
|
||||||
|
|
||||||
|
if csr, err = x509.CreateCertificateRequest(rand.Reader, template, privateKey); err != nil {
|
||||||
|
return fmt.Errorf("failed to create certificate request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if privateKeyPath, csrPath, err = cryptoGetWritePathsFromCmd(cmd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = utils.WriteKeyToPEM(privateKey, privateKeyPath, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = utils.WriteCertificateBytesToPEM(csr, csrPath, true); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoCertificateGenerateRunE(cmd *cobra.Command, _ []string, privateKey interface{}) (err error) {
|
||||||
|
var (
|
||||||
|
template, caCertificate, parent *x509.Certificate
|
||||||
|
publicKey, caPrivateKey, signatureKey interface{}
|
||||||
|
)
|
||||||
|
|
||||||
|
if publicKey = utils.PublicKeyFromPrivateKey(privateKey); publicKey == nil {
|
||||||
|
return fmt.Errorf("failed to obtain public key from private key")
|
||||||
|
}
|
||||||
|
|
||||||
|
if caPrivateKey, caCertificate, err = cryptoGetCAFromCmd(cmd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
signatureKey = privateKey
|
||||||
|
|
||||||
|
if caPrivateKey != nil {
|
||||||
|
signatureKey = caPrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
if template, err = cryptoGetCertificateFromCmd(cmd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b := strings.Builder{}
|
||||||
|
|
||||||
|
b.WriteString("Generating Certificate\n\n")
|
||||||
|
|
||||||
|
b.WriteString(fmt.Sprintf("\tSerial: %x\n\n", template.SerialNumber))
|
||||||
|
|
||||||
|
switch caCertificate {
|
||||||
|
case nil:
|
||||||
|
parent = template
|
||||||
|
|
||||||
|
b.WriteString("Signed By:\n\tSelf-Signed\n")
|
||||||
|
default:
|
||||||
|
parent = caCertificate
|
||||||
|
|
||||||
|
b.WriteString(fmt.Sprintf("Signed By:\n\t%s\n", caCertificate.Subject.CommonName))
|
||||||
|
b.WriteString(fmt.Sprintf("\tSerial: %x, Expires: %s\n", caCertificate.SerialNumber, caCertificate.NotAfter.Format(time.RFC3339)))
|
||||||
|
}
|
||||||
|
|
||||||
|
b.WriteString("\nSubject:\n")
|
||||||
|
b.WriteString(fmt.Sprintf("\tCommon Name: %s, Organization: %s, Organizational Unit: %s\n", template.Subject.CommonName, template.Subject.Organization, template.Subject.OrganizationalUnit))
|
||||||
|
b.WriteString(fmt.Sprintf("\tCountry: %v, Province: %v, Street Address: %v, Postal Code: %v, Locality: %v\n\n", template.Subject.Country, template.Subject.Province, template.Subject.StreetAddress, template.Subject.PostalCode, template.Subject.Locality))
|
||||||
|
|
||||||
|
b.WriteString("Properties:\n")
|
||||||
|
b.WriteString(fmt.Sprintf("\tNot Before: %s, Not After: %s\n", template.NotBefore.Format(time.RFC3339), template.NotAfter.Format(time.RFC3339)))
|
||||||
|
|
||||||
|
b.WriteString(fmt.Sprintf("\tCA: %v, CSR: %v, Signature Algorithm: %s, Public Key Algorithm: %s", template.IsCA, false, template.SignatureAlgorithm, template.PublicKeyAlgorithm))
|
||||||
|
|
||||||
|
switch k := privateKey.(type) {
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
b.WriteString(fmt.Sprintf(", Bits: %d", k.N.BitLen()))
|
||||||
|
case *ecdsa.PrivateKey:
|
||||||
|
b.WriteString(fmt.Sprintf(", Elliptic Curve: %s", k.Curve.Params().Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
b.WriteString(fmt.Sprintf("\n\tSubject Alternative Names: %s\n\n", strings.Join(cryptoSANsToString(template.DNSNames, template.IPAddresses), ", ")))
|
||||||
|
|
||||||
|
var (
|
||||||
|
privateKeyPath, certificatePath string
|
||||||
|
certificate []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
if privateKeyPath, certificatePath, err = cryptoGetWritePathsFromCmd(cmd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b.WriteString("Output Paths:\n")
|
||||||
|
b.WriteString(fmt.Sprintf("\tPrivate Key: %s\n", privateKeyPath))
|
||||||
|
b.WriteString(fmt.Sprintf("\tCertificate: %s\n\n", certificatePath))
|
||||||
|
|
||||||
|
fmt.Print(b.String())
|
||||||
|
|
||||||
|
b.Reset()
|
||||||
|
|
||||||
|
if certificate, err = x509.CreateCertificate(rand.Reader, template, parent, publicKey, signatureKey); err != nil {
|
||||||
|
return fmt.Errorf("failed to create certificate: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = utils.WriteKeyToPEM(privateKey, privateKeyPath, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = utils.WriteCertificateBytesToPEM(certificate, certificatePath, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoPairGenerateRunE(cmd *cobra.Command, _ []string, privateKey interface{}) (err error) {
|
||||||
|
var (
|
||||||
|
privateKeyPath, publicKeyPath string
|
||||||
|
pkcs8 bool
|
||||||
|
)
|
||||||
|
|
||||||
|
if pkcs8, err = cmd.Flags().GetBool(cmdFlagNamePKCS8); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if privateKeyPath, publicKeyPath, err = cryptoGetWritePathsFromCmd(cmd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b := strings.Builder{}
|
||||||
|
|
||||||
|
b.WriteString("Generating key pair\n\n")
|
||||||
|
|
||||||
|
switch k := privateKey.(type) {
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
b.WriteString(fmt.Sprintf("\tAlgorithm: RSA-%d %d bits\n\n", k.Size(), k.N.BitLen()))
|
||||||
|
case *ecdsa.PrivateKey:
|
||||||
|
b.WriteString(fmt.Sprintf("\tAlgorithm: ECDSA Curve %s\n\n", k.Curve.Params().Name))
|
||||||
|
case ed25519.PrivateKey:
|
||||||
|
b.WriteString("\tAlgorithm: Ed25519\n\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
b.WriteString("Output Paths:\n")
|
||||||
|
b.WriteString(fmt.Sprintf("\tPrivate Key: %s\n", privateKeyPath))
|
||||||
|
b.WriteString(fmt.Sprintf("\tPublic Key: %s\n\n", publicKeyPath))
|
||||||
|
|
||||||
|
fmt.Print(b.String())
|
||||||
|
|
||||||
|
b.Reset()
|
||||||
|
|
||||||
|
if err = utils.WriteKeyToPEM(privateKey, privateKeyPath, pkcs8); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var publicKey interface{}
|
||||||
|
|
||||||
|
if publicKey = utils.PublicKeyFromPrivateKey(privateKey); publicKey == nil {
|
||||||
|
return fmt.Errorf("failed to obtain public key from private key")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = utils.WriteKeyToPEM(publicKey, publicKeyPath, pkcs8); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,426 @@
|
||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func cmdFlagsCryptoCertificateCommon(cmd *cobra.Command) {
|
||||||
|
cmd.Flags().String(cmdFlagNameSignature, "SHA256", "signature algorithm for the certificate")
|
||||||
|
|
||||||
|
cmd.Flags().StringP(cmdFlagNameCommonName, "c", "", "certificate common name")
|
||||||
|
cmd.Flags().StringSliceP(cmdFlagNameOrganization, "o", []string{"Authelia"}, "certificate organization")
|
||||||
|
cmd.Flags().StringSlice(cmdFlagNameOrganizationalUnit, nil, "certificate organizational unit")
|
||||||
|
cmd.Flags().StringSlice(cmdFlagNameCountry, nil, "certificate country")
|
||||||
|
cmd.Flags().StringSlice(cmdFlagNameProvince, nil, "certificate province")
|
||||||
|
cmd.Flags().StringSliceP(cmdFlagNameLocality, "l", nil, "certificate locality")
|
||||||
|
cmd.Flags().StringSliceP(cmdFlagNameStreetAddress, "s", nil, "certificate street address")
|
||||||
|
cmd.Flags().StringSliceP(cmdFlagNamePostcode, "p", nil, "certificate postcode")
|
||||||
|
|
||||||
|
cmd.Flags().String(cmdFlagNameNotBefore, "", fmt.Sprintf("earliest date and time the certificate is considered valid formatted as %s (default is now)", timeLayoutCertificateNotBefore))
|
||||||
|
cmd.Flags().Duration(cmdFlagNameDuration, 365*24*time.Hour, "duration of time the certificate is valid for")
|
||||||
|
cmd.Flags().StringSlice(cmdFlagNameSANs, nil, "subject alternative names")
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdFlagsCryptoCertificateGenerate(cmd *cobra.Command) {
|
||||||
|
cmd.Flags().String(cmdFlagNamePathCA, "", "source directory of the certificate authority files, if not provided the certificate will be self-signed")
|
||||||
|
cmd.Flags().String(cmdFlagNameFileCAPrivateKey, "ca.private.pem", "certificate authority private key to use to signing this certificate")
|
||||||
|
cmd.Flags().String(cmdFlagNameFileCACertificate, "ca.public.crt", "certificate authority certificate to use when signing this certificate")
|
||||||
|
cmd.Flags().String(cmdFlagNameFileCertificate, "public.crt", "name of the file to export the certificate data to")
|
||||||
|
|
||||||
|
cmd.Flags().StringSlice(cmdFlagNameExtendedUsage, nil, "specify the extended usage types of the certificate")
|
||||||
|
|
||||||
|
cmd.Flags().Bool(cmdFlagNameCA, false, "create the certificate as a certificate authority certificate")
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdFlagsCryptoCertificateRequest(cmd *cobra.Command) {
|
||||||
|
cmd.Flags().String(cmdFlagNameFileCSR, "request.csr", "name of the file to export the certificate request data to")
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdFlagsCryptoPairGenerate(cmd *cobra.Command) {
|
||||||
|
cmd.Flags().String(cmdFlagNameFilePublicKey, "public.pem", "name of the file to export the public key data to")
|
||||||
|
cmd.Flags().Bool(cmdFlagNamePKCS8, false, "force PKCS #8 ASN.1 format")
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdFlagsCryptoPrivateKey(cmd *cobra.Command) {
|
||||||
|
cmd.Flags().String(cmdFlagNameFilePrivateKey, "private.pem", "name of the file to export the private key data to")
|
||||||
|
cmd.Flags().StringP(cmdFlagNameDirectory, "d", "", "directory where the generated keys, certificates, etc will be stored")
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdFlagsCryptoPrivateKeyRSA(cmd *cobra.Command) {
|
||||||
|
cmd.Flags().IntP(cmdFlagNameBits, "b", 2048, "number of RSA bits for the certificate")
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdFlagsCryptoPrivateKeyECDSA(cmd *cobra.Command) {
|
||||||
|
cmd.Flags().StringP(cmdFlagNameCurve, "b", "P256", "Sets the elliptic curve which can be P224, P256, P384, or P521")
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdFlagsCryptoPrivateKeyEd25519(cmd *cobra.Command) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoSANsToString(dnsSANs []string, ipSANs []net.IP) (sans []string) {
|
||||||
|
sans = make([]string, len(dnsSANs)+len(ipSANs))
|
||||||
|
|
||||||
|
j := 0
|
||||||
|
|
||||||
|
for i, dnsSAN := range dnsSANs {
|
||||||
|
sans[j] = fmt.Sprintf("DNS.%d:%s", i+1, dnsSAN)
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, ipSAN := range ipSANs {
|
||||||
|
sans[j] = fmt.Sprintf("IP.%d:%s", i+1, ipSAN)
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
|
||||||
|
return sans
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoGetWritePathsFromCmd(cmd *cobra.Command) (privateKey, publicKey string, err error) {
|
||||||
|
var dir string
|
||||||
|
|
||||||
|
if dir, err = cmd.Flags().GetString(cmdFlagNameDirectory); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
ca, _ := cmd.Flags().GetBool(cmdFlagNameCA)
|
||||||
|
csr := cmd.Use == cmdUseRequest
|
||||||
|
|
||||||
|
var private, public string
|
||||||
|
|
||||||
|
var flagPrivate, flagPublic string
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ca && csr:
|
||||||
|
flagPrivate, flagPublic = cmdFlagNameFileCAPrivateKey, cmdFlagNameFileCSR
|
||||||
|
case csr:
|
||||||
|
flagPrivate, flagPublic = cmdFlagNameFilePrivateKey, cmdFlagNameFileCSR
|
||||||
|
case ca:
|
||||||
|
flagPrivate, flagPublic = cmdFlagNameFileCAPrivateKey, cmdFlagNameFileCACertificate
|
||||||
|
case cmd.Parent().Parent().Use == cmdUsePair:
|
||||||
|
flagPrivate, flagPublic = cmdFlagNameFilePrivateKey, cmdFlagNameFilePublicKey
|
||||||
|
default:
|
||||||
|
flagPrivate, flagPublic = cmdFlagNameFilePrivateKey, cmdFlagNameFileCertificate
|
||||||
|
}
|
||||||
|
|
||||||
|
if private, err = cmd.Flags().GetString(flagPrivate); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if public, err = cmd.Flags().GetString(flagPublic); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return filepath.Join(dir, private), filepath.Join(dir, public), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoGenPrivateKeyFromCmd(cmd *cobra.Command) (privateKey interface{}, err error) {
|
||||||
|
switch cmd.Parent().Use {
|
||||||
|
case cmdUseRSA:
|
||||||
|
var (
|
||||||
|
bits int
|
||||||
|
)
|
||||||
|
|
||||||
|
if bits, err = cmd.Flags().GetInt(cmdFlagNameBits); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if privateKey, err = rsa.GenerateKey(rand.Reader, bits); err != nil {
|
||||||
|
return nil, fmt.Errorf("generating RSA private key resulted in an error: %w", err)
|
||||||
|
}
|
||||||
|
case cmdUseECDSA:
|
||||||
|
var (
|
||||||
|
curveStr string
|
||||||
|
curve elliptic.Curve
|
||||||
|
)
|
||||||
|
|
||||||
|
if curveStr, err = cmd.Flags().GetString(cmdFlagNameCurve); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if curve = utils.EllipticCurveFromString(curveStr); curve == nil {
|
||||||
|
return nil, fmt.Errorf("invalid curve '%s' was specified: curve must be P224, P256, P384, or P521", curveStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if privateKey, err = ecdsa.GenerateKey(curve, rand.Reader); err != nil {
|
||||||
|
return nil, fmt.Errorf("generating ECDSA private key resulted in an error: %w", err)
|
||||||
|
}
|
||||||
|
case cmdUseEd25519:
|
||||||
|
if _, privateKey, err = ed25519.GenerateKey(rand.Reader); err != nil {
|
||||||
|
return nil, fmt.Errorf("generating Ed25519 private key resulted in an error: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return privateKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoGetCAFromCmd(cmd *cobra.Command) (privateKey interface{}, cert *x509.Certificate, err error) {
|
||||||
|
if !cmd.Flags().Changed(cmdFlagNamePathCA) {
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
dir, filePrivateKey, fileCertificate string
|
||||||
|
|
||||||
|
ok bool
|
||||||
|
|
||||||
|
certificate interface{}
|
||||||
|
)
|
||||||
|
|
||||||
|
if dir, err = cmd.Flags().GetString(cmdFlagNamePathCA); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if filePrivateKey, err = cmd.Flags().GetString(cmdFlagNameFileCAPrivateKey); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileCertificate, err = cmd.Flags().GetString(cmdFlagNameFileCACertificate); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
bytesPrivateKey, bytesCertificate []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
pathPrivateKey := filepath.Join(dir, filePrivateKey)
|
||||||
|
if bytesPrivateKey, err = os.ReadFile(pathPrivateKey); err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("could not read private key file '%s': %w", pathPrivateKey, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if privateKey, err = utils.ParseX509FromPEM(bytesPrivateKey); err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("could not parse private key from file '%s': %w", pathPrivateKey, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if privateKey == nil || !utils.IsX509PrivateKey(privateKey) {
|
||||||
|
return nil, nil, fmt.Errorf("could not parse private key from file '%s': does not appear to be a private key", pathPrivateKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
pathCertificate := filepath.Join(dir, fileCertificate)
|
||||||
|
if bytesCertificate, err = os.ReadFile(pathCertificate); err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("could not read certificate file '%s': %w", pathCertificate, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if certificate, err = utils.ParseX509FromPEM(bytesCertificate); err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("could not parse certificate from file '%s': %w", pathCertificate, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cert, ok = utils.CastX509AsCertificate(certificate); !ok {
|
||||||
|
return nil, nil, fmt.Errorf("could not parse certificate from file '%s': does not appear to be a certificate", pathCertificate)
|
||||||
|
}
|
||||||
|
|
||||||
|
return privateKey, cert, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoGetCSRFromCmd(cmd *cobra.Command) (csr *x509.CertificateRequest, err error) {
|
||||||
|
var (
|
||||||
|
subject *pkix.Name
|
||||||
|
dnsSANs []string
|
||||||
|
ipSANs []net.IP
|
||||||
|
)
|
||||||
|
|
||||||
|
if subject, err = cryptoGetSubjectFromCmd(cmd); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyAlg, sigAlg := cryptoGetAlgFromCmd(cmd)
|
||||||
|
|
||||||
|
if dnsSANs, ipSANs, err = cryptoGetSANsFromCmd(cmd); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
csr = &x509.CertificateRequest{
|
||||||
|
Subject: *subject,
|
||||||
|
PublicKeyAlgorithm: keyAlg,
|
||||||
|
SignatureAlgorithm: sigAlg,
|
||||||
|
|
||||||
|
DNSNames: dnsSANs,
|
||||||
|
IPAddresses: ipSANs,
|
||||||
|
}
|
||||||
|
|
||||||
|
return csr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoGetSANsFromCmd(cmd *cobra.Command) (dnsSANs []string, ipSANs []net.IP, err error) {
|
||||||
|
var (
|
||||||
|
sans []string
|
||||||
|
)
|
||||||
|
|
||||||
|
if sans, err = cmd.Flags().GetStringSlice(cmdFlagNameSANs); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, san := range sans {
|
||||||
|
if ipSAN := net.ParseIP(san); ipSAN != nil {
|
||||||
|
ipSANs = append(ipSANs, ipSAN)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
dnsSANs = append(dnsSANs, san)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dnsSANs, ipSANs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoGetAlgFromCmd(cmd *cobra.Command) (keyAlg x509.PublicKeyAlgorithm, sigAlg x509.SignatureAlgorithm) {
|
||||||
|
sigAlgStr, _ := cmd.Flags().GetString(cmdFlagNameSignature)
|
||||||
|
keyAlgStr := cmd.Parent().Use
|
||||||
|
|
||||||
|
return utils.KeySigAlgorithmFromString(keyAlgStr, sigAlgStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoGetSubjectFromCmd(cmd *cobra.Command) (subject *pkix.Name, err error) {
|
||||||
|
var (
|
||||||
|
commonName string
|
||||||
|
organization, organizationalUnit, country, locality, province, streetAddress, postcode []string
|
||||||
|
)
|
||||||
|
|
||||||
|
if commonName, err = cmd.Flags().GetString(cmdFlagNameCommonName); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if organization, err = cmd.Flags().GetStringSlice(cmdFlagNameOrganization); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if organizationalUnit, err = cmd.Flags().GetStringSlice(cmdFlagNameOrganizationalUnit); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if country, err = cmd.Flags().GetStringSlice(cmdFlagNameCountry); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if locality, err = cmd.Flags().GetStringSlice(cmdFlagNameLocality); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if province, err = cmd.Flags().GetStringSlice(cmdFlagNameProvince); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if streetAddress, err = cmd.Flags().GetStringSlice(cmdFlagNameStreetAddress); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if postcode, err = cmd.Flags().GetStringSlice(cmdFlagNamePostcode); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pkix.Name{
|
||||||
|
CommonName: commonName,
|
||||||
|
Organization: organization,
|
||||||
|
OrganizationalUnit: organizationalUnit,
|
||||||
|
Country: country,
|
||||||
|
Locality: locality,
|
||||||
|
Province: province,
|
||||||
|
StreetAddress: streetAddress,
|
||||||
|
PostalCode: postcode,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoGetCertificateFromCmd(cmd *cobra.Command) (certificate *x509.Certificate, err error) {
|
||||||
|
var (
|
||||||
|
ca bool
|
||||||
|
subject *pkix.Name
|
||||||
|
notBeforeStr string
|
||||||
|
duration time.Duration
|
||||||
|
)
|
||||||
|
|
||||||
|
if ca, err = cmd.Flags().GetBool(cmdFlagNameCA); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if subject, err = cryptoGetSubjectFromCmd(cmd); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if notBeforeStr, err = cmd.Flags().GetString(cmdFlagNameNotBefore); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if duration, err = cmd.Flags().GetDuration(cmdFlagNameDuration); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
notBefore time.Time
|
||||||
|
serialNumber *big.Int
|
||||||
|
dnsSANs, extKeyUsages []string
|
||||||
|
ipSANs []net.IP
|
||||||
|
)
|
||||||
|
|
||||||
|
switch len(notBeforeStr) {
|
||||||
|
case 0:
|
||||||
|
notBefore = time.Now()
|
||||||
|
default:
|
||||||
|
if notBefore, err = time.Parse(timeLayoutCertificateNotBefore, notBeforeStr); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse not before: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||||
|
|
||||||
|
if serialNumber, err = rand.Int(rand.Reader, serialNumberLimit); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to generate serial number: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dnsSANs, ipSANs, err = cryptoGetSANsFromCmd(cmd); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyAlg, sigAlg := cryptoGetAlgFromCmd(cmd)
|
||||||
|
|
||||||
|
if extKeyUsages, err = cmd.Flags().GetStringSlice(cmdFlagNameExtendedUsage); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
certificate = &x509.Certificate{
|
||||||
|
SerialNumber: serialNumber,
|
||||||
|
Subject: *subject,
|
||||||
|
|
||||||
|
NotBefore: notBefore,
|
||||||
|
NotAfter: notBefore.Add(duration),
|
||||||
|
|
||||||
|
IsCA: ca,
|
||||||
|
|
||||||
|
KeyUsage: utils.X509ParseKeyUsage(nil, ca),
|
||||||
|
ExtKeyUsage: utils.X509ParseExtendedKeyUsage(extKeyUsages, ca),
|
||||||
|
|
||||||
|
PublicKeyAlgorithm: keyAlg,
|
||||||
|
SignatureAlgorithm: sigAlg,
|
||||||
|
|
||||||
|
DNSNames: dnsSANs,
|
||||||
|
IPAddresses: ipSANs,
|
||||||
|
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
return certificate, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fmtCryptoUse(use string) string {
|
||||||
|
switch use {
|
||||||
|
case cmdUseEd25519:
|
||||||
|
return "Ed25519"
|
||||||
|
default:
|
||||||
|
return strings.ToUpper(use)
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,9 +36,8 @@ func NewRootCmd() (cmd *cobra.Command) {
|
||||||
|
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
newBuildInfoCmd(),
|
newBuildInfoCmd(),
|
||||||
newCertificatesCmd(),
|
newCryptoCmd(),
|
||||||
newHashPasswordCmd(),
|
newHashPasswordCmd(),
|
||||||
NewRSACmd(),
|
|
||||||
newStorageCmd(),
|
newStorageCmd(),
|
||||||
newValidateConfigCmd(),
|
newValidateConfigCmd(),
|
||||||
newAccessControlCommand(),
|
newAccessControlCommand(),
|
||||||
|
|
|
@ -1,110 +0,0 @@
|
||||||
package commands
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewRSACmd returns a new RSA Cmd.
|
|
||||||
func NewRSACmd() (cmd *cobra.Command) {
|
|
||||||
cmd = &cobra.Command{
|
|
||||||
Use: "rsa",
|
|
||||||
Short: cmdAutheliaRSAShort,
|
|
||||||
Long: cmdAutheliaRSALong,
|
|
||||||
Example: cmdAutheliaRSAExample,
|
|
||||||
Args: cobra.NoArgs,
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.AddCommand(newRSAGenerateCmd())
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func newRSAGenerateCmd() (cmd *cobra.Command) {
|
|
||||||
cmd = &cobra.Command{
|
|
||||||
Use: "generate",
|
|
||||||
Short: cmdAutheliaRSAGenerateShort,
|
|
||||||
Long: cmdAutheliaRSAGenerateLong,
|
|
||||||
Example: cmdAutheliaRSAGenerateExample,
|
|
||||||
Args: cobra.NoArgs,
|
|
||||||
Run: cmdRSAGenerateRun,
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Flags().StringP("dir", "d", "", "Target directory where the keypair will be stored")
|
|
||||||
cmd.Flags().IntP("key-size", "b", 2048, "Sets the key size in bits")
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func cmdRSAGenerateRun(cmd *cobra.Command, _ []string) {
|
|
||||||
bits, err := cmd.Flags().GetInt("key-size")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to parse key-size flag: %v\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
privateKey, publicKey := utils.GenerateRsaKeyPair(bits)
|
|
||||||
|
|
||||||
rsaTargetDirectory, err := cmd.Flags().GetString("dir")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to parse dir flag: %v\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
keyPath := filepath.Join(rsaTargetDirectory, "key.pem")
|
|
||||||
|
|
||||||
keyOut, err := os.OpenFile(keyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to open %s for writing: %v\n", keyPath, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if err := keyOut.Close(); err != nil {
|
|
||||||
fmt.Printf("Unable to close private key file: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
_, err = keyOut.WriteString(utils.ExportRsaPrivateKeyAsPemStr(privateKey))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to write private key: %v\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("RSA Private Key written to %s\n", keyPath)
|
|
||||||
|
|
||||||
certPath := filepath.Join(rsaTargetDirectory, "key.pub")
|
|
||||||
|
|
||||||
certOut, err := os.OpenFile(certPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to open %s for writing: %v\n", keyPath, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if err := certOut.Close(); err != nil {
|
|
||||||
fmt.Printf("Failed to close public key file: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
publicPem, err := utils.ExportRsaPublicKeyAsPemStr(publicKey)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to marshal public key: %v\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = certOut.WriteString(publicPem)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to write private key: %v\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("RSA Public Key written to %s\n", certPath)
|
|
||||||
}
|
|
|
@ -86,11 +86,17 @@ func (m KeyManager) GetActivePrivateKey() (key *rsa.PrivateKey, err error) {
|
||||||
|
|
||||||
// AddActivePrivateKeyData adds a rsa.PublicKey given the key in the PEM string format, then sets it to the active key.
|
// AddActivePrivateKeyData adds a rsa.PublicKey given the key in the PEM string format, then sets it to the active key.
|
||||||
func (m *KeyManager) AddActivePrivateKeyData(data string) (key *rsa.PrivateKey, webKey *jose.JSONWebKey, err error) {
|
func (m *KeyManager) AddActivePrivateKeyData(data string) (key *rsa.PrivateKey, webKey *jose.JSONWebKey, err error) {
|
||||||
key, err = utils.ParseRsaPrivateKeyFromPemStr(data)
|
ikey, err := utils.ParseX509FromPEM([]byte(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
|
||||||
|
if key, ok = ikey.(*rsa.PrivateKey); !ok {
|
||||||
|
return nil, nil, errors.New("key must be an RSA private key")
|
||||||
|
}
|
||||||
|
|
||||||
webKey, err = m.AddActivePrivateKey(key)
|
webKey, err = m.AddActivePrivateKey(key)
|
||||||
|
|
||||||
return key, webKey, err
|
return key, webKey, err
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package suites
|
package suites
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
@ -13,6 +14,7 @@ import (
|
||||||
|
|
||||||
"github.com/authelia/authelia/v4/internal/model"
|
"github.com/authelia/authelia/v4/internal/model"
|
||||||
"github.com/authelia/authelia/v4/internal/storage"
|
"github.com/authelia/authelia/v4/internal/storage"
|
||||||
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CLISuite struct {
|
type CLISuite struct {
|
||||||
|
@ -37,7 +39,7 @@ func (s *CLISuite) SetupTest() {
|
||||||
coverageArg := ""
|
coverageArg := ""
|
||||||
|
|
||||||
if os.Getenv("CI") == t {
|
if os.Getenv("CI") == t {
|
||||||
testArg = "-test.coverprofile=/authelia/coverage-$(date +%s).txt"
|
testArg = "-test.coverprofile=/authelia/coverage-$(cat /proc/sys/kernel/random/uuid).txt"
|
||||||
coverageArg = "COVERAGE"
|
coverageArg = "COVERAGE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,79 +96,526 @@ func (s *CLISuite) TestShouldHashPasswordSHA512() {
|
||||||
s.Assert().Contains(output, "Password hash: $6$rounds=50000")
|
s.Assert().Contains(output, "Password hash: $6$rounds=50000")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestShouldGenerateCertificateRSA() {
|
func (s *CLISuite) TestShouldGenerateRSACertificateRequest() {
|
||||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/"})
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "request", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
s.Assert().NoError(err)
|
s.Assert().NoError(err)
|
||||||
s.Assert().Contains(output, "Certificate written to /tmp/cert.pem")
|
s.Assert().Contains(output, "Generating Certificate Request")
|
||||||
s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tSignature Algorithm: SHA256-RSA, Public Key Algorithm: RSA, Bits: 2048")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate Request: /tmp/request.csr")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateECDSACurveP224CertificateRequest() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ecdsa", "request", "--curve=P224", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating Certificate Request")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tSignature Algorithm: ECDSA-SHA256, Public Key Algorithm: ECDSA, Elliptic Curve: P-224")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate Request: /tmp/request.csr")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateECDSACurveP256CertificateRequest() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ecdsa", "request", "--curve=P256", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating Certificate Request")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tSignature Algorithm: ECDSA-SHA256, Public Key Algorithm: ECDSA, Elliptic Curve: P-256")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate Request: /tmp/request.csr")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateECDSACurveP384CertificateRequest() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ecdsa", "request", "--curve=P384", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating Certificate Request")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tSignature Algorithm: ECDSA-SHA256, Public Key Algorithm: ECDSA, Elliptic Curve: P-384")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate Request: /tmp/request.csr")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateECDSACurveP521CertificateRequest() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ecdsa", "request", "--curve=P521", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating Certificate Request")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tSignature Algorithm: ECDSA-SHA256, Public Key Algorithm: ECDSA, Elliptic Curve: P-521")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate Request: /tmp/request.csr")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateEd25519CertificateRequest() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ed25519", "request", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating Certificate Request")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tSignature Algorithm: Ed25519, Public Key Algorithm: Ed25519")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate Request: /tmp/request.csr")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateCertificateRSA() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tSelf-Signed")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tCA: false, CSR: false, Signature Algorithm: SHA256-RSA, Public Key Algorithm: RSA, Bits: 2048")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/public.crt")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestShouldGenerateCertificateRSAWithIPAddress() {
|
func (s *CLISuite) TestShouldGenerateCertificateRSAWithIPAddress() {
|
||||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=127.0.0.1", "--dir=/tmp/"})
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--common-name=example.com", "--sans", "*.example.com,127.0.0.1", "--directory=/tmp/"})
|
||||||
s.Assert().NoError(err)
|
s.Assert().NoError(err)
|
||||||
s.Assert().Contains(output, "Certificate written to /tmp/cert.pem")
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tSelf-Signed")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tCA: false, CSR: false, Signature Algorithm: SHA256-RSA, Public Key Algorithm: RSA, Bits: 2048")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com, IP.1:127.0.0.1")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/public.crt")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestShouldGenerateCertificateRSAWithStartDate() {
|
func (s *CLISuite) TestShouldGenerateCertificateRSAWithNotBefore() {
|
||||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--start-date='Jan 1 15:04:05 2011'"})
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--common-name=example.com", "--sans='*.example.com'", "--not-before", "'Jan 1 15:04:05 2011'", "--directory=/tmp/"})
|
||||||
s.Assert().NoError(err)
|
s.Assert().NoError(err)
|
||||||
s.Assert().Contains(output, "Certificate written to /tmp/cert.pem")
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tSelf-Signed")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tNot Before: 2011-01-01T15:04:05Z, Not After: 2012-01-01T15:04:05Z")
|
||||||
|
s.Assert().Contains(output, "\tCA: false, CSR: false, Signature Algorithm: SHA256-RSA, Public Key Algorithm: RSA, Bits: 2048")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/public.crt")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestShouldFailGenerateCertificateRSAWithStartDate() {
|
func (s *CLISuite) TestShouldFailGenerateCertificateRSAWithInvalidNotBefore() {
|
||||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--start-date=Jan"})
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--common-name=example.com", "--sans='*.example.com'", "--not-before", "Jan", "--directory=/tmp/"})
|
||||||
s.Assert().NotNil(err)
|
s.Assert().NotNil(err)
|
||||||
s.Assert().Contains(output, "Failed to parse start date: parsing time \"Jan\" as \"Jan 2 15:04:05 2006\": cannot parse \"\" as \"2\"")
|
s.Assert().Contains(output, "Error: failed to parse not before: parsing time \"Jan\" as \"Jan 2 15:04:05 2006\": cannot parse \"\" as \"2\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateCertificateRSAWith4096Bits() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--bits=4096", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tSelf-Signed")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tCA: false, CSR: false, Signature Algorithm: SHA256-RSA, Public Key Algorithm: RSA, Bits: 4096")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/public.crt")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateCertificateWithCustomizedSubject() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--common-name=example.com", "--sans='*.example.com'", "--country=Australia", "--organization='Acme Co.'", "--organizational-unit=Tech", "--province=QLD", "--street-address='123 Smith St'", "--postcode=4000", "--locality=Internet", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tSelf-Signed")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Acme Co.], Organizational Unit: [Tech]")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [Australia], Province: [QLD], Street Address: [123 Smith St], Postal Code: [4000], Locality: [Internet]")
|
||||||
|
s.Assert().Contains(output, "\tCA: false, CSR: false, Signature Algorithm: SHA256-RSA, Public Key Algorithm: RSA, Bits: 2048")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/public.crt")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestShouldGenerateCertificateCA() {
|
func (s *CLISuite) TestShouldGenerateCertificateCA() {
|
||||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--ca"})
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--common-name='Authelia Standalone Root Certificate Authority'", "--ca", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tSelf-Signed")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: Authelia Standalone Root Certificate Authority, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tCA: true, CSR: false, Signature Algorithm: SHA256-RSA, Public Key Algorithm: RSA, Bits: 2048")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: ")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/ca.private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/ca.public.crt")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateCertificateCAAndSignCertificate() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--common-name='Authelia Standalone Root Certificate Authority'", "--ca", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tSelf-Signed")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: Authelia Standalone Root Certificate Authority, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tCA: true, CSR: false, Signature Algorithm: SHA256-RSA, Public Key Algorithm: RSA, Bits: 2048")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: ")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/ca.private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/ca.public.crt")
|
||||||
|
|
||||||
|
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--common-name=example.com", "--sans='*.example.com'", "--path.ca", "/tmp/", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tAuthelia Standalone Root Certificate Authority")
|
||||||
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, ", Expires: ")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tCA: false, CSR: false, Signature Algorithm: SHA256-RSA, Public Key Algorithm: RSA, Bits: 2048")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/public.crt")
|
||||||
|
|
||||||
|
// Check the certificates look fine.
|
||||||
|
privateKeyData, err := os.ReadFile("/tmp/private.pem")
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
|
||||||
|
certificateData, err := os.ReadFile("/tmp/public.crt")
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
|
||||||
|
privateKeyCAData, err := os.ReadFile("/tmp/ca.private.pem")
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
|
||||||
|
certificateCAData, err := os.ReadFile("/tmp/ca.public.crt")
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
|
||||||
|
s.Assert().False(bytes.Equal(privateKeyData, privateKeyCAData))
|
||||||
|
s.Assert().False(bytes.Equal(certificateData, certificateCAData))
|
||||||
|
|
||||||
|
privateKey, err := utils.ParseX509FromPEM(privateKeyData)
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().True(utils.IsX509PrivateKey(privateKey))
|
||||||
|
|
||||||
|
privateCAKey, err := utils.ParseX509FromPEM(privateKeyCAData)
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().True(utils.IsX509PrivateKey(privateCAKey))
|
||||||
|
|
||||||
|
c, err := utils.ParseX509FromPEM(certificateData)
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().False(utils.IsX509PrivateKey(c))
|
||||||
|
|
||||||
|
cCA, err := utils.ParseX509FromPEM(certificateCAData)
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().False(utils.IsX509PrivateKey(cCA))
|
||||||
|
|
||||||
|
certificate, ok := utils.CastX509AsCertificate(c)
|
||||||
|
s.Assert().True(ok)
|
||||||
|
|
||||||
|
certificateCA, ok := utils.CastX509AsCertificate(cCA)
|
||||||
|
s.Assert().True(ok)
|
||||||
|
|
||||||
|
s.Require().NotNil(certificate)
|
||||||
|
s.Require().NotNil(certificateCA)
|
||||||
|
|
||||||
|
err = certificate.CheckSignatureFrom(certificateCA)
|
||||||
|
|
||||||
s.Assert().NoError(err)
|
s.Assert().NoError(err)
|
||||||
s.Assert().Contains(output, "Certificate written to /tmp/cert.pem")
|
|
||||||
s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestShouldGenerateCertificateEd25519() {
|
func (s *CLISuite) TestShouldGenerateCertificateEd25519() {
|
||||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--ed25519"})
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ed25519", "generate", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
s.Assert().NoError(err)
|
s.Assert().NoError(err)
|
||||||
s.Assert().Contains(output, "Certificate written to /tmp/cert.pem")
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tSelf-Signed")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tCA: false, CSR: false, Signature Algorithm: Ed25519, Public Key Algorithm: Ed25519")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/public.crt")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldFailGenerateCertificateParseNotBefore() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ecdsa", "generate", "--not-before=invalid", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
|
s.Assert().NotNil(err)
|
||||||
|
s.Assert().Contains(output, "Error: failed to parse not before: parsing time \"invalid\" as \"Jan 2 15:04:05 2006\": cannot parse \"invalid\" as \"Jan\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestShouldFailGenerateCertificateECDSA() {
|
func (s *CLISuite) TestShouldFailGenerateCertificateECDSA() {
|
||||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--ecdsa-curve=invalid"})
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ecdsa", "generate", "--curve=invalid", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
s.Assert().NotNil(err)
|
s.Assert().NotNil(err)
|
||||||
s.Assert().Contains(output, "Failed to generate private key: unrecognized elliptic curve: \"invalid\"")
|
s.Assert().Contains(output, "Error: invalid curve 'invalid' was specified: curve must be P224, P256, P384, or P521")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestShouldGenerateCertificateECDSAP224() {
|
func (s *CLISuite) TestShouldGenerateCertificateECDSACurveP224() {
|
||||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--ecdsa-curve=P224"})
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ecdsa", "generate", "--curve=P224", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
s.Assert().NoError(err)
|
s.Assert().NoError(err)
|
||||||
s.Assert().Contains(output, "Certificate written to /tmp/cert.pem")
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tSelf-Signed")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tCA: false, CSR: false, Signature Algorithm: ECDSA-SHA256, Public Key Algorithm: ECDSA, Elliptic Curve: P-224")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/public.crt")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestShouldGenerateCertificateECDSAP256() {
|
func (s *CLISuite) TestShouldGenerateCertificateECDSACurveP256() {
|
||||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--ecdsa-curve=P256"})
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ecdsa", "generate", "--curve=P256", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
s.Assert().NoError(err)
|
s.Assert().NoError(err)
|
||||||
s.Assert().Contains(output, "Certificate written to /tmp/cert.pem")
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tSelf-Signed")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tCA: false, CSR: false, Signature Algorithm: ECDSA-SHA256, Public Key Algorithm: ECDSA, Elliptic Curve: P-256")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/public.crt")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestShouldGenerateCertificateECDSAP384() {
|
func (s *CLISuite) TestShouldGenerateCertificateECDSACurveP384() {
|
||||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--ecdsa-curve=P384"})
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ecdsa", "generate", "--curve=P384", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
s.Assert().NoError(err)
|
s.Assert().NoError(err)
|
||||||
s.Assert().Contains(output, "Certificate written to /tmp/cert.pem")
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tSelf-Signed")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tCA: false, CSR: false, Signature Algorithm: ECDSA-SHA256, Public Key Algorithm: ECDSA, Elliptic Curve: P-384")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/public.crt")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestShouldGenerateCertificateECDSAP521() {
|
func (s *CLISuite) TestShouldGenerateCertificateECDSACurveP521() {
|
||||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--ecdsa-curve=P521"})
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ecdsa", "generate", "--curve=P521", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"})
|
||||||
s.Assert().NoError(err)
|
s.Assert().NoError(err)
|
||||||
s.Assert().Contains(output, "Certificate written to /tmp/cert.pem")
|
s.Assert().Contains(output, "Generating Certificate")
|
||||||
s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
|
s.Assert().Contains(output, "\tSerial: ")
|
||||||
|
s.Assert().Contains(output, "Signed By:\n\tSelf-Signed")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "\tCommon Name: example.com, Organization: [Authelia], Organizational Unit: []")
|
||||||
|
s.Assert().Contains(output, "\tCountry: [], Province: [], Street Address: [], Postal Code: [], Locality: []")
|
||||||
|
s.Assert().Contains(output, "\tCA: false, CSR: false, Signature Algorithm: ECDSA-SHA256, Public Key Algorithm: ECDSA, Elliptic Curve: P-521")
|
||||||
|
s.Assert().Contains(output, "\tSubject Alternative Names: DNS.1:*.example.com")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tCertificate: /tmp/public.crt")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateRSAKeyPair() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "pair", "rsa", "generate", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating key pair")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Algorithm: RSA-256 2048 bits\n\n")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tPublic Key: /tmp/public.pem")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateRSAKeyPairWith4069Bits() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "pair", "rsa", "generate", "--bits=4096", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating key pair")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Algorithm: RSA-512 4096 bits\n\n")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tPublic Key: /tmp/public.pem")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateECDSAKeyPair() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "pair", "ecdsa", "generate", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating key pair")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Algorithm: ECDSA Curve P-256\n\n")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tPublic Key: /tmp/public.pem")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateECDSAKeyPairCurveP224() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "pair", "ecdsa", "generate", "--curve=P224", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating key pair")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Algorithm: ECDSA Curve P-224\n\n")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tPublic Key: /tmp/public.pem")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateECDSAKeyPairCurveP256() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "pair", "ecdsa", "generate", "--curve=P256", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating key pair")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Algorithm: ECDSA Curve P-256\n\n")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tPublic Key: /tmp/public.pem")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateECDSAKeyPairCurveP384() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "pair", "ecdsa", "generate", "--curve=P384", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating key pair")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Algorithm: ECDSA Curve P-384\n\n")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tPublic Key: /tmp/public.pem")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateECDSAKeyPairCurveP521() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "pair", "ecdsa", "generate", "--curve=P521", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating key pair")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Algorithm: ECDSA Curve P-521\n\n")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tPublic Key: /tmp/public.pem")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldGenerateEd25519KeyPair() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "pair", "ed25519", "generate", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
s.Assert().Contains(output, "Generating key pair")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Algorithm: Ed25519\n\n")
|
||||||
|
|
||||||
|
s.Assert().Contains(output, "Output Paths:")
|
||||||
|
s.Assert().Contains(output, "\tPrivate Key: /tmp/private.pem")
|
||||||
|
s.Assert().Contains(output, "\tPublic Key: /tmp/public.pem")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldNotGenerateECDSAKeyPairCurveInvalid() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "pair", "ecdsa", "generate", "--curve=invalid", "--directory=/tmp/"})
|
||||||
|
s.Assert().NotNil(err)
|
||||||
|
s.Assert().Contains(output, "Error: invalid curve 'invalid' was specified: curve must be P224, P256, P384, or P521")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldNotGenerateRSAWithBadCAPath() {
|
||||||
|
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--path.ca=/tmp/invalid", "--directory=/tmp/"})
|
||||||
|
s.Assert().NotNil(err)
|
||||||
|
s.Assert().Contains(output, "Error: could not read private key file '/tmp/invalid/ca.private.pem': open /tmp/invalid/ca.private.pem: no such file or directory\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldNotGenerateRSAWithBadCAFileNames() {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
output string
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--common-name='Authelia Standalone Root Certificate Authority'", "--ca", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
|
||||||
|
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--path.ca=/tmp/", "--file.ca-private-key=invalid.pem", "--directory=/tmp/"})
|
||||||
|
s.Assert().NotNil(err)
|
||||||
|
s.Assert().Contains(output, "Error: could not read private key file '/tmp/invalid.pem': open /tmp/invalid.pem: no such file or directory\n")
|
||||||
|
|
||||||
|
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--path.ca=/tmp/", "--file.ca-certificate=invalid.crt", "--directory=/tmp/"})
|
||||||
|
s.Assert().NotNil(err)
|
||||||
|
s.Assert().Contains(output, "Error: could not read certificate file '/tmp/invalid.crt': open /tmp/invalid.crt: no such file or directory\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLISuite) TestShouldNotGenerateRSAWithBadCAFileContent() {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
output string
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--common-name='Authelia Standalone Root Certificate Authority'", "--ca", "--directory=/tmp/"})
|
||||||
|
s.Assert().NoError(err)
|
||||||
|
|
||||||
|
s.Require().NoError(os.WriteFile("/tmp/ca.private.bad.pem", []byte("INVALID"), 0600)) //nolint:gosec
|
||||||
|
s.Require().NoError(os.WriteFile("/tmp/ca.public.bad.crt", []byte("INVALID"), 0600)) //nolint:gosec
|
||||||
|
|
||||||
|
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--path.ca=/tmp/", "--file.ca-private-key=ca.private.bad.pem", "--directory=/tmp/"})
|
||||||
|
s.Assert().NotNil(err)
|
||||||
|
s.Assert().Contains(output, "Error: could not parse private key from file '/tmp/ca.private.bad.pem': failed to parse PEM block containing the key\n")
|
||||||
|
|
||||||
|
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--path.ca=/tmp/", "--file.ca-certificate=ca.public.bad.crt", "--directory=/tmp/"})
|
||||||
|
s.Assert().NotNil(err)
|
||||||
|
s.Assert().Contains(output, "Error: could not parse certificate from file '/tmp/ca.public.bad.crt': failed to parse PEM block containing the key\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestStorageShouldShowErrWithoutConfig() {
|
func (s *CLISuite) TestStorageShouldShowErrWithoutConfig() {
|
||||||
|
|
|
@ -8,9 +8,9 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-rod/rod"
|
"github.com/go-rod/rod"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetLoginBaseURL returns the URL of the login portal and the path prefix if specified.
|
// GetLoginBaseURL returns the URL of the login portal and the path prefix if specified.
|
||||||
|
@ -24,7 +24,6 @@ func GetLoginBaseURL() string {
|
||||||
|
|
||||||
func (rs *RodSession) collectCoverage(page *rod.Page) {
|
func (rs *RodSession) collectCoverage(page *rod.Page) {
|
||||||
coverageDir := "../../web/.nyc_output"
|
coverageDir := "../../web/.nyc_output"
|
||||||
now := time.Now()
|
|
||||||
|
|
||||||
resp, err := page.Eval("() => JSON.stringify(window.__coverage__)")
|
resp, err := page.Eval("() => JSON.stringify(window.__coverage__)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -36,7 +35,7 @@ func (rs *RodSession) collectCoverage(page *rod.Page) {
|
||||||
_ = os.MkdirAll(coverageDir, 0775)
|
_ = os.MkdirAll(coverageDir, 0775)
|
||||||
|
|
||||||
if coverageData != "<nil>" {
|
if coverageData != "<nil>" {
|
||||||
err = os.WriteFile(fmt.Sprintf("%s/coverage-%d.json", coverageDir, now.Unix()), []byte(coverageData), 0664) //nolint:gosec
|
err = os.WriteFile(fmt.Sprintf("%s/coverage-%s.json", coverageDir, uuid.New().String()), []byte(coverageData), 0664) //nolint:gosec
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,253 +0,0 @@
|
||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/ed25519"
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/pem"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
|
||||||
"github.com/authelia/authelia/v4/internal/logging"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PEMBlockType represent an enum of the existing PEM block types.
|
|
||||||
type PEMBlockType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Certificate block type.
|
|
||||||
Certificate PEMBlockType = iota
|
|
||||||
// PrivateKey block type.
|
|
||||||
PrivateKey
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewTLSConfig generates a tls.Config from a schema.TLSConfig and a x509.CertPool.
|
|
||||||
func NewTLSConfig(config *schema.TLSConfig, defaultMinVersion uint16, certPool *x509.CertPool) (tlsConfig *tls.Config) {
|
|
||||||
minVersion, err := TLSStringToTLSConfigVersion(config.MinimumVersion)
|
|
||||||
if err != nil {
|
|
||||||
minVersion = defaultMinVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
return &tls.Config{
|
|
||||||
ServerName: config.ServerName,
|
|
||||||
InsecureSkipVerify: config.SkipVerify, //nolint:gosec // Informed choice by user. Off by default.
|
|
||||||
MinVersion: minVersion,
|
|
||||||
RootCAs: certPool,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewX509CertPool generates a x509.CertPool from the system PKI and the directory specified.
|
|
||||||
func NewX509CertPool(directory string) (certPool *x509.CertPool, warnings []error, errors []error) {
|
|
||||||
certPool, err := x509.SystemCertPool()
|
|
||||||
if err != nil {
|
|
||||||
warnings = append(warnings, fmt.Errorf("could not load system certificate pool which may result in untrusted certificate issues: %v", err))
|
|
||||||
certPool = x509.NewCertPool()
|
|
||||||
}
|
|
||||||
|
|
||||||
logger := logging.Logger()
|
|
||||||
|
|
||||||
logger.Tracef("Starting scan of directory %s for certificates", directory)
|
|
||||||
|
|
||||||
if directory != "" {
|
|
||||||
certsFileInfo, err := os.ReadDir(directory)
|
|
||||||
if err != nil {
|
|
||||||
errors = append(errors, fmt.Errorf("could not read certificates from directory %v", err))
|
|
||||||
} else {
|
|
||||||
for _, certFileInfo := range certsFileInfo {
|
|
||||||
nameLower := strings.ToLower(certFileInfo.Name())
|
|
||||||
|
|
||||||
if !certFileInfo.IsDir() && (strings.HasSuffix(nameLower, ".cer") || strings.HasSuffix(nameLower, ".crt") || strings.HasSuffix(nameLower, ".pem")) {
|
|
||||||
certPath := filepath.Join(directory, certFileInfo.Name())
|
|
||||||
|
|
||||||
logger.Tracef("Found possible cert %s, attempting to add it to the pool", certPath)
|
|
||||||
|
|
||||||
certBytes, err := os.ReadFile(certPath)
|
|
||||||
if err != nil {
|
|
||||||
errors = append(errors, fmt.Errorf("could not read certificate %v", err))
|
|
||||||
} else if ok := certPool.AppendCertsFromPEM(certBytes); !ok {
|
|
||||||
errors = append(errors, fmt.Errorf("could not import certificate %s", certFileInfo.Name()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Tracef("Finished scan of directory %s for certificates", directory)
|
|
||||||
|
|
||||||
return certPool, warnings, errors
|
|
||||||
}
|
|
||||||
|
|
||||||
// TLSStringToTLSConfigVersion returns a go crypto/tls version for a tls.Config based on string input.
|
|
||||||
func TLSStringToTLSConfigVersion(input string) (version uint16, err error) {
|
|
||||||
switch strings.ToUpper(input) {
|
|
||||||
case "TLS1.3", TLS13:
|
|
||||||
return tls.VersionTLS13, nil
|
|
||||||
case "TLS1.2", TLS12:
|
|
||||||
return tls.VersionTLS12, nil
|
|
||||||
case "TLS1.1", TLS11:
|
|
||||||
return tls.VersionTLS11, nil
|
|
||||||
case "TLS1.0", TLS10:
|
|
||||||
return tls.VersionTLS10, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, ErrTLSVersionNotSupported
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateCertificate generate a certificate given a private key. RSA, Ed25519 and ECDSA are officially supported.
|
|
||||||
func GenerateCertificate(privateKeyBuilder PrivateKeyBuilder, hosts []string, validFrom time.Time, validFor time.Duration, isCA bool) ([]byte, []byte, error) {
|
|
||||||
privateKey, err := privateKeyBuilder.Build()
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("unable to build private key: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
notBefore := validFrom
|
|
||||||
notAfter := validFrom.Add(validFor)
|
|
||||||
|
|
||||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
|
||||||
|
|
||||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("failed to generate serial number: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
template := x509.Certificate{
|
|
||||||
SerialNumber: serialNumber,
|
|
||||||
Subject: pkix.Name{
|
|
||||||
Organization: []string{"Acme Co"},
|
|
||||||
},
|
|
||||||
NotBefore: notBefore,
|
|
||||||
NotAfter: notAfter,
|
|
||||||
|
|
||||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
|
||||||
BasicConstraintsValid: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, h := range hosts {
|
|
||||||
if ip := net.ParseIP(h); ip != nil {
|
|
||||||
template.IPAddresses = append(template.IPAddresses, ip)
|
|
||||||
} else {
|
|
||||||
template.DNSNames = append(template.DNSNames, h)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if isCA {
|
|
||||||
template.IsCA = true
|
|
||||||
template.KeyUsage |= x509.KeyUsageCertSign
|
|
||||||
}
|
|
||||||
|
|
||||||
certDERBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(privateKey), privateKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("failed to create certificate: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
certPEMBytes, err := ConvertDERToPEM(certDERBytes, Certificate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("faile to convert certificate in DER format into PEM: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
keyDERBytes, err := x509.MarshalPKCS8PrivateKey(privateKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("failed to marshal private key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
keyPEMBytes, err := ConvertDERToPEM(keyDERBytes, PrivateKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("faile to convert certificate in DER format into PEM: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return certPEMBytes, keyPEMBytes, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConvertDERToPEM convert certificate in DER format into PEM format.
|
|
||||||
func ConvertDERToPEM(der []byte, blockType PEMBlockType) ([]byte, error) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
|
|
||||||
var blockTypeStr string
|
|
||||||
|
|
||||||
switch blockType {
|
|
||||||
case Certificate:
|
|
||||||
blockTypeStr = "CERTIFICATE"
|
|
||||||
case PrivateKey:
|
|
||||||
blockTypeStr = "PRIVATE KEY"
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unknown PEM block type %d", blockType)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := pem.Encode(&buf, &pem.Block{Type: blockTypeStr, Bytes: der}); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to encode DER data into PEM: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func publicKey(privateKey interface{}) interface{} {
|
|
||||||
switch k := privateKey.(type) {
|
|
||||||
case *rsa.PrivateKey:
|
|
||||||
return &k.PublicKey
|
|
||||||
case *ecdsa.PrivateKey:
|
|
||||||
return &k.PublicKey
|
|
||||||
case ed25519.PrivateKey:
|
|
||||||
return k.Public().(ed25519.PublicKey)
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrivateKeyBuilder interface for a private key builder.
|
|
||||||
type PrivateKeyBuilder interface {
|
|
||||||
Build() (interface{}, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RSAKeyBuilder builder of RSA private key.
|
|
||||||
type RSAKeyBuilder struct {
|
|
||||||
keySizeInBits int
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithKeySize configure the key size to use with RSA.
|
|
||||||
func (rkb RSAKeyBuilder) WithKeySize(bits int) RSAKeyBuilder {
|
|
||||||
rkb.keySizeInBits = bits
|
|
||||||
return rkb
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a RSA private key.
|
|
||||||
func (rkb RSAKeyBuilder) Build() (interface{}, error) {
|
|
||||||
return rsa.GenerateKey(rand.Reader, rkb.keySizeInBits)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ed25519KeyBuilder builder of Ed25519 private key.
|
|
||||||
type Ed25519KeyBuilder struct{}
|
|
||||||
|
|
||||||
// Build an Ed25519 private key.
|
|
||||||
func (ekb Ed25519KeyBuilder) Build() (interface{}, error) {
|
|
||||||
_, priv, err := ed25519.GenerateKey(rand.Reader)
|
|
||||||
return priv, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// ECDSAKeyBuilder builder of ECDSA private key.
|
|
||||||
type ECDSAKeyBuilder struct {
|
|
||||||
curve elliptic.Curve
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithCurve configure the curve to use for the ECDSA private key.
|
|
||||||
func (ekb ECDSAKeyBuilder) WithCurve(curve elliptic.Curve) ECDSAKeyBuilder {
|
|
||||||
ekb.curve = curve
|
|
||||||
return ekb
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build an ECDSA private key.
|
|
||||||
func (ekb ECDSAKeyBuilder) Build() (interface{}, error) {
|
|
||||||
return ecdsa.GenerateKey(ekb.curve, rand.Reader)
|
|
||||||
}
|
|
|
@ -1,169 +0,0 @@
|
||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/tls"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestShouldSetupDefaultTLSMinVersionOnErr(t *testing.T) {
|
|
||||||
schemaTLSConfig := &schema.TLSConfig{
|
|
||||||
MinimumVersion: "NotAVersion",
|
|
||||||
ServerName: "golang.org",
|
|
||||||
SkipVerify: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
tlsConfig := NewTLSConfig(schemaTLSConfig, tls.VersionTLS12, nil)
|
|
||||||
|
|
||||||
assert.Equal(t, uint16(tls.VersionTLS12), tlsConfig.MinVersion)
|
|
||||||
assert.Equal(t, "golang.org", tlsConfig.ServerName)
|
|
||||||
assert.True(t, tlsConfig.InsecureSkipVerify)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestShouldReturnCorrectTLSVersions(t *testing.T) {
|
|
||||||
tls13 := uint16(tls.VersionTLS13)
|
|
||||||
tls12 := uint16(tls.VersionTLS12)
|
|
||||||
tls11 := uint16(tls.VersionTLS11)
|
|
||||||
tls10 := uint16(tls.VersionTLS10)
|
|
||||||
|
|
||||||
version, err := TLSStringToTLSConfigVersion(TLS13)
|
|
||||||
assert.Equal(t, tls13, version)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
version, err = TLSStringToTLSConfigVersion("TLS" + TLS13)
|
|
||||||
assert.Equal(t, tls13, version)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
version, err = TLSStringToTLSConfigVersion(TLS12)
|
|
||||||
assert.Equal(t, tls12, version)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
version, err = TLSStringToTLSConfigVersion("TLS" + TLS12)
|
|
||||||
assert.Equal(t, tls12, version)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
version, err = TLSStringToTLSConfigVersion(TLS11)
|
|
||||||
assert.Equal(t, tls11, version)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
version, err = TLSStringToTLSConfigVersion("TLS" + TLS11)
|
|
||||||
assert.Equal(t, tls11, version)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
version, err = TLSStringToTLSConfigVersion(TLS10)
|
|
||||||
assert.Equal(t, tls10, version)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
version, err = TLSStringToTLSConfigVersion("TLS" + TLS10)
|
|
||||||
assert.Equal(t, tls10, version)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestShouldReturnZeroAndErrorOnInvalidTLSVersions(t *testing.T) {
|
|
||||||
version, err := TLSStringToTLSConfigVersion("TLS1.4")
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Equal(t, uint16(0), version)
|
|
||||||
assert.EqualError(t, err, "supplied tls version isn't supported")
|
|
||||||
|
|
||||||
version, err = TLSStringToTLSConfigVersion("SSL3.0")
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Equal(t, uint16(0), version)
|
|
||||||
assert.EqualError(t, err, "supplied tls version isn't supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestShouldReturnErrWhenX509DirectoryNotExist(t *testing.T) {
|
|
||||||
pool, warnings, errors := NewX509CertPool("/tmp/asdfzyxabc123/not/a/real/dir")
|
|
||||||
assert.NotNil(t, pool)
|
|
||||||
|
|
||||||
if runtime.GOOS == windows {
|
|
||||||
require.Len(t, warnings, 1)
|
|
||||||
assert.EqualError(t, warnings[0], "could not load system certificate pool which may result in untrusted certificate issues: crypto/x509: system root pool is not available on Windows")
|
|
||||||
} else {
|
|
||||||
assert.Len(t, warnings, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
require.Len(t, errors, 1)
|
|
||||||
|
|
||||||
if runtime.GOOS == windows {
|
|
||||||
assert.EqualError(t, errors[0], "could not read certificates from directory open /tmp/asdfzyxabc123/not/a/real/dir: The system cannot find the path specified.")
|
|
||||||
} else {
|
|
||||||
assert.EqualError(t, errors[0], "could not read certificates from directory open /tmp/asdfzyxabc123/not/a/real/dir: no such file or directory")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestShouldNotReturnErrWhenX509DirectoryExist(t *testing.T) {
|
|
||||||
pool, warnings, errors := NewX509CertPool("/tmp")
|
|
||||||
assert.NotNil(t, pool)
|
|
||||||
|
|
||||||
if runtime.GOOS == windows {
|
|
||||||
require.Len(t, warnings, 1)
|
|
||||||
assert.EqualError(t, warnings[0], "could not load system certificate pool which may result in untrusted certificate issues: crypto/x509: system root pool is not available on Windows")
|
|
||||||
} else {
|
|
||||||
assert.Len(t, warnings, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Len(t, errors, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestShouldReadCertsFromDirectoryButNotKeys(t *testing.T) {
|
|
||||||
pool, warnings, errors := NewX509CertPool("../suites/common/ssl/")
|
|
||||||
assert.NotNil(t, pool)
|
|
||||||
require.Len(t, errors, 1)
|
|
||||||
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
require.Len(t, warnings, 1)
|
|
||||||
assert.EqualError(t, warnings[0], "could not load system certificate pool which may result in untrusted certificate issues: crypto/x509: system root pool is not available on Windows")
|
|
||||||
} else {
|
|
||||||
assert.Len(t, warnings, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.EqualError(t, errors[0], "could not import certificate key.pem")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestShouldGenerateCertificateAndPersistIt(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
Name string
|
|
||||||
PrivateKeyBuilder PrivateKeyBuilder
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
Name: "P224",
|
|
||||||
PrivateKeyBuilder: ECDSAKeyBuilder{}.WithCurve(elliptic.P224()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "P256",
|
|
||||||
PrivateKeyBuilder: ECDSAKeyBuilder{}.WithCurve(elliptic.P256()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "P384",
|
|
||||||
PrivateKeyBuilder: ECDSAKeyBuilder{}.WithCurve(elliptic.P384()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "P521",
|
|
||||||
PrivateKeyBuilder: ECDSAKeyBuilder{}.WithCurve(elliptic.P521()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "Ed25519",
|
|
||||||
PrivateKeyBuilder: Ed25519KeyBuilder{},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "RSA",
|
|
||||||
PrivateKeyBuilder: RSAKeyBuilder{keySizeInBits: 2048},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
|
||||||
t.Run(tc.Name, func(t *testing.T) {
|
|
||||||
certBytes, keyBytes, err := GenerateCertificate(tc.PrivateKeyBuilder, []string{"authelia.com", "example.org"}, time.Now(), 3*time.Hour, false)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.True(t, len(certBytes) > 0)
|
|
||||||
assert.True(t, len(keyBytes) > 0)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -31,6 +31,36 @@ const (
|
||||||
unknown = "unknown"
|
unknown = "unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// X.509 consts.
|
||||||
|
const (
|
||||||
|
BlockTypeRSAPrivateKey = "RSA PRIVATE KEY"
|
||||||
|
BlockTypeRSAPublicKey = "RSA PUBLIC KEY"
|
||||||
|
BlockTypeECDSAPrivateKey = "EC PRIVATE KEY"
|
||||||
|
BlockTypePKCS8PrivateKey = "PRIVATE KEY"
|
||||||
|
BlockTypePKIXPublicKey = "PUBLIC KEY"
|
||||||
|
BlockTypeCertificate = "CERTIFICATE"
|
||||||
|
BlockTypeCertificateRequest = "CERTIFICATE REQUEST"
|
||||||
|
|
||||||
|
KeyAlgorithmRSA = "RSA"
|
||||||
|
KeyAlgorithmECDSA = "ECDSA"
|
||||||
|
KeyAlgorithmEd25519 = "ED25519"
|
||||||
|
|
||||||
|
HashAlgorithmSHA1 = "SHA1"
|
||||||
|
HashAlgorithmSHA256 = "SHA256"
|
||||||
|
HashAlgorithmSHA384 = "SHA384"
|
||||||
|
HashAlgorithmSHA512 = "SHA512"
|
||||||
|
|
||||||
|
EllipticCurveP224 = "P224"
|
||||||
|
EllipticCurveP256 = "P256"
|
||||||
|
EllipticCurveP384 = "P384"
|
||||||
|
EllipticCurveP521 = "P521"
|
||||||
|
|
||||||
|
EllipticCurveAltP224 = "P-224"
|
||||||
|
EllipticCurveAltP256 = "P-256"
|
||||||
|
EllipticCurveAltP384 = "P-384"
|
||||||
|
EllipticCurveAltP521 = "P-521"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Hour is an int based representation of the time unit.
|
// Hour is an int based representation of the time unit.
|
||||||
Hour = time.Minute * 60 //nolint:revive
|
Hour = time.Minute * 60 //nolint:revive
|
||||||
|
|
|
@ -0,0 +1,582 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"encoding/pem"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||||||
|
"github.com/authelia/authelia/v4/internal/logging"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PEMBlockType represent an enum of the existing PEM block types.
|
||||||
|
type PEMBlockType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Certificate block type.
|
||||||
|
Certificate PEMBlockType = iota
|
||||||
|
// PrivateKey block type.
|
||||||
|
PrivateKey
|
||||||
|
)
|
||||||
|
|
||||||
|
// GenerateCertificate generate a certificate given a private key. RSA, Ed25519 and ECDSA are officially supported.
|
||||||
|
func GenerateCertificate(privateKeyBuilder PrivateKeyBuilder, hosts []string, validFrom time.Time, validFor time.Duration, isCA bool) ([]byte, []byte, error) {
|
||||||
|
privateKey, err := privateKeyBuilder.Build()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("unable to build private key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
notBefore := validFrom
|
||||||
|
notAfter := validFrom.Add(validFor)
|
||||||
|
|
||||||
|
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||||
|
|
||||||
|
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to generate serial number: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
template := x509.Certificate{
|
||||||
|
SerialNumber: serialNumber,
|
||||||
|
Subject: pkix.Name{
|
||||||
|
Organization: []string{"Acme Co"},
|
||||||
|
},
|
||||||
|
NotBefore: notBefore,
|
||||||
|
NotAfter: notAfter,
|
||||||
|
|
||||||
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||||
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, h := range hosts {
|
||||||
|
if ip := net.ParseIP(h); ip != nil {
|
||||||
|
template.IPAddresses = append(template.IPAddresses, ip)
|
||||||
|
} else {
|
||||||
|
template.DNSNames = append(template.DNSNames, h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isCA {
|
||||||
|
template.IsCA = true
|
||||||
|
template.KeyUsage |= x509.KeyUsageCertSign
|
||||||
|
}
|
||||||
|
|
||||||
|
certDERBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(privateKey), privateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to create certificate: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
certPEMBytes, err := ConvertDERToPEM(certDERBytes, Certificate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to convert certificate in DER format into PEM: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyDERBytes, err := x509.MarshalPKCS8PrivateKey(privateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to marshal private key: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPEMBytes, err := ConvertDERToPEM(keyDERBytes, PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("faile to convert certificate in DER format into PEM: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return certPEMBytes, keyPEMBytes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertDERToPEM convert certificate in DER format into PEM format.
|
||||||
|
func ConvertDERToPEM(der []byte, blockType PEMBlockType) ([]byte, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
var blockTypeStr string
|
||||||
|
|
||||||
|
switch blockType {
|
||||||
|
case Certificate:
|
||||||
|
blockTypeStr = "CERTIFICATE"
|
||||||
|
case PrivateKey:
|
||||||
|
blockTypeStr = "PRIVATE KEY"
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown PEM block type %d", blockType)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := pem.Encode(&buf, &pem.Block{Type: blockTypeStr, Bytes: der}); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to encode DER data into PEM: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func publicKey(privateKey interface{}) interface{} {
|
||||||
|
switch k := privateKey.(type) {
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
return &k.PublicKey
|
||||||
|
case *ecdsa.PrivateKey:
|
||||||
|
return &k.PublicKey
|
||||||
|
case ed25519.PrivateKey:
|
||||||
|
return k.Public().(ed25519.PublicKey)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrivateKeyBuilder interface for a private key builder.
|
||||||
|
type PrivateKeyBuilder interface {
|
||||||
|
Build() (interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RSAKeyBuilder builder of RSA private key.
|
||||||
|
type RSAKeyBuilder struct {
|
||||||
|
keySizeInBits int
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithKeySize configure the key size to use with RSA.
|
||||||
|
func (rkb RSAKeyBuilder) WithKeySize(bits int) RSAKeyBuilder {
|
||||||
|
rkb.keySizeInBits = bits
|
||||||
|
return rkb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a RSA private key.
|
||||||
|
func (rkb RSAKeyBuilder) Build() (interface{}, error) {
|
||||||
|
return rsa.GenerateKey(rand.Reader, rkb.keySizeInBits)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ed25519KeyBuilder builder of Ed25519 private key.
|
||||||
|
type Ed25519KeyBuilder struct{}
|
||||||
|
|
||||||
|
// Build an Ed25519 private key.
|
||||||
|
func (ekb Ed25519KeyBuilder) Build() (interface{}, error) {
|
||||||
|
_, priv, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
return priv, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ECDSAKeyBuilder builder of ECDSA private key.
|
||||||
|
type ECDSAKeyBuilder struct {
|
||||||
|
curve elliptic.Curve
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCurve configure the curve to use for the ECDSA private key.
|
||||||
|
func (ekb ECDSAKeyBuilder) WithCurve(curve elliptic.Curve) ECDSAKeyBuilder {
|
||||||
|
ekb.curve = curve
|
||||||
|
return ekb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build an ECDSA private key.
|
||||||
|
func (ekb ECDSAKeyBuilder) Build() (interface{}, error) {
|
||||||
|
return ecdsa.GenerateKey(ekb.curve, rand.Reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseX509FromPEM parses PEM bytes and returns a PKCS key.
|
||||||
|
func ParseX509FromPEM(data []byte) (key interface{}, err error) {
|
||||||
|
block, _ := pem.Decode(data)
|
||||||
|
if block == nil {
|
||||||
|
return nil, errors.New("failed to parse PEM block containing the key")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch block.Type {
|
||||||
|
case BlockTypeRSAPrivateKey:
|
||||||
|
key, err = x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||||
|
case BlockTypeECDSAPrivateKey:
|
||||||
|
key, err = x509.ParseECPrivateKey(block.Bytes)
|
||||||
|
case BlockTypePKCS8PrivateKey:
|
||||||
|
key, err = x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||||
|
case BlockTypeRSAPublicKey:
|
||||||
|
key, err = x509.ParsePKCS1PublicKey(block.Bytes)
|
||||||
|
case BlockTypePKIXPublicKey:
|
||||||
|
key, err = x509.ParsePKIXPublicKey(block.Bytes)
|
||||||
|
case BlockTypeCertificate:
|
||||||
|
key, err = x509.ParseCertificate(block.Bytes)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown block type: %s", block.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return key, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CastX509AsCertificate converts an interface to an *x509.Certificate.
|
||||||
|
func CastX509AsCertificate(c interface{}) (certificate *x509.Certificate, ok bool) {
|
||||||
|
switch t := c.(type) {
|
||||||
|
case x509.Certificate:
|
||||||
|
return &t, true
|
||||||
|
case *x509.Certificate:
|
||||||
|
return t, true
|
||||||
|
default:
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsX509PrivateKey returns true if the provided interface is an rsa.PrivateKey, ecdsa.PrivateKey, or ed25519.PrivateKey.
|
||||||
|
func IsX509PrivateKey(i interface{}) bool {
|
||||||
|
switch i.(type) {
|
||||||
|
case rsa.PrivateKey, *rsa.PrivateKey, ecdsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey, *ed25519.PrivateKey:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTLSConfig generates a tls.Config from a schema.TLSConfig and a x509.CertPool.
|
||||||
|
func NewTLSConfig(config *schema.TLSConfig, defaultMinVersion uint16, certPool *x509.CertPool) (tlsConfig *tls.Config) {
|
||||||
|
minVersion, err := TLSStringToTLSConfigVersion(config.MinimumVersion)
|
||||||
|
if err != nil {
|
||||||
|
minVersion = defaultMinVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
return &tls.Config{
|
||||||
|
ServerName: config.ServerName,
|
||||||
|
InsecureSkipVerify: config.SkipVerify, //nolint:gosec // Informed choice by user. Off by default.
|
||||||
|
MinVersion: minVersion,
|
||||||
|
RootCAs: certPool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewX509CertPool generates a x509.CertPool from the system PKI and the directory specified.
|
||||||
|
func NewX509CertPool(directory string) (certPool *x509.CertPool, warnings []error, errors []error) {
|
||||||
|
certPool, err := x509.SystemCertPool()
|
||||||
|
if err != nil {
|
||||||
|
warnings = append(warnings, fmt.Errorf("could not load system certificate pool which may result in untrusted certificate issues: %v", err))
|
||||||
|
certPool = x509.NewCertPool()
|
||||||
|
}
|
||||||
|
|
||||||
|
logger := logging.Logger()
|
||||||
|
|
||||||
|
logger.Tracef("Starting scan of directory %s for certificates", directory)
|
||||||
|
|
||||||
|
if directory != "" {
|
||||||
|
certsFileInfo, err := os.ReadDir(directory)
|
||||||
|
if err != nil {
|
||||||
|
errors = append(errors, fmt.Errorf("could not read certificates from directory %v", err))
|
||||||
|
} else {
|
||||||
|
for _, certFileInfo := range certsFileInfo {
|
||||||
|
nameLower := strings.ToLower(certFileInfo.Name())
|
||||||
|
|
||||||
|
if !certFileInfo.IsDir() && (strings.HasSuffix(nameLower, ".cer") || strings.HasSuffix(nameLower, ".crt") || strings.HasSuffix(nameLower, ".pem")) {
|
||||||
|
certPath := filepath.Join(directory, certFileInfo.Name())
|
||||||
|
|
||||||
|
logger.Tracef("Found possible cert %s, attempting to add it to the pool", certPath)
|
||||||
|
|
||||||
|
certBytes, err := os.ReadFile(certPath)
|
||||||
|
if err != nil {
|
||||||
|
errors = append(errors, fmt.Errorf("could not read certificate %v", err))
|
||||||
|
} else if ok := certPool.AppendCertsFromPEM(certBytes); !ok {
|
||||||
|
errors = append(errors, fmt.Errorf("could not import certificate %s", certFileInfo.Name()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Tracef("Finished scan of directory %s for certificates", directory)
|
||||||
|
|
||||||
|
return certPool, warnings, errors
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLSStringToTLSConfigVersion returns a go crypto/tls version for a tls.Config based on string input.
|
||||||
|
func TLSStringToTLSConfigVersion(input string) (version uint16, err error) {
|
||||||
|
switch strings.ToUpper(input) {
|
||||||
|
case "TLS1.3", TLS13:
|
||||||
|
return tls.VersionTLS13, nil
|
||||||
|
case "TLS1.2", TLS12:
|
||||||
|
return tls.VersionTLS12, nil
|
||||||
|
case "TLS1.1", TLS11:
|
||||||
|
return tls.VersionTLS11, nil
|
||||||
|
case "TLS1.0", TLS10:
|
||||||
|
return tls.VersionTLS10, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, ErrTLSVersionNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteCertificateBytesToPEM writes a certificate/csr to a file in the PEM format.
|
||||||
|
func WriteCertificateBytesToPEM(cert []byte, path string, csr bool) (err error) {
|
||||||
|
out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to open %s for writing: %w", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
blockType := BlockTypeCertificate
|
||||||
|
if csr {
|
||||||
|
blockType = BlockTypeCertificateRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = pem.Encode(out, &pem.Block{Bytes: cert, Type: blockType}); err != nil {
|
||||||
|
_ = out.Close()
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteKeyToPEM writes a key that can be encoded as a PEM to a file in the PEM format.
|
||||||
|
func WriteKeyToPEM(key interface{}, path string, pkcs8 bool) (err error) {
|
||||||
|
pemBlock, err := PEMBlockFromX509Key(key, pkcs8)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to open %s for writing: %w", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = pem.Encode(out, pemBlock); err != nil {
|
||||||
|
_ = out.Close()
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// PEMBlockFromX509Key turns a PublicKey or PrivateKey into a pem.Block.
|
||||||
|
func PEMBlockFromX509Key(key interface{}, pkcs8 bool) (pemBlock *pem.Block, err error) {
|
||||||
|
var (
|
||||||
|
data []byte
|
||||||
|
blockType string
|
||||||
|
)
|
||||||
|
|
||||||
|
switch k := key.(type) {
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
if pkcs8 {
|
||||||
|
blockType = BlockTypePKCS8PrivateKey
|
||||||
|
data, err = x509.MarshalPKCS8PrivateKey(key)
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
blockType = BlockTypeRSAPrivateKey
|
||||||
|
data = x509.MarshalPKCS1PrivateKey(k)
|
||||||
|
case *ecdsa.PrivateKey:
|
||||||
|
if pkcs8 {
|
||||||
|
blockType = BlockTypePKCS8PrivateKey
|
||||||
|
data, err = x509.MarshalPKCS8PrivateKey(key)
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
blockType = BlockTypeECDSAPrivateKey
|
||||||
|
data, err = x509.MarshalECPrivateKey(k)
|
||||||
|
case ed25519.PrivateKey:
|
||||||
|
blockType = BlockTypePKCS8PrivateKey
|
||||||
|
data, err = x509.MarshalPKCS8PrivateKey(k)
|
||||||
|
case *rsa.PublicKey:
|
||||||
|
if pkcs8 {
|
||||||
|
blockType = BlockTypePKIXPublicKey
|
||||||
|
data, err = x509.MarshalPKIXPublicKey(key)
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
blockType = BlockTypeRSAPublicKey
|
||||||
|
data = x509.MarshalPKCS1PublicKey(k)
|
||||||
|
case *ecdsa.PublicKey, ed25519.PublicKey:
|
||||||
|
blockType = BlockTypePKIXPublicKey
|
||||||
|
data, err = x509.MarshalPKIXPublicKey(k)
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("failed to match key type: %T", k)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to marshal key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pem.Block{
|
||||||
|
Type: blockType,
|
||||||
|
Bytes: data,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeySigAlgorithmFromString returns a x509.PublicKeyAlgorithm and x509.SignatureAlgorithm given a keyAlgorithm and signatureAlgorithm string.
|
||||||
|
func KeySigAlgorithmFromString(keyAlgorithm, signatureAlgorithm string) (keyAlg x509.PublicKeyAlgorithm, sigAlg x509.SignatureAlgorithm) {
|
||||||
|
keyAlg = PublicKeyAlgorithmFromString(keyAlgorithm)
|
||||||
|
|
||||||
|
if keyAlg == x509.UnknownPublicKeyAlgorithm {
|
||||||
|
return x509.UnknownPublicKeyAlgorithm, x509.UnknownSignatureAlgorithm
|
||||||
|
}
|
||||||
|
|
||||||
|
switch keyAlg {
|
||||||
|
case x509.RSA:
|
||||||
|
return keyAlg, RSASignatureAlgorithmFromString(signatureAlgorithm)
|
||||||
|
case x509.ECDSA:
|
||||||
|
return keyAlg, ECDSASignatureAlgorithmFromString(signatureAlgorithm)
|
||||||
|
case x509.Ed25519:
|
||||||
|
return keyAlg, x509.PureEd25519
|
||||||
|
default:
|
||||||
|
return keyAlg, x509.UnknownSignatureAlgorithm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublicKeyAlgorithmFromString returns a x509.PublicKeyAlgorithm given an appropriate string.
|
||||||
|
func PublicKeyAlgorithmFromString(algorithm string) (alg x509.PublicKeyAlgorithm) {
|
||||||
|
switch strings.ToUpper(algorithm) {
|
||||||
|
case KeyAlgorithmRSA:
|
||||||
|
return x509.RSA
|
||||||
|
case KeyAlgorithmECDSA:
|
||||||
|
return x509.ECDSA
|
||||||
|
case KeyAlgorithmEd25519:
|
||||||
|
return x509.Ed25519
|
||||||
|
default:
|
||||||
|
return x509.UnknownPublicKeyAlgorithm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RSASignatureAlgorithmFromString returns a x509.SignatureAlgorithm for the RSA x509.PublicKeyAlgorithm given an
|
||||||
|
// algorithm string.
|
||||||
|
func RSASignatureAlgorithmFromString(algorithm string) (alg x509.SignatureAlgorithm) {
|
||||||
|
switch strings.ToUpper(algorithm) {
|
||||||
|
case HashAlgorithmSHA1:
|
||||||
|
return x509.SHA1WithRSA
|
||||||
|
case HashAlgorithmSHA256:
|
||||||
|
return x509.SHA256WithRSA
|
||||||
|
case HashAlgorithmSHA384:
|
||||||
|
return x509.SHA384WithRSA
|
||||||
|
case HashAlgorithmSHA512:
|
||||||
|
return x509.SHA512WithRSA
|
||||||
|
default:
|
||||||
|
return x509.UnknownSignatureAlgorithm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ECDSASignatureAlgorithmFromString returns a x509.SignatureAlgorithm for the ECDSA x509.PublicKeyAlgorithm given an
|
||||||
|
// algorithm string.
|
||||||
|
func ECDSASignatureAlgorithmFromString(algorithm string) (alg x509.SignatureAlgorithm) {
|
||||||
|
switch strings.ToUpper(algorithm) {
|
||||||
|
case HashAlgorithmSHA1:
|
||||||
|
return x509.ECDSAWithSHA1
|
||||||
|
case HashAlgorithmSHA256:
|
||||||
|
return x509.ECDSAWithSHA256
|
||||||
|
case HashAlgorithmSHA384:
|
||||||
|
return x509.ECDSAWithSHA384
|
||||||
|
case HashAlgorithmSHA512:
|
||||||
|
return x509.ECDSAWithSHA512
|
||||||
|
default:
|
||||||
|
return x509.UnknownSignatureAlgorithm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EllipticCurveFromString turns a string into an elliptic.Curve.
|
||||||
|
func EllipticCurveFromString(curveString string) (curve elliptic.Curve) {
|
||||||
|
switch strings.ToUpper(curveString) {
|
||||||
|
case EllipticCurveAltP224, EllipticCurveP224:
|
||||||
|
return elliptic.P224()
|
||||||
|
case EllipticCurveAltP256, EllipticCurveP256:
|
||||||
|
return elliptic.P256()
|
||||||
|
case EllipticCurveAltP384, EllipticCurveP384:
|
||||||
|
return elliptic.P384()
|
||||||
|
case EllipticCurveAltP521, EllipticCurveP521:
|
||||||
|
return elliptic.P521()
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublicKeyFromPrivateKey returns a PublicKey when provided with a PrivateKey.
|
||||||
|
func PublicKeyFromPrivateKey(privateKey interface{}) (publicKey interface{}) {
|
||||||
|
switch k := privateKey.(type) {
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
return &k.PublicKey
|
||||||
|
case *ecdsa.PrivateKey:
|
||||||
|
return &k.PublicKey
|
||||||
|
case ed25519.PrivateKey:
|
||||||
|
return k.Public().(ed25519.PublicKey)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// X509ParseKeyUsage parses a list of key usages. If provided with an empty list returns a default of Key Encipherment
|
||||||
|
// and Digital Signature unless ca is true in which case it returns Cert Sign.
|
||||||
|
func X509ParseKeyUsage(keyUsages []string, ca bool) (keyUsage x509.KeyUsage) {
|
||||||
|
if len(keyUsages) == 0 {
|
||||||
|
keyUsage = x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature
|
||||||
|
if ca {
|
||||||
|
keyUsage |= x509.KeyUsageCertSign
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyUsage
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, keyUsageString := range keyUsages {
|
||||||
|
switch strings.ToLower(keyUsageString) {
|
||||||
|
case "digitalsignature", "digital_signature":
|
||||||
|
keyUsage |= x509.KeyUsageDigitalSignature
|
||||||
|
case "keyencipherment", "key_encipherment":
|
||||||
|
keyUsage |= x509.KeyUsageKeyEncipherment
|
||||||
|
case "dataencipherment", "data_encipherment":
|
||||||
|
keyUsage |= x509.KeyUsageDataEncipherment
|
||||||
|
case "keyagreement", "key_agreement":
|
||||||
|
keyUsage |= x509.KeyUsageKeyAgreement
|
||||||
|
case "certsign", "cert_sign", "certificatesign", "certificate_sign":
|
||||||
|
keyUsage |= x509.KeyUsageCertSign
|
||||||
|
case "crlsign", "crl_sign":
|
||||||
|
keyUsage |= x509.KeyUsageCRLSign
|
||||||
|
case "encipheronly", "encipher_only":
|
||||||
|
keyUsage |= x509.KeyUsageEncipherOnly
|
||||||
|
case "decipheronly", "decipher_only":
|
||||||
|
keyUsage |= x509.KeyUsageDecipherOnly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyUsage
|
||||||
|
}
|
||||||
|
|
||||||
|
// X509ParseExtendedKeyUsage parses a list of extended key usages. If provided with an empty list returns a default of
|
||||||
|
// Server Auth unless ca is true in which case it returns a default of Any.
|
||||||
|
func X509ParseExtendedKeyUsage(extKeyUsages []string, ca bool) (extKeyUsage []x509.ExtKeyUsage) {
|
||||||
|
if len(extKeyUsages) == 0 {
|
||||||
|
if ca {
|
||||||
|
extKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
|
||||||
|
} else {
|
||||||
|
extKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
|
||||||
|
}
|
||||||
|
|
||||||
|
return extKeyUsage
|
||||||
|
}
|
||||||
|
|
||||||
|
loop:
|
||||||
|
for _, extKeyUsageString := range extKeyUsages {
|
||||||
|
switch strings.ToLower(extKeyUsageString) {
|
||||||
|
case "any":
|
||||||
|
extKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
|
||||||
|
break loop
|
||||||
|
case "serverauth", "server_auth":
|
||||||
|
extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageServerAuth)
|
||||||
|
case "clientauth", "client_auth":
|
||||||
|
extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageClientAuth)
|
||||||
|
case "codesigning", "code_signing":
|
||||||
|
extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageCodeSigning)
|
||||||
|
case "emailprotection", "email_protection":
|
||||||
|
extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageEmailProtection)
|
||||||
|
case "ipsecendsystem", "ipsec_endsystem", "ipsec_end_system":
|
||||||
|
extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageIPSECEndSystem)
|
||||||
|
case "ipsectunnel", "ipsec_tunnel":
|
||||||
|
extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageIPSECTunnel)
|
||||||
|
case "ipsecuser", "ipsec_user":
|
||||||
|
extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageIPSECUser)
|
||||||
|
case "ocspsigning", "ocsp_signing":
|
||||||
|
extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageOCSPSigning)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return extKeyUsage
|
||||||
|
}
|
|
@ -0,0 +1,538 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestShouldSetupDefaultTLSMinVersionOnErr(t *testing.T) {
|
||||||
|
schemaTLSConfig := &schema.TLSConfig{
|
||||||
|
MinimumVersion: "NotAVersion",
|
||||||
|
ServerName: "golang.org",
|
||||||
|
SkipVerify: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsConfig := NewTLSConfig(schemaTLSConfig, tls.VersionTLS12, nil)
|
||||||
|
|
||||||
|
assert.Equal(t, uint16(tls.VersionTLS12), tlsConfig.MinVersion)
|
||||||
|
assert.Equal(t, "golang.org", tlsConfig.ServerName)
|
||||||
|
assert.True(t, tlsConfig.InsecureSkipVerify)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldReturnCorrectTLSVersions(t *testing.T) {
|
||||||
|
tls13 := uint16(tls.VersionTLS13)
|
||||||
|
tls12 := uint16(tls.VersionTLS12)
|
||||||
|
tls11 := uint16(tls.VersionTLS11)
|
||||||
|
tls10 := uint16(tls.VersionTLS10)
|
||||||
|
|
||||||
|
version, err := TLSStringToTLSConfigVersion(TLS13)
|
||||||
|
assert.Equal(t, tls13, version)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
version, err = TLSStringToTLSConfigVersion("TLS" + TLS13)
|
||||||
|
assert.Equal(t, tls13, version)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
version, err = TLSStringToTLSConfigVersion(TLS12)
|
||||||
|
assert.Equal(t, tls12, version)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
version, err = TLSStringToTLSConfigVersion("TLS" + TLS12)
|
||||||
|
assert.Equal(t, tls12, version)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
version, err = TLSStringToTLSConfigVersion(TLS11)
|
||||||
|
assert.Equal(t, tls11, version)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
version, err = TLSStringToTLSConfigVersion("TLS" + TLS11)
|
||||||
|
assert.Equal(t, tls11, version)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
version, err = TLSStringToTLSConfigVersion(TLS10)
|
||||||
|
assert.Equal(t, tls10, version)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
version, err = TLSStringToTLSConfigVersion("TLS" + TLS10)
|
||||||
|
assert.Equal(t, tls10, version)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldReturnZeroAndErrorOnInvalidTLSVersions(t *testing.T) {
|
||||||
|
version, err := TLSStringToTLSConfigVersion("TLS1.4")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, uint16(0), version)
|
||||||
|
assert.EqualError(t, err, "supplied tls version isn't supported")
|
||||||
|
|
||||||
|
version, err = TLSStringToTLSConfigVersion("SSL3.0")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, uint16(0), version)
|
||||||
|
assert.EqualError(t, err, "supplied tls version isn't supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldReturnErrWhenX509DirectoryNotExist(t *testing.T) {
|
||||||
|
pool, warnings, errors := NewX509CertPool("/tmp/asdfzyxabc123/not/a/real/dir")
|
||||||
|
assert.NotNil(t, pool)
|
||||||
|
|
||||||
|
if runtime.GOOS == windows {
|
||||||
|
require.Len(t, warnings, 1)
|
||||||
|
assert.EqualError(t, warnings[0], "could not load system certificate pool which may result in untrusted certificate issues: crypto/x509: system root pool is not available on Windows")
|
||||||
|
} else {
|
||||||
|
assert.Len(t, warnings, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Len(t, errors, 1)
|
||||||
|
|
||||||
|
if runtime.GOOS == windows {
|
||||||
|
assert.EqualError(t, errors[0], "could not read certificates from directory open /tmp/asdfzyxabc123/not/a/real/dir: The system cannot find the path specified.")
|
||||||
|
} else {
|
||||||
|
assert.EqualError(t, errors[0], "could not read certificates from directory open /tmp/asdfzyxabc123/not/a/real/dir: no such file or directory")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldNotReturnErrWhenX509DirectoryExist(t *testing.T) {
|
||||||
|
pool, warnings, errors := NewX509CertPool("/tmp")
|
||||||
|
assert.NotNil(t, pool)
|
||||||
|
|
||||||
|
if runtime.GOOS == windows {
|
||||||
|
require.Len(t, warnings, 1)
|
||||||
|
assert.EqualError(t, warnings[0], "could not load system certificate pool which may result in untrusted certificate issues: crypto/x509: system root pool is not available on Windows")
|
||||||
|
} else {
|
||||||
|
assert.Len(t, warnings, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Len(t, errors, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldReadCertsFromDirectoryButNotKeys(t *testing.T) {
|
||||||
|
pool, warnings, errors := NewX509CertPool("../suites/common/ssl/")
|
||||||
|
assert.NotNil(t, pool)
|
||||||
|
require.Len(t, errors, 1)
|
||||||
|
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
require.Len(t, warnings, 1)
|
||||||
|
assert.EqualError(t, warnings[0], "could not load system certificate pool which may result in untrusted certificate issues: crypto/x509: system root pool is not available on Windows")
|
||||||
|
} else {
|
||||||
|
assert.Len(t, warnings, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.EqualError(t, errors[0], "could not import certificate key.pem")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldGenerateCertificateAndPersistIt(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
Name string
|
||||||
|
PrivateKeyBuilder PrivateKeyBuilder
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "P224",
|
||||||
|
PrivateKeyBuilder: ECDSAKeyBuilder{}.WithCurve(elliptic.P224()),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P256",
|
||||||
|
PrivateKeyBuilder: ECDSAKeyBuilder{}.WithCurve(elliptic.P256()),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P384",
|
||||||
|
PrivateKeyBuilder: ECDSAKeyBuilder{}.WithCurve(elliptic.P384()),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P521",
|
||||||
|
PrivateKeyBuilder: ECDSAKeyBuilder{}.WithCurve(elliptic.P521()),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Ed25519",
|
||||||
|
PrivateKeyBuilder: Ed25519KeyBuilder{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "RSA",
|
||||||
|
PrivateKeyBuilder: RSAKeyBuilder{keySizeInBits: 2048},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.Name, func(t *testing.T) {
|
||||||
|
certBytes, keyBytes, err := GenerateCertificate(tc.PrivateKeyBuilder, []string{"authelia.com", "example.org"}, time.Now(), 3*time.Hour, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, len(certBytes) > 0)
|
||||||
|
assert.True(t, len(keyBytes) > 0)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldParseKeySigAlgorithm(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
Name string
|
||||||
|
InputKey, InputSig string
|
||||||
|
ExpectedKeyAlg x509.PublicKeyAlgorithm
|
||||||
|
ExpectedSigAlg x509.SignatureAlgorithm
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "ShouldNotParseInvalidKeyAlg",
|
||||||
|
InputKey: "DDD",
|
||||||
|
InputSig: "SHA1",
|
||||||
|
ExpectedKeyAlg: x509.UnknownPublicKeyAlgorithm,
|
||||||
|
ExpectedSigAlg: x509.UnknownSignatureAlgorithm,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyRSASigSHA1",
|
||||||
|
InputKey: "RSA",
|
||||||
|
InputSig: "SHA1",
|
||||||
|
ExpectedKeyAlg: x509.RSA,
|
||||||
|
ExpectedSigAlg: x509.SHA1WithRSA,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyRSASigSHA256",
|
||||||
|
InputKey: "RSA",
|
||||||
|
InputSig: "SHA256",
|
||||||
|
ExpectedKeyAlg: x509.RSA,
|
||||||
|
ExpectedSigAlg: x509.SHA256WithRSA,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyRSASigSHA384",
|
||||||
|
InputKey: "RSA",
|
||||||
|
InputSig: "SHA384",
|
||||||
|
ExpectedKeyAlg: x509.RSA,
|
||||||
|
ExpectedSigAlg: x509.SHA384WithRSA,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyRSASigSHA512",
|
||||||
|
InputKey: "RSA",
|
||||||
|
InputSig: "SHA512",
|
||||||
|
ExpectedKeyAlg: x509.RSA,
|
||||||
|
ExpectedSigAlg: x509.SHA512WithRSA,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldNotParseKeyRSASigInvalid",
|
||||||
|
InputKey: "RSA",
|
||||||
|
InputSig: "INVALID",
|
||||||
|
ExpectedKeyAlg: x509.RSA,
|
||||||
|
ExpectedSigAlg: x509.UnknownSignatureAlgorithm,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyECDSASigSHA1",
|
||||||
|
InputKey: "ECDSA",
|
||||||
|
InputSig: "SHA1",
|
||||||
|
ExpectedKeyAlg: x509.ECDSA,
|
||||||
|
ExpectedSigAlg: x509.ECDSAWithSHA1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyECDSASigSHA256",
|
||||||
|
InputKey: "ECDSA",
|
||||||
|
InputSig: "SHA256",
|
||||||
|
ExpectedKeyAlg: x509.ECDSA,
|
||||||
|
ExpectedSigAlg: x509.ECDSAWithSHA256,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyECDSASigSHA384",
|
||||||
|
InputKey: "ECDSA",
|
||||||
|
InputSig: "SHA384",
|
||||||
|
ExpectedKeyAlg: x509.ECDSA,
|
||||||
|
ExpectedSigAlg: x509.ECDSAWithSHA384,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyECDSASigSHA512",
|
||||||
|
InputKey: "ECDSA",
|
||||||
|
InputSig: "SHA512",
|
||||||
|
ExpectedKeyAlg: x509.ECDSA,
|
||||||
|
ExpectedSigAlg: x509.ECDSAWithSHA512,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldNotParseKeyECDSASigInvalid",
|
||||||
|
InputKey: "ECDSA",
|
||||||
|
InputSig: "INVALID",
|
||||||
|
ExpectedKeyAlg: x509.ECDSA,
|
||||||
|
ExpectedSigAlg: x509.UnknownSignatureAlgorithm,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyEd25519SigSHA1",
|
||||||
|
InputKey: "ED25519",
|
||||||
|
InputSig: "SHA1",
|
||||||
|
ExpectedKeyAlg: x509.Ed25519,
|
||||||
|
ExpectedSigAlg: x509.PureEd25519,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyEd25519SigSHA256",
|
||||||
|
InputKey: "ED25519",
|
||||||
|
InputSig: "SHA256",
|
||||||
|
ExpectedKeyAlg: x509.Ed25519,
|
||||||
|
ExpectedSigAlg: x509.PureEd25519,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyEd25519SigSHA384",
|
||||||
|
InputKey: "ED25519",
|
||||||
|
InputSig: "SHA384",
|
||||||
|
ExpectedKeyAlg: x509.Ed25519,
|
||||||
|
ExpectedSigAlg: x509.PureEd25519,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyEd25519SigSHA512",
|
||||||
|
InputKey: "ED25519",
|
||||||
|
InputSig: "SHA512",
|
||||||
|
ExpectedKeyAlg: x509.Ed25519,
|
||||||
|
ExpectedSigAlg: x509.PureEd25519,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ShouldParseKeyEd25519SigInvalid",
|
||||||
|
InputKey: "ED25519",
|
||||||
|
InputSig: "INVALID",
|
||||||
|
ExpectedKeyAlg: x509.Ed25519,
|
||||||
|
ExpectedSigAlg: x509.PureEd25519,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.Name, func(t *testing.T) {
|
||||||
|
actualKey, actualSig := KeySigAlgorithmFromString(tc.InputKey, tc.InputSig)
|
||||||
|
actualKeyLower, actualSigLower := KeySigAlgorithmFromString(strings.ToLower(tc.InputKey), strings.ToLower(tc.InputSig))
|
||||||
|
|
||||||
|
assert.Equal(t, tc.ExpectedKeyAlg, actualKey)
|
||||||
|
assert.Equal(t, tc.ExpectedSigAlg, actualSig)
|
||||||
|
assert.Equal(t, tc.ExpectedKeyAlg, actualKeyLower)
|
||||||
|
assert.Equal(t, tc.ExpectedSigAlg, actualSigLower)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldParseCurves(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
Name string
|
||||||
|
Input string
|
||||||
|
Expected elliptic.Curve
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "P224-Standard",
|
||||||
|
Input: "P224",
|
||||||
|
Expected: elliptic.P224(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P224-Lowercase",
|
||||||
|
Input: "p224",
|
||||||
|
Expected: elliptic.P224(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P224-Hyphenated",
|
||||||
|
Input: "P-224",
|
||||||
|
Expected: elliptic.P224(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P256-Standard",
|
||||||
|
Input: "P256",
|
||||||
|
Expected: elliptic.P256(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P256-Lowercase",
|
||||||
|
Input: "p256",
|
||||||
|
Expected: elliptic.P256(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P256-Hyphenated",
|
||||||
|
Input: "P-256",
|
||||||
|
Expected: elliptic.P256(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P384-Standard",
|
||||||
|
Input: "P384",
|
||||||
|
Expected: elliptic.P384(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P384-Lowercase",
|
||||||
|
Input: "p384",
|
||||||
|
Expected: elliptic.P384(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P384-Hyphenated",
|
||||||
|
Input: "P-384",
|
||||||
|
Expected: elliptic.P384(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P521-Standard",
|
||||||
|
Input: "P521",
|
||||||
|
Expected: elliptic.P521(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P521-Lowercase",
|
||||||
|
Input: "p521",
|
||||||
|
Expected: elliptic.P521(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "P521-Hyphenated",
|
||||||
|
Input: "P-521",
|
||||||
|
Expected: elliptic.P521(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Invalid",
|
||||||
|
Input: "521",
|
||||||
|
Expected: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.Name, func(t *testing.T) {
|
||||||
|
actual := EllipticCurveFromString(tc.Input)
|
||||||
|
|
||||||
|
assert.Equal(t, tc.Expected, actual)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMustBuildPrivateKey(b PrivateKeyBuilder) interface{} {
|
||||||
|
k, err := b.Build()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return k
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPublicKeyFromPrivateKey(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
Name string
|
||||||
|
PrivateKey interface{}
|
||||||
|
Expected interface{}
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "RSA2048",
|
||||||
|
PrivateKey: testMustBuildPrivateKey(RSAKeyBuilder{}.WithKeySize(512)),
|
||||||
|
Expected: &rsa.PublicKey{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "ECDSA-P256",
|
||||||
|
PrivateKey: testMustBuildPrivateKey(ECDSAKeyBuilder{}.WithCurve(elliptic.P256())),
|
||||||
|
Expected: &ecdsa.PublicKey{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Ed25519",
|
||||||
|
PrivateKey: testMustBuildPrivateKey(Ed25519KeyBuilder{}),
|
||||||
|
Expected: ed25519.PublicKey{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Invalid",
|
||||||
|
PrivateKey: 8,
|
||||||
|
Expected: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.Name, func(t *testing.T) {
|
||||||
|
actual := PublicKeyFromPrivateKey(tc.PrivateKey)
|
||||||
|
|
||||||
|
if tc.Expected == nil {
|
||||||
|
assert.Nil(t, actual)
|
||||||
|
} else {
|
||||||
|
assert.IsType(t, tc.Expected, actual)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestX509ParseKeyUsage(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
have [][]string
|
||||||
|
ca bool
|
||||||
|
expected x509.KeyUsage
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"ShouldParseDefault", nil, false, x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseDefaultCA", nil, true, x509.KeyUsageCertSign | x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseDigitalSignature", [][]string{{"digital_signature"}, {"Digital_Signature"}, {"digitalsignature"}, {"digitalSignature"}}, false, x509.KeyUsageDigitalSignature,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseKeyEncipherment", [][]string{{"key_encipherment"}, {"Key_Encipherment"}, {"keyencipherment"}, {"keyEncipherment"}}, false, x509.KeyUsageKeyEncipherment,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseDataEncipherment", [][]string{{"data_encipherment"}, {"Data_Encipherment"}, {"dataencipherment"}, {"dataEncipherment"}}, false, x509.KeyUsageDataEncipherment,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseKeyAgreement", [][]string{{"key_agreement"}, {"Key_Agreement"}, {"keyagreement"}, {"keyAgreement"}}, false, x509.KeyUsageKeyAgreement,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseCertSign", [][]string{{"cert_sign"}, {"Cert_Sign"}, {"certsign"}, {"certSign"}, {"certificate_sign"}, {"Certificate_Sign"}, {"certificatesign"}, {"certificateSign"}}, false, x509.KeyUsageCertSign,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseCRLSign", [][]string{{"crl_sign"}, {"CRL_Sign"}, {"crlsign"}, {"CRLSign"}}, false, x509.KeyUsageCRLSign,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseEncipherOnly", [][]string{{"encipher_only"}, {"Encipher_Only"}, {"encipheronly"}, {"encipherOnly"}}, false, x509.KeyUsageEncipherOnly,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseDecipherOnly", [][]string{{"decipher_only"}, {"Decipher_Only"}, {"decipheronly"}, {"decipherOnly"}}, false, x509.KeyUsageDecipherOnly,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ShouldParseMulti", [][]string{{"digitalSignature", "keyEncipherment", "dataEncipherment", "certSign", "crlSign"}}, false, x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageDataEncipherment | x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
if len(tc.have) == 0 {
|
||||||
|
actual := X509ParseKeyUsage(nil, tc.ca)
|
||||||
|
|
||||||
|
assert.Equal(t, tc.expected, actual)
|
||||||
|
}
|
||||||
|
for _, have := range tc.have {
|
||||||
|
t.Run(strings.Join(have, ","), func(t *testing.T) {
|
||||||
|
actual := X509ParseKeyUsage(have, tc.ca)
|
||||||
|
|
||||||
|
assert.Equal(t, tc.expected, actual)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestX509ParseExtendedKeyUsage(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
have [][]string
|
||||||
|
ca bool
|
||||||
|
expected []x509.ExtKeyUsage
|
||||||
|
}{
|
||||||
|
{"ShouldParseDefault", nil, false, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}},
|
||||||
|
{"ShouldParseDefaultCA", nil, true, []x509.ExtKeyUsage{x509.ExtKeyUsageAny}},
|
||||||
|
{"ShouldParseAny", [][]string{{"any"}, {"Any"}, {"any", "server_auth"}}, false, []x509.ExtKeyUsage{x509.ExtKeyUsageAny}},
|
||||||
|
{"ShouldParseServerAuth", [][]string{{"server_auth"}, {"Server_Auth"}, {"serverauth"}, {"serverAuth"}}, false, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}},
|
||||||
|
{"ShouldParseClientAuth", [][]string{{"client_auth"}, {"Client_Auth"}, {"clientauth"}, {"clientAuth"}}, false, []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}},
|
||||||
|
{"ShouldParseCodeSigning", [][]string{{"code_signing"}, {"Code_Signing"}, {"codesigning"}, {"codeSigning"}}, false, []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning}},
|
||||||
|
{"ShouldParseEmailProtection", [][]string{{"email_protection"}, {"Email_Protection"}, {"emailprotection"}, {"emailProtection"}}, false, []x509.ExtKeyUsage{x509.ExtKeyUsageEmailProtection}},
|
||||||
|
{"ShouldParseIPSECEndSystem", [][]string{{"ipsec_endsystem"}, {"IPSEC_Endsystem"}, {"ipsec_end_system"}, {"IPSEC_End_System"}, {"ipsecendsystem"}, {"ipsecEndSystem"}}, false, []x509.ExtKeyUsage{x509.ExtKeyUsageIPSECEndSystem}},
|
||||||
|
{"ShouldParseIPSECTunnel", [][]string{{"ipsec_tunnel"}, {"IPSEC_Tunnel"}, {"ipsectunnel"}, {"ipsecTunnel"}}, false, []x509.ExtKeyUsage{x509.ExtKeyUsageIPSECTunnel}},
|
||||||
|
{"ShouldParseIPSECUser", [][]string{{"ipsec_user"}, {"IPSEC_User"}, {"ipsecuser"}, {"ipsecUser"}}, false, []x509.ExtKeyUsage{x509.ExtKeyUsageIPSECUser}},
|
||||||
|
{"ShouldParseOCSPSigning", [][]string{{"ocsp_signing"}, {"OCSP_Signing"}, {"ocspsigning"}, {"ocspSigning"}}, false, []x509.ExtKeyUsage{x509.ExtKeyUsageOCSPSigning}},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
if len(tc.have) == 0 {
|
||||||
|
actual := X509ParseExtendedKeyUsage(nil, tc.ca)
|
||||||
|
|
||||||
|
assert.Equal(t, tc.expected, actual)
|
||||||
|
}
|
||||||
|
for _, have := range tc.have {
|
||||||
|
t.Run(strings.Join(have, ","), func(t *testing.T) {
|
||||||
|
actual := X509ParseExtendedKeyUsage(have, tc.ca)
|
||||||
|
|
||||||
|
assert.Equal(t, tc.expected, actual)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,83 +0,0 @@
|
||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/pem"
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GenerateRsaKeyPair generate an RSA key pair.
|
|
||||||
// bits can be 2048 or 4096.
|
|
||||||
func GenerateRsaKeyPair(bits int) (*rsa.PrivateKey, *rsa.PublicKey) {
|
|
||||||
privkey, _ := rsa.GenerateKey(rand.Reader, bits)
|
|
||||||
return privkey, &privkey.PublicKey
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExportRsaPrivateKeyAsPemStr marshal a rsa private key into PEM string.
|
|
||||||
func ExportRsaPrivateKeyAsPemStr(privkey *rsa.PrivateKey) string {
|
|
||||||
privkeyBytes := x509.MarshalPKCS1PrivateKey(privkey)
|
|
||||||
privkeyPem := pem.EncodeToMemory(
|
|
||||||
&pem.Block{
|
|
||||||
Type: "RSA PRIVATE KEY",
|
|
||||||
Bytes: privkeyBytes,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
return string(privkeyPem)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseRsaPrivateKeyFromPemStr parse a RSA private key from PEM string.
|
|
||||||
func ParseRsaPrivateKeyFromPemStr(privPEM string) (*rsa.PrivateKey, error) {
|
|
||||||
block, _ := pem.Decode([]byte(privPEM))
|
|
||||||
if block == nil {
|
|
||||||
return nil, errors.New("failed to parse PEM block containing the key")
|
|
||||||
}
|
|
||||||
|
|
||||||
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return priv, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExportRsaPublicKeyAsPemStr marshal a RSA public into a PEM string.
|
|
||||||
func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) (string, error) {
|
|
||||||
pubkeyBytes, err := x509.MarshalPKIXPublicKey(pubkey)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
pubkeyPem := pem.EncodeToMemory(
|
|
||||||
&pem.Block{
|
|
||||||
Type: "RSA PUBLIC KEY",
|
|
||||||
Bytes: pubkeyBytes,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
return string(pubkeyPem), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseRsaPublicKeyFromPemStr parse RSA public key from a PEM string.
|
|
||||||
func ParseRsaPublicKeyFromPemStr(pubPEM string) (*rsa.PublicKey, error) {
|
|
||||||
block, _ := pem.Decode([]byte(pubPEM))
|
|
||||||
if block == nil {
|
|
||||||
return nil, errors.New("failed to parse PEM block containing the key")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch pub := pub.(type) {
|
|
||||||
case *rsa.PublicKey:
|
|
||||||
return pub, nil
|
|
||||||
default:
|
|
||||||
break // fall through.
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, errors.New("key type is not RSA")
|
|
||||||
}
|
|
Loading…
Reference in New Issue