Class: Vagrant::Util::Keypair::Ed25519
- Inherits:
-
Object
- Object
- Vagrant::Util::Keypair::Ed25519
- Defined in:
- lib/vagrant/util/keypair.rb
Constant Summary collapse
- AUTH_MAGIC =
Magic string header
"openssh-key-v1".freeze
- KEY_TYPE =
Key type identifier
"ssh-ed25519".freeze
- PRIVATE_KEY_START =
Header of private key file content
"-----BEGIN OPENSSH PRIVATE KEY-----\n".freeze
- PRIVATE_KEY_END =
Footer of private key file content
"-----END OPENSSH PRIVATE KEY-----\n".freeze
Class Method Summary collapse
-
.create(password = nil) ⇒ Array<String, String, String>
Creates an ed25519 SSH key pair something that's needed, it can be revisited.
-
.padded_string(s, blocksize) ⇒ String
Encodes given string with padding to block size.
-
.string(s) ⇒ String
Encodes given string.
Class Method Details
.create(password = nil) ⇒ Array<String, String, String>
Note:
Password support was not included as it's not actively used anywhere. If it ends up being
Creates an ed25519 SSH key pair something that's needed, it can be revisited
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 88 89 90 91 92 |
# File 'lib/vagrant/util/keypair.rb', line 45 def self.create(password=nil) if password raise NotImplementedError, "Ed25519 key pair generation does not support passwords" end # Generate the key base_key = ::Ed25519::SigningKey.generate # Define the comment used for the key comment = "vagrant" # Grab the raw public key public_key = base_key.verify_key.to_bytes # Encode the public key for use building the openssh private key encoded_public_key = string(KEY_TYPE) + string(public_key) # Format the public key into the openssh public key format for writing openssh_public_key = "#{KEY_TYPE} #{Base64.encode64(encoded_public_key).gsub("\n", "")} #{comment}" # Agent encoded private key is used when building the openssh private key # (https://datatracker.ietf.org/doc/html/draft-miller-ssh-agent#section-4.2.3) # (https://dnaeon.github.io/openssh-private-key-binary-format/) agent_private_key = [ ([SecureRandom.random_number((2**32)-1)] * 2).pack("NN"), # checkint, random uint32 value, twice (used for encryption verification) encoded_public_key, # includes the key type and public key string(base_key.seed + public_key), # private key with public key concatenated string(comment), # comment for the key ].join # Build openssh private key data (https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key) private_key = [ AUTH_MAGIC + "\0", # Magic string string("none"), # cipher name, no encryption, so none string("none"), # kdf name, no encryption, so none string(""), # kdf options/data, no encryption, so empty string [1].pack("N"), # Number of keys (just one) string(encoded_public_key), # The public key padded_string(agent_private_key, 8) # Private key encoded with agent rules, padded for 8 byte block size ].join # Create the openssh private key content openssh_private_key = [ PRIVATE_KEY_START, Base64.encode64(private_key), PRIVATE_KEY_END, ].join return [public_key, openssh_private_key, openssh_public_key] end |
.padded_string(s, blocksize) ⇒ String
Encodes given string with padding to block size
36 37 38 39 |
# File 'lib/vagrant/util/keypair.rb', line 36 def self.padded_string(s, blocksize) pad = blocksize - (s.length % blocksize) string(s + Array(1..pad).pack("c*")) end |
.string(s) ⇒ String
Encodes given string
27 28 29 |
# File 'lib/vagrant/util/keypair.rb', line 27 def self.string(s) [s.length].pack("N") + s end |