github.com/glycerine/xcryptossh@v7.0.4+incompatible/test/cert_test.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build darwin dragonfly freebsd linux netbsd openbsd
     6  
     7  package test
     8  
     9  import (
    10  	"bytes"
    11  	"context"
    12  	"crypto/rand"
    13  	"testing"
    14  
    15  	"github.com/glycerine/xcryptossh"
    16  )
    17  
    18  // Test both logging in with a cert, and also that the certificate presented by an OpenSSH host can be validated correctly
    19  func TestCertLogin(t *testing.T) {
    20  	ctx, cancelctx := context.WithCancel(context.Background())
    21  	defer cancelctx()
    22  
    23  	halt := ssh.NewHalter()
    24  	defer halt.ReqStop.Close()
    25  
    26  	s := newServer(t)
    27  	defer s.Shutdown()
    28  
    29  	// Use a key different from the default.
    30  	clientKey := testSigners["dsa"]
    31  	caAuthKey := testSigners["ecdsa"]
    32  	cert := &ssh.Certificate{
    33  		Key:             clientKey.PublicKey(),
    34  		ValidPrincipals: []string{username()},
    35  		CertType:        ssh.UserCert,
    36  		ValidBefore:     ssh.CertTimeInfinity,
    37  	}
    38  	if err := cert.SignCert(rand.Reader, caAuthKey); err != nil {
    39  		t.Fatalf("SetSignature: %v", err)
    40  	}
    41  
    42  	certSigner, err := ssh.NewCertSigner(cert, clientKey)
    43  	if err != nil {
    44  		t.Fatalf("NewCertSigner: %v", err)
    45  	}
    46  
    47  	conf := &ssh.ClientConfig{
    48  		User: username(),
    49  		HostKeyCallback: (&ssh.CertChecker{
    50  			IsHostAuthority: func(pk ssh.PublicKey, addr string) bool {
    51  				return bytes.Equal(pk.Marshal(), testPublicKeys["ca"].Marshal())
    52  			},
    53  		}).CheckHostKey,
    54  		Config: ssh.Config{Halt: halt},
    55  	}
    56  	conf.Auth = append(conf.Auth, ssh.PublicKeys(certSigner))
    57  
    58  	for _, test := range []struct {
    59  		addr    string
    60  		succeed bool
    61  	}{
    62  		{addr: "host.example.com:22", succeed: true},
    63  		{addr: "host.example.com:10000", succeed: true}, // non-standard port must be OK
    64  		{addr: "host.example.com", succeed: false},      // port must be specified
    65  		{addr: "host.ex4mple.com:22", succeed: false},   // wrong host
    66  	} {
    67  		client, err := s.TryDialWithAddr(ctx, conf, test.addr)
    68  
    69  		// Always close client if opened successfully
    70  		if err == nil {
    71  			client.Close()
    72  		}
    73  
    74  		// Now evaluate whether the test failed or passed
    75  		if test.succeed {
    76  			if err != nil {
    77  				t.Fatalf("TryDialWithAddr: %v", err)
    78  			}
    79  		} else {
    80  			if err == nil {
    81  				t.Fatalf("TryDialWithAddr, unexpected success")
    82  			}
    83  		}
    84  	}
    85  }