feat: user service
This commit is contained in:
@@ -38,6 +38,11 @@ var (
|
||||
// ErrInvalidEventSignature reports that one gateway event signature is not
|
||||
// a raw Ed25519 signature for the canonical event signing input.
|
||||
ErrInvalidEventSignature = errors.New("invalid event signature")
|
||||
|
||||
// ErrInvalidResponseSignature reports that one gateway unary response
|
||||
// signature is not a raw Ed25519 signature for the canonical response
|
||||
// signing input.
|
||||
ErrInvalidResponseSignature = errors.New("invalid response signature")
|
||||
)
|
||||
|
||||
// RequestSigningFields stores the canonical public request fields bound into
|
||||
@@ -85,6 +90,25 @@ type EventSigningFields struct {
|
||||
PayloadHash []byte
|
||||
}
|
||||
|
||||
// ResponseSigningFields stores the canonical public unary response fields
|
||||
// bound into one gateway signature input.
|
||||
type ResponseSigningFields struct {
|
||||
// ProtocolVersion identifies the gateway transport envelope version.
|
||||
ProtocolVersion string
|
||||
|
||||
// RequestID is the transport correlation identifier echoed by the gateway.
|
||||
RequestID string
|
||||
|
||||
// TimestampMS carries the gateway response timestamp in milliseconds.
|
||||
TimestampMS int64
|
||||
|
||||
// ResultCode stores the stable opaque gateway result code.
|
||||
ResultCode string
|
||||
|
||||
// PayloadHash stores the raw SHA-256 digest of PayloadBytes.
|
||||
PayloadHash []byte
|
||||
}
|
||||
|
||||
// ComputePayloadHash returns the canonical raw SHA-256 digest for payloadBytes.
|
||||
func ComputePayloadHash(payloadBytes []byte) []byte {
|
||||
sum := sha256.Sum256(payloadBytes)
|
||||
@@ -154,6 +178,28 @@ func BuildEventSigningInput(fields EventSigningFields) []byte {
|
||||
return buf
|
||||
}
|
||||
|
||||
// BuildResponseSigningInput returns the canonical byte sequence the v1
|
||||
// gateway unary response signature covers.
|
||||
func BuildResponseSigningInput(fields ResponseSigningFields) []byte {
|
||||
size := len("galaxy-response-v1") +
|
||||
len(fields.ProtocolVersion) +
|
||||
len(fields.RequestID) +
|
||||
len(fields.ResultCode) +
|
||||
len(fields.PayloadHash) +
|
||||
(5 * binary.MaxVarintLen64) +
|
||||
8
|
||||
|
||||
buf := make([]byte, 0, size)
|
||||
buf = appendLengthPrefixedString(buf, "galaxy-response-v1")
|
||||
buf = appendLengthPrefixedString(buf, fields.ProtocolVersion)
|
||||
buf = appendLengthPrefixedString(buf, fields.RequestID)
|
||||
buf = binary.BigEndian.AppendUint64(buf, uint64(fields.TimestampMS))
|
||||
buf = appendLengthPrefixedString(buf, fields.ResultCode)
|
||||
buf = appendLengthPrefixedBytes(buf, fields.PayloadHash)
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
// SignRequest returns one raw Ed25519 client signature for the canonical v1
|
||||
// request signing input.
|
||||
func SignRequest(privateKey ed25519.PrivateKey, fields RequestSigningFields) []byte {
|
||||
@@ -173,6 +219,19 @@ func VerifyEventSignature(publicKey ed25519.PublicKey, signature []byte, fields
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifyResponseSignature reports whether signature authenticates fields under
|
||||
// publicKey using the canonical gateway unary-response signing input.
|
||||
func VerifyResponseSignature(publicKey ed25519.PublicKey, signature []byte, fields ResponseSigningFields) error {
|
||||
if len(publicKey) != ed25519.PublicKeySize || len(signature) != ed25519.SignatureSize {
|
||||
return ErrInvalidResponseSignature
|
||||
}
|
||||
if !ed25519.Verify(publicKey, BuildResponseSigningInput(fields), signature) {
|
||||
return ErrInvalidResponseSignature
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func appendLengthPrefixedString(dst []byte, value string) []byte {
|
||||
return appendLengthPrefixedBytes(dst, []byte(value))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user