Skip to content

Commit 0e09bfa

Browse files
committed
fix: address final review comments
1 parent c652725 commit 0e09bfa

6 files changed

Lines changed: 43 additions & 89 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- Consolidate shared `connect` status-line formatting between standard and verbose text output paths. ([#121])
1717
- Centralize pre-commit hooks under the shared `sensiblebit/.github` hook set (including shared `markdownlint`) and run dependency update hooks first; refresh resulting indirect Go and web lockfile dependencies. ([#128])
1818
- Remove the arbitrary 200-file cap from WASM upload and inspect flows; rely on byte limits instead. ([#129])
19+
- Enforce a stricter repo-local `golangci-lint` policy and refactor error handling, protocol encoding helpers, file-permission behavior, and tests to satisfy the higher lint bar. ([#130])
1920

2021
### Added
2122

bundle.go

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,21 @@ var (
3030
mozillaRootKeys map[string][]byte // RawSubject → marshaled PKIX public key
3131

3232
// ErrChainVerificationFailed indicates that certificate path validation failed.
33-
ErrChainVerificationFailed = errors.New("chain verification failed")
34-
errMozillaRootParse = errors.New("parsing embedded Mozilla root certificates")
35-
errAIAAddressBlocked = errors.New("blocked address for AIA fetch")
36-
errAIAPrivateAddress = errors.New("blocked private address for AIA fetch")
37-
errAIAUnsupportedScheme = errors.New("unsupported scheme")
38-
errAIAMissingHostname = errors.New("missing hostname in URL")
39-
errAIAResolveNoIPs = errors.New("no IP addresses returned")
40-
errFetchLeafHTTPSRequired = errors.New("invalid URL scheme")
41-
errFetchLeafNotTLS = errors.New("TLS dial did not return TLS connection")
42-
errFetchLeafNoCerts = errors.New("no certificates returned by TLS server")
43-
errAIAFetchRedirects = errors.New("AIA redirect limit exceeded")
44-
errAIAHTTPStatus = errors.New("AIA server returned non-200 status")
45-
errBundleLeafNil = errors.New("leaf certificate is nil")
46-
errBundleUnknownTrustStore = errors.New("unknown trust_store")
33+
ErrChainVerificationFailed = errors.New("chain verification failed")
34+
errMozillaRootParse = errors.New("parsing embedded Mozilla root certificates")
35+
errAIAAddressBlocked = errors.New("blocked address for AIA fetch")
36+
errAIAPrivateAddress = errors.New("blocked private address for AIA fetch")
37+
errAIAUnsupportedScheme = errors.New("unsupported scheme")
38+
errAIAMissingHostname = errors.New("missing hostname in URL")
39+
errAIAResolveNoIPs = errors.New("no IP addresses returned")
40+
errFetchLeafHTTPSRequired = errors.New("invalid URL scheme")
41+
errFetchLeafMissingHostname = errors.New("fetch leaf URL is missing hostname")
42+
errFetchLeafNotTLS = errors.New("TLS dial did not return TLS connection")
43+
errFetchLeafNoCerts = errors.New("no certificates returned by TLS server")
44+
errAIAFetchRedirects = errors.New("AIA redirect limit exceeded")
45+
errAIAHTTPStatus = errors.New("AIA server returned non-200 status")
46+
errBundleLeafNil = errors.New("leaf certificate is nil")
47+
errBundleUnknownTrustStore = errors.New("unknown trust_store")
4748
)
4849

4950
// privateNetworks contains CIDR ranges for private, reserved, and shared
@@ -384,7 +385,7 @@ func FetchLeafFromURL(ctx context.Context, input FetchLeafFromURLInput) (*x509.C
384385

385386
host := parsed.Hostname()
386387
if host == "" {
387-
return nil, errAIAMissingHostname
388+
return nil, errFetchLeafMissingHostname
388389
}
389390
port := parsed.Port()
390391
if port == "" {

cmd/certkit/readonly_commands_test.go

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -289,44 +289,6 @@ func TestRunScan_CommandSurface(t *testing.T) {
289289
}
290290
}
291291

292-
func TestRunScan_DumpCertsPermissions(t *testing.T) {
293-
snap := snapshotReadonlyGlobals()
294-
t.Cleanup(func() { restoreReadonlyGlobals(snap) })
295-
296-
dir := t.TempDir()
297-
_, cert := generateKeyAndCert(t, "scan.example.com", false)
298-
writeCertPEM(t, dir, "leaf.pem", cert)
299-
300-
passwordList = nil
301-
passwordFile = ""
302-
verbose = false
303-
jsonOutput = false
304-
scanBundlePath = ""
305-
scanConfigPath = filepath.Join(dir, "missing-config.yaml")
306-
scanForceExport = true
307-
scanDuplicates = false
308-
scanDumpKeys = ""
309-
scanDumpCerts = filepath.Join(dir, "dumped-certs.pem")
310-
scanMaxFileSize = 10 * 1024 * 1024
311-
scanFormat = "text"
312-
scanAllowPrivateNetwork = false
313-
scanSaveDB = ""
314-
scanLoadDB = ""
315-
316-
_, _, err := captureOutput(t, func() error { return runScan(newCommandWithContext(), []string{dir}) })
317-
if err != nil {
318-
t.Fatalf("runScan with --dump-certs failed: %v", err)
319-
}
320-
321-
info, err := os.Stat(scanDumpCerts)
322-
if err != nil {
323-
t.Fatalf("stat dumped certs: %v", err)
324-
}
325-
if perm := info.Mode().Perm(); perm != 0o644 {
326-
t.Fatalf("dumped certs permissions = %04o, want 0644", perm)
327-
}
328-
}
329-
330292
func TestRunInspect_CommandSurface(t *testing.T) {
331293
snap := snapshotReadonlyGlobals()
332294
t.Cleanup(func() { restoreReadonlyGlobals(snap) })

internal/csr_test.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,6 @@ func TestGenerateCSRFiles_WithExistingKey(t *testing.T) {
206206
if perm := csrInfo.Mode().Perm(); perm != 0o644 {
207207
t.Errorf("csr file permissions = %04o, want 0644", perm)
208208
}
209-
outDirInfo, err := os.Stat(outDir)
210-
if err != nil {
211-
t.Fatal(err)
212-
}
213-
if perm := outDirInfo.Mode().Perm(); perm != 0o755 {
214-
t.Errorf("output directory permissions = %04o, want 0755", perm)
215-
}
216209
if !key.PublicKey.Equal(csr.PublicKey) {
217210
t.Error("CSR public key does not match existing key — CSR was signed by a different key")
218211
}

internal/keygen_test.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,6 @@ func TestGenerateKeyFiles(t *testing.T) {
137137
t.Errorf("key file permissions = %04o, want 0600", perm)
138138
}
139139

140-
dirInfo, err := os.Stat(dir)
141-
if err != nil {
142-
t.Fatal(err)
143-
}
144-
if perm := dirInfo.Mode().Perm(); perm != 0o755 {
145-
t.Errorf("output directory permissions = %04o, want 0755", perm)
146-
}
147-
148140
// Verify pub.pem exists, is parseable, and has standard permissions
149141
pubPath := filepath.Join(dir, "pub.pem")
150142
pubData := mustReadTestFile(t, pubPath)

legacyprobe_test.go

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,21 @@ func mustWrapTLSRecord(t *testing.T, handshakeMsg []byte) []byte {
2727

2828
// buildCertificateMessageBody constructs a TLS Certificate message body
2929
// from DER-encoded certificates.
30-
func buildCertificateMessageBody(certs ...[]byte) []byte {
30+
func buildCertificateMessageBody(t *testing.T, certs ...[]byte) []byte {
31+
t.Helper()
3132
var entries []byte
3233
for _, cert := range certs {
3334
certLen, err := checkedUint24Len(len(cert), "certificate entry")
3435
if err != nil {
35-
panic(err)
36+
t.Fatalf("certificate entry length: %v", err)
3637
}
3738
entries = appendUint24(entries, certLen)
3839
entries = append(entries, cert...)
3940
}
4041
var body []byte
4142
entriesLen, err := checkedUint24Len(len(entries), "certificate message entries")
4243
if err != nil {
43-
panic(err)
44+
t.Fatalf("certificate message entries length: %v", err)
4445
}
4546
body = appendUint24(body, entriesLen)
4647
body = append(body, entries...)
@@ -69,10 +70,10 @@ func TestReadServerCertificates(t *testing.T) {
6970
}
7071

7172
// Build a ServerHello handshake message (cipher 0x0033, TLS 1.2).
72-
serverHello := buildMockServerHello(0x0303, 0x0033)
73+
serverHello := buildMockServerHello(t, 0x0303, 0x0033)
7374

7475
// Build a Certificate handshake message.
75-
certMsg := buildCertificateHandshakeMessage(certDER)
76+
certMsg := buildCertificateHandshakeMessage(t, certDER)
7677

7778
// Build a Certificate handshake message that spans two records by splitting
7879
// mid-message. This exercises the "incomplete message, need more records"
@@ -117,7 +118,7 @@ func TestReadServerCertificates(t *testing.T) {
117118
},
118119
{
119120
name: "alert record",
120-
records: buildAlertRecord(),
121+
records: buildAlertRecord(t),
121122
wantErr: errAlertReceived,
122123
},
123124
{
@@ -129,12 +130,12 @@ func TestReadServerCertificates(t *testing.T) {
129130
},
130131
{
131132
name: "oversized TLS record",
132-
records: buildRawTLSRecord(0x16, 16641),
133+
records: buildRawTLSRecord(t, 0x16, 16641),
133134
wantErrContains: "tls record too large",
134135
},
135136
{
136137
name: "unexpected content type",
137-
records: buildRawTLSRecord(0x17, 1), // ApplicationData
138+
records: buildRawTLSRecord(t, 0x17, 1), // ApplicationData
138139
wantErrContains: "unexpected tls content type",
139140
},
140141
}
@@ -190,8 +191,8 @@ func TestReadServerCertificates_AlertAfterServerHello(t *testing.T) {
190191
// WHY: Legacy parser must return parsed ServerHello context even when a
191192
// fatal alert follows, preserving diagnostic signal for callers.
192193
t.Parallel()
193-
serverHello := buildMockServerHello(0x0303, 0x0033)
194-
records := append(mustWrapTLSRecord(t, serverHello), buildAlertRecord()...)
194+
serverHello := buildMockServerHello(t, 0x0303, 0x0033)
195+
records := append(mustWrapTLSRecord(t, serverHello), buildAlertRecord(t)...)
195196

196197
sh, certs, err := readServerCertificates(bytes.NewReader(records))
197198
if !errors.Is(err, errAlertReceived) {
@@ -236,7 +237,8 @@ func TestReadServerCertificates_PayloadLimit(t *testing.T) {
236237
}
237238

238239
// buildMockServerHello builds a minimal ServerHello handshake message.
239-
func buildMockServerHello(version, cipherSuite uint16) []byte {
240+
func buildMockServerHello(t *testing.T, version, cipherSuite uint16) []byte {
241+
t.Helper()
240242
var body []byte
241243
// Version (2 bytes).
242244
body = appendUint16(body, version)
@@ -253,20 +255,21 @@ func buildMockServerHello(version, cipherSuite uint16) []byte {
253255
msg := []byte{0x02}
254256
bodyLen, err := checkedUint24Len(len(body), "server hello body")
255257
if err != nil {
256-
panic(err)
258+
t.Fatalf("server hello body length: %v", err)
257259
}
258260
msg = appendUint24(msg, bodyLen)
259261
msg = append(msg, body...)
260262
return msg
261263
}
262264

263265
// buildCertificateHandshakeMessage builds a TLS Certificate handshake message.
264-
func buildCertificateHandshakeMessage(certs ...[]byte) []byte {
265-
body := buildCertificateMessageBody(certs...)
266+
func buildCertificateHandshakeMessage(t *testing.T, certs ...[]byte) []byte {
267+
t.Helper()
268+
body := buildCertificateMessageBody(t, certs...)
266269
msg := []byte{0x0B} // Certificate
267270
bodyLen, err := checkedUint24Len(len(body), "certificate handshake body")
268271
if err != nil {
269-
panic(err)
272+
t.Fatalf("certificate handshake body length: %v", err)
270273
}
271274
msg = appendUint24(msg, bodyLen)
272275
msg = append(msg, body...)
@@ -277,26 +280,28 @@ func buildCertificateHandshakeMessage(certs ...[]byte) []byte {
277280
// payload of payloadLen zero bytes. Unlike wrapTLSRecord it does NOT cap the
278281
// payload size, so it can be used to construct intentionally oversized records
279282
// for negative test cases.
280-
func buildRawTLSRecord(contentType byte, payloadLen int) []byte {
283+
func buildRawTLSRecord(t *testing.T, contentType byte, payloadLen int) []byte {
284+
t.Helper()
281285
record := []byte{contentType, 0x03, 0x03}
282286
payloadSize, err := checkedUint16Len(payloadLen, "raw TLS record payload")
283287
if err != nil {
284-
panic(err)
288+
t.Fatalf("raw TLS record payload length: %v", err)
285289
}
286290
record = appendUint16(record, payloadSize)
287291
record = append(record, make([]byte, payloadLen)...)
288292
return record
289293
}
290294

291295
// buildAlertRecord builds a TLS Alert record.
292-
func buildAlertRecord() []byte {
296+
func buildAlertRecord(t *testing.T) []byte {
297+
t.Helper()
293298
// Alert: handshake_failure (40), fatal (2).
294299
payload := []byte{0x02, 0x28}
295300
record := []byte{0x15} // ContentType: Alert
296301
record = append(record, 0x03, 0x01)
297302
payloadLen, err := checkedUint16Len(len(payload), "alert payload")
298303
if err != nil {
299-
panic(err)
304+
t.Fatalf("alert payload length: %v", err)
300305
}
301306
record = appendUint16(record, payloadLen)
302307
record = append(record, payload...)
@@ -339,8 +344,8 @@ func TestLegacyFallbackConnect(t *testing.T) {
339344
}
340345

341346
// Send ServerHello + Certificate as raw TLS records.
342-
serverHello := buildMockServerHello(0x0303, 0x0033)
343-
certMsg := buildCertificateHandshakeMessage(leaf.DER)
347+
serverHello := buildMockServerHello(t, 0x0303, 0x0033)
348+
certMsg := buildCertificateHandshakeMessage(t, leaf.DER)
344349
helloDone := []byte{0x0E, 0x00, 0x00, 0x00} // ServerHelloDone
345350

346351
// Pack all handshake messages into a single TLS record.

0 commit comments

Comments
 (0)