Skip to content
Snippets Groups Projects
Select Git revision
  • 321e26fae746e661d713cedfb6642609e680cafe
  • ballinvoher default protected
  • client-http-server-for-token
  • master
  • gitlab-auth-issue
  • windows
  • microsoft
  • message
  • azure_auth
  • prometheus
  • permission-templates
  • no-datastore
  • save-public-keys
  • gitlab-group-level-start
  • v1.1.0
  • v1.0.0
  • v0.1
17 results

edkey.go

Blame
    • fuero's avatar
      321e26fa
      Saving private keys (#61) · 321e26fa
      fuero authored
      * enables saving private keys
      
      * renames public_file_prefix to key_file_prefix and updates its docs to better reflect the changes
      321e26fa
      History
      Saving private keys (#61)
      fuero authored
      * enables saving private keys
      
      * renames public_file_prefix to key_file_prefix and updates its docs to better reflect the changes
    edkey.go 2.22 KiB
    package edkey
    
    import (
    	"math/rand"
    
    	"golang.org/x/crypto/ed25519"
    	"golang.org/x/crypto/ssh"
    )
    
    /* Writes ed25519 private keys into the new OpenSSH private key format.
    I have no idea why this isn't implemented anywhere yet, you can do seemingly
    everything except write it to disk in the OpenSSH private key format. */
    func MarshalED25519PrivateKey(key ed25519.PrivateKey) []byte {
    	// Add our key header (followed by a null byte)
    	magic := append([]byte("openssh-key-v1"), 0)
    
    	var w struct {
    		CipherName   string
    		KdfName      string
    		KdfOpts      string
    		NumKeys      uint32
    		PubKey       []byte
    		PrivKeyBlock []byte
    	}
    
    	// Fill out the private key fields
    	pk1 := struct {
    		Check1  uint32
    		Check2  uint32
    		Keytype string
    		Pub     []byte
    		Priv    []byte
    		Comment string
    		Pad     []byte `ssh:"rest"`
    	}{}
    
    	// Set our check ints
    	ci := rand.Uint32()
    	pk1.Check1 = ci
    	pk1.Check2 = ci
    
    	// Set our key type
    	pk1.Keytype = ssh.KeyAlgoED25519
    
    	// Add the pubkey to the optionally-encrypted block
    	pk, ok := key.Public().(ed25519.PublicKey)
    	if !ok {
    		//fmt.Fprintln(os.Stderr, "ed25519.PublicKey type assertion failed on an ed25519 public key. This should never ever happen.")
    		return nil
    	}
    	pubKey := []byte(pk)
    	pk1.Pub = pubKey
    
    	// Add our private key
    	pk1.Priv = []byte(key)
    
    	// Might be useful to put something in here at some point
    	pk1.Comment = ""
    
    	// Add some padding to match the encryption block size within PrivKeyBlock (without Pad field)
    	// 8 doesn't match the documentation, but that's what ssh-keygen uses for unencrypted keys. *shrug*
    	bs := 8
    	blockLen := len(ssh.Marshal(pk1))
    	padLen := (bs - (blockLen % bs)) % bs
    	pk1.Pad = make([]byte, padLen)
    
    	// Padding is a sequence of bytes like: 1, 2, 3...
    	for i := 0; i < padLen; i++ {
    		pk1.Pad[i] = byte(i + 1)
    	}