Skip to content

Commit

Permalink
update key length check for FIPS compliance
Browse files Browse the repository at this point in the history
  • Loading branch information
jm96441n committed Jun 27, 2023
1 parent f03248a commit 8ba9e20
Showing 1 changed file with 37 additions and 12 deletions.
49 changes: 37 additions & 12 deletions agent/structs/config_entry_inline_certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/miekg/dns"

"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/version"
)

// InlineCertificateConfigEntry manages the configuration for an inline certificate
Expand Down Expand Up @@ -43,7 +44,7 @@ func (e *InlineCertificateConfigEntry) GetEnterpriseMeta() *acl.EnterpriseMeta {
}
func (e *InlineCertificateConfigEntry) GetRaftIndex() *RaftIndex { return &e.RaftIndex }

// Envoy will silently reject any keys that are less than 2048 bytes long
// 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

Expand All @@ -58,17 +59,7 @@ func (e *InlineCertificateConfigEntry) Validate() error {
return errors.New("failed to parse private key PEM")
}

if privateKeyBlock.Type == "RSA PRIVATE KEY" {
key, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
if err != nil {
return err
}

// ensure private key is of the correct length
if key.N.BitLen() < MinKeyLength {
return errors.New("key length must be at least 2048 bits")
}
}
err := validateKeyLength(privateKeyBlock)

certificateBlock, _ := pem.Decode([]byte(e.Certificate))
if certificateBlock == nil {
Expand Down Expand Up @@ -102,6 +93,40 @@ func (e *InlineCertificateConfigEntry) Validate() error {
return nil
}

func validateKeyLength(privateKeyBlock *pem.Block) error {
if privateKeyBlock.Type != "RSA PRIVATE KEY" {
return nil
}

lenCheckFn := nonFipsLenCheck

if version.IsFIPS() {
lenCheckFn = fipsLenCheck
}
key, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
if err != nil {
return err
}

return lenCheckFn(key.N.BitLen())
}

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 {
Expand Down

0 comments on commit 8ba9e20

Please sign in to comment.