What version of Go are you using (go version)?
$ go version
go version go1.15.2 darwin/amd64
Does this issue reproduce with the latest release?
YES
What operating system and processor architecture are you using (go env)?
go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/harikrishnanbalagopal/Library/Caches/go-build"
GOENV="/Users/harikrishnanbalagopal/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/harikrishnanbalagopal/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/harikrishnanbalagopal/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.15.2/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.15.2/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/harikrishnanbalagopal/go/src/github.com/konveyor/testkey/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/09/5yjxv27n6njfskvvmkv9v8m40000gn/T/go-build525969776=/tmp/go-build -gno-record-gcc-switches -fno-common"
GOROOT/bin/go version: go version go1.15.2 darwin/amd64
GOROOT/bin/go tool compile -V: compile version go1.15.2
uname -v: Darwin Kernel Version 19.6.0: Thu Jun 18 20:49:00 PDT 2020; root:xnu-6153.141.1~1/RELEASE_X86_64
ProductName: Mac OS X
ProductVersion: 10.15.6
BuildVersion: 19G2021
lldb --version: lldb-1103.0.22.10
Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
What did you do?
Example with the command to use to generate the keys and the keys themselves:
https://play.golang.org/p/F2nUIO_S6hT
Called x509.IsEncryptedPEMBlock on pem.Blocks created using pem.Decode.
pem.Decode is called on valid encrypted RSA private keys generated using the following commands:
ssh-keygen -m PEM -t rsa -b 4096 -C 'foobar@example.com'
ssh-keygen -m PKCS8 -t rsa -b 4096 -C 'foobar@example.com'
ssh-keygen -m RFC4716 -t rsa -b 4096 -C 'foobar@example.com'
Also called ssh.ParseRawPrivateKeyWithPassphrase on each of those keys.
What did you expect to see?
The x509.IsEncryptedPEMBlock function should report true in all the cases given in the example.
The ssh.ParseRawPrivateKeyWithPassphrase should succeed on the PKCS8 key instead of failing as it does in the example.
Note that ssh-keygen -yf mykey is able to detect that the file is a valid encrypted key and decrypt it given the correct password in all the 3 cases. So IsEncryptedPEMBlock and ParseRawPrivateKeyWithPassphrase should be able to handle them as well.
What did you see instead?
x509.IsEncryptedPEMBlock incorrectly returns false when given the pem.Blocks of the PKCS8 and RFC4716 keys.
ssh-keygen lets you specify the format for the key file using the -m flag:
https://www.man7.org/linux/man-pages/man1/ssh-keygen.1.html
There are 3 supported formats: PEM, PKCS8 and RFC4716. x509.IsEncryptedPEMBlock only reports correctly on keys generated using PEM. This is because keys generated using PKCS8 and RFC4716 no longer have headers that indicate that the data is encrypted and the decryption algorithm to use. x509.IsEncryptedPEMBlock checks for those headers in order to determine whether the data is encrypted:
|
func IsEncryptedPEMBlock(b *pem.Block) bool { |
|
_, ok := b.Headers["DEK-Info"] |
|
return ok |
|
} |
Interestingly the ssh.ParseRawPrivateKeyWithPassphrase function fails on PKCS8 but is able to handle RFC4716 because of this special case: https://github.com/golang/crypto/blob/master/ssh/keys.go#L1156-L1158
I have tried the example with go version go1.15.2 darwin/amd64 and the latest golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee on my Macbook Pro macOS Catalina 10.15.6
What version of Go are you using (
go version)?Does this issue reproduce with the latest release?
YES
What operating system and processor architecture are you using (
go env)?go envOutputWhat did you do?
Example with the command to use to generate the keys and the keys themselves:
https://play.golang.org/p/F2nUIO_S6hT
Called
x509.IsEncryptedPEMBlockonpem.Blocks created usingpem.Decode.pem.Decodeis called on valid encrypted RSA private keys generated using the following commands:ssh-keygen -m PEM -t rsa -b 4096 -C 'foobar@example.com'ssh-keygen -m PKCS8 -t rsa -b 4096 -C 'foobar@example.com'ssh-keygen -m RFC4716 -t rsa -b 4096 -C 'foobar@example.com'Also called
ssh.ParseRawPrivateKeyWithPassphraseon each of those keys.What did you expect to see?
The
x509.IsEncryptedPEMBlockfunction should report true in all the cases given in the example.The
ssh.ParseRawPrivateKeyWithPassphraseshould succeed on thePKCS8key instead of failing as it does in the example.Note that
ssh-keygen -yf mykeyis able to detect that the file is a valid encrypted key and decrypt it given the correct password in all the 3 cases. SoIsEncryptedPEMBlockandParseRawPrivateKeyWithPassphraseshould be able to handle them as well.What did you see instead?
x509.IsEncryptedPEMBlockincorrectly returns false when given thepem.Blocks of thePKCS8andRFC4716keys.ssh-keygenlets you specify the format for the key file using the-mflag:https://www.man7.org/linux/man-pages/man1/ssh-keygen.1.html
There are 3 supported formats:
PEM,PKCS8andRFC4716.x509.IsEncryptedPEMBlockonly reports correctly on keys generated usingPEM. This is because keys generated usingPKCS8andRFC4716no longer have headers that indicate that the data is encrypted and the decryption algorithm to use.x509.IsEncryptedPEMBlockchecks for those headers in order to determine whether the data is encrypted:go/src/crypto/x509/pem_decrypt.go
Lines 99 to 102 in 5b509d9
Interestingly the
ssh.ParseRawPrivateKeyWithPassphrasefunction fails onPKCS8but is able to handleRFC4716because of this special case: https://github.com/golang/crypto/blob/master/ssh/keys.go#L1156-L1158I have tried the example with
go version go1.15.2 darwin/amd64and the latestgolang.org/x/crypto v0.0.0-20201012173705-84dcc777aaeeon my Macbook PromacOS Catalina 10.15.6