github.com/grailbio/base@v0.0.11/security/ssh/certificateauthority/ssh_test.go (about)

     1  // Copyright 2018 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache-2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  package certificateauthority
     6  
     7  import (
     8  	"io/ioutil"
     9  	"testing"
    10  
    11  	"bytes"
    12  	"os/exec"
    13  	"time"
    14  
    15  	"github.com/grailbio/base/security/keycrypt"
    16  	"github.com/grailbio/testutil/assert"
    17  )
    18  
    19  //ssh-keygen -s testdata/ssh_key.pem -I CA -O clear  testdata/ssh_key.pem.pub
    20  func TestAuthority(t *testing.T) {
    21  	sshPEM, err := ioutil.ReadFile("testdata/ssh_key.pem")
    22  	assert.NoError(t, err)
    23  	sshCERT, err := ioutil.ReadFile("testdata/ssh_key.pem-cert.pub")
    24  	assert.NoError(t, err)
    25  	userPubKey, err := ioutil.ReadFile("testdata/user_ssh_key.pem.pub")
    26  	assert.NoError(t, err)
    27  
    28  	ca := CertificateAuthority{PrivateKey: keycrypt.Static(sshPEM), Certificate: string(sshCERT)}
    29  	err = ca.Init()
    30  	assert.NoError(t, err)
    31  
    32  	cr := CertificateRequest{
    33  		// SSH Public Key that is being signed
    34  		SshPublicKey: []byte(userPubKey),
    35  
    36  		// List of host names, or usernames that will be added to the cert
    37  		Principals: []string{"ubuntu"},
    38  		Ttl:        time.Duration(3600) * time.Second,
    39  		KeyID:      "foo",
    40  
    41  		CertType: "user",
    42  
    43  		CriticalOptions: nil,
    44  
    45  		// Extensions to assign to the ssh Certificate
    46  		// The default allow basic function - permit-pty is usually required
    47  		Extensions: []string{
    48  			"permit-X11-forwarding",
    49  			"permit-agent-forwarding",
    50  			"permit-port-forwarding",
    51  			"permit-pty",
    52  			"permit-user-rc",
    53  		},
    54  	}
    55  	execTime := time.Date(2020, time.January, 19, 0, 0, 0, 0, time.UTC)
    56  	sshCert, err := ca.issueWithKeyUsage(execTime, cr)
    57  	assert.NoError(t, err)
    58  
    59  	// Check the golang created certificate against the one created with
    60  	// ssh-keygen -t rsa-sha2-256 -s testdata/ssh_key.pem -I foo -V 20200118160000:20200118170000  -n ubuntu testdata/user_ssh_key.pem
    61  	preCreatedUserCert, err := ioutil.ReadFile("testdata/user_ssh_key.pem-cert.pub")
    62  	assert.NoError(t, err)
    63  
    64  	cmd := exec.Command("ssh-keygen", "-L", "-f", "-")
    65  	cmd.Stdin = bytes.NewBuffer([]byte(preCreatedUserCert))
    66  	preCreatedOutput, err := cmd.Output()
    67  	assert.NoError(t, err)
    68  
    69  	cmd = exec.Command("ssh-keygen", "-L", "-f", "-")
    70  	cmd.Stdin = bytes.NewBuffer([]byte(sshCert))
    71  	output, err := cmd.Output()
    72  	assert.NoError(t, err)
    73  
    74  	if string(preCreatedOutput) != string(output) {
    75  		t.Errorf("IssueWithKeyUsage: got %q, want %q", output, preCreatedOutput)
    76  	}
    77  }
    78  
    79  func TestValidateCertType(t *testing.T) {
    80  	cases := []struct {
    81  		input     string
    82  		expected  uint32
    83  		expectErr bool
    84  	}{
    85  		{"user", 1, false},
    86  		{"host", 2, false},
    87  		{"FOO", 0, true},
    88  	}
    89  	for _, c := range cases {
    90  		got, err := validateCertType(c.input)
    91  		if got != c.expected {
    92  			t.Errorf("TestValidateCertType(%q): got %q, want %q", c.input, got, c.expected)
    93  		}
    94  		errCheck := (err != nil)
    95  		if errCheck != c.expectErr {
    96  			t.Errorf("TestValidateCertType(%q): got err %q, want %t", c.input, err, c.expectErr)
    97  		}
    98  	}
    99  }