@ -10,8 +10,10 @@ import (
"errors"
"fmt"
"github.com/hashicorp/consul/acl"
"github.com/miekg/dns"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/version"
)
// InlineCertificateConfigEntry manages the configuration for an inline certificate
@ -42,8 +44,13 @@ func (e *InlineCertificateConfigEntry) GetEnterpriseMeta() *acl.EnterpriseMeta {
}
func ( e * InlineCertificateConfigEntry ) GetRaftIndex ( ) * RaftIndex { return & e . RaftIndex }
// Envoy will silently reject any RSA keys that are less than 2048 bytes long
// https://github.com/envoyproxy/envoy/blob/main/source/extensions/transport_sockets/tls/context_impl.cc#L238
const MinKeyLength = 2048
func ( e * InlineCertificateConfigEntry ) Validate ( ) error {
if err := validateConfigEntryMeta ( e . Meta ) ; err != nil {
err := validateConfigEntryMeta ( e . Meta )
if err != nil {
return err
}
@ -52,13 +59,18 @@ func (e *InlineCertificateConfigEntry) Validate() error {
return errors . New ( "failed to parse private key PEM" )
}
err = validateKeyLength ( privateKeyBlock )
if err != nil {
return err
}
certificateBlock , _ := pem . Decode ( [ ] byte ( e . Certificate ) )
if certificateBlock == nil {
return errors . New ( "failed to parse certificate PEM" )
}
// make sure we have a valid x509 certificate
_ , err : = x509 . ParseCertificate ( certificateBlock . Bytes )
_ , err = x509 . ParseCertificate ( certificateBlock . Bytes )
if err != nil {
return fmt . Errorf ( "failed to parse certificate: %w" , err )
}
@ -84,6 +96,41 @@ func (e *InlineCertificateConfigEntry) Validate() error {
return nil
}
func validateKeyLength ( privateKeyBlock * pem . Block ) error {
if privateKeyBlock . Type != "RSA PRIVATE KEY" {
return nil
}
key , err := x509 . ParsePKCS1PrivateKey ( privateKeyBlock . Bytes )
if err != nil {
return err
}
keyBitLen := key . N . BitLen ( )
if version . IsFIPS ( ) {
return fipsLenCheck ( keyBitLen )
}
return nonFipsLenCheck ( keyBitLen )
}
func nonFipsLenCheck ( keyLen int ) error {
// ensure private key is of the correct length
if keyLen < MinKeyLength {
return errors . New ( "key length must be at least 2048 bits" )
}
return nil
}
func fipsLenCheck ( keyLen int ) error {
if keyLen != 2048 && keyLen != 3072 && keyLen != 4096 {
return errors . New ( "key length invalid: only RSA lengths of 2048, 3072, and 4096 are allowed in FIPS mode" )
}
return nil
}
func ( e * InlineCertificateConfigEntry ) Hosts ( ) ( [ ] string , error ) {
certificateBlock , _ := pem . Decode ( [ ] byte ( e . Certificate ) )
if certificateBlock == nil {