Skip to content

Commit

Permalink
helper/acctest: Add NewSSHKeyPair function (#12894)
Browse files Browse the repository at this point in the history
Many cloud services prevent duplicate key pairs with different names.
Among them are Digital Ocean, Joyent Triton and Packet. Consequently, if
tests leave dangling resources it is not enough to simply randomise the
name, the entire key material must be regenerated.

This commit adds a helper method that returns a new randomly generated
key pair, where the public key material is formatted in OpenSSH
"authorized keys" format, and the private key material is PEM encoded.
  • Loading branch information
jen20 authored and mbfrahry committed Mar 28, 2017
1 parent b59a7df commit fcb4fed
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions helper/acctest/random.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
package acctest

import (
"bufio"
"bytes"
crand "crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"math/rand"
"strings"
"time"

"golang.org/x/crypto/ssh"
)

// Helpers for generating random tidbits for use in identifiers to prevent
Expand Down Expand Up @@ -30,6 +40,28 @@ func RandStringFromCharSet(strlen int, charSet string) string {
return string(result)
}

// RandSSHKeyPair generates a public and private SSH key pair. The public key is
// returned in OpenSSH format, and the private key is PEM encoded.
func RandSSHKeyPair(comment string) (string, string, error) {
privateKey, err := rsa.GenerateKey(crand.Reader, 1024)
if err != nil {
return "", "", err
}

var privateKeyBuffer bytes.Buffer
privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}
if err := pem.Encode(bufio.NewWriter(&privateKeyBuffer), privateKeyPEM); err != nil {
return "", "", err
}

publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
if err != nil {
return "", "", err
}
keyMaterial := strings.TrimSpace(string(ssh.MarshalAuthorizedKey(publicKey)))
return fmt.Sprintf("%s %s", keyMaterial, comment), privateKeyBuffer.String(), nil
}

// Seeds random with current timestamp
func reseed() {
rand.Seed(time.Now().UTC().UnixNano())
Expand Down

0 comments on commit fcb4fed

Please sign in to comment.