Skip to content

Commit b27f2aa

Browse files
authored
Merge pull request #155 from eriknordmark/register-403-per-spec
server: return 403 on unregistered onboarding cert/serial
2 parents 4875249 + 738ab82 commit b27f2aa

2 files changed

Lines changed: 60 additions & 1 deletion

File tree

pkg/server/commonHandler.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,14 @@ func registerProcess(manager driver.DeviceManager, registerMessage []byte, onboa
155155
_, usedSerial := err.(*common.UsedSerialError)
156156
switch {
157157
case invalidCert, invalidSerial:
158-
return http.StatusUnauthorized, fmt.Errorf("failed authentication %v", err)
158+
// The auth-container signature already verified upstream
159+
// (apiHandlerv2.register checks SenderCertHash and the
160+
// signature before calling here); a well-formed cert or
161+
// serial that is simply not pre-registered is the
162+
// "valid credentials without authorization" case the
163+
// eve-api spec maps to 403 (APIv2.md, /register section
164+
// and the table at lines 134-142).
165+
return http.StatusForbidden, fmt.Errorf("not pre-registered %v", err)
159166
case usedSerial:
160167
return http.StatusConflict, fmt.Errorf("used serial %v", err)
161168
}

pkg/server/commonHandler_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2026 Zededa, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package server
5+
6+
import (
7+
"crypto/x509"
8+
"net/http"
9+
"testing"
10+
11+
"github.com/golang/protobuf/proto"
12+
"github.com/lf-edge/adam/pkg/driver/memory"
13+
ax "github.com/lf-edge/adam/pkg/x509"
14+
"github.com/lf-edge/eve-api/go/register"
15+
)
16+
17+
// TestRegisterProcessForbiddenForUnknownCert verifies that when the
18+
// auth-container signature has already verified upstream but the (cert,
19+
// serial) tuple is not in the controller's pre-registration set,
20+
// registerProcess returns 403 Forbidden — per APIv2.md /register:
21+
// "Valid credentials without authorization: 403".
22+
//
23+
// Prior to this fix the same condition mapped to 401 Unauthorized, which
24+
// confused "missing/invalid credentials" with "valid credentials, not
25+
// pre-registered" and prevented EVE's cmd/client from raising
26+
// LedBlinkOnboardingFailureNotFound (which is keyed off 403).
27+
func TestRegisterProcessForbiddenForUnknownCert(t *testing.T) {
28+
dm := &memory.DeviceManager{}
29+
30+
certB, _, err := ax.Generate("CN=test-onboard", "")
31+
if err != nil {
32+
t.Fatalf("generate cert: %v", err)
33+
}
34+
cert, err := x509.ParseCertificate(certB)
35+
if err != nil {
36+
t.Fatalf("parse cert: %v", err)
37+
}
38+
39+
msg := &register.ZRegisterMsg{Serial: "test-serial"}
40+
msgBytes, err := proto.Marshal(msg)
41+
if err != nil {
42+
t.Fatalf("marshal register message: %v", err)
43+
}
44+
45+
status, err := registerProcess(dm, msgBytes, cert)
46+
if status != http.StatusForbidden {
47+
t.Errorf("status: got %d, want %d (%s)", status, http.StatusForbidden, http.StatusText(http.StatusForbidden))
48+
}
49+
if err == nil {
50+
t.Error("err: got nil, want non-nil (failure should carry context)")
51+
}
52+
}

0 commit comments

Comments
 (0)