refactor: private key decoding and generators (#4116)
parent
32bd2eba60
commit
3f39914c8f
|
@ -1,6 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/rsa"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -181,6 +183,8 @@ var decodedTypes = []reflect.Type{
|
||||||
reflect.TypeOf(url.URL{}),
|
reflect.TypeOf(url.URL{}),
|
||||||
reflect.TypeOf(time.Duration(0)),
|
reflect.TypeOf(time.Duration(0)),
|
||||||
reflect.TypeOf(schema.Address{}),
|
reflect.TypeOf(schema.Address{}),
|
||||||
|
reflect.TypeOf(rsa.PrivateKey{}),
|
||||||
|
reflect.TypeOf(ecdsa.PrivateKey{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsType(needle reflect.Type, haystack []reflect.Type) (contains bool) {
|
func containsType(needle reflect.Type, haystack []reflect.Type) (contains bool) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: "Commit Message Guidelines"
|
title: "Commit Message"
|
||||||
description: "Authelia Development Commit Message Guidelines"
|
description: "Authelia Development Commit Message Guidelines"
|
||||||
lead: "This section covers the git commit message guidelines we use for development."
|
lead: "This section covers the git commit message guidelines we use for development."
|
||||||
date: 2021-01-30T19:29:07+11:00
|
date: 2021-01-30T19:29:07+11:00
|
||||||
|
@ -7,8 +7,8 @@ draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
contributing:
|
contributing:
|
||||||
parent: "development"
|
parent: "guidelines"
|
||||||
weight: 231
|
weight: 320
|
||||||
toc: true
|
toc: true
|
||||||
aliases:
|
aliases:
|
||||||
- /docs/contributing/commitmsg-guidelines.html
|
- /docs/contributing/commitmsg-guidelines.html
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "Documentation"
|
title: "Documentation"
|
||||||
description: "Authelia Development Documentation Guidelines"
|
description: "Authelia Development Documentation Guidelines"
|
||||||
lead: "This section covers the guidelines we use when writing documentation."
|
lead: "This section covers the guidelines we use when writing documentation."
|
||||||
date: 2021-01-30T19:29:07+11:00
|
date: 2022-10-02T14:32:16+11:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "Guidelines"
|
title: "Guidelines"
|
||||||
description: "An introduction into guidelines for contributing to the Authelia project."
|
description: "An introduction into guidelines for contributing to the Authelia project."
|
||||||
lead: "An introduction into guidelines for contributing to the Authelia project."
|
lead: "An introduction into guidelines for contributing to the Authelia project."
|
||||||
date: 2022-06-15T17:51:47+10:00
|
date: 2022-10-02T14:32:16+11:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: "Istio"
|
title: "Istio"
|
||||||
description: "A guide to integrating Authelia with the Istio Kubernetes Ingress."
|
description: "A guide to integrating Authelia with the Istio Kubernetes Ingress."
|
||||||
lead: "A guide to integrating Authelia with the Istio Kubernetes Ingress."
|
lead: "A guide to integrating Authelia with the Istio Kubernetes Ingress."
|
||||||
date: 2022-06-15T17:51:47+10:00
|
date: 2022-10-02T13:59:09+11:00
|
||||||
draft: false
|
draft: false
|
||||||
images: []
|
images: []
|
||||||
menu:
|
menu:
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,7 @@
|
||||||
package configuration
|
package configuration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -343,8 +344,8 @@ func StringToX509CertificateChainHookFunc() mapstructure.DecodeHookFuncType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// StringToRSAPrivateKeyHookFunc decodes strings to rsa.PrivateKey's.
|
// StringToPrivateKeyHookFunc decodes strings to rsa.PrivateKey's.
|
||||||
func StringToRSAPrivateKeyHookFunc() mapstructure.DecodeHookFuncType {
|
func StringToPrivateKeyHookFunc() mapstructure.DecodeHookFuncType {
|
||||||
return func(f reflect.Type, t reflect.Type, data interface{}) (value interface{}, err error) {
|
return func(f reflect.Type, t reflect.Type, data interface{}) (value interface{}, err error) {
|
||||||
if f.Kind() != reflect.String {
|
if f.Kind() != reflect.String {
|
||||||
return data, nil
|
return data, nil
|
||||||
|
@ -354,28 +355,53 @@ func StringToRSAPrivateKeyHookFunc() mapstructure.DecodeHookFuncType {
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedType := reflect.TypeOf(rsa.PrivateKey{})
|
expectedTypeRSA := reflect.TypeOf(rsa.PrivateKey{})
|
||||||
|
expectedTypeECDSA := reflect.TypeOf(ecdsa.PrivateKey{})
|
||||||
|
|
||||||
if t.Elem() != expectedType {
|
var (
|
||||||
return data, nil
|
i any
|
||||||
}
|
expectedType reflect.Type
|
||||||
|
)
|
||||||
|
|
||||||
dataStr := data.(string)
|
dataStr := data.(string)
|
||||||
|
|
||||||
var result *rsa.PrivateKey
|
switch t.Elem() {
|
||||||
|
case expectedTypeRSA:
|
||||||
|
var result *rsa.PrivateKey
|
||||||
|
|
||||||
if dataStr == "" {
|
if dataStr == "" {
|
||||||
return result, nil
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedType = expectedTypeRSA
|
||||||
|
case expectedTypeECDSA:
|
||||||
|
var result *ecdsa.PrivateKey
|
||||||
|
|
||||||
|
if dataStr == "" {
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedType = expectedTypeECDSA
|
||||||
|
default:
|
||||||
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var i interface{}
|
|
||||||
|
|
||||||
if i, err = utils.ParseX509FromPEM([]byte(dataStr)); err != nil {
|
if i, err = utils.ParseX509FromPEM([]byte(dataStr)); err != nil {
|
||||||
return nil, fmt.Errorf(errFmtDecodeHookCouldNotParseBasic, "*", expectedType, err)
|
return nil, fmt.Errorf(errFmtDecodeHookCouldNotParseBasic, "*", expectedType, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch r := i.(type) {
|
switch r := i.(type) {
|
||||||
case *rsa.PrivateKey:
|
case *rsa.PrivateKey:
|
||||||
|
if expectedType != expectedTypeRSA {
|
||||||
|
return nil, fmt.Errorf(errFmtDecodeHookCouldNotParseBasic, "*", expectedType, fmt.Errorf("the data is for a %T not a *%s", r, expectedType))
|
||||||
|
}
|
||||||
|
|
||||||
|
return r, nil
|
||||||
|
case *ecdsa.PrivateKey:
|
||||||
|
if expectedType != expectedTypeECDSA {
|
||||||
|
return nil, fmt.Errorf(errFmtDecodeHookCouldNotParseBasic, "*", expectedType, fmt.Errorf("the data is for a %T not a *%s", r, expectedType))
|
||||||
|
}
|
||||||
|
|
||||||
return r, nil
|
return r, nil
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf(errFmtDecodeHookCouldNotParseBasic, "*", expectedType, fmt.Errorf("the data is for a %T not a *%s", r, expectedType))
|
return nil, fmt.Errorf(errFmtDecodeHookCouldNotParseBasic, "*", expectedType, fmt.Errorf("the data is for a %T not a *%s", r, expectedType))
|
||||||
|
|
|
@ -23,8 +23,8 @@ import (
|
||||||
func TestStringToMailAddressHookFunc(t *testing.T) {
|
func TestStringToMailAddressHookFunc(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
have interface{}
|
have any
|
||||||
want interface{}
|
want any
|
||||||
err string
|
err string
|
||||||
decode bool
|
decode bool
|
||||||
}{
|
}{
|
||||||
|
@ -78,8 +78,8 @@ func TestStringToMailAddressHookFunc(t *testing.T) {
|
||||||
func TestStringToMailAddressHookFuncPointer(t *testing.T) {
|
func TestStringToMailAddressHookFuncPointer(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
have interface{}
|
have any
|
||||||
want interface{}
|
want any
|
||||||
err string
|
err string
|
||||||
decode bool
|
decode bool
|
||||||
}{
|
}{
|
||||||
|
@ -139,8 +139,8 @@ func TestStringToMailAddressHookFuncPointer(t *testing.T) {
|
||||||
func TestStringToURLHookFunc(t *testing.T) {
|
func TestStringToURLHookFunc(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
have interface{}
|
have any
|
||||||
want interface{}
|
want any
|
||||||
err string
|
err string
|
||||||
decode bool
|
decode bool
|
||||||
}{
|
}{
|
||||||
|
@ -212,8 +212,8 @@ func TestStringToURLHookFunc(t *testing.T) {
|
||||||
func TestStringToURLHookFuncPointer(t *testing.T) {
|
func TestStringToURLHookFuncPointer(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
have interface{}
|
have any
|
||||||
want interface{}
|
want any
|
||||||
err string
|
err string
|
||||||
decode bool
|
decode bool
|
||||||
}{
|
}{
|
||||||
|
@ -285,8 +285,8 @@ func TestStringToURLHookFuncPointer(t *testing.T) {
|
||||||
func TestToTimeDurationHookFunc(t *testing.T) {
|
func TestToTimeDurationHookFunc(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
have interface{}
|
have any
|
||||||
want interface{}
|
want any
|
||||||
err string
|
err string
|
||||||
decode bool
|
decode bool
|
||||||
}{
|
}{
|
||||||
|
@ -405,8 +405,8 @@ func TestToTimeDurationHookFunc(t *testing.T) {
|
||||||
func TestToTimeDurationHookFuncPointer(t *testing.T) {
|
func TestToTimeDurationHookFuncPointer(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
have interface{}
|
have any
|
||||||
want interface{}
|
want any
|
||||||
err string
|
err string
|
||||||
decode bool
|
decode bool
|
||||||
}{
|
}{
|
||||||
|
@ -526,8 +526,8 @@ func TestToTimeDurationHookFuncPointer(t *testing.T) {
|
||||||
func TestStringToRegexpFunc(t *testing.T) {
|
func TestStringToRegexpFunc(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
have interface{}
|
have any
|
||||||
want interface{}
|
want any
|
||||||
err string
|
err string
|
||||||
decode bool
|
decode bool
|
||||||
wantGrps []string
|
wantGrps []string
|
||||||
|
@ -640,8 +640,8 @@ func TestStringToRegexpFunc(t *testing.T) {
|
||||||
func TestStringToRegexpFuncPointers(t *testing.T) {
|
func TestStringToRegexpFuncPointers(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
have interface{}
|
have any
|
||||||
want interface{}
|
want any
|
||||||
err string
|
err string
|
||||||
decode bool
|
decode bool
|
||||||
wantGrps []string
|
wantGrps []string
|
||||||
|
@ -775,8 +775,8 @@ func TestStringToAddressHookFunc(t *testing.T) {
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
have interface{}
|
have any
|
||||||
expected interface{}
|
expected any
|
||||||
err string
|
err string
|
||||||
decode bool
|
decode bool
|
||||||
}{
|
}{
|
||||||
|
@ -867,51 +867,108 @@ func TestStringToAddressHookFunc(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStringToRSAPrivateKeyHookFunc(t *testing.T) {
|
func TestStringToPrivateKeyHookFunc(t *testing.T) {
|
||||||
var nilkey *rsa.PrivateKey
|
var (
|
||||||
|
nilRSA *rsa.PrivateKey
|
||||||
|
nilECDSA *ecdsa.PrivateKey
|
||||||
|
nilCert *x509.Certificate
|
||||||
|
)
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
have interface{}
|
have any
|
||||||
want interface{}
|
want any
|
||||||
err string
|
err string
|
||||||
decode bool
|
decode bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
desc: "ShouldDecodeRSAPrivateKey",
|
desc: "ShouldDecodeRSAPrivateKey",
|
||||||
have: x509PrivateKeyRSA1,
|
have: x509PrivateKeyRSA1,
|
||||||
want: mustParseRSAPrivateKey(x509PrivateKeyRSA1),
|
want: MustParseRSAPrivateKey(x509PrivateKeyRSA1),
|
||||||
|
decode: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "ShouldDecodeECDSAPrivateKey",
|
||||||
|
have: x509PrivateKeyEC1,
|
||||||
|
want: MustParseECDSAPrivateKey(x509PrivateKeyEC1),
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldNotDecodeToECDSAPrivateKey",
|
desc: "ShouldNotDecodeToECDSAPrivateKey",
|
||||||
have: x509PrivateKeyRSA1,
|
have: x509PrivateKeyRSA1,
|
||||||
want: &ecdsa.PrivateKey{},
|
want: &ecdsa.PrivateKey{},
|
||||||
decode: false,
|
decode: true,
|
||||||
|
err: "could not decode to a *ecdsa.PrivateKey: the data is for a *rsa.PrivateKey not a *ecdsa.PrivateKey",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldNotDecodeEmptyKey",
|
desc: "ShouldNotDecodeEmptyRSAKey",
|
||||||
have: "",
|
have: "",
|
||||||
want: nilkey,
|
want: nilRSA,
|
||||||
|
decode: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "ShouldNotDecodeEmptyECDSAKey",
|
||||||
|
have: "",
|
||||||
|
want: nilECDSA,
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldNotDecodeECDSAKeyToRSAKey",
|
desc: "ShouldNotDecodeECDSAKeyToRSAKey",
|
||||||
have: x509PrivateKeyEC1,
|
have: x509PrivateKeyEC1,
|
||||||
want: nilkey,
|
want: nilRSA,
|
||||||
decode: true,
|
decode: true,
|
||||||
err: "could not decode to a *rsa.PrivateKey: the data is for a *ecdsa.PrivateKey not a *rsa.PrivateKey",
|
err: "could not decode to a *rsa.PrivateKey: the data is for a *ecdsa.PrivateKey not a *rsa.PrivateKey",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "ShouldNotDecodeRSAKeyToECDSAKey",
|
||||||
|
have: x509PrivateKeyRSA1,
|
||||||
|
want: nilECDSA,
|
||||||
|
decode: true,
|
||||||
|
err: "could not decode to a *ecdsa.PrivateKey: the data is for a *rsa.PrivateKey not a *ecdsa.PrivateKey",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldNotDecodeBadRSAPrivateKey",
|
desc: "ShouldNotDecodeBadRSAPrivateKey",
|
||||||
have: x509PrivateKeyRSA2,
|
have: x509PrivateKeyRSA2,
|
||||||
want: nilkey,
|
want: nilRSA,
|
||||||
decode: true,
|
decode: true,
|
||||||
err: "could not decode to a *rsa.PrivateKey: failed to parse PEM block containing the key",
|
err: "could not decode to a *rsa.PrivateKey: failed to parse PEM block containing the key",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "ShouldNotDecodeBadECDSAPrivateKey",
|
||||||
|
have: x509PrivateKeyEC2,
|
||||||
|
want: nilECDSA,
|
||||||
|
decode: true,
|
||||||
|
err: "could not decode to a *ecdsa.PrivateKey: failed to parse PEM block containing the key",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "ShouldNotDecodeCertificateToRSAPrivateKey",
|
||||||
|
have: x509CertificateRSA1,
|
||||||
|
want: nilRSA,
|
||||||
|
decode: true,
|
||||||
|
err: "could not decode to a *rsa.PrivateKey: the data is for a *x509.Certificate not a *rsa.PrivateKey",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "ShouldNotDecodeCertificateToECDSAPrivateKey",
|
||||||
|
have: x509CertificateRSA1,
|
||||||
|
want: nilECDSA,
|
||||||
|
decode: true,
|
||||||
|
err: "could not decode to a *ecdsa.PrivateKey: the data is for a *x509.Certificate not a *ecdsa.PrivateKey",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "ShouldNotDecodeRSAKeyToCertificate",
|
||||||
|
have: x509PrivateKeyRSA1,
|
||||||
|
want: nilCert,
|
||||||
|
decode: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "ShouldNotDecodeECDSAKeyToCertificate",
|
||||||
|
have: x509PrivateKeyEC1,
|
||||||
|
want: nilCert,
|
||||||
|
decode: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
hook := configuration.StringToRSAPrivateKeyHookFunc()
|
hook := configuration.StringToPrivateKeyHookFunc()
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.desc, func(t *testing.T) {
|
t.Run(tc.desc, func(t *testing.T) {
|
||||||
|
@ -944,25 +1001,25 @@ func TestStringToX509CertificateHookFunc(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "ShouldDecodeRSACertificate",
|
desc: "ShouldDecodeRSACertificate",
|
||||||
have: x509CertificateRSA1,
|
have: x509CertificateRSA1,
|
||||||
want: mustParseX509Certificate(x509CertificateRSA1),
|
want: MustParseX509Certificate(x509CertificateRSA1),
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldDecodeECDSACertificate",
|
desc: "ShouldDecodeECDSACertificate",
|
||||||
have: x509CACertificateECDSA,
|
have: x509CACertificateECDSA,
|
||||||
want: mustParseX509Certificate(x509CACertificateECDSA),
|
want: MustParseX509Certificate(x509CACertificateECDSA),
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldDecodeRSACACertificate",
|
desc: "ShouldDecodeRSACACertificate",
|
||||||
have: x509CACertificateRSA,
|
have: x509CACertificateRSA,
|
||||||
want: mustParseX509Certificate(x509CACertificateRSA),
|
want: MustParseX509Certificate(x509CACertificateRSA),
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldDecodeECDSACACertificate",
|
desc: "ShouldDecodeECDSACACertificate",
|
||||||
have: x509CACertificateECDSA,
|
have: x509CACertificateECDSA,
|
||||||
want: mustParseX509Certificate(x509CACertificateECDSA),
|
want: MustParseX509Certificate(x509CACertificateECDSA),
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1020,50 +1077,50 @@ func TestStringToX509CertificateChainHookFunc(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "ShouldDecodeRSACertificate",
|
desc: "ShouldDecodeRSACertificate",
|
||||||
have: x509CertificateRSA1,
|
have: x509CertificateRSA1,
|
||||||
expected: mustParseX509CertificateChain(x509CertificateRSA1),
|
expected: MustParseX509CertificateChain(x509CertificateRSA1),
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldDecodeRSACertificateNoPtr",
|
desc: "ShouldDecodeRSACertificateNoPtr",
|
||||||
have: x509CertificateRSA1,
|
have: x509CertificateRSA1,
|
||||||
expected: *mustParseX509CertificateChain(x509CertificateRSA1),
|
expected: *MustParseX509CertificateChain(x509CertificateRSA1),
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldDecodeRSACertificateChain",
|
desc: "ShouldDecodeRSACertificateChain",
|
||||||
have: buildChain(x509CertificateRSA1, x509CACertificateRSA),
|
have: BuildChain(x509CertificateRSA1, x509CACertificateRSA),
|
||||||
expected: mustParseX509CertificateChain(x509CertificateRSA1, x509CACertificateRSA),
|
expected: MustParseX509CertificateChain(x509CertificateRSA1, x509CACertificateRSA),
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldDecodeRSACertificateChainNoPtr",
|
desc: "ShouldDecodeRSACertificateChainNoPtr",
|
||||||
have: buildChain(x509CertificateRSA1, x509CACertificateRSA),
|
have: BuildChain(x509CertificateRSA1, x509CACertificateRSA),
|
||||||
expected: *mustParseX509CertificateChain(x509CertificateRSA1, x509CACertificateRSA),
|
expected: *MustParseX509CertificateChain(x509CertificateRSA1, x509CACertificateRSA),
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldNotDecodeBadRSACertificateChain",
|
desc: "ShouldNotDecodeBadRSACertificateChain",
|
||||||
have: buildChain(x509CertificateRSA1, x509CACertificateECDSA),
|
have: BuildChain(x509CertificateRSA1, x509CACertificateECDSA),
|
||||||
expected: mustParseX509CertificateChain(x509CertificateRSA1, x509CACertificateECDSA),
|
expected: MustParseX509CertificateChain(x509CertificateRSA1, x509CACertificateECDSA),
|
||||||
verr: "certificate #1 in chain is not signed properly by certificate #2 in chain: x509: signature algorithm specifies an RSA public key, but have public key of type *ecdsa.PublicKey",
|
verr: "certificate #1 in chain is not signed properly by certificate #2 in chain: x509: signature algorithm specifies an RSA public key, but have public key of type *ecdsa.PublicKey",
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldDecodeECDSACertificate",
|
desc: "ShouldDecodeECDSACertificate",
|
||||||
have: x509CACertificateECDSA,
|
have: x509CACertificateECDSA,
|
||||||
expected: mustParseX509CertificateChain(x509CACertificateECDSA),
|
expected: MustParseX509CertificateChain(x509CACertificateECDSA),
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldDecodeRSACACertificate",
|
desc: "ShouldDecodeRSACACertificate",
|
||||||
have: x509CACertificateRSA,
|
have: x509CACertificateRSA,
|
||||||
expected: mustParseX509CertificateChain(x509CACertificateRSA),
|
expected: MustParseX509CertificateChain(x509CACertificateRSA),
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "ShouldDecodeECDSACACertificate",
|
desc: "ShouldDecodeECDSACACertificate",
|
||||||
have: x509CACertificateECDSA,
|
have: x509CACertificateECDSA,
|
||||||
expected: mustParseX509CertificateChain(x509CACertificateECDSA),
|
expected: MustParseX509CertificateChain(x509CACertificateECDSA),
|
||||||
decode: true,
|
decode: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1175,6 +1232,11 @@ bad key
|
||||||
MHcCAQEEIMn970LSn8aKVhBM4vyUmpZyEdCT4riN+Lp4QU04zUhYoAoGCCqGSM49
|
MHcCAQEEIMn970LSn8aKVhBM4vyUmpZyEdCT4riN+Lp4QU04zUhYoAoGCCqGSM49
|
||||||
AwEHoUQDQgAEMD69n22nd78GmaRDzy/s7muqhbc/OEnFS2mNtiRAA5FaX+kbkCB5
|
AwEHoUQDQgAEMD69n22nd78GmaRDzy/s7muqhbc/OEnFS2mNtiRAA5FaX+kbkCB5
|
||||||
8pu/k2jkaSVNZtBYKPVAibHkhvakjVb66A==
|
8pu/k2jkaSVNZtBYKPVAibHkhvakjVb66A==
|
||||||
|
-----END EC PRIVATE KEY-----`
|
||||||
|
|
||||||
|
x509PrivateKeyEC2 = `
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
bad key
|
||||||
-----END EC PRIVATE KEY-----`
|
-----END EC PRIVATE KEY-----`
|
||||||
|
|
||||||
x509CertificateRSA1 = `
|
x509CertificateRSA1 = `
|
||||||
|
@ -1232,14 +1294,14 @@ uDv6M2spMi0CIQC8uOSMcv11vp1ylsGg38N6XYA+GQa1BHRd79+91hC+7w==
|
||||||
-----END CERTIFICATE-----`
|
-----END CERTIFICATE-----`
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustParseRSAPrivateKey(data string) *rsa.PrivateKey {
|
func MustParseRSAPrivateKey(data string) *rsa.PrivateKey {
|
||||||
block, _ := pem.Decode([]byte(data))
|
block, _ := pem.Decode([]byte(data))
|
||||||
if block == nil || block.Bytes == nil || len(block.Bytes) == 0 {
|
if block == nil || block.Bytes == nil || len(block.Bytes) == 0 {
|
||||||
panic("not pem encoded")
|
panic("not pem encoded")
|
||||||
}
|
}
|
||||||
|
|
||||||
if block.Type != "RSA PRIVATE KEY" {
|
if block.Type != "RSA PRIVATE KEY" {
|
||||||
panic("not private key")
|
panic("not rsa private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||||
|
@ -1250,7 +1312,25 @@ func mustParseRSAPrivateKey(data string) *rsa.PrivateKey {
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustParseX509Certificate(data string) *x509.Certificate {
|
func MustParseECDSAPrivateKey(data string) *ecdsa.PrivateKey {
|
||||||
|
block, _ := pem.Decode([]byte(data))
|
||||||
|
if block == nil || block.Bytes == nil || len(block.Bytes) == 0 {
|
||||||
|
panic("not pem encoded")
|
||||||
|
}
|
||||||
|
|
||||||
|
if block.Type != "EC PRIVATE KEY" {
|
||||||
|
panic("not ecdsa private key")
|
||||||
|
}
|
||||||
|
|
||||||
|
key, err := x509.ParseECPrivateKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
func MustParseX509Certificate(data string) *x509.Certificate {
|
||||||
block, _ := pem.Decode([]byte(data))
|
block, _ := pem.Decode([]byte(data))
|
||||||
if block == nil || len(block.Bytes) == 0 {
|
if block == nil || len(block.Bytes) == 0 {
|
||||||
panic("not a PEM")
|
panic("not a PEM")
|
||||||
|
@ -1264,7 +1344,7 @@ func mustParseX509Certificate(data string) *x509.Certificate {
|
||||||
return cert
|
return cert
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildChain(pems ...string) string {
|
func BuildChain(pems ...string) string {
|
||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
|
|
||||||
for i, data := range pems {
|
for i, data := range pems {
|
||||||
|
@ -1278,8 +1358,8 @@ func buildChain(pems ...string) string {
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustParseX509CertificateChain(datas ...string) *schema.X509CertificateChain {
|
func MustParseX509CertificateChain(datas ...string) *schema.X509CertificateChain {
|
||||||
chain, err := schema.NewX509CertificateChain(buildChain(datas...))
|
chain, err := schema.NewX509CertificateChain(BuildChain(datas...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ func unmarshal(ko *koanf.Koanf, val *schema.StructValidator, path string, o inte
|
||||||
StringToAddressHookFunc(),
|
StringToAddressHookFunc(),
|
||||||
StringToX509CertificateHookFunc(),
|
StringToX509CertificateHookFunc(),
|
||||||
StringToX509CertificateChainHookFunc(),
|
StringToX509CertificateChainHookFunc(),
|
||||||
StringToRSAPrivateKeyHookFunc(),
|
StringToPrivateKeyHookFunc(),
|
||||||
ToTimeDurationHookFunc(),
|
ToTimeDurationHookFunc(),
|
||||||
),
|
),
|
||||||
Metadata: nil,
|
Metadata: nil,
|
||||||
|
|
Loading…
Reference in New Issue