From 7983aa866159235d7c6771972230179c94f794da Mon Sep 17 00:00:00 2001
From: Mariano Cano <mariano@smallstep.com>
Date: Wed, 31 Jul 2019 18:16:17 -0700
Subject: [PATCH] Add azure ssh tests.

---
 authority/provisioner/azure_test.go | 70 +++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/authority/provisioner/azure_test.go b/authority/provisioner/azure_test.go
index dc8e514c..f9594045 100644
--- a/authority/provisioner/azure_test.go
+++ b/authority/provisioner/azure_test.go
@@ -2,6 +2,7 @@ package provisioner
 
 import (
 	"context"
+	"crypto"
 	"crypto/sha256"
 	"crypto/x509"
 	"encoding/hex"
@@ -307,6 +308,75 @@ func TestAzure_AuthorizeSign(t *testing.T) {
 	}
 }
 
+func TestAzure_AuthorizeSign_SSH(t *testing.T) {
+	tm, fn := mockNow()
+	defer fn()
+
+	p1, srv, err := generateAzureWithServer()
+	assert.FatalError(t, err)
+	defer srv.Close()
+
+	t1, err := p1.GetIdentityToken("subject", "caURL")
+	assert.FatalError(t, err)
+
+	key, err := generateJSONWebKey()
+	assert.FatalError(t, err)
+
+	signer, err := generateJSONWebKey()
+	assert.FatalError(t, err)
+
+	hostDuration := p1.claimer.DefaultHostSSHCertDuration()
+	expectedHostOptions := &SSHOptions{
+		CertType: "host", Principals: []string{"virtualMachine"},
+		ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(hostDuration)),
+	}
+
+	type args struct {
+		token   string
+		sshOpts SSHOptions
+	}
+	tests := []struct {
+		name        string
+		azure       *Azure
+		args        args
+		expected    *SSHOptions
+		wantErr     bool
+		wantSignErr bool
+	}{
+		{"ok", p1, args{t1, SSHOptions{}}, expectedHostOptions, false, false},
+		{"ok-type", p1, args{t1, SSHOptions{CertType: "host"}}, expectedHostOptions, false, false},
+		{"ok-principals", p1, args{t1, SSHOptions{Principals: []string{"virtualMachine"}}}, expectedHostOptions, false, false},
+		{"ok-options", p1, args{t1, SSHOptions{CertType: "host", Principals: []string{"virtualMachine"}}}, expectedHostOptions, false, false},
+		{"fail-type", p1, args{t1, SSHOptions{CertType: "user"}}, nil, false, true},
+		{"fail-principal", p1, args{t1, SSHOptions{Principals: []string{"smallstep.com"}}}, nil, false, true},
+		{"fail-extra-principal", p1, args{t1, SSHOptions{Principals: []string{"virtualMachine", "smallstep.com"}}}, nil, false, true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ctx := NewContextWithMethod(context.Background(), SignSSHMethod)
+			got, err := tt.azure.AuthorizeSign(ctx, tt.args.token)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("Azure.AuthorizeSign() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if err != nil {
+				assert.Nil(t, got)
+			} else if assert.NotNil(t, got) {
+				cert, err := signSSHCertificate(key.Public().Key, tt.args.sshOpts, got, signer.Key.(crypto.Signer))
+				if (err != nil) != tt.wantSignErr {
+					t.Errorf("SignSSH error = %v, wantSignErr %v", err, tt.wantSignErr)
+				} else {
+					if tt.wantSignErr {
+						assert.Nil(t, cert)
+					} else {
+						assert.NoError(t, validateSSHCertificate(cert, tt.expected))
+					}
+				}
+			}
+		})
+	}
+}
+
 func TestAzure_AuthorizeRenewal(t *testing.T) {
 	p1, err := generateAzure()
 	assert.FatalError(t, err)