Go ValidateHashFormat was still validating the old -00 format (algorithm:base64url with sha-256/sha-384/sha-512 prefix). Updated to validate plain base64url without prefix per -01 spec and RFC 9449. Python was already updated but uncommitted. Both refimpls now match.
78 lines
1.7 KiB
Go
78 lines
1.7 KiB
Go
package ect
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"regexp"
|
|
)
|
|
|
|
// ExtMaxSize is the recommended max serialized size of ext (Section 4.2.7).
|
|
const ExtMaxSize = 4096
|
|
|
|
// ExtMaxDepth is the recommended max JSON nesting depth in ext.
|
|
const ExtMaxDepth = 5
|
|
|
|
// DefaultMaxPredLength is the recommended max number of predecessor references.
|
|
const DefaultMaxPredLength = 100
|
|
|
|
// uuidRegex matches RFC 9562 UUID: 8-4-4-4-12 hex.
|
|
var uuidRegex = regexp.MustCompile(`^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`)
|
|
|
|
// base64urlRegex matches a non-empty base64url string without padding.
|
|
var base64urlRegex = regexp.MustCompile(`^[A-Za-z0-9_-]+$`)
|
|
|
|
// ValidateExt returns an error if ext exceeds ExtMaxSize or ExtMaxDepth.
|
|
func ValidateExt(ext map[string]interface{}) error {
|
|
if ext == nil || len(ext) == 0 {
|
|
return nil
|
|
}
|
|
b, err := json.Marshal(ext)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(b) > ExtMaxSize {
|
|
return ErrExtSize
|
|
}
|
|
if depth(b) > ExtMaxDepth {
|
|
return ErrExtDepth
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func depth(b []byte) int {
|
|
var max, level int
|
|
for _, c := range b {
|
|
switch c {
|
|
case '{', '[':
|
|
level++
|
|
if level > max {
|
|
max = level
|
|
}
|
|
case '}', ']':
|
|
level--
|
|
}
|
|
}
|
|
return max
|
|
}
|
|
|
|
// ValidUUID returns true if s is a UUID string (RFC 9562).
|
|
func ValidUUID(s string) bool {
|
|
return uuidRegex.MatchString(s)
|
|
}
|
|
|
|
// ValidateHashFormat returns nil if s is empty or is plain base64url (no padding)
|
|
// per draft-nennemann-wimse-ect-01 and RFC 9449 (no algorithm prefix).
|
|
func ValidateHashFormat(s string) error {
|
|
if s == "" {
|
|
return nil
|
|
}
|
|
if !base64urlRegex.MatchString(s) {
|
|
return ErrHashFormat
|
|
}
|
|
_, err := base64.RawURLEncoding.DecodeString(s)
|
|
if err != nil {
|
|
return ErrHashFormat
|
|
}
|
|
return nil
|
|
}
|