hide-protocol 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c2a953028799de42c33b2d4500308cdc35dd51f0ab3a421135869f9b7f22659f
4
- data.tar.gz: b666943d4bed7075eb7899e3ac5a5b9c7475db0cd6cca222e7ed29cca8b158ee
3
+ metadata.gz: 488170733ac5d9ecacaaa15a84b6c069836d921851fb7efbcf9e13bb7e0483ee
4
+ data.tar.gz: c4c4398f9cb79ddd41c9abbc211de485ac9a1135c782c116818de60579dbb707
5
5
  SHA512:
6
- metadata.gz: b4e375e687c8c6dbdfec9bc487fbf0b8aedc32cf1e72f7139d018e5922ed9bf11f4951dd9cef88893b9cdd4642f46ef82e4c796a4f365135ed354228d25665aa
7
- data.tar.gz: 99059cec81d10c21228681a9ea36a2985f944e3e34379e03921cc35a3a3a6106733ed26899d7ec701280e48ab897356b2a0a9acf040b299cf1f6d307400a2a25
6
+ metadata.gz: ff80e1e2bdfddf7eac4de7c34746bf73b40f39d37fbd06c0ab85d41325df870622df44b631f9c563eb9f6a926defc441fb56ae8af929af12fe11edfe2d97b957
7
+ data.tar.gz: 0fb2bd25697dcfe863aec6b608e49c12349ea83f803c39359b8d4b72b29a1b244386909247f2df7c64f27b490e4c7b421eb8bd0a7e24b7e9e419036b8da328ac
@@ -107,7 +107,18 @@ module Hide
107
107
  hide_challenge_answer: [[VOIDP, VOIDP, SIZE_T, VOIDP], INT32],
108
108
  hide_spent_nonces_new: [[], VOIDP],
109
109
  hide_spent_nonces_free: [[VOIDP], VOID],
110
- hide_challenge_accept: [[VOIDP, VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP, SIZE_T, UINT64], INT32]
110
+ hide_challenge_accept: [[VOIDP, VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP, SIZE_T, UINT64], INT32],
111
+ hide_identity_verify: [[VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP], INT32],
112
+ hide_identity_trusts_device: [[VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP], INT32],
113
+ hide_identity_head: [[VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP], INT32],
114
+ hide_epoch_verify: [[VOIDP, SIZE_T, VOIDP], INT32],
115
+ hide_epoch_public_key: [[VOIDP, SIZE_T, UINT64, VOIDP], INT32],
116
+ hide_transparency_verify_inclusion: [
117
+ [VOIDP, SIZE_T, UINT64, UINT64, VOIDP, SIZE_T, VOIDP, SIZE_T], INT32
118
+ ],
119
+ hide_transparency_verify_consistency: [
120
+ [UINT64, UINT64, VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP, SIZE_T], INT32
121
+ ]
111
122
  }.freeze
112
123
 
113
124
  FUNCTIONS = SIGNATURES.each_with_object({}) do |(name, (args, ret)), acc|
@@ -163,6 +174,11 @@ module Hide
163
174
  raw.dup.force_encoding(Encoding::UTF_8).scrub
164
175
  end
165
176
 
177
+ # Reads a size_t out-parameter written into a pointer-sized slot.
178
+ def self.read_count(slot)
179
+ read_word(slot, 0)
180
+ end
181
+
166
182
  # A slot holding one pointer-sized out-parameter.
167
183
  def self.pointer_slot
168
184
  slot = Fiddle::Pointer.malloc(WORD, Fiddle::RUBY_FREE)
data/lib/hide_protocol.rb CHANGED
@@ -29,6 +29,13 @@ module Hide
29
29
  # The data was altered, or is not a HIDE container.
30
30
  class AuthenticationError < Error; end
31
31
 
32
+ # The bytes did not decode at all.
33
+ #
34
+ # A subclass of AuthenticationError so that code which only cares that
35
+ # something failed is unaffected, while a caller that must tell corruption
36
+ # from forgery can rescue this specifically.
37
+ class MalformedError < AuthenticationError; end
38
+
32
39
  # The passphrase is wrong, or the key file was modified.
33
40
  class WrongPassphraseError < Error; end
34
41
 
@@ -56,7 +63,7 @@ module Hide
56
63
  Binding::ERR_NOT_A_KEY => NotAKeyError,
57
64
  Binding::ERR_AUTHENTICATION => AuthenticationError,
58
65
  Binding::ERR_NO_MATCHING_RECIPIENT => NoMatchingRecipientError,
59
- Binding::ERR_MALFORMED => AuthenticationError,
66
+ Binding::ERR_MALFORMED => MalformedError,
60
67
  Binding::ERR_TOO_LARGE => TooLargeError,
61
68
  Binding::ERR_CHALLENGE_EXPIRED => ChallengeExpiredError,
62
69
  Binding::ERR_CHALLENGE_REPLAYED => ChallengeReplayedError
@@ -173,6 +180,118 @@ module Hide
173
180
  Binding.take(out)
174
181
  end
175
182
 
183
+ # Replays an identity log and returns how many devices it trusts now.
184
+ #
185
+ # Raises MalformedError for a log that does not decode and
186
+ # AuthenticationError for one that decodes but does not verify — the
187
+ # distinction that tells corruption from forgery. A count is returned
188
+ # rather than a boolean: a caller who forgot to test one would read every
189
+ # failure as a pass.
190
+ def verify_identity(log, recovery_key)
191
+ bytes = binary(log, "log")
192
+ recovery = binary(recovery_key, "recovery key")
193
+ slot = Binding.pointer_slot
194
+ check(Binding.call(
195
+ :hide_identity_verify,
196
+ buffer_arg(bytes), bytes.bytesize,
197
+ buffer_arg(recovery), recovery.bytesize,
198
+ slot
199
+ ))
200
+ Binding.read_count(slot)
201
+ end
202
+
203
+ # Whether the log trusts this device right now.
204
+ #
205
+ # A boolean is right here — this is a membership query, not a
206
+ # cryptographic check. The log is still verified first, so false means
207
+ # "not a member", never "did not verify": that raises.
208
+ def identity_trusts_device(log, recovery_key, device_public_key)
209
+ bytes = binary(log, "log")
210
+ recovery = binary(recovery_key, "recovery key")
211
+ device = binary(device_public_key, "device public key")
212
+ slot = Binding.pointer_slot
213
+ check(Binding.call(
214
+ :hide_identity_trusts_device,
215
+ buffer_arg(bytes), bytes.bytesize,
216
+ buffer_arg(recovery), recovery.bytesize,
217
+ buffer_arg(device), device.bytesize,
218
+ slot
219
+ ))
220
+ (Binding.read_count(slot) & 0xFFFFFFFF) != 0
221
+ end
222
+
223
+ # The head link: 32 bytes naming this exact history.
224
+ def identity_head(log, recovery_key)
225
+ bytes = binary(log, "log")
226
+ recovery = binary(recovery_key, "recovery key")
227
+ out = Binding.empty_buffer
228
+ check(Binding.call(
229
+ :hide_identity_head,
230
+ buffer_arg(bytes), bytes.bytesize,
231
+ buffer_arg(recovery), recovery.bytesize,
232
+ out
233
+ ))
234
+ Binding.take(out)
235
+ end
236
+
237
+ # Verifies a published epoch history and returns how many epochs it holds.
238
+ def verify_epoch_chain(chain)
239
+ bytes = binary(chain, "chain")
240
+ slot = Binding.pointer_slot
241
+ check(Binding.call(:hide_epoch_verify, buffer_arg(bytes), bytes.bytesize, slot))
242
+ Binding.read_count(slot)
243
+ end
244
+
245
+ # The public key a sender should encrypt to for this epoch.
246
+ #
247
+ # The chain is verified first, so a key is never returned from a history
248
+ # that does not hold together. An epoch beyond the chain raises
249
+ # InvalidArgumentError.
250
+ def epoch_public_key(chain, epoch)
251
+ bytes = binary(chain, "chain")
252
+ out = Binding.empty_buffer
253
+ check(Binding.call(
254
+ :hide_epoch_public_key,
255
+ buffer_arg(bytes), bytes.bytesize, Integer(epoch), out
256
+ ))
257
+ Binding.take(out)
258
+ end
259
+
260
+ # Checks that leaf is entry index of a log of size entries under root.
261
+ #
262
+ # path is the concatenated 32-byte hashes; any other length raises
263
+ # InvalidArgumentError. Nothing is returned, for the same reason verify
264
+ # returns nothing.
265
+ def verify_inclusion(leaf, index, size, path, root)
266
+ leaf_bytes = binary(leaf, "leaf")
267
+ path_bytes = binary(path, "path")
268
+ root_bytes = binary(root, "root")
269
+ check(Binding.call(
270
+ :hide_transparency_verify_inclusion,
271
+ buffer_arg(leaf_bytes), leaf_bytes.bytesize,
272
+ Integer(index), Integer(size),
273
+ buffer_arg(path_bytes), path_bytes.bytesize,
274
+ buffer_arg(root_bytes), root_bytes.bytesize
275
+ ))
276
+ nil
277
+ end
278
+
279
+ # Checks that old_root really is the root the log had before it grew to
280
+ # new_root. This is the check that catches a rewritten history.
281
+ def verify_consistency(old_size, new_size, path, old_root, new_root)
282
+ path_bytes = binary(path, "path")
283
+ old_bytes = binary(old_root, "old root")
284
+ new_bytes = binary(new_root, "new root")
285
+ check(Binding.call(
286
+ :hide_transparency_verify_consistency,
287
+ Integer(old_size), Integer(new_size),
288
+ buffer_arg(path_bytes), path_bytes.bytesize,
289
+ buffer_arg(old_bytes), old_bytes.bytesize,
290
+ buffer_arg(new_bytes), new_bytes.bytesize
291
+ ))
292
+ nil
293
+ end
294
+
176
295
  def check(code)
177
296
  return if code == Binding::OK
178
297
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hide-protocol
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - HIDE contributors