Skip to content
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
9 changes: 8 additions & 1 deletion pkg/server/commonHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,14 @@ func registerProcess(manager driver.DeviceManager, registerMessage []byte, onboa
_, usedSerial := err.(*common.UsedSerialError)
switch {
case invalidCert, invalidSerial:
return http.StatusUnauthorized, fmt.Errorf("failed authentication %v", err)
// The auth-container signature already verified upstream
// (apiHandlerv2.register checks SenderCertHash and the
// signature before calling here); a well-formed cert or
// serial that is simply not pre-registered is the
// "valid credentials without authorization" case the
// eve-api spec maps to 403 (APIv2.md, /register section
// and the table at lines 134-142).
return http.StatusForbidden, fmt.Errorf("not pre-registered %v", err)
case usedSerial:
return http.StatusConflict, fmt.Errorf("used serial %v", err)
}
Expand Down
52 changes: 52 additions & 0 deletions pkg/server/commonHandler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2026 Zededa, Inc.
// SPDX-License-Identifier: Apache-2.0

package server

import (
"crypto/x509"
"net/http"
"testing"

"github.com/golang/protobuf/proto"
"github.com/lf-edge/adam/pkg/driver/memory"
ax "github.com/lf-edge/adam/pkg/x509"
"github.com/lf-edge/eve-api/go/register"
)

// TestRegisterProcessForbiddenForUnknownCert verifies that when the
// auth-container signature has already verified upstream but the (cert,
// serial) tuple is not in the controller's pre-registration set,
// registerProcess returns 403 Forbidden — per APIv2.md /register:
// "Valid credentials without authorization: 403".
//
// Prior to this fix the same condition mapped to 401 Unauthorized, which
// confused "missing/invalid credentials" with "valid credentials, not
// pre-registered" and prevented EVE's cmd/client from raising
// LedBlinkOnboardingFailureNotFound (which is keyed off 403).
func TestRegisterProcessForbiddenForUnknownCert(t *testing.T) {
dm := &memory.DeviceManager{}

certB, _, err := ax.Generate("CN=test-onboard", "")
if err != nil {
t.Fatalf("generate cert: %v", err)
}
cert, err := x509.ParseCertificate(certB)
if err != nil {
t.Fatalf("parse cert: %v", err)
}

msg := &register.ZRegisterMsg{Serial: "test-serial"}
msgBytes, err := proto.Marshal(msg)
if err != nil {
t.Fatalf("marshal register message: %v", err)
}

status, err := registerProcess(dm, msgBytes, cert)
if status != http.StatusForbidden {
t.Errorf("status: got %d, want %d (%s)", status, http.StatusForbidden, http.StatusText(http.StatusForbidden))
}
if err == nil {
t.Error("err: got nil, want non-nil (failure should carry context)")
}
}
Loading