77
88import std/ sugar
99import pkg/ stew/ byteutils, pkg/ results
10- import multicodec, crypto/ crypto, protobuf/ minprotobuf, vbuffer
10+ import multicodec, crypto/ crypto, vbuffer
11+ import protobuf_serialization
1112
1213export crypto
1314
1819 EnvelopeInvalidSignature
1920 EnvelopeWrongType
2021
21- Envelope * = object
22- publicKey* : PublicKey
23- domain* : string
24- payloadType* : seq [byte ]
25- payload: seq [byte ]
26- signature* : Signature
22+ Envelope * {.proto3 .} = object
23+ publicKey* {.fieldNumber : 1 , ext .}: PublicKey
24+ payloadType* {.fieldNumber : 2 .}: seq [byte ]
25+ payload {.fieldNumber : 3 .}: seq [byte ]
26+ signature* {.fieldNumber : 5 , ext .}: Signature
2727
28- proc mapProtobufError (e: ProtoError ): EnvelopeError =
29- case e
30- of RequiredFieldMissing : EnvelopeFieldMissing
31- else : EnvelopeInvalidProtobuf
32-
33- proc getSignatureBuffer (e: Envelope ): seq [byte ] =
28+ proc getSignatureBuffer (e: Envelope , domain: string ): seq [byte ] =
3429 var buffer = initVBuffer ()
3530
36- let domainBytes = e.domain.toBytes ()
37- buffer.writeSeq (domainBytes)
31+ buffer.writeSeq (domain.toBytes ())
3832 buffer.writeSeq (e.payloadType)
3933 buffer.writeSeq (e.payload)
4034
4135 buffer.buffer
4236
43- proc decode * (
44- T: typedesc [Envelope ], buf: sink seq [byte ], domain: string
45- ): Result [Envelope , EnvelopeError ] =
46- let pb = initProtoBuffer (move (buf))
47- var envelope = Envelope ()
48-
49- envelope.domain = domain
50- ? pb.getRequiredField (1 , envelope.publicKey).mapErr (mapProtobufError)
51- discard ? pb.getField (2 , envelope.payloadType).mapErr (mapProtobufError)
52- ? pb.getRequiredField (3 , envelope.payload).mapErr (mapProtobufError)
53- ? pb.getRequiredField (5 , envelope.signature).mapErr (mapProtobufError)
54-
55- if envelope.signature.verify (envelope.getSignatureBuffer (), envelope.publicKey) ==
56- false :
57- err (EnvelopeInvalidSignature )
58- else :
59- ok (envelope)
60-
6137proc init * (
6238 T: typedesc [Envelope ],
6339 privateKey: PrivateKey ,
@@ -67,49 +43,43 @@ proc init*(
6743): Result [Envelope , CryptoError ] =
6844 var envelope = Envelope (
6945 publicKey: ? privateKey.getPublicKey (),
70- domain: domain,
7146 payloadType: move (payloadType),
7247 payload: move (payload),
7348 )
7449
75- envelope.signature = ? privateKey.sign (envelope.getSignatureBuffer ())
50+ envelope.signature = ? privateKey.sign (envelope.getSignatureBuffer (domain ))
7651
7752 ok (envelope)
7853
79- proc encode * (env: Envelope ): Result [seq [byte ], CryptoError ] =
80- var pb = initProtoBuffer ()
54+ proc verify * (envelope: Envelope , domain: string ): bool =
55+ envelope.signature.verify (envelope.getSignatureBuffer (domain), envelope.publicKey)
56+
57+ proc encode * (envelope: Envelope ): seq [byte ] =
58+ Protobuf .encode (envelope)
8159
82- try :
83- pb.write (1 , env.publicKey)
84- pb.write (2 , env.payloadType)
85- pb.write (3 , env.payload)
86- pb.write (5 , env.signature)
87- except ResultError [CryptoError ] as exc:
88- return err (exc.error)
60+ proc decode * (
61+ _: type Envelope , buf: seq [byte ], domain: string
62+ ): Result [Envelope , EnvelopeError ] =
63+ let envelope =
64+ try :
65+ Protobuf .decode (buf, Envelope )
66+ except SerializationError :
67+ return err (EnvelopeInvalidProtobuf )
8968
90- pb. finish ()
91- ok (pb.buffer )
69+ if envelope.publicKey. getBytes ().isErr:
70+ return err ( EnvelopeFieldMissing )
9271
93- proc payload * (env: Envelope ): seq [byte ] =
72+ if envelope.signature.data.len == 0 :
73+ return err (EnvelopeFieldMissing )
74+
75+ if not envelope.verify (domain):
76+ return err (EnvelopeInvalidSignature )
77+
78+ ok (envelope)
79+
80+ proc payload * (envelope: Envelope ): seq [byte ] =
9481 # Payload is readonly
95- env.payload
96-
97- proc getField * (
98- pb: ProtoBuffer , field: int , value: var Envelope , domain: string
99- ): ProtoResult [bool ] =
100- var buffer: seq [byte ]
101- let res = ? pb.getField (field, buffer)
102- if not (res):
103- ok (false )
104- else :
105- value = Envelope .decode (move (buffer), domain).valueOr:
106- return err (ProtoError .IncorrectBlob )
107- ok (true )
108-
109- proc write * (pb: var ProtoBuffer , field: int , env: Envelope ): Result [void , CryptoError ] =
110- let e = ? env.encode ()
111- pb.write (field, e)
112- ok ()
82+ envelope.payload
11383
11484type SignedPayload * [T] = object
11585 # T needs to have .encode(), .decode(), .payloadType(), .payloadDomain()
@@ -126,31 +96,20 @@ proc init*[T](
12696
12797 ok (SignedPayload [T](data: data, envelope: envelope))
12898
129- proc getField * [T](
130- pb: ProtoBuffer , field: int , value: var SignedPayload [T]
131- ): ProtoResult [bool ] =
132- if not ? getField (pb, field, value.envelope, T.payloadDomain):
133- ok (false )
134- else :
135- mixin decode
136- value.data = ? T.decode (value.envelope.payload).mapErr (x => ProtoError .IncorrectBlob )
137- ok (true )
138-
13999proc decode * [T](
140100 _: typedesc [SignedPayload [T]], envelope: Envelope
141101): Result [SignedPayload [T], EnvelopeError ] =
142102 mixin decode
143103
144- if envelope.domain != T.payloadDomain :
104+ if envelope.payloadType != T.payloadType :
145105 return err (EnvelopeWrongType )
106+ if not envelope.verify (T.payloadDomain):
107+ return err (EnvelopeInvalidSignature )
146108
147109 let
148110 data = ? T.decode (envelope.payload).mapErr (x => EnvelopeInvalidProtobuf )
149111 signedPayload = SignedPayload [T](envelope: envelope, data: data)
150112
151- if envelope.payloadType != T.payloadType:
152- return err (EnvelopeWrongType )
153-
154113 when compiles (? signedPayload.checkValid ()):
155114 ? signedPayload.checkValid ()
156115
@@ -162,5 +121,5 @@ proc decode*[T](
162121 let envelope = ? Envelope .decode (move (buffer), T.payloadDomain)
163122 SignedPayload [T].decode (envelope)
164123
165- proc encode * [T](msg: SignedPayload [T]): Result [ seq [byte ], CryptoError ] =
124+ proc encode * [T](msg: SignedPayload [T]): seq [byte ] =
166125 msg.envelope.encode ()
0 commit comments