minisign 0.0.3 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/minisign.rb +68 -9
  3. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab99f429385b0f4e6588f199322c1d3b4f0e74fc3653d44d9b7e3be64a16c1a4
4
- data.tar.gz: 87d81af21c0f8dfe4cd90846f921014dcc7383ea7a09ee5811ff22102fc3a8ba
3
+ metadata.gz: 8dd11c61143149fd612a6c08a084a4e5831ec66f860c6a706edea18fc53bec00
4
+ data.tar.gz: f7b6013996e7e72b35ad8c500e2bf5d24ebc2a9abe0d1d09bda86cfaca2d4ba8
5
5
  SHA512:
6
- metadata.gz: d2009870037a601e9417f2ea753486aa5a9b1dcca7effb7293924649978320992969c28113056953e95afeb854f05f25b1738e3dd5af203346a66b325d013884
7
- data.tar.gz: 771fa8348725c66211b95eff9e3790c0a57dfa8bcd67fafeaebe2276982a8704e69763f3a62d273192ee813449b44e72ebe22ff424ad7efd28df6c2d0a7e2366
6
+ metadata.gz: 615740c7d8fde14c2de494b2f7f9d28ebfaff2cb583210e29ee18573b97180d2a3d1ff3631085cdb53803d35a08cd31d01457c321a45d6d8b684849bcf69cb08
7
+ data.tar.gz: d89f2cace36de94f4909420161a120888a929b3a097b00cbfa33e7081f7dcb15bacd93ca21be52df9f36009c5b3f1455b75dd49c29c99c3299d6130c8561a8b7
data/lib/minisign.rb CHANGED
@@ -4,35 +4,94 @@ require 'ed25519'
4
4
  require 'base64'
5
5
  require 'openssl'
6
6
 
7
+ # `minisign` is a rubygem for verifying {https://jedisct1.github.io/minisign minisign} signatures.
8
+ # @author Jesse Shawl
7
9
  module Minisign
8
10
  # Parse a .minisig file's contents
9
11
  class Signature
10
- attr_reader :signature, :comment, :comment_signature
11
-
12
+ # @param str [String] The contents of the .minisig file
13
+ # @example
14
+ # Minisign::Signature.new(File.read('test/example.txt.minisig'))
12
15
  def initialize(str)
13
- lines = str.split("\n")
14
- @signature = Base64.decode64(lines[1])[10..]
15
- @comment = lines[2].split('trusted comment: ')[1]
16
- @comment_signature = Base64.decode64(lines[3])
16
+ @lines = str.split("\n")
17
+ end
18
+
19
+ # @return [String] the key id
20
+ # @example
21
+ # Minisign::Signature.new(File.read('test/example.txt.minisig')).key_id
22
+ # #=> "E86FECED695E8E0"
23
+ def key_id
24
+ encoded_signature[2..9].bytes.map { |c| c.to_s(16) }.reverse.join.upcase
25
+ end
26
+
27
+ # @return [String] the trusted comment
28
+ # @example
29
+ # Minisign::Signature.new(File.read('test/example.txt.minisig')).trusted_comment
30
+ # #=> "timestamp:1653934067\tfile:example.txt\thashed"
31
+ def trusted_comment
32
+ @lines[2].split('trusted comment: ')[1]
33
+ end
34
+
35
+ def trusted_comment_signature
36
+ Base64.decode64(@lines[3])
37
+ end
38
+
39
+ # @return [String] the signature
40
+ def signature
41
+ encoded_signature[10..]
42
+ end
43
+
44
+ private
45
+
46
+ def encoded_signature
47
+ Base64.decode64(@lines[1])
17
48
  end
18
49
  end
19
50
 
20
51
  # Parse ed25519 verify key from minisign public key
21
52
  class PublicKey
53
+ # Parse the ed25519 verify key from the minisign public key
54
+ #
55
+ # @param str [String] The minisign public key
56
+ # @example
57
+ # Minisign::PublicKey.new('RWTg6JXWzv6GDtDphRQ/x7eg0LaWBcTxPZ7i49xEeiqXVcR+r79OZRWM')
22
58
  def initialize(str)
23
- @public_key = Base64.strict_decode64(str)[10..]
59
+ @decoded = Base64.strict_decode64(str)
60
+ @public_key = @decoded[10..]
24
61
  @verify_key = Ed25519::VerifyKey.new(@public_key)
25
62
  end
26
63
 
64
+ # @return [String] the key id
65
+ # @example
66
+ # Minisign::PublicKey.new('RWTg6JXWzv6GDtDphRQ/x7eg0LaWBcTxPZ7i49xEeiqXVcR+r79OZRWM').key_id
67
+ # #=> "E86FECED695E8E0"
68
+ def key_id
69
+ @decoded[2..9].bytes.map { |c| c.to_s(16) }.reverse.join.upcase
70
+ end
71
+
72
+ # Verify a message's signature
73
+ #
74
+ # @param sig [Minisign::Signature]
75
+ # @param message [String] the content that was signed
76
+ # @return [String] the trusted comment
77
+ # @raise Ed25519::VerifyError on invalid signatures
78
+ # @raise RuntimeError on tampered trusted comments
27
79
  def verify(sig, message)
28
80
  blake = OpenSSL::Digest.new('BLAKE2b512')
81
+ ensure_matching_key_ids(sig.key_id, key_id)
29
82
  @verify_key.verify(sig.signature, blake.digest(message))
30
83
  begin
31
- @verify_key.verify(sig.comment_signature, sig.signature + sig.comment)
84
+ @verify_key.verify(sig.trusted_comment_signature, sig.signature + sig.trusted_comment)
32
85
  rescue Ed25519::VerifyError
33
86
  raise 'Comment signature verification failed'
34
87
  end
35
- "Signature and comment signature verified\nTrusted comment: #{sig.comment}"
88
+ "Signature and comment signature verified\nTrusted comment: #{sig.trusted_comment}"
89
+ end
90
+
91
+ private
92
+
93
+ def ensure_matching_key_ids(key_id1, key_id2)
94
+ raise "Signature key id is #{key_id1}\nbut the key id in the public key is #{key_id2}" unless key_id1 == key_id2
36
95
  end
37
96
  end
38
97
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minisign
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jesse Shawl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-30 00:00:00.000000000 Z
11
+ date: 2022-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ed25519
@@ -34,7 +34,8 @@ files:
34
34
  homepage: https://rubygems.org/gems/minisign
35
35
  licenses:
36
36
  - MIT
37
- metadata: {}
37
+ metadata:
38
+ rubygems_mfa_required: 'true'
38
39
  post_install_message:
39
40
  rdoc_options: []
40
41
  require_paths: