func checkKey(jobs <-chan string, wg *sync.WaitGroup, block *pem.Block) { // https://github.com/golang/go/issues/10171 // golang's fix? expand the documentation ... defer wg.Done() for passwordStr := range jobs { password := []byte(passwordStr) key, err := x509.DecryptPEMBlock(block, password) if err == nil { // we now have a candidate, is it random noise or is can be parsed? // for some reason ParseRawPrivateKey fails so its brute force time // https://github.com/golang/go/issues/8581 - ed25519 are not currently supported by Golang _, err := ssh.ParseDSAPrivateKey(key) if err == nil { printNDie(password) } // not DSA? maybe RSA _, err = x509.ParsePKCS1PrivateKey(key) if err == nil { printNDie(password) } // ECDSA? _, err = x509.ParseECPrivateKey(key) if err == nil { printNDie(password) } } } }
// ref golang.org/x/crypto/ssh/keys.go#ParseRawPrivateKey. func parsePemBlock(block *pem.Block) (interface{}, error) { switch block.Type { case "RSA PRIVATE KEY": return x509.ParsePKCS1PrivateKey(block.Bytes) case "EC PRIVATE KEY": return x509.ParseECPrivateKey(block.Bytes) case "DSA PRIVATE KEY": return ssh.ParseDSAPrivateKey(block.Bytes) default: return nil, fmt.Errorf("rtop: unsupported key type %q", block.Type) } }
func signerFromBlock(block *pem.Block) (ssh.Signer, error) { var key interface{} var err error switch block.Type { case "RSA PRIVATE KEY": key, err = x509.ParsePKCS1PrivateKey(block.Bytes) case "EC PRIVATE KEY": key, err = x509.ParseECPrivateKey(block.Bytes) case "DSA PRIVATE KEY": key, err = ssh.ParseDSAPrivateKey(block.Bytes) default: return nil, fmt.Errorf("unsupported key type %q", block.Type) } if err != nil { return nil, err } signer, err := ssh.NewSignerFromKey(key) if err != nil { return nil, err } return signer, nil }
func addKey(conf *ssh.ServerConfig, block *pem.Block) (err error) { var key interface{} switch block.Type { case "RSA PRIVATE KEY": key, err = x509.ParsePKCS1PrivateKey(block.Bytes) case "EC PRIVATE KEY": key, err = x509.ParseECPrivateKey(block.Bytes) case "DSA PRIVATE KEY": key, err = ssh.ParseDSAPrivateKey(block.Bytes) default: return fmt.Errorf("unsupported key type %q", block.Type) } if err != nil { return err } signer, err := ssh.NewSignerFromKey(key) if err != nil { return err } conf.AddHostKey(signer) return nil }