add token framing, crypto and errors
This commit is contained in:
parent
71483982ca
commit
a6aad1a1d6
5 changed files with 448 additions and 0 deletions
58
framing.go
Normal file
58
framing.go
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package ficha
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const tokenVersion = "v1"
|
||||
|
||||
// encodeToken builds the wire format: v1.<keyID>.<base64url(none||ciphertext)>
|
||||
func encodeToken(keyID string, nonce, ciphertext []byte) string {
|
||||
body := make([]byte, 0, len(nonce)+len(ciphertext))
|
||||
body = append(body, nonce...)
|
||||
body = append(body, ciphertext...)
|
||||
|
||||
var b strings.Builder
|
||||
b.Grow(len(tokenVersion) + 1 + len(keyID) + 1 + base64.RawURLEncoding.EncodedLen(len(body)))
|
||||
b.WriteString(tokenVersion)
|
||||
b.WriteByte('.')
|
||||
b.WriteString(keyID)
|
||||
b.WriteByte('.')
|
||||
b.WriteString(base64.RawURLEncoding.EncodeToString(body))
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// decodeToken parses the wire format and splits the body back into nonce and ciphertext.
|
||||
// Returns ErrInvalidToken for any malformed input.
|
||||
func decodeToken(token string) (keyID string, nonce, ciphertext []byte, err error) {
|
||||
parts := strings.SplitN(token, ".", 3)
|
||||
if len(parts) != 3 {
|
||||
return "", nil, nil, ErrInvalidToken
|
||||
}
|
||||
if parts[0] != tokenVersion {
|
||||
return "", nil, nil, ErrInvalidToken
|
||||
}
|
||||
if parts[1] == "" {
|
||||
return "", nil, nil, ErrInvalidToken
|
||||
}
|
||||
|
||||
body, err := base64.RawURLEncoding.DecodeString(parts[2])
|
||||
if err != nil {
|
||||
return "", nil, nil, ErrInvalidToken
|
||||
}
|
||||
|
||||
// body must be at least nonce + auth tag (16 bytes)
|
||||
if len(body) < nonceSize+16 {
|
||||
return "", nil, nil, ErrInvalidToken
|
||||
}
|
||||
|
||||
return parts[1], body[:nonceSize], body[nonceSize:], nil
|
||||
}
|
||||
|
||||
// aadFor builds the AAD bytes for a given version+keyID. Both encrypt
|
||||
// and decrypt must use the same construction.
|
||||
func aadFor(keyID string) []byte {
|
||||
return []byte(tokenVersion + "." + keyID)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue