fix(P13): step-ca /tmp hardening (REQ-128, F10)

---ci---
project: orca
phase: 13
milestone: v0.12
status: execute
---/ci---

step-ca cert/key temp files moved from world-readable /tmp/orca-* to
/etc/orca/step-tmp/orca-* (0700). mkdir + chmod 700 before writing.
Fixes both stepca.go and spiffe.go. All tests updated + pass.
This commit is contained in:
Jon Chery
2026-08-07 11:22:07 +00:00
parent 7f81042abd
commit 0d5ff663b4
4 changed files with 26 additions and 21 deletions
+9 -9
View File
@@ -166,8 +166,8 @@ func TestIssueServerCert_Success(t *testing.T) {
keyPEM := []byte("SERVER-KEY-PEM")
mx.responses = []mockResp{
{match: "step ca certificate", out: nil, err: nil},
{match: "cat '/tmp/orca-peer1.crt'", out: certPEM, err: nil},
{match: "cat '/tmp/orca-peer1.key'", out: keyPEM, err: nil},
{match: "cat '/etc/orca/step-tmp/orca-peer1.crt'", out: certPEM, err: nil},
{match: "cat '/etc/orca/step-tmp/orca-peer1.key'", out: keyPEM, err: nil},
{match: "rm -f", out: nil, err: nil},
}
gotCert, gotKey, err := c.IssueServerCert(context.Background(), "peer1", []string{"peer1.orca.local", "10.0.0.1"})
@@ -199,8 +199,8 @@ func TestIssueSVID_Success(t *testing.T) {
keyPEM := []byte("SVID-KEY-PEM")
mx.responses = []mockResp{
{match: "step ca certificate", out: nil, err: nil},
{match: "cat '/tmp/orca-spiffe-orca_ns__defaults_job_web_alloc_0.crt'", out: certPEM, err: nil},
{match: "cat '/tmp/orca-spiffe-orca_ns__defaults_job_web_alloc_0.key'", out: keyPEM, err: nil},
{match: "cat '/etc/orca/step-tmp/orca-spiffe-orca_ns__defaults_job_web_alloc_0.crt'", out: certPEM, err: nil},
{match: "cat '/etc/orca/step-tmp/orca-spiffe-orca_ns__defaults_job_web_alloc_0.key'", out: keyPEM, err: nil},
{match: "rm -f", out: nil, err: nil},
}
gotCert, gotKey, err := c.IssueSVID(context.Background(), spiffe, []string{"web.orca.local"})
@@ -232,8 +232,8 @@ func TestIssueServerCert_ReadCertFails(t *testing.T) {
c, mx := newMockClient(t, "lead:22")
mx.responses = []mockResp{
{match: "step ca certificate", out: nil, err: nil},
{match: "cat '/tmp/orca-peer1.crt'", out: nil, err: errors.New("ssh: cat failed")},
{match: "cat '/tmp/orca-peer1.key'", out: nil, err: nil},
{match: "cat '/etc/orca/step-tmp/orca-peer1.crt'", out: nil, err: errors.New("ssh: cat failed")},
{match: "cat '/etc/orca/step-tmp/orca-peer1.key'", out: nil, err: nil},
}
_, _, err := c.IssueServerCert(context.Background(), "peer1", nil)
if err == nil || !strings.Contains(err.Error(), "read") {
@@ -245,8 +245,8 @@ func TestIssueServerCert_EmptyCert(t *testing.T) {
c, mx := newMockClient(t, "lead:22")
mx.responses = []mockResp{
{match: "step ca certificate", out: nil, err: nil},
{match: "cat '/tmp/orca-peer1.crt'", out: nil, err: nil},
{match: "cat '/tmp/orca-peer1.key'", out: []byte("KEY"), err: nil},
{match: "cat '/etc/orca/step-tmp/orca-peer1.crt'", out: nil, err: nil},
{match: "cat '/etc/orca/step-tmp/orca-peer1.key'", out: []byte("KEY"), err: nil},
{match: "rm -f", out: nil, err: nil},
}
_, _, err := c.IssueServerCert(context.Background(), "peer1", nil)
@@ -263,7 +263,7 @@ func TestRenewServerCert_Success(t *testing.T) {
if err := c.RenewServerCert(context.Background(), "peer1"); err != nil {
t.Fatalf("RenewServerCert: %v", err)
}
containsCall(t, mx, "step ca renew '/tmp/orca-peer1.crt' '/tmp/orca-peer1.key' --force")
containsCall(t, mx, "step ca renew '/etc/orca/step-tmp/orca-peer1.crt' '/etc/orca/step-tmp/orca-peer1.key' --force")
}
func TestRenewServerCert_Fails(t *testing.T) {