Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make escrow of encrypted storage key more reliable #3770

Merged
merged 5 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion pkg/pillar/cmd/vaultmgr/vaultmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,8 @@ func publishVaultKey(ctx *vaultMgrContext, vaultName string) error {
var encryptedVaultKey []byte
//we try to fill EncryptedVaultKey only in case of tpm enabled
//otherwise we leave it empty
if etpm.IsTpmEnabled() {
isTpmEnabled := etpm.IsTpmEnabled()
if isTpmEnabled {
if !ctx.defaultVaultUnlocked {
log.Errorf("Vault is not yet unlocked, waiting for Controller key")
return nil
Expand All @@ -504,6 +505,7 @@ func publishVaultKey(ctx *vaultMgrContext, vaultName string) error {

encryptedKey, err := etpm.EncryptDecryptUsingTpm(keyBytes, true)
if err != nil {
// XXX should we still send with no key?
return fmt.Errorf("Failed to encrypt vault key %w", err)
}

Expand All @@ -524,6 +526,7 @@ func publishVaultKey(ctx *vaultMgrContext, vaultName string) error {
keyFromDevice := types.EncryptedVaultKeyFromDevice{}
keyFromDevice.Name = vaultName
keyFromDevice.EncryptedVaultKey = encryptedVaultKey
keyFromDevice.IsTpmEnabled = isTpmEnabled
key := keyFromDevice.Key()
log.Tracef("Publishing EncryptedVaultKeyFromDevice %s\n", key)
pub := ctx.pubVaultKeyFromDevice
Expand Down
6 changes: 4 additions & 2 deletions pkg/pillar/cmd/zedagent/attesttask.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,13 +450,14 @@
}
// bail if V2API is not supported
if !zedcloud.UseV2API() {
attestCtx.zedagentCtx.publishedAttestEscrow = true

Check warning on line 453 in pkg/pillar/cmd/zedagent/attesttask.go

View check run for this annotation

Codecov / codecov/patch

pkg/pillar/cmd/zedagent/attesttask.go#L453

Added line #L453 was not covered by tests
eriknordmark marked this conversation as resolved.
Show resolved Hide resolved
return zattest.ErrNoVerifier
}
if attestCtx.SkipEscrow {
log.Notice("[ATTEST] Escrow successful skipped")
return nil
}
if attestCtx.EscrowData == nil {
if attestCtx.EscrowData == nil || len(attestCtx.EscrowData) == 0 {

Check warning on line 460 in pkg/pillar/cmd/zedagent/attesttask.go

View check run for this annotation

Codecov / codecov/patch

pkg/pillar/cmd/zedagent/attesttask.go#L460

Added line #L460 was not covered by tests
errorDescription := types.ErrorDescription{Error: "[ATTEST] No escrow data"}
log.Error(errorDescription.Error)
setAttestErrorAndTriggerInfo(ctx, errorDescription)
Expand Down Expand Up @@ -537,6 +538,7 @@
return zattest.ErrITokenMismatch
case attest.AttestStorageKeysResponseCode_ATTEST_STORAGE_KEYS_RESPONSE_CODE_SUCCESS:
log.Notice("[ATTEST] Escrow successful")
attestCtx.zedagentCtx.publishedAttestEscrow = true

Check warning on line 541 in pkg/pillar/cmd/zedagent/attesttask.go

View check run for this annotation

Codecov / codecov/patch

pkg/pillar/cmd/zedagent/attesttask.go#L541

Added line #L541 was not covered by tests
ctx.ClearError()
triggerPublishDevInfo(attestCtx.zedagentCtx)
// we sent storage keys successfully
Expand Down Expand Up @@ -800,7 +802,7 @@
attestCtx := ctx.attestCtx
attestCtx.EscrowData = vaultKey.EncryptedVaultKey
attestCtx.SkipEscrow = false
if len(attestCtx.EscrowData) == 0 {
if !vaultKey.IsTpmEnabled {

Check warning on line 805 in pkg/pillar/cmd/zedagent/attesttask.go

View check run for this annotation

Codecov / codecov/patch

pkg/pillar/cmd/zedagent/attesttask.go#L805

Added line #L805 was not covered by tests
attestCtx.SkipEscrow = true
}

Expand Down
2 changes: 0 additions & 2 deletions pkg/pillar/cmd/zedagent/handlecertconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,6 @@ func publishEdgeNodeCertsToController(ctx *zedagentContext) {
log.Tracef("publishEdgeNodeCertsToController: after send, total elapse sec %v",
time.Since(startPubTime).Seconds())
ctx.cipherCtx.iteration++
// XXX remove log?
log.Noticef("Maybe sent EdgeNodeCerts")
// The getDeferredSentHandlerFunction will set ctx.publishedEdgeNodeCerts
// when the message has been sent.
}
Expand Down
11 changes: 3 additions & 8 deletions pkg/pillar/cmd/zedagent/handleconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,9 @@
if getconfigCtx.configProcessingRV != configOK {
log.Noticef("config processing flag is not OK: %s", getconfigCtx.configProcessingRV)
}
if ctx.publishedEdgeNodeCerts && !ctx.publishedAttestEscrow {
log.Warning("Not yet published AttestEscrow")
}

Check warning on line 475 in pkg/pillar/cmd/zedagent/handleconfig.go

View check run for this annotation

Codecov / codecov/patch

pkg/pillar/cmd/zedagent/handleconfig.go#L473-L475

Added lines #L473 - L475 were not covered by tests
}
ctx.ps.StillRunning(wdName, warningTime, errorTime)
}
Expand Down Expand Up @@ -608,14 +611,6 @@
configProcessingRetval, []netdump.TracedNetRequest) {

log.Tracef("getLatestConfig(%s, %d)", url, iteration)
// On first boot, if we haven't yet published our certificates we defer
// to ensure that the controller has our certs and can add encrypted
// secrets to our config.
if getconfigCtx.zedagentCtx.bootReason == types.BootReasonFirst &&
!getconfigCtx.zedagentCtx.publishedEdgeNodeCerts {
log.Noticef("Defer fetching config until our EdgeNodeCerts have been published")
return deferConfig, nil
}
ctx := getconfigCtx.zedagentCtx
const bailOnHTTPErr = false // For 4xx and 5xx HTTP errors we try other interfaces
// except http.StatusForbidden(which returns error
Expand Down
21 changes: 16 additions & 5 deletions pkg/pillar/cmd/zedagent/zedagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,12 @@
// Track the counter from force.fallback.counter to detect changes
forceFallbackCounter int

// Interlock with controller to ensure we get the encrypted secrets
// Used for retry of EdgeNodeCerts
publishedEdgeNodeCerts bool

// Used for retry of SendAttestEscrow
publishedAttestEscrow bool

attestationTryCount int
// cli options
versionPtr *bool
Expand Down Expand Up @@ -439,6 +442,10 @@
// XXX defer this until we have some config from cloud or saved copy
getconfigCtx.pubAppInstanceConfig.SignalRestarted()

// Initialize remote attestation context. Do this before we get events
// from the AttestQuote and EncryptedKeyFromDevice subscriptions
attestModuleInitialize(zedagentCtx)

Check warning on line 448 in pkg/pillar/cmd/zedagent/zedagent.go

View check run for this annotation

Codecov / codecov/patch

pkg/pillar/cmd/zedagent/zedagent.go#L445-L448

Added lines #L445 - L448 were not covered by tests
// With device UUID, zedagent is ready to initialize and activate all subscriptions.
initPostOnboardSubs(zedagentCtx)

Expand All @@ -450,9 +457,6 @@
//initialize cipher processing block
cipherModuleInitialize(zedagentCtx)

//initialize remote attestation context
attestModuleInitialize(zedagentCtx)

// Pick up debug aka log level before we start real work
waitUntilGCReady(zedagentCtx, stillRunning)

Expand Down Expand Up @@ -2552,7 +2556,7 @@
ctx.publishedEdgeNodeCerts = true
}
} else {
if _, ok := itemType.(attest.ZAttestReqType); ok {
if el, ok := itemType.(attest.ZAttestReqType); ok {

Check warning on line 2559 in pkg/pillar/cmd/zedagent/zedagent.go

View check run for this annotation

Codecov / codecov/patch

pkg/pillar/cmd/zedagent/zedagent.go#L2559

Added line #L2559 was not covered by tests
switch result {
case types.SenderStatusUpgrade:
log.Functionf("sendAttestReqProtobuf: Controller upgrade in progress")
Expand All @@ -2566,6 +2570,13 @@
log.Functionf("sendAttestReqProtobuf: Controller SenderStatusNotFound")
potentialUUIDUpdate(ctx.getconfigCtx)
}
if el == attest.ZAttestReqType_ATTEST_REQ_CERT {
log.Warnf("sendAttestReqProtobuf: Failed to send EdgeNodeCerts: %s",
result.String())
// XXX should we declare maintenance mode?
// We get SenderStatusNotFound when a cert can
// not be replaced in the controller for security reasons.
}

Check warning on line 2579 in pkg/pillar/cmd/zedagent/zedagent.go

View check run for this annotation

Codecov / codecov/patch

pkg/pillar/cmd/zedagent/zedagent.go#L2573-L2579

Added lines #L2573 - L2579 were not covered by tests
if !ctx.publishedEdgeNodeCerts {
// Attestation request does not clog the send queue (issued
// with the `ignoreErr` set to true), but once fails has to
Expand Down
1 change: 1 addition & 0 deletions pkg/pillar/types/vaultmgrtypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ func (status VaultStatus) LogKey() string {
type EncryptedVaultKeyFromDevice struct {
Name string
EncryptedVaultKey []byte // empty if no TPM enabled
IsTpmEnabled bool
}

// Key returns name of the vault corresponding to this object
Expand Down
Loading