MCPcopy Create free account
hub / github.com/PerpetualSoftware/pad / VerifyClaimCode

Function VerifyClaimCode

internal/server/claim_codes.go:127–144  ·  view source on GitHub ↗

VerifyClaimCode returns true if code matches the derived code for (userID, workspaceID) at the current OR previous time bucket — the sliding 5–10 minute lifetime described in IDEA-1517 §4. Constant-time compare prevents timing oracles from leaking which of the two derivations failed (which would re

(secret []byte, userID, workspaceID, code string, at time.Time)

Source from the content-addressed store, hash-verified

125// Empty code, empty userID, or empty workspaceID always return false —
126// no need to even derive in those cases.
127func VerifyClaimCode(secret []byte, userID, workspaceID, code string, at time.Time) bool {
128 if code == "" || userID == "" || workspaceID == "" || len(secret) < 16 {
129 return false
130 }
131 if len(code) != claimCodeDigits {
132 return false
133 }
134 bucket := at.UTC().Unix() / claimBucketSeconds
135 current := deriveClaimCodeForBucket(secret, userID, workspaceID, bucket)
136 previous := deriveClaimCodeForBucket(secret, userID, workspaceID, bucket-1)
137 codeBytes := []byte(code)
138 // ConstantTimeCompare returns 1 on match. OR the two results so
139 // either matching bucket passes; subtle's compare doesn't panic
140 // on equal-length operands so length-mismatch isn't a concern
141 // here (we already gated on claimCodeDigits above).
142 return subtle.ConstantTimeCompare(codeBytes, []byte(current)) == 1 ||
143 subtle.ConstantTimeCompare(codeBytes, []byte(previous)) == 1
144}

Calls 1

deriveClaimCodeForBucketFunction · 0.85