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: 9 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,15 @@ func writePEM(path, blockType string, der []byte, mode os.FileMode) error {
if err := pem.Encode(f, &pem.Block{Type: blockType, Bytes: der}); err != nil {
return fmt.Errorf("encode %s: %w", path, err)
}
// fsync the data file so a crash after writePEM returns doesn't lose the cert.
if err := f.Sync(); err != nil {
return fmt.Errorf("sync %s: %w", path, err)
}
// fsync the parent directory so the directory entry is committed.
if dir, err := os.Open(filepath.Dir(path)); err == nil {
dir.Sync() // best-effort; Close will report any delayed error
dir.Close()
}
return nil
}

Expand Down
31 changes: 31 additions & 0 deletions zz_pilot_ca_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,37 @@ func TestRandomSerial_Unique(t *testing.T) {
}
}

// TestWritePEM_FsyncBeforeClose pins that writePEM produces valid
// PEM files and that the file is readable immediately after the call
// returns (data durability via fsync).
func TestWritePEM_FsyncBeforeClose(t *testing.T) {
t.Parallel()
dir := t.TempDir()
path := filepath.Join(dir, "test.crt")
der := make([]byte, 32)
for i := range der {
der[i] = byte(i)
}
if err := writePEM(path, "CERTIFICATE", der, 0o644); err != nil {
t.Fatalf("writePEM: %v", err)
}
// Immediately read back — data must be on disk (fsync'd).
raw, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read back: %v", err)
}
block, _ := pem.Decode(raw)
if block == nil {
t.Fatal("no PEM block found")
}
if block.Type != "CERTIFICATE" {
t.Fatalf("expected CERTIFICATE, got %q", block.Type)
}
if len(block.Bytes) != 32 {
t.Fatalf("expected 32 DER bytes, got %d", len(block.Bytes))
}
}

// mustReadCert reads a PEM-encoded cert and parses it, failing the
// test on any error.
func mustReadCert(t *testing.T, path string) *x509.Certificate {
Expand Down
Loading