summaryrefslogtreecommitdiff
path: root/internal/suites/suite_cli_test.go
diff options
context:
space:
mode:
authorJames Elliott <james-d-elliott@users.noreply.github.com>2022-06-27 18:27:57 +1000
committerGitHub <noreply@github.com>2022-06-27 18:27:57 +1000
commitfcac438637c43f55e84e226be323119042580bf5 (patch)
tree6b519d0dd1e3268575707affd8b64e87570238fe /internal/suites/suite_cli_test.go
parent0b5f92d9eb557d24dea33f991055555ea25551c4 (diff)
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>
Diffstat (limited to 'internal/suites/suite_cli_test.go')
-rw-r--r--internal/suites/suite_cli_test.go525
1 files changed, 487 insertions, 38 deletions
diff --git a/internal/suites/suite_cli_test.go b/internal/suites/suite_cli_test.go
index 74edcf016..b236e1dd9 100644
--- a/internal/suites/suite_cli_test.go
+++ b/internal/suites/suite_cli_test.go
@@ -1,6 +1,7 @@
package suites
import (
+ "bytes"
"context"
"fmt"
"os"
@@ -13,6 +14,7 @@ import (
"github.com/authelia/authelia/v4/internal/model"
"github.com/authelia/authelia/v4/internal/storage"
+ "github.com/authelia/authelia/v4/internal/utils"
)
type CLISuite struct {
@@ -37,7 +39,7 @@ func (s *CLISuite) SetupTest() {
coverageArg := ""
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"
}
@@ -94,79 +96,526 @@ func (s *CLISuite) TestShouldHashPasswordSHA512() {
s.Assert().Contains(output, "Password hash: $6$rounds=50000")
}
+func (s *CLISuite) TestShouldGenerateRSACertificateRequest() {
+ 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().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: 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, "certificates", "generate", "--host=*.example.com", "--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'", "--directory=/tmp/"})
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")
+ 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() {
- 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().Contains(output, "Certificate written to /tmp/cert.pem")
- s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
+ 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, 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() {
- 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'"})
+func (s *CLISuite) TestShouldGenerateCertificateRSAWithNotBefore() {
+ 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().Contains(output, "Certificate written to /tmp/cert.pem")
- s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
+ 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, "\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() {
- output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--start-date=Jan"})
+func (s *CLISuite) TestShouldFailGenerateCertificateRSAWithInvalidNotBefore() {
+ 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().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() {
- 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().Contains(output, "Certificate written to /tmp/cert.pem")
- s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
}
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().Contains(output, "Certificate written to /tmp/cert.pem")
- s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
+ 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: 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() {
- 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().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() {
- output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--ecdsa-curve=P224"})
+func (s *CLISuite) TestShouldGenerateCertificateECDSACurveP224() {
+ 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().Contains(output, "Certificate written to /tmp/cert.pem")
- s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
+ 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: 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() {
- output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--ecdsa-curve=P256"})
+func (s *CLISuite) TestShouldGenerateCertificateECDSACurveP256() {
+ 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().Contains(output, "Certificate written to /tmp/cert.pem")
- s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
+ 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: 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() {
- output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--ecdsa-curve=P384"})
+func (s *CLISuite) TestShouldGenerateCertificateECDSACurveP384() {
+ 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().Contains(output, "Certificate written to /tmp/cert.pem")
- s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
+ 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: 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() {
- output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "certificates", "generate", "--host=*.example.com", "--dir=/tmp/", "--ecdsa-curve=P521"})
+func (s *CLISuite) TestShouldGenerateCertificateECDSACurveP521() {
+ 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().Contains(output, "Certificate written to /tmp/cert.pem")
- s.Assert().Contains(output, "Private Key written to /tmp/key.pem")
+ 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: 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() {