...

Source file src/github.com/sigstore/rekor/pkg/pki/ssh/ssh_test.go

Documentation: github.com/sigstore/rekor/pkg/pki/ssh

     1  // Copyright 2022 The Sigstore Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package ssh
    16  
    17  import (
    18  	"encoding/base64"
    19  	"math/rand"
    20  	"reflect"
    21  	"strings"
    22  	"testing"
    23  
    24  	"github.com/sigstore/sigstore/pkg/cryptoutils"
    25  	"golang.org/x/crypto/ssh"
    26  )
    27  
    28  func TestIdentities(t *testing.T) {
    29  	// from ssh_e2e_test.go
    30  	publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDXofkiahE7uavjWvxnwkUF27qMgz7pdTwzSv0XzVG6EtirOv3PDWct4YKoXE9c0EqbxnIfYEKwEextdvB7zkgwczdJSHxf/18jQumLn/FuoCmugVSk1H5Qli/qzwBpaTnOk3WuakGuoYUl8ZAokKKgOKLA0aZJ1WRQ2ZCZggA3EkwNZiY17y9Q6HqdgQcH6XN8aAMADNVJdMAJb33hSRJjjsAPTmzBTishP8lYDoGRSsSE7/8XRBCEV5E4I8mI9GElcZwV/1KJx98mpH8QvMzXM1idFcwPRtt1NTAOshwgUU0Fu1x8lU5RQIa6ZKW36qNQLvLxy/BscC7B/mdLptoDs/ot9NimUXZcgCR1a2Q3o7Wi6jIgcgJcyV10Nba81ol4RdN4qPHnVZIzuo+dBkqwG3CMtB4Rj84+Qi+7zyU01hIPreoxQDXaayiGPBUUIiAlW9gsiuRWJzNnu3cvuWDLVfQIkjh7Wug58z+v2NOJ7IMdyERillhzDcvVHaq14+U= test@rekor.dev"
    31  	expectedKey, _, _, _, _ := ssh.ParseAuthorizedKey([]byte(publicKey))
    32  
    33  	pub, err := NewPublicKey(strings.NewReader(publicKey))
    34  	if err != nil {
    35  		t.Fatal(err)
    36  	}
    37  
    38  	if !reflect.DeepEqual(pub.EmailAddresses(), []string{"test@rekor.dev"}) {
    39  		t.Fatalf("expected email address, got %v", pub.EmailAddresses())
    40  	}
    41  	if !reflect.DeepEqual(pub.Subjects(), []string{"test@rekor.dev"}) {
    42  		t.Fatalf("expected email address as subject, got %v", pub.Subjects())
    43  	}
    44  
    45  	keyVal := expectedKey.(ssh.CryptoPublicKey).CryptoPublicKey()
    46  	pkixKey, err := cryptoutils.MarshalPublicKeyToDER(keyVal)
    47  	if err != nil {
    48  		t.Fatal(err)
    49  	}
    50  	ids, err := pub.Identities()
    51  	if err != nil {
    52  		t.Fatal(err)
    53  	}
    54  	if len(ids) != 1 {
    55  		t.Errorf("too many identities, expected 1, got %v", len(ids))
    56  	}
    57  	if !reflect.DeepEqual(ids[0].Crypto.(ssh.PublicKey).Marshal(), expectedKey.Marshal()) {
    58  		t.Errorf("certificates did not match")
    59  	}
    60  	if !reflect.DeepEqual(ids[0].Raw, pkixKey) {
    61  		t.Errorf("raw identities did not match, expected %v, got %v", string(pkixKey), string(ids[0].Raw))
    62  	}
    63  	// removing "SHA256:" prefix
    64  	fp, _ := base64.RawStdEncoding.DecodeString(ids[0].Fingerprint[7:])
    65  	if len(fp) != 32 {
    66  		t.Errorf("fingerprint is not expected length of 32 (32-byte sha256): %d", len(fp))
    67  	}
    68  }
    69  
    70  func TestIdentitiesParsesAllKeyTypes(t *testing.T) {
    71  	for _, k := range []string{
    72  		// DSA is not supported
    73  		"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDXofkiahE7uavjWvxnwkUF27qMgz7pdTwzSv0XzVG6EtirOv3PDWct4YKoXE9c0EqbxnIfYEKwEextdvB7zkgwczdJSHxf/18jQumLn/FuoCmugVSk1H5Qli/qzwBpaTnOk3WuakGuoYUl8ZAokKKgOKLA0aZJ1WRQ2ZCZggA3EkwNZiY17y9Q6HqdgQcH6XN8aAMADNVJdMAJb33hSRJjjsAPTmzBTishP8lYDoGRSsSE7/8XRBCEV5E4I8mI9GElcZwV/1KJx98mpH8QvMzXM1idFcwPRtt1NTAOshwgUU0Fu1x8lU5RQIa6ZKW36qNQLvLxy/BscC7B/mdLptoDs/ot9NimUXZcgCR1a2Q3o7Wi6jIgcgJcyV10Nba81ol4RdN4qPHnVZIzuo+dBkqwG3CMtB4Rj84+Qi+7zyU01hIPreoxQDXaayiGPBUUIiAlW9gsiuRWJzNnu3cvuWDLVfQIkjh7Wug58z+v2NOJ7IMdyERillhzDcvVHaq14+U= test@rekor.dev",
    74  		"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNLCu01+wpXe3xB5olXCN4SqU2rQu0qjSRKJO4Bg+JRCPU+ENcgdA5srTU8xYDz/GEa4dzK5ldPw4J/gZgSXCMs=",
    75  		"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBLSsu/HNKiaALhQ26UDv+N0AFdMb26fMVrOKe866CGu6ajSf9HUOhJFdjhseihB2rTalMPr8MrcXNLufii4mL8u4l9fUQXFgwnM/ZpiVPSs6C+8i4u/ZDg7Nx2NXybNIgQ==",
    76  		"ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACB4WgRgGBRo6Uk+cRgg8tJPCbEtGURRWlUA7PDDerXR+P9O6mm3L99Etxsyh5XNYqXyaMNtH5c51ooMajrFwcayAHIhPPb8X3CsTwEfIUQ96aDyHQMotbRfnkn6uefeUTRrSNcqeAndUtVyAqBdqbsq2mgJYXHrz2NUKlPFYgauQi+WQ==",
    77  		"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIXffBYeYL+WVzVru8npl5JHt2cjlr4ornFTWzoij9sx",
    78  		"sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGRNqlFgED/pf4zXz8IzqA6CALNwYcwgd4MQDmIS1GOtn1SySFObiuyJaOlpqkV5FeEifhxfIC2ejKKtNyO4CysAAAAEc3NoOg== user@host",
    79  		"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIJjzc2a20RjCvN/0ibH6UpGuN9F9hDvD7x182bOesNhHAAAABHNzaDo= user@host",
    80  		"ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgb1srW/W3ZDjYAO45xLYAwzHBDLsJ4Ux6ICFIkTjb1LEAAAADAQABAAAAYQCkoR51poH0wE8w72cqSB8Sszx+vAhzcMdCO0wqHTj7UNENHWEXGrU0E0UQekD7U+yhkhtoyjbPOVIP7hNa6aRk/ezdh/iUnCIt4Jt1v3Z1h1P+hA4QuYFMHNB+rmjPwAcAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAHcAAAAHc3NoLXJzYQAAAAMBAAEAAABhANFS2kaktpSGc+CcmEKPyw9mJC4nZKxHKTgLVZeaGbFZOvJTNzBspQHdy7Q1uKSfktxpgjZnksiu/tFF9ngyY2KFoc+U88ya95IZUycBGCUbBQ8+bhDtw/icdDGQD5WnUwAAAG8AAAAHc3NoLXJzYQAAAGC8Y9Z2LQKhIhxf52773XaWrXdxP0t3GBVo4A10vUWiYoAGepr6rQIoGGXFxT4B9Gp+nEBJjOwKDXPrAevow0T9ca8gZN+0ykbhSrXLE5Ao48rqr3zP4O1/9P7e6gp0gw8=",
    81  	} {
    82  		pub, err := NewPublicKey(strings.NewReader(k))
    83  		if err != nil {
    84  			t.Fatal(err)
    85  		}
    86  		ids, err := pub.Identities()
    87  		if err != nil {
    88  			t.Fatal(err)
    89  		}
    90  		if len(ids) == 0 {
    91  			t.Fatal("expected identities to be found")
    92  		}
    93  	}
    94  }
    95  
    96  func randomSuffix(n int) string {
    97  	const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    98  
    99  	b := make([]byte, n)
   100  	for i := range b {
   101  		b[i] = letterBytes[rand.Intn(len(letterBytes))]
   102  	}
   103  	return string(b)
   104  }
   105  
   106  func TestPubKeyParsingLimit(t *testing.T) {
   107  	// limit on NewPublicKey should be 65536 bytes, so let's generate a short one first and then extend it to ensure it fails
   108  	publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDXofkiahE7uavjWvxnwkUF27qMgz7pdTwzSv0XzVG6EtirOv3PDWct4YKoXE9c0EqbxnIfYEKwEextdvB7zkgwczdJSHxf/18jQumLn/FuoCmugVSk1H5Qli/qzwBpaTnOk3WuakGuoYUl8ZAokKKgOKLA0aZJ1WRQ2ZCZggA3EkwNZiY17y9Q6HqdgQcH6XN8aAMADNVJdMAJb33hSRJjjsAPTmzBTishP8lYDoGRSsSE7/8XRBCEV5E4I8mI9GElcZwV/1KJx98mpH8QvMzXM1idFcwPRtt1NTAOshwgUU0Fu1x8lU5RQIa6ZKW36qNQLvLxy/BscC7B/mdLptoDs/ot9NimUXZcgCR1a2Q3o7Wi6jIgcgJcyV10Nba81ol4RdN4qPHnVZIzuo+dBkqwG3CMtB4Rj84+Qi+7zyU01hIPreoxQDXaayiGPBUUIiAlW9gsiuRWJzNnu3cvuWDLVfQIkjh7Wug58z+v2NOJ7IMdyERillhzDcvVHaq14+U= "
   109  	randomLongComment := randomSuffix(32768)
   110  
   111  	validKey := publicKey + randomLongComment
   112  
   113  	if _, err := NewPublicKey(strings.NewReader(validKey)); err != nil {
   114  		t.Errorf("unexpected error parsing valid-length key: %v", err)
   115  	}
   116  
   117  	// now we should be exceeding the length
   118  	validKey += randomLongComment
   119  
   120  	if _, err := NewPublicKey(strings.NewReader(validKey)); err == nil {
   121  		t.Errorf("expected an error parsing invalid-length key")
   122  	}
   123  }
   124  

View as plain text