Class: SshSig::Blob

Inherits:
Object
  • Object
show all
Extended by:
Serializable
Includes:
Serializable
Defined in:
lib/ssh_sig/blob.rb

Constant Summary

Constants included from Serializable

Serializable::BEGIN_SIGNATURE, Serializable::END_SIGNATURE, Serializable::HASHALG_ALLOWED, Serializable::MAGIC_PREAMBLE, Serializable::SIGALG_ALLOWED, Serializable::SIG_VERSION

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Serializable

hash_algorithm_allowed?, signature_algorithm_allowed?

Constructor Details

#initialize(public_key:, namespace:, hash_algorithm:, signature:) ⇒ Blob

Returns a new instance of Blob.



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/ssh_sig/blob.rb', line 13

def initialize(
  public_key:,
  namespace:,
  hash_algorithm:,
  signature:
)
  @public_key = public_key
  @namespace = namespace
  @hash_algorithm = hash_algorithm
  @signature = signature
end

Instance Attribute Details

#hash_algorithmObject (readonly)

Returns the value of attribute hash_algorithm.



11
12
13
# File 'lib/ssh_sig/blob.rb', line 11

def hash_algorithm
  @hash_algorithm
end

#namespaceObject (readonly)

Returns the value of attribute namespace.



11
12
13
# File 'lib/ssh_sig/blob.rb', line 11

def namespace
  @namespace
end

#signatureObject (readonly)

Returns the value of attribute signature.



11
12
13
# File 'lib/ssh_sig/blob.rb', line 11

def signature
  @signature
end

Class Method Details

.from_armor(armor) ⇒ Object



31
32
33
# File 'lib/ssh_sig/blob.rb', line 31

def self.from_armor(armor)
  from_bytes(armor_to_blob(armor))
end

.from_bytes(blob) ⇒ Object

decode_blob parses the binary signature data as described in github.com/openssh/openssh-portable/blob/e665ed2d0c24fe11d5470ce72fa1e187377d3fc4/PROTOCOL.sshsig

byte MAGIC_PREAMBLE uint32 SIG_VERSION string publickey string namespace string reserved string hash_algorithm string signature

Raises:



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/ssh_sig/blob.rb', line 45

def self.from_bytes(blob)
  buf = ::Net::SSH::Buffer.new(blob)

  preamble = buf.read!(6)

  raise DecodeError, 'Invalid magic preamble' unless preamble == MAGIC_PREAMBLE

  version = read_uint64(buf)

  raise DecodeError, 'Unsupported signature version' unless version == SIG_VERSION

  public_key = buf.read_key

  raise DecodeError, 'Signature is missing public key' if public_key.nil?

  namespace = buf.read_string

  raise DecodeError, 'Signature is missing namespace' if namespace.nil?

  # Read past the reserved value and ignore it.
  buf.read_string

  hash_algorithm = buf.read_string

  raise DecodeError, 'Signature is missing hash algorithm' if hash_algorithm.nil?
  raise DecodeError, 'Hash algorithm is not supported' unless hash_algorithm_allowed?(hash_algorithm)

  signature_raw = buf.read_string

  raise DecodeError, 'Signature is missing signed data' if signature_raw.nil?

  signature = Signature.from_bytes(signature_raw)

  raise DecodeError, 'Signature algorithm is not supported' \
    unless signature_algorithm_allowed?(signature.algorithm)

  Blob.new(
    public_key: public_key,
    namespace: namespace,
    hash_algorithm: hash_algorithm,
    signature: signature
  )
end

Instance Method Details

#public_key_untrustedObject

public_key is parsed from the signature data and is untrusted We make this clear using accessor naming



27
28
29
# File 'lib/ssh_sig/blob.rb', line 27

def public_key_untrusted
  @public_key
end

#signature_data(message) ⇒ Object

signature_data creates the “message” passed to the signing function as described in section 3 of github.com/openssh/openssh-portable/blob/b7ffbb17e37f59249c31f1ff59d6c5d80888f689/PROTOCOL.sshsig

Despite the documentation’s use of the word “concatenated”, this data must use the same DER-like encoding as the signature blob.

byte MAGIC_PREAMBLE string namespace string reserved string hash_algorithm string H(message)



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/ssh_sig/blob.rb', line 101

def signature_data(message)
  buf = ::Net::SSH::Buffer.new

  buf.write(MAGIC_PREAMBLE)
  buf.write_string(namespace)
  buf.write_string('') # reserved
  buf.write_string(hash_algorithm)
  buf.write_string(hash(message))

  buf.to_s
end