go.crypto/ssh: introduce Signer method, an abstraction of

private keys.

R=agl, jpsugar, jonathan.mark.pittman
CC=golang-dev
https://golang.org/cl/13338044
This commit is contained in:
Han-Wen Nienhuys
2013-09-19 14:45:31 -04:00
committed by Adam Langley
parent 28dc961a18
commit 934c14ffe9
9 changed files with 394 additions and 250 deletions
+3 -9
View File
@@ -1,8 +1,6 @@
package test
import (
"crypto/x509"
"encoding/pem"
"reflect"
"strings"
"testing"
@@ -171,16 +169,12 @@ func testAuthorizedKeys(t *testing.T, authKeys []byte, expected []authResult) {
}
func getTestPublicKey(t *testing.T) ssh.PublicKey {
block, _ := pem.Decode([]byte(testClientPrivateKey))
if block == nil {
t.Fatalf("pem.Decode: %v", testClientPrivateKey)
}
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
priv, err := ssh.ParsePrivateKey([]byte(testClientPrivateKey))
if err != nil {
t.Fatalf("x509.ParsePKCS1PrivateKey: %v", err)
t.Fatalf("ParsePrivateKey: %v", err)
}
return ssh.NewRSAPublicKey(&priv.PublicKey)
return priv.PublicKey()
}
func TestAuth(t *testing.T) {
+22 -47
View File
@@ -10,12 +10,7 @@ package test
import (
"bytes"
"crypto"
"crypto/dsa"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
@@ -53,25 +48,23 @@ HostbasedAuthentication no
`
var (
configTmpl template.Template
rsakey *rsa.PrivateKey
serializedHostKey []byte
configTmpl template.Template
privateKey ssh.Signer
hostKey ssh.Signer
)
func init() {
template.Must(configTmpl.Parse(sshd_config))
block, _ := pem.Decode([]byte(testClientPrivateKey))
rsakey, _ = x509.ParsePKCS1PrivateKey(block.Bytes)
block, _ = pem.Decode([]byte(keys["ssh_host_rsa_key"]))
if block == nil {
panic("pem.Decode ssh_host_rsa_key")
}
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
var err error
hostKey, err = ssh.ParsePrivateKey([]byte(keys["ssh_host_rsa_key"]))
if err != nil {
panic("ParsePKCS1PrivateKey: " + err.Error())
panic("ParsePrivateKey: " + err.Error())
}
privateKey, err = ssh.ParsePrivateKey([]byte(testClientPrivateKey))
if err != nil {
panic("ParsePrivateKey: " + err.Error())
}
serializedHostKey = ssh.MarshalPublicKey(ssh.NewRSAPublicKey(&priv.PublicKey))
}
type server struct {
@@ -106,26 +99,26 @@ type storedHostKey struct {
keys map[string][]byte
}
func (k *storedHostKey) Add(algo string, public []byte) {
func (k *storedHostKey) Add(key ssh.PublicKey) {
if k.keys == nil {
k.keys = map[string][]byte{}
}
k.keys[algo] = append([]byte(nil), public...)
k.keys[key.PublicKeyAlgo()] = append([]byte(nil), ssh.MarshalPublicKey(key)...)
}
func (k *storedHostKey) Check(addr string, remote net.Addr, algo string, key []byte) error {
if k.keys == nil || bytes.Compare(key, k.keys[algo]) != 0 {
return errors.New("host key mismatch")
return fmt.Errorf("host key mismatch. Got %q, want %q", key, k.keys[algo])
}
return nil
}
func clientConfig() *ssh.ClientConfig {
keyChecker := storedHostKey{}
keyChecker.Add("ssh-rsa", serializedHostKey)
keyChecker.Add(hostKey.PublicKey())
kc := new(keychain)
kc.keys = append(kc.keys, rsakey)
kc.keys = append(kc.keys, privateKey)
config := &ssh.ClientConfig{
User: username(),
Auth: []ssh.ClientAuth{
@@ -261,34 +254,20 @@ func newServer(t *testing.T) *server {
}
}
// keychain implements the ClientKeyring interface
// keychain implements the ClientKeyring interface.
type keychain struct {
keys []interface{}
keys []ssh.Signer
}
func (k *keychain) Key(i int) (ssh.PublicKey, error) {
if i < 0 || i >= len(k.keys) {
return nil, nil
}
switch key := k.keys[i].(type) {
case *rsa.PrivateKey:
return ssh.NewRSAPublicKey(&key.PublicKey), nil
case *dsa.PrivateKey:
return ssh.NewDSAPublicKey(&key.PublicKey), nil
}
panic("unknown key type")
return k.keys[i].PublicKey(), nil
}
func (k *keychain) Sign(i int, rand io.Reader, data []byte) (sig []byte, err error) {
hashFunc := crypto.SHA1
h := hashFunc.New()
h.Write(data)
digest := h.Sum(nil)
switch key := k.keys[i].(type) {
case *rsa.PrivateKey:
return rsa.SignPKCS1v15(rand, key, hashFunc, digest)
}
return nil, errors.New("ssh: unknown key type")
return k.keys[i].Sign(rand, data)
}
func (k *keychain) loadPEM(file string) error {
@@ -296,14 +275,10 @@ func (k *keychain) loadPEM(file string) error {
if err != nil {
return err
}
block, _ := pem.Decode(buf)
if block == nil {
return errors.New("ssh: no key found")
}
r, err := x509.ParsePKCS1PrivateKey(block.Bytes)
key, err := ssh.ParsePrivateKey(buf)
if err != nil {
return err
}
k.keys = append(k.keys, r)
k.keys = append(k.keys, key)
return nil
}