7

In a program I am developing I need a way to add public keys into the authorized_keys file during development, so I am using command line arguments to do so.

I have omitted most of the code, but if you would like to view all of the code, here is the repository, with the problem line being located in main.go on line 20.

b, err := ioutil.ReadFile(os.Args[1])
if err != nil {
    log.Fatalf("Fatal error trying to read new public key file: %s", err)
}

newAuthorizedKey, err := ssh.ParsePublicKey(b)
if err != nil {
    log.Fatalf("Fatal error trying to parse new public key: %s", err)
}

The "short read" error comes from the ssh.ParsePublicKey function. The command line argument that I am passing in is the location of a public key to add to the authorized_keys file of this program (e.g. ~/.ssh/id_rsa.pub). I have ensured that the file is correctly being passed into the program.

I have looked at the source code in hopes of debugging this "short read" error, but I can't figure out what is going on. The location for source code of the ParsePublicKey function in crypto/ssh is located here, and the location of source code of the parseString function, which is what the ParsePublicKey function is using to generate the "short read" error, is located here, also in crypto/ssh.

  • 1
    The documentation for [`ParsePublicKey`](https://godoc.org/golang.org/x/crypto/ssh#ParsePublicKey) says it parses public keys in wire format, not the on disk format used by openssh. – JimB Dec 29 '17 at 00:50
  • Wasn't aware that there were multiple formats, is there a way to convert to wire format? @JimB – George Edward Shaw IV Dec 29 '17 at 00:51
  • 1
    You don’t need to parse anything, id_rsa.pub _is_ the authorized_keys format. Most people add them on the cli just by appending them directly to the authorized_keys file. – JimB Dec 29 '17 at 00:58
  • The reason I'm trying to convert it into a `ssh.PublicKey` interface is because [`MarshalAuthorizedKey`](https://godoc.org/golang.org/x/crypto/ssh#MarshalAuthorizedKey) takes in a `ssh.PublicKey` interface and returns an authorized key ready to be appended to the authorized_keys file. Do they only have this function to get the key back into the format that it was on the disk? @JimB – George Edward Shaw IV Dec 29 '17 at 01:03
  • 1
    No, they have that function for when you don’t already have a .pub file. – JimB Dec 29 '17 at 01:12
  • Oh okay, thank you for your help @JimB – George Edward Shaw IV Dec 29 '17 at 01:13

1 Answers1

10

I think some of the comments to the question lead at this, but the function ssh.ParseAuthorizedKey([]byte) is able to read interpret the file at ~/.ssh/id_rsa.pub.

https://godoc.org/golang.org/x/crypto/ssh#ParseAuthorizedKey

Your example should work like this:

b, err := ioutil.ReadFile(os.Args[1])
if err != nil {
    log.Fatalf("Fatal error trying to read new public key file: %s", err)
}

newAuthorizedKey, _, _, _, err := ssh.ParseAuthorizedKey(b)
if err != nil {
    log.Fatalf("Fatal error trying to parse new public key: %s", err)
}
royvandewater
  • 1,368
  • 2
  • 14
  • 16