Module: Kitchen::Driver::Oci::Mixin::SshKeys::ED25519

Defined in:
lib/kitchen/driver/oci/mixin/ssh_keys.rb

Overview

Mixins required to generate a ED25519 key pair.

Author:

  • Justin Steele <justin.steele@oracle.com>

Instance Method Summary collapse

Instance Method Details

#encode_private_key(public_key, private_seed) ⇒ String

Encodes the private key.

Parameters:

  • public_key (String)

    the byte representation of the Ed25519::VerifyKey.

  • private_seed (String)

    the byte representation of the Ed25519::SigningKey.

Returns:

  • (String)


150
151
152
153
154
155
156
157
158
# File 'lib/kitchen/driver/oci/mixin/ssh_keys.rb', line 150

def encode_private_key(public_key, private_seed)
  buf  = header(public_key)
  priv = private_section(public_key, private_seed)
  padlen = (-priv.bytesize) & 7
  priv << (1..padlen).to_a.pack("C*")
  buf << pack_string(priv)
  b64 = Base64.strict_encode64(buf).scan(/.{1,70}/).join("\n")
  "-----BEGIN OPENSSH PRIVATE KEY-----\n#{b64}\n-----END OPENSSH PRIVATE KEY-----\n"
end

#encode_public_key(public_key) ⇒ String

Encodes the public key.

Parameters:

  • public_key (String)

    the byte representation of the Ed25519::VerifyKey.

Returns:

  • (String)


195
196
197
198
# File 'lib/kitchen/driver/oci/mixin/ssh_keys.rb', line 195

def encode_public_key(public_key)
  blob = [algorithm.bytesize].pack("N") + algorithm + [public_key.bytesize].pack("N") + public_key
  [algorithm, Base64.strict_encode64(blob), config[:instance_name]].compact.join(" ")
end

#generate_key_pairObject

Generates an ED25519 key pair to be used to SSH to the instance and updates the state with the full path to the private key.



109
110
111
112
113
114
115
116
# File 'lib/kitchen/driver/oci/mixin/ssh_keys.rb', line 109

def generate_key_pair
  signing_key = Ed25519::SigningKey.generate
  private_seed = signing_key.to_bytes
  public_key = signing_key.verify_key.to_bytes
  write_private_key(public_key, private_seed)
  write_public_key(public_key)
  state.store(:ssh_key, private_key_file)
end

#header(public_key) ⇒ String

“openssh-key-v1” header: magic, cipher/kdf, nkeys, and the public key blob(s).

Parameters:

  • public_key (String)

    the byte representation of the Ed25519::VerifyKey.

Returns:

  • (String)


164
165
166
167
168
169
170
171
172
173
# File 'lib/kitchen/driver/oci/mixin/ssh_keys.rb', line 164

def header(public_key)
  [
    "openssh-key-v1\0",
    pack_string("none"),  # ciphername
    pack_string("none"),  # kdfname
    pack_string(""),      # kdfoptions
    [1].pack("N"),        # nkeys
    pack_string(pub_blob(public_key)),
  ].join
end

#pack_string(str) ⇒ String

Packs a string as SSH “string” (4-byte len + bytes).

Parameters:

  • str (String)

    the portion of the key being packed.

Returns:

  • (String)


122
123
124
# File 'lib/kitchen/driver/oci/mixin/ssh_keys.rb', line 122

def pack_string(str)
  [str.bytesize].pack("N") + str
end

#private_section(public_key, private_seed) ⇒ String

Correct private section: checkints, key fields, comment, padding

Parameters:

  • public_key (String)

    the byte representation of the Ed25519::VerifyKey.

  • private_seed (String)

    the byte representation of the Ed25519::SigningKey.

Returns:

  • (String)


180
181
182
183
184
185
186
187
188
189
# File 'lib/kitchen/driver/oci/mixin/ssh_keys.rb', line 180

def private_section(public_key, private_seed)
  checkint = SecureRandom.random_number(2**32)
  [
    [checkint, checkint].pack("N*"),
    pack_string(algorithm),
    pack_string(public_key),
    pack_string(private_seed + public_key),
    pack_string(config[:instance_name] || ""),
  ].join
end

#pub_blob(public_key) ⇒ String

SSH public key blob: string keytype + string key (32 bytes).

Parameters:

  • public_key (String)

    the byte representation of the Ed25519::VerifyKey.

Returns:

  • (String)


204
205
206
# File 'lib/kitchen/driver/oci/mixin/ssh_keys.rb', line 204

def pub_blob(public_key)
  pack_string(algorithm) + pack_string(public_key)
end

#write_private_key(public_key, private_seed) ⇒ Object

Writes the encoded private key.

Parameters:

  • public_key (String)

    the byte representation of the Ed25519::VerifyKey.

  • private_seed (String)

    the byte representation of the Ed25519::SigningKey.



130
131
132
133
134
# File 'lib/kitchen/driver/oci/mixin/ssh_keys.rb', line 130

def write_private_key(public_key, private_seed)
  private_key = encode_private_key(public_key, private_seed)
  File.open(private_key_file, "w") { |f| f.write(private_key) }
  File.chmod(0600, private_key_file)
end

#write_public_key(public_key) ⇒ Object

Writes the encoded public key.

Parameters:

  • public_key (String)

    the byte representation of the Ed25519::VerifyKey.



139
140
141
142
143
# File 'lib/kitchen/driver/oci/mixin/ssh_keys.rb', line 139

def write_public_key(public_key)
  pub_key = encode_public_key(public_key)
  File.open(public_key_file, "w") { |f| f.write(pub_key) }
  File.chmod(0600, public_key_file)
end