Skip to content

Commit

Permalink
Test if cert valid dates and warn for thresholds
Browse files Browse the repository at this point in the history
check cert valid for date, info at longest threshold, warn
at the shortest threshold, and error when  out of date.

Attempt to include these thresholds within the global configuration
data.

This commit for review and help integrating service into the rest
of EVE.

SEE: EVE-125
  • Loading branch information
famleebob committed Dec 5, 2022
1 parent 6c85ce0 commit 7defb9f
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
10 changes: 10 additions & 0 deletions pkg/pillar/types/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ const (
MetricInterval GlobalSettingKey = "timer.metric.interval"
// DiskScanMetricInterval global setting key
DiskScanMetricInterval GlobalSettingKey = "timer.metric.diskscan.interval"
// CertExpireInfo and CertExpireWarn global thresholds (in days)
CertExpireInfo GlobalSettingKey = "timer.metric.certinfolog"
CertExpireWarn GlobalSettingKey = "timer.metric.certwarnlog"
// ResetIfCloudGoneTime global setting key
ResetIfCloudGoneTime GlobalSettingKey = "timer.reboot.no.network"
// FallbackIfCloudGoneTime global setting key
Expand Down Expand Up @@ -738,6 +741,13 @@ func NewConfigItemSpecMap() ConfigItemSpecMap {
// Need to be careful about max value. Controller may use metric message to
// update status of device (online / suspect etc ).
configItemSpecMap.AddIntItem(MetricInterval, 60, 5, HourInSec)
// thresholds to log info then warn for x509 certificates
// default is to log Info at 60 days before expiry, and Warn at 30
configItemSpecMap.AddIntItem(CertExpireInfo, 60*24*HourInSec, 24*HourInSec, 365*24*HourInSec)
configItemSpecMap.AddIntItem(CertExpireWarn, 30*24*HourInSec, 24*HourInSec, 365*24*HourInSec)
// ? Do we need to specify frequency of logging for each of the
// two levels -- that is, more frequent logging say hourly for
// the Warn level ?
// timer.reboot.no.network (seconds) - reboot after no cloud connectivity
// Max designed to allow the option of never rebooting even if device
// can't connect to the cloud
Expand Down
91 changes: 91 additions & 0 deletions pkg/pillar/zedcloud/authen.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"net/http"
"os"
"strings"
"time"

zauth "github.com/lf-edge/eve/api/go/auth"
zcert "github.com/lf-edge/eve/api/go/certs"
Expand Down Expand Up @@ -511,6 +512,20 @@ func VerifySigningCertChain(log *base.LogObject, certs []*zcert.ZCert) ([]byte,
}
}
}

// verify date range of certificates
for _, cert := range certs {
realCert, err := x509.ParseCertificate(cert.Cert)
if err != nil {
errStr := fmt.Sprintf("certificate PEM parse fail")
log.Errorln("verifySignature: " + errStr)
return nil, err
}
if !verifyx509TimeStamps(log, realCert) {
return nil, errors.New("Cert not in valid time")
}
}

log.Tracef("VerifySigningCertChain: success\n")
return sigCertBytes, nil
}
Expand Down Expand Up @@ -559,6 +574,82 @@ func verifySignature(log *base.LogObject, certByte []byte, interm *x509.CertPool
return nil
}

func verifyx509TimeStamps(log *base.LogObject, realCert *x509.Certificate) bool {
rightNow := time.Now()
notBefore := realCert.NotBefore
notAfter := realCert.NotAfter
certName := realCert.Subject
certValid := true
// HACK for compilation test DUMMY thresholds
type configInfo struct {
// only need to define thresholds to
// inform and warn the owners
infoThreshold time.Duration
warnThreshold time.Duration
}

type certStatus uint8
const (
allCertsAreValid certStatus = iota
aCertIsInfo
aCertIsWarn
aCertIsINVALID
)

type statusInfo struct {
CertStatus certStatus
}

// assume default will be 60 days before for Info
// and 30 days for the Warning
var SystemConfig = configInfo{time.Hour * 24 * 60,
time.Hour * 24 * 30}

var CurrCertStatus = statusInfo{allCertsAreValid}
// HACK end

// verify the NotBefore, and NotAfter
if rightNow.After(notBefore) {
// Cert is active (after NotBefore date)
// process thresholds
validDuration := notAfter.Sub(rightNow)
switch {
case validDuration < 0:
log.Errorf("%s: expired %v ago",
certName,
-validDuration)
certValid = false
CurrCertStatus.CertStatus = aCertIsINVALID
case validDuration < SystemConfig.warnThreshold:
log.Warnf("%s: expires in %v (%v days or less)",
certName,
validDuration,
SystemConfig.warnThreshold/24)
if CurrCertStatus.CertStatus < aCertIsWarn {
CurrCertStatus.CertStatus = aCertIsWarn
}
case validDuration < SystemConfig.infoThreshold:
log.Noticef("%s: expires in %v (%v Days or less)",
certName,
validDuration,
SystemConfig.infoThreshold/24)
if CurrCertStatus.CertStatus < aCertIsWarn {
CurrCertStatus.CertStatus = aCertIsWarn
}
default:
log.Errorf("%s: %v until it expires",
certName, validDuration)
}
} else {
// Current date is notBefore the Cert is valid
log.Errorf("%s: not yet valid, for %v",
certName, notBefore.Sub(rightNow))
certValid = false
CurrCertStatus.CertStatus = aCertIsINVALID
}
return certValid
}

// SaveServerSigningCert saves server (i.e. controller) signing certificate into the persist
// partition.
func SaveServerSigningCert(ctx *ZedCloudContext, certByte []byte) error {
Expand Down

0 comments on commit 7defb9f

Please sign in to comment.