Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/crypto/ssh: ParsePrivateKey fails to parse BER encoded key #14145

Closed
rickard-von-essen opened this issue Jan 29, 2016 · 5 comments
Closed

x/crypto/ssh: ParsePrivateKey fails to parse BER encoded key #14145

rickard-von-essen opened this issue Jan 29, 2016 · 5 comments

Comments

@rickard-von-essen
Copy link

A key created with Parmiko (OpenStack/Nova) which is valid according to OpenSSL can't be parsed by ssh.ParsePrivateKey.

Trying to parse the example key with ssh.ParsePrivateKey gives:

$ go run fail.go
2016/01/29 11:06:26 asn1: structure error: superfluous leading zeros in length
exit status 1

Verifying the PEM

Verifying the example.pem (see the key at the bottom):

$ openssl rsa -in example.pem  -check -noout
RSA key ok
$ openssl rsa -in example.pem  -text -noout > /dev/null && echo "OK"
OK
$ openssl asn1parse -in example.pem
    0:d=0  hl=4 l=1193 cons: SEQUENCE
    4:d=1  hl=2 l=   1 prim: INTEGER           :00
    7:d=1  hl=4 l= 257 prim: INTEGER           :A350BF890B6EEE24942513B24202A6E55B496DA3E0E4610FEC80BEED34D9DA456759AF55314DFBB1729693427BA111DC499FDD851C8D0DCB2FB1C14053A577151A59C624C4BC2A880602F2A15DE0FB091A9FE80302A366AA6EFB95D508C0C5D3EE7DC07968A9C34B8E07364D8C036101FF2A1C84F63D7A13E8B7DA0A87F83E53EE7024F1782FA84F9CC0FCC6D0A069DE3641E7476EA28CC69CDAF442F74FB55A96792B009513AA9DDA411195BF606C01AC34B13F5ABA91EDBC7877C7AC2ED137979CF09014C1EB729DA23302AD7FD90621D3D794C1415B053D0AA17414F70577ECB27BAD32409FEBE5F43C842441C5BA46A291E67387305741D6410285A29833
  268:d=1  hl=2 l=   3 prim: INTEGER           :010001
  273:d=1  hl=4 l= 257 prim: INTEGER           :9104FBFFA2926F8F35A9B2D2C08100587BF63910A37BC8A0CE3F08CB33FA1B3333F1D49A8EBC93BA5F694BFC663181DD9DD7026AD80E7CE82742EDBAC44C12F13F43E689F1D4B0E3B68AD98EE70107896F05FD8CE6C3D83F916B8001FAD2CB1845178F597FD1F764590B187245D91E441AA3F74D2E272B0710C8692A9ED095EE9F9098FBE5074E634F7BEC7368CB9F6C975D511BBB55F9663F3671D1701F8652736043BFC8B1047CBECCE18BC744CC17487110774D21E023193C987E2C83AF99A030FE30EA2806BCFF2AA41E5F13AD1928210F2C6CB1330EBD9C36D724AE9800AC8D095003EFD144975C8B6099567D802D388E94784D1150F7838B8DAF20DC81
  534:d=1  hl=4 l= 129 prim: INTEGER           :BDCD9CE5E242544DDCD82D8AF143B7F9D41F9E385EB6D6495E4D82E9AEBF08E1565413186D2ADB077475B3324C55B5DED0ED4706F4BF8FA9ADC35670F74B60B522E5243B7782A5AF778E18B008845841F47B133B919ED56B4077D868282BF1A86659DA1E654AFC9520C3A74FE1F8C6A6124B0D123640F97C055A0EB270B806C1
  667:d=1  hl=4 l= 129 prim: INTEGER           :DC4633E621EA68E75E901617705A64ABCBA4F929F6EC29A777BA4B7CAFD858401BDCF89EF57D297ED0353BCCF4B56F69BC4052FA9036ED2E796B7F1ABE66529190225CC24E6771D5F7D5598B9594D0F83D03DA08890BD6EAD77D6F5BAE565E6AA3D7C22BFAF5EC4ECD0858A6B6A48DB6B351FD7D3C83E9780E9D4EBAB826EFF3
  800:d=1  hl=4 l= 128 prim: INTEGER           :20632885B5A119DF9B72ABFACC8680AB39BE177288FEEBFBE30298F7252165F385969D178AF14824B283AF0B432950FA6F6E3DB37B2A00EAB442E3CA2CF888CCFFE257D769E23A4181C616825B41B209B71D154011EE277EC0A6729FFB52DC4E9F00700EC5BC10F3A57E9D5B2D3515389B60811F7D7082E1DDCBEB3C19ADDD41
  932:d=1  hl=4 l= 129 prim: INTEGER           :BB111FB83C6B5FA5C668256AC86EEBF9FE1B5FC364C1116AF8C20CA39A8EE7FBA1EE1A729CD72BAB57D52DB114CD150E3DE27ED5EE2DC765E596063EC71E0CD7340A0AAEB5792272ED6392057A0605261C632E027BA8C35F739C423B2126964E88508EC55CFF072DB0F07AA13291330CCAE3419CDF0CC3F4C2AC9394FD198C43
 1065:d=1  hl=4 l= 128 prim: INTEGER           :0156F5A8064B8B61D51AD5C2782328708F7A7411D504AF1C31EFDC4DC442D6B57742B70B1ED109D0690CD78D2291D5ABCB936968D267E126E980E36BB0AA21F3E3D07732922CF14B82FB0E1D20B7B239FA4BB2C81809844808C3798AED4E3B9E6F4C991FFAED1238212F7BF1E9155CFDA819D62A554847BCCB8E8B1F1AEF6C64

Example Go Code

package main

import (
        "golang.org/x/crypto/ssh"
        "io/ioutil"
        "log"
)

func main() {

        key, err := ioutil.ReadFile("./example.pem")
        if err != nil {
                log.Fatal(err)
        }
        _, err = ssh.ParsePrivateKey(key)
        if err != nil {
                log.Fatal(err)
        }
}

Environment

  • Go 1.5.2 darwin/amd64
  • OpenSSL 0.9.8zg 14 July 2015
  • OS X 10.11 Beta (15A278b)

example.pem

-----BEGIN RSA PRIVATE KEY-----
MIIEqQIBAAKCAQEAo1C/iQtu7iSUJROyQgKm5VtJbaPg5GEP7IC+7TTZ2kVnWa9V
MU37sXKWk0J7oRHcSZ/dhRyNDcsvscFAU6V3FRpZxiTEvCqIBgLyoV3g+wkan+gD
AqNmqm77ldUIwMXT7n3AeWipw0uOBzZNjANhAf8qHIT2PXoT6LfaCof4PlPucCTx
eC+oT5zA/MbQoGneNkHnR26ijMac2vRC90+1WpZ5KwCVE6qd2kERlb9gbAGsNLE/
WrqR7bx4d8esLtE3l5zwkBTB63KdojMCrX/ZBiHT15TBQVsFPQqhdBT3BXfssnut
MkCf6+X0PIQkQcW6RqKR5nOHMFdB1kEChaKYMwIDAQABAoIBAQCRBPv/opJvjzWp
stLAgQBYe/Y5EKN7yKDOPwjLM/obMzPx1JqOvJO6X2lL/GYxgd2d1wJq2A586CdC
7brETBLxP0PmifHUsOO2itmO5wEHiW8F/Yzmw9g/kWuAAfrSyxhFF49Zf9H3ZFkL
GHJF2R5EGqP3TS4nKwcQyGkqntCV7p+QmPvlB05jT3vsc2jLn2yXXVEbu1X5Zj82
cdFwH4ZSc2BDv8ixBHy+zOGLx0TMF0hxEHdNIeAjGTyYfiyDr5mgMP4w6igGvP8q
pB5fE60ZKCEPLGyxMw69nDbXJK6YAKyNCVAD79FEl1yLYJlWfYAtOI6UeE0RUPeD
i42vINyBAoIAgQC9zZzl4kJUTdzYLYrxQ7f51B+eOF621kleTYLprr8I4VZUExht
KtsHdHWzMkxVtd7Q7UcG9L+Pqa3DVnD3S2C1IuUkO3eCpa93jhiwCIRYQfR7EzuR
ntVrQHfYaCgr8ahmWdoeZUr8lSDDp0/h+MamEksNEjZA+XwFWg6ycLgGwQKCAIEA
3EYz5iHqaOdekBYXcFpkq8uk+Sn27Cmnd7pLfK/YWEAb3Pie9X0pftA1O8z0tW9p
vEBS+pA27S55a38avmZSkZAiXMJOZ3HV99VZi5WU0Pg9A9oIiQvW6td9b1uuVl5q
o9fCK/r17E7NCFimtqSNtrNR/X08g+l4Dp1Ourgm7/MCggCAIGMohbWhGd+bcqv6
zIaAqzm+F3KI/uv74wKY9yUhZfOFlp0XivFIJLKDrwtDKVD6b249s3sqAOq0QuPK
LPiIzP/iV9dp4jpBgcYWgltBsgm3HRVAEe4nfsCmcp/7UtxOnwBwDsW8EPOlfp1b
LTUVOJtggR99cILh3cvrPBmt3UECggCBALsRH7g8a1+lxmglashu6/n+G1/DZMER
avjCDKOajuf7oe4acpzXK6tX1S2xFM0VDj3iftXuLcdl5ZYGPsceDNc0CgqutXki
cu1jkgV6BgUmHGMuAnuow19znEI7ISaWTohQjsVc/wctsPB6oTKRMwzK40Gc3wzD
9MKsk5T9GYxDAoIAgAFW9agGS4th1RrVwngjKHCPenQR1QSvHDHv3E3EQta1d0K3
Cx7RCdBpDNeNIpHVq8uTaWjSZ+Em6YDja7CqIfPj0HcykizxS4L7Dh0gt7I5+kuy
yBgJhEgIw3mK7U47nm9MmR/67RI4IS978ekVXP2oGdYqVUhHvMuOix8a72xk
-----END RSA PRIVATE KEY-----
@musgravejw
Copy link

@rickard-von-essen the failure in your example seems to be related to the private key. Also seeing a difference in the output of what openssl parses and the example. This would indicate a discrepancy in the encoding of the private key.

$ openssl rsa -in example.pem -check
RSA key ok
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
[abbrev]
pB5fE60ZKCEPLGyxMw69nDbXJK6YAKyNCVAD79FEl1yLYJlWfYAtOI6UeE0RUPeD
i42vINyBAoGBAL3NnOXiQlRN3NgtivFDt/nUH544XrbWSV5NgumuvwjhVlQTGG0q
2wd0dbMyTFW13tDtRwb0v4+prcNWcPdLYLUi5SQ7d4Klr3eOGLAIhFhB9HsTO5Ge
1WtAd9hoKCvxqGZZ2h5lSvyVIMOnT+H4xqYSSw0SNkD5fAVaDrJwuAbBAoGBANxG
M+Yh6mjnXpAWF3BaZKvLpPkp9uwpp3e6S3yv2FhAG9z4nvV9KX7QNTvM9LVvabxA
UvqQNu0ueWt/Gr5mUpGQIlzCTmdx1ffVWYuVlND4PQPaCIkL1urXfW9brlZeaqPX
wiv69exOzQhYprakjbazUf19PIPpeA6dTrq4Ju/zAoGAIGMohbWhGd+bcqv6zIaA
qzm+F3KI/uv74wKY9yUhZfOFlp0XivFIJLKDrwtDKVD6b249s3sqAOq0QuPKLPiI
zP/iV9dp4jpBgcYWgltBsgm3HRVAEe4nfsCmcp/7UtxOnwBwDsW8EPOlfp1bLTUV
OJtggR99cILh3cvrPBmt3UECgYEAuxEfuDxrX6XGaCVqyG7r+f4bX8NkwRFq+MIM
o5qO5/uh7hpynNcrq1fVLbEUzRUOPeJ+1e4tx2XllgY+xx4M1zQKCq61eSJy7WOS
BXoGBSYcYy4Ce6jDX3OcQjshJpZOiFCOxVz/By2w8HqhMpEzDMrjQZzfDMP0wqyT
lP0ZjEMCgYABVvWoBkuLYdUa1cJ4Iyhwj3p0EdUErxwx79xNxELWtXdCtwse0QnQ
aQzXjSKR1avLk2lo0mfhJumA42uwqiHz49B3MpIs8UuC+w4dILeyOfpLssgYCYRI
CMN5iu1OO55vTJkf+u0SOCEve/HpFVz9qBnWKlVIR7zLjosfGu9sZA==
-----END RSA PRIVATE KEY-----
$ cat example.pem 
-----BEGIN RSA PRIVATE KEY-----
[abbrev]
pB5fE60ZKCEPLGyxMw69nDbXJK6YAKyNCVAD79FEl1yLYJlWfYAtOI6UeE0RUPeD
i42vINyBAoIAgQC9zZzl4kJUTdzYLYrxQ7f51B+eOF621kleTYLprr8I4VZUExht
KtsHdHWzMkxVtd7Q7UcG9L+Pqa3DVnD3S2C1IuUkO3eCpa93jhiwCIRYQfR7EzuR
ntVrQHfYaCgr8ahmWdoeZUr8lSDDp0/h+MamEksNEjZA+XwFWg6ycLgGwQKCAIEA
3EYz5iHqaOdekBYXcFpkq8uk+Sn27Cmnd7pLfK/YWEAb3Pie9X0pftA1O8z0tW9p
vEBS+pA27S55a38avmZSkZAiXMJOZ3HV99VZi5WU0Pg9A9oIiQvW6td9b1uuVl5q
o9fCK/r17E7NCFimtqSNtrNR/X08g+l4Dp1Ourgm7/MCggCAIGMohbWhGd+bcqv6
zIaAqzm+F3KI/uv74wKY9yUhZfOFlp0XivFIJLKDrwtDKVD6b249s3sqAOq0QuPK
LPiIzP/iV9dp4jpBgcYWgltBsgm3HRVAEe4nfsCmcp/7UtxOnwBwDsW8EPOlfp1b
LTUVOJtggR99cILh3cvrPBmt3UECggCBALsRH7g8a1+lxmglashu6/n+G1/DZMER
avjCDKOajuf7oe4acpzXK6tX1S2xFM0VDj3iftXuLcdl5ZYGPsceDNc0CgqutXki
cu1jkgV6BgUmHGMuAnuow19znEI7ISaWTohQjsVc/wctsPB6oTKRMwzK40Gc3wzD
9MKsk5T9GYxDAoIAgAFW9agGS4th1RrVwngjKHCPenQR1QSvHDHv3E3EQta1d0K3
Cx7RCdBpDNeNIpHVq8uTaWjSZ+Em6YDja7CqIfPj0HcykizxS4L7Dh0gt7I5+kuy
yBgJhEgIw3mK7U47nm9MmR/67RI4IS978ekVXP2oGdYqVUhHvMuOix8a72xk
-----END RSA PRIVATE KEY-----

@rickard-von-essen
Copy link
Author

@musgravejw Sorry I should have add that detail, I knew that.

The point of the bug report is that applying Postel's law and seeing OpenSSL as a reference implementation I think also ssh.ParsePrivateKey() should handle this key.

@coreywright
Copy link

To be very precise, the "issue" is that Go, by way of its asn1 package, only supports the stricter/subset "DER"/"Distinguished Encoding Rules" and not the superset "BER"/"Basic Encoding Rules", impeding interoperability as both are valid asn1 encodings.

Quoted from the latest version of the asn1 package (see

// Package asn1 implements parsing of DER-encoded ASN.1 data structures,
// as defined in ITU-T Rec X.690.
):

// Package asn1 implements parsing of DER-encoded ASN.1 data structures,
// as defined in ITU-T Rec X.690.

I have tried to address this on the Paramiko side (see paramiko/paramiko#572), but was led to believe the problem would be shortly addressed in a different manner, which I will re-engage based on this new/renewed interest. Regardless of Paramiko, it would improve Go's general crypto interoperability to support BER (ie Postel's Law).

@minux
Copy link
Member

minux commented Feb 4, 2016 via email

@rickard-von-essen rickard-von-essen changed the title x/crypto/ssh: ParsePrivateKey fails to parse valid key x/crypto/ssh: ParsePrivateKey fails to parse BER encoded key Feb 8, 2016
@agl
Copy link
Contributor

agl commented Mar 10, 2016

We don't wish to support BER I'm afraid.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants