github.com/argoproj/argo-cd/v3@v3.2.1/util/cert/cert_test.go (about)

     1  package cert
     2  
     3  import (
     4  	"os"
     5  	"path"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/argoproj/argo-cd/v3/common"
    12  )
    13  
    14  const (
    15  	TestCert1CN            = "CN=foo.example.com,OU=SpecOps,O=Capone\\, Inc,L=Chicago,ST=IL,C=US"
    16  	TestCert2CN            = "CN=bar.example.com,OU=Testsuite,O=Testing Corp,L=Hanover,ST=Lower Saxony,C=DE"
    17  	TestTLSValidSingleCert = `
    18  -----BEGIN CERTIFICATE-----
    19  MIIFvTCCA6WgAwIBAgIUGrTmW3qc39zqnE08e3qNDhUkeWswDQYJKoZIhvcNAQEL
    20  BQAwbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv
    21  MRQwEgYDVQQKDAtDYXBvbmUsIEluYzEQMA4GA1UECwwHU3BlY09wczEYMBYGA1UE
    22  AwwPZm9vLmV4YW1wbGUuY29tMB4XDTE5MDcwODEzNTUwNVoXDTIwMDcwNzEzNTUw
    23  NVowbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv
    24  MRQwEgYDVQQKDAtDYXBvbmUsIEluYzEQMA4GA1UECwwHU3BlY09wczEYMBYGA1UE
    25  AwwPZm9vLmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
    26  AgEA3csSO13w7qQXKeSLNcpeuAe6wAjXYbRkRl6ariqzTEDcFTKmy2QiXJTKoEGn
    27  bvwxq0T91var7rxY88SGL/qi8Zmo0tVSR0XvKSKcghFIkQOTyDmVgMPZGCvixt4q
    28  gQ7hUVSk4KkFmtcqBVuvnzI1d/DKfZAGKdmGcfRpuAsnVhac3swP0w4Tl1BFrK9U
    29  vuIkz4KwXG77s5oB8rMUnyuLasLsGNpvpvXhkcQRhp6vpcCO2bS7kOTTelAPIucw
    30  P37qkOEdZdiWCLrr57dmhg6tmcVlmBMg6JtmfLxn2HQd9ZrCKlkWxMk5NYs6CAW5
    31  kgbDZUWQTAsnHeoJKbcgtPkIbxDRxNpPukFMtbA4VEWv1EkODXy9FyEKDOI/PV6K
    32  /80oLkgCIhCkP2mvwSFheU0RHTuZ0o0vVolP5TEOq5iufnDN4wrxqb12o//XLRc0
    33  RiLqGVVxhFdyKCjVxcLfII9AAp5Tse4PMh6bf6jDfB3OMvGkhMbJWhKXdR2NUTl0
    34  esKawMPRXIn5g3oBdNm8kyRsTTnvB567pU8uNSmA8j3jxfGCPynI8JdiwKQuW/+P
    35  WgLIflgxqAfG85dVVOsFmF9o5o24dDslvv9yHnHH102c6ijPCg1EobqlyFzqqxOD
    36  Wf2OPjIkzoTH+O27VRugnY/maIU1nshNO7ViRX5zIxEUtNMCAwEAAaNTMFEwHQYD
    37  VR0OBBYEFNY4gDLgPBidogkmpO8nq5yAq5g+MB8GA1UdIwQYMBaAFNY4gDLgPBid
    38  ogkmpO8nq5yAq5g+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB
    39  AJ0WGioNtGNg3m6ywpmxNThorQD5ZvDMlmZlDVk78E2wfNyMhwbVhKhlAnONv0wv
    40  kmsGjibY75nRZ+EK9PxSJ644841fryQXQ+bli5fhr7DW3uTKwaRsnzETJXRJuljq
    41  6+c6Zyg1/mqwnyx7YvPgVh3w496DYx/jm6Fm1IEq3BzOmn6H/gGPq3gbURzEqI3h
    42  P+kC2vJa8RZWrpa05Xk/Q1QUkErDX9vJghb9z3+GgirISZQzqWRghII/znv3NOE6
    43  zoIgaaWNFn8KPeBVpUoboH+IhpgibsnbTbI0G7AMtFq6qm3kn/4DZ2N2tuh1G2tT
    44  zR2Fh7hJbU7CrqxANrgnIoHG/nLSvzE24ckLb0Vj69uGQlwnZkn9fz6F7KytU+Az
    45  NoB2rjufaB0GQi1azdboMvdGSOxhSCAR8otWT5yDrywCqVnEvjw0oxKmuRduNe2/
    46  6AcG6TtK2/K+LHuhymiAwZM2qE6VD2odvb+tCzDkZOIeoIz/JcVlNpXE9FuVl250
    47  9NWvugeghq7tUv81iJ8ninBefJ4lUfxAehTPQqX+zXcfxgjvMRCi/ig73nLyhmjx
    48  r2AaraPFgrprnxUibP4L7jxdr+iiw5bWN9/B81PodrS7n5TNtnfnpZD6X6rThqOP
    49  xO7Tr5lAo74vNUkF2EHNaI28/RGnJPm2TIxZqy4rNH6L
    50  -----END CERTIFICATE-----
    51  `
    52  )
    53  
    54  const TestTLSInvalidPEMData = `
    55  MIIF1zCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL
    56  BQAwezELMAkGA1UEBhMCREUxFTATBgNVBAgMDExvd2VyIFNheG9ueTEQMA4GA1UE
    57  BwwHSGFub3ZlcjEVMBMGA1UECgwMVGVzdGluZyBDb3JwMRIwEAYDVQQLDAlUZXN0
    58  c3VpdGUxGDAWBgNVBAMMD2Jhci5leGFtcGxlLmNvbTAeFw0xOTA3MDgxMzU2MTda
    59  Fw0yMDA3MDcxMzU2MTdaMHsxCzAJBgNVBAYTAkRFMRUwEwYDVQQIDAxMb3dlciBT
    60  YXhvbnkxEDAOBgNVBAcMB0hhbm92ZXIxFTATBgNVBAoMDFRlc3RpbmcgQ29ycDES
    61  MBAGA1UECwwJVGVzdHN1aXRlMRgwFgYDVQQDDA9iYXIuZXhhbXBsZS5jb20wggIi
    62  MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCv4mHMdVUcafmaSHVpUM0zZWp5
    63  NFXfboxA4inuOkE8kZlbGSe7wiG9WqLirdr39Ts+WSAFA6oANvbzlu3JrEQ2CHPc
    64  CNQm6diPREFwcDPFCe/eMawbwkQAPVSHPts0UoRxnpZox5pn69ghncBR+jtvx+/u
    65  P6HdwW0qqTvfJnfAF1hBJ4oIk2AXiip5kkIznsAh9W6WRy6nTVCeetmIepDOGe0G
    66  ZJIRn/OfSz7NzKylfDCat2z3EAutyeT/5oXZoWOmGg/8T7pn/pR588GoYYKRQnp+
    67  YilqCPFX+az09EqqK/iHXnkdZ/Z2fCuU+9M/Zhrnlwlygl3RuVBI6xhm/ZsXtL2E
    68  Gxa61lNy6pyx5+hSxHEFEJshXLtioRd702VdLKxEOuYSXKeJDs1x9o6cJ75S6hko
    69  `
    70  
    71  const TestTLSInvalidSingleCert = `
    72  -----BEGIN CERTIFICATE-----
    73  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
   104  XWyb96wrUlv+E8I=
   105  -----END CERTIFICATE-----
   106  `
   107  
   108  const TestTLSValidMultiCert = `
   109  -----BEGIN CERTIFICATE-----
   110  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
   141  -----END CERTIFICATE-----
   142  -----BEGIN CERTIFICATE-----
   143  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
   174  XWyb96wrUlv+E8I=
   175  -----END CERTIFICATE-----
   176  `
   177  
   178  // Taken from hack/ssh_known_hosts
   179  const TestValidSSHKnownHostsData = `
   180  # BitBucket
   181  bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
   182  # GitHub
   183  github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
   184  # GitLab
   185  gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
   186  gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
   187  gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
   188  # Azure
   189  ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
   190  vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
   191  `
   192  
   193  const TestInvalidSSHKnownHostsData = `
   194  bitbucket.org AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
   195  # GitHub
   196  github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
   197  # GitLab
   198  gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
   199  gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
   200  gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
   201  # Azure
   202  ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
   203  vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
   204  `
   205  
   206  func TestTLSCertificateValidPEMValidCert(t *testing.T) {
   207  	// Valid PEM data, single certificate, expect array of length 1
   208  	certificates, err := ParseTLSCertificatesFromData(TestTLSValidSingleCert)
   209  	require.NoError(t, err)
   210  	assert.Len(t, certificates, 1)
   211  	// Expect good decode
   212  	x509Cert, err := DecodePEMCertificateToX509(certificates[0])
   213  	require.NoError(t, err)
   214  	assert.Equal(t, TestCert1CN, x509Cert.Subject.String())
   215  }
   216  
   217  func TestTLSCertificateValidPEMInvalidCert(t *testing.T) {
   218  	// Valid PEM data, but invalid certificate
   219  	certificates, err := ParseTLSCertificatesFromData(TestTLSInvalidSingleCert)
   220  	require.NoError(t, err)
   221  	assert.Len(t, certificates, 1)
   222  	// Expect bad decode
   223  	_, err = DecodePEMCertificateToX509(certificates[0])
   224  	require.Error(t, err)
   225  }
   226  
   227  func TestTLSCertificateInvalidPEM(t *testing.T) {
   228  	// Invalid PEM data, expect array of length 0
   229  	certificates, err := ParseTLSCertificatesFromData(TestTLSInvalidPEMData)
   230  	require.NoError(t, err)
   231  	assert.Empty(t, certificates)
   232  }
   233  
   234  func TestTLSCertificateValidPEMValidCertMulti(t *testing.T) {
   235  	// Valid PEM data, two certificates, expect array of length 2
   236  	certificates, err := ParseTLSCertificatesFromData(TestTLSValidMultiCert)
   237  	require.NoError(t, err)
   238  	assert.Len(t, certificates, 2)
   239  	// Expect good decode
   240  	x509Cert, err := DecodePEMCertificateToX509(certificates[0])
   241  	require.NoError(t, err)
   242  	assert.Equal(t, TestCert1CN, x509Cert.Subject.String())
   243  	x509Cert, err = DecodePEMCertificateToX509(certificates[1])
   244  	require.NoError(t, err)
   245  	assert.Equal(t, TestCert2CN, x509Cert.Subject.String())
   246  }
   247  
   248  func TestTLSCertificateValidPEMValidCertFromFile(t *testing.T) {
   249  	// Valid PEM data, single certificate from file, expect array of length 1
   250  	certificates, err := ParseTLSCertificatesFromPath("../../test/certificates/cert1.pem")
   251  	require.NoError(t, err)
   252  	assert.Len(t, certificates, 1)
   253  	// Expect good decode
   254  	x509Cert, err := DecodePEMCertificateToX509(certificates[0])
   255  	require.NoError(t, err)
   256  	assert.Equal(t, TestCert1CN, x509Cert.Subject.String())
   257  }
   258  
   259  func TestTLSCertPool(t *testing.T) {
   260  	certificates, err := ParseTLSCertificatesFromData(TestTLSValidMultiCert)
   261  	require.NoError(t, err)
   262  	assert.Len(t, certificates, 2)
   263  	certPool := GetCertPoolFromPEMData(certificates)
   264  	assert.NotNil(t, certPool)
   265  }
   266  
   267  func TestTLSCertificateCertFromNonExistingFile(t *testing.T) {
   268  	// Non-existing file, expect err
   269  	_, err := ParseTLSCertificatesFromPath("../../test/certificates/cert_nonexisting.pem")
   270  	require.Error(t, err)
   271  }
   272  
   273  func TestSSHKnownHostsDataParseData(t *testing.T) {
   274  	// Expect valid data with 7 known host entries
   275  	entries, err := ParseSSHKnownHostsFromData(TestValidSSHKnownHostsData)
   276  	require.NoError(t, err)
   277  	assert.Len(t, entries, 7)
   278  }
   279  
   280  func TestSSHKnownHostsDataParseFile(t *testing.T) {
   281  	// Expect valid data with 7 known host entries
   282  	entries, err := ParseSSHKnownHostsFromPath("../../test/certificates/ssh_known_hosts")
   283  	require.NoError(t, err)
   284  	assert.Len(t, entries, 7)
   285  }
   286  
   287  func TestSSHKnownHostsDataParseNonExistingFile(t *testing.T) {
   288  	// Expect valid data with 7 known host entries
   289  	entries, err := ParseSSHKnownHostsFromPath("../../test/certificates/ssh_known_hosts_invalid")
   290  	require.Error(t, err)
   291  	assert.Nil(t, entries)
   292  }
   293  
   294  func TestSSHKnownHostsDataTokenize(t *testing.T) {
   295  	// All entries should parse to valid SSH public keys
   296  	// All entries should be tokenizable, and tokens should be feedable to decoder
   297  	entries, err := ParseSSHKnownHostsFromData(TestValidSSHKnownHostsData)
   298  	require.NoError(t, err)
   299  	for _, entry := range entries {
   300  		hosts, _, err := KnownHostsLineToPublicKey(entry)
   301  		require.NoError(t, err)
   302  		assert.Len(t, hosts, 1)
   303  		hoststring, subtype, certdata, err := TokenizeSSHKnownHostsEntry(entry)
   304  		require.NoError(t, err)
   305  		hosts, _, err = TokenizedDataToPublicKey(hoststring, subtype, string(certdata))
   306  		require.NoError(t, err)
   307  		assert.Len(t, hosts, 1)
   308  	}
   309  }
   310  
   311  func TestMatchHostName(t *testing.T) {
   312  	matchHostName := "foo.example.com"
   313  	assert.True(t, MatchHostName(matchHostName, "*"))
   314  	assert.True(t, MatchHostName(matchHostName, "*.example.com"))
   315  	assert.True(t, MatchHostName(matchHostName, "foo.*"))
   316  	assert.True(t, MatchHostName(matchHostName, "foo.*.com"))
   317  	assert.True(t, MatchHostName(matchHostName, "fo?.example.com"))
   318  	assert.False(t, MatchHostName(matchHostName, "foo?.example.com"))
   319  	assert.False(t, MatchHostName(matchHostName, "bar.example.com"))
   320  	assert.False(t, MatchHostName(matchHostName, "*.otherexample.com"))
   321  	assert.False(t, MatchHostName(matchHostName, "foo.otherexample.*"))
   322  }
   323  
   324  func TestSSHFingerprintSHA256(t *testing.T) {
   325  	// actual SHA256 fingerprints for keys defined above
   326  	fingerprints := [...]string{
   327  		"46OSHA1Rmj8E8ERTC6xkNcmGOw9oFxYr0WF6zWW8l1E",
   328  		"uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s",
   329  		"HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw",
   330  		"eUXGGm1YGsMAS7vkcx6JOJdOGHPem5gQp4taiCfCLB8",
   331  		"ROQFvPThGrW4RuWLoL9tq9I9zJ42fK4XywyRtbOz/EQ",
   332  		"ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og",
   333  		"ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og",
   334  	}
   335  	entries, err := ParseSSHKnownHostsFromData(TestValidSSHKnownHostsData)
   336  	require.NoError(t, err)
   337  	assert.Len(t, entries, 7)
   338  	for idx, entry := range entries {
   339  		_, pubKey, err := KnownHostsLineToPublicKey(entry)
   340  		require.NoError(t, err)
   341  		fp := SSHFingerprintSHA256(pubKey)
   342  		assert.Equal(t, fp, fingerprints[idx])
   343  	}
   344  }
   345  
   346  func TestSSHFingerPrintSHA256FromString(t *testing.T) {
   347  	// actual SHA256 fingerprints for keys defined above
   348  	fingerprints := [...]string{
   349  		"46OSHA1Rmj8E8ERTC6xkNcmGOw9oFxYr0WF6zWW8l1E",
   350  		"uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s",
   351  		"HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw",
   352  		"eUXGGm1YGsMAS7vkcx6JOJdOGHPem5gQp4taiCfCLB8",
   353  		"ROQFvPThGrW4RuWLoL9tq9I9zJ42fK4XywyRtbOz/EQ",
   354  		"ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og",
   355  		"ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og",
   356  	}
   357  	entries, err := ParseSSHKnownHostsFromData(TestValidSSHKnownHostsData)
   358  	require.NoError(t, err)
   359  	assert.Len(t, entries, 7)
   360  	for idx, entry := range entries {
   361  		fp := SSHFingerprintSHA256FromString(entry)
   362  		assert.Equal(t, fp, fingerprints[idx])
   363  	}
   364  }
   365  
   366  func TestServerNameWithoutPort(t *testing.T) {
   367  	hostNames := map[string]string{
   368  		"localhost":            "localhost",
   369  		"localhost:9443":       "localhost",
   370  		"localhost:":           "localhost",
   371  		"localhost:abc":        "localhost",
   372  		"localhost.:22":        "localhost.",
   373  		"foo.example.com:443":  "foo.example.com",
   374  		"foo.example.com.:443": "foo.example.com.",
   375  	}
   376  	for inp, res := range hostNames {
   377  		assert.Equal(t, res, ServerNameWithoutPort(inp))
   378  	}
   379  }
   380  
   381  func TestValidHostnames(t *testing.T) {
   382  	hostNames := map[string]bool{
   383  		"localhost":                          true,
   384  		"localhost.localdomain":              true,
   385  		"foo.example.com":                    true,
   386  		"argocd-server.svc.kubernetes.local": true,
   387  		"localhost.":                         true,
   388  		"github.com.":                        true,
   389  		"foo_bar.example.com":                true,
   390  		"_svc.example.com":                   true,
   391  		"_svc.example_.com":                  false,
   392  		"_.example.com":                      false,
   393  		"localhost..":                        false,
   394  		"localhost..localdomain":             false,
   395  		".localhost":                         false,
   396  		"local_host":                         true,
   397  		"localhost.local_domain":             true,
   398  	}
   399  
   400  	for hostName, valid := range hostNames {
   401  		t.Run("Test validity for hostname "+hostName, func(t *testing.T) {
   402  			assert.Equal(t, valid, IsValidHostname(hostName, false))
   403  		})
   404  	}
   405  }
   406  
   407  func TestValidFQDNs(t *testing.T) {
   408  	hostNames := map[string]bool{
   409  		"localhost":                          false,
   410  		"localhost.localdomain":              false,
   411  		"foo.example.com.":                   true,
   412  		"argocd-server.svc.kubernetes.local": false,
   413  		"localhost.":                         true,
   414  		"github.com.":                        true,
   415  		"localhost..":                        false,
   416  		"localhost..localdomain":             false,
   417  		"localhost..localdomain.":            false,
   418  		".localhost":                         false,
   419  		"local_host":                         false,
   420  		"localhost.local_domain":             false,
   421  		"localhost.local_domain.":            false,
   422  	}
   423  
   424  	for hostName, valid := range hostNames {
   425  		assert.Equal(t, valid, IsValidHostname(hostName, true))
   426  	}
   427  }
   428  
   429  func TestEscapeBracketPattern(t *testing.T) {
   430  	// input: expected output
   431  	patternList := map[string]string{
   432  		"foo.bar":         "foo.bar",
   433  		"[foo.bar]":       `\[foo.bar\]`,
   434  		"foo[bar]baz":     `foo\[bar\]baz`,
   435  		`foo\[bar\]baz`:   `foo\\[bar\\]baz`,
   436  		"foo[[[bar]]]baz": `foo\[\[\[bar\]\]\]baz`,
   437  	}
   438  
   439  	for original, expected := range patternList {
   440  		assert.Equal(t, expected, nonBracketedPattern(original))
   441  	}
   442  }
   443  
   444  func TestGetTLSCertificateDataPath(t *testing.T) {
   445  	t.Run("Get default path", func(t *testing.T) {
   446  		t.Setenv(common.EnvVarTLSDataPath, "")
   447  		path := GetTLSCertificateDataPath()
   448  		assert.Equal(t, common.DefaultPathTLSConfig, path)
   449  	})
   450  
   451  	t.Run("Get custom path", func(t *testing.T) {
   452  		t.Setenv(common.EnvVarTLSDataPath, "/some/where")
   453  		path := GetTLSCertificateDataPath()
   454  		assert.Equal(t, "/some/where", path)
   455  	})
   456  }
   457  
   458  func TestGetSSHKnownHostsDataPath(t *testing.T) {
   459  	t.Run("Get default path", func(t *testing.T) {
   460  		t.Setenv(common.EnvVarSSHDataPath, "")
   461  		p := GetSSHKnownHostsDataPath()
   462  		assert.Equal(t, path.Join(common.DefaultPathSSHConfig, "ssh_known_hosts"), p)
   463  	})
   464  
   465  	t.Run("Get custom path", func(t *testing.T) {
   466  		t.Setenv(common.EnvVarSSHDataPath, "/some/where")
   467  		path := GetSSHKnownHostsDataPath()
   468  		assert.Equal(t, "/some/where/ssh_known_hosts", path)
   469  	})
   470  }
   471  
   472  func TestGetCertificateForConnect(t *testing.T) {
   473  	t.Run("Success", func(t *testing.T) {
   474  		temppath := t.TempDir()
   475  		cert, err := os.ReadFile("../../test/fixture/certs/argocd-test-server.crt")
   476  		if err != nil {
   477  			panic(err)
   478  		}
   479  		err = os.WriteFile(path.Join(temppath, "127.0.0.1"), cert, 0o666)
   480  		if err != nil {
   481  			panic(err)
   482  		}
   483  		t.Setenv(common.EnvVarTLSDataPath, temppath)
   484  		certs, err := GetCertificateForConnect("127.0.0.1")
   485  		require.NoError(t, err)
   486  		assert.Len(t, certs, 1)
   487  	})
   488  
   489  	t.Run("No cert found", func(t *testing.T) {
   490  		temppath := t.TempDir()
   491  		t.Setenv(common.EnvVarTLSDataPath, temppath)
   492  		certs, err := GetCertificateForConnect("127.0.0.1")
   493  		require.NoError(t, err)
   494  		assert.Empty(t, certs)
   495  	})
   496  
   497  	t.Run("No valid cert in file", func(t *testing.T) {
   498  		temppath := t.TempDir()
   499  		err := os.WriteFile(path.Join(temppath, "127.0.0.1"), []byte("foobar"), 0o666)
   500  		if err != nil {
   501  			panic(err)
   502  		}
   503  		t.Setenv(common.EnvVarTLSDataPath, temppath)
   504  		certs, err := GetCertificateForConnect("127.0.0.1")
   505  		require.Error(t, err)
   506  		assert.Empty(t, certs)
   507  		assert.ErrorContains(t, err, "no certificates found")
   508  	})
   509  }
   510  
   511  func TestGetCertBundlePathForRepository(t *testing.T) {
   512  	t.Run("Success", func(t *testing.T) {
   513  		temppath := t.TempDir()
   514  		cert, err := os.ReadFile("../../test/fixture/certs/argocd-test-server.crt")
   515  		if err != nil {
   516  			panic(err)
   517  		}
   518  		err = os.WriteFile(path.Join(temppath, "127.0.0.1"), cert, 0o666)
   519  		if err != nil {
   520  			panic(err)
   521  		}
   522  		t.Setenv(common.EnvVarTLSDataPath, temppath)
   523  		certpath, err := GetCertBundlePathForRepository("127.0.0.1")
   524  		require.NoError(t, err)
   525  		assert.Equal(t, certpath, path.Join(temppath, "127.0.0.1"))
   526  	})
   527  
   528  	t.Run("No cert found", func(t *testing.T) {
   529  		temppath := t.TempDir()
   530  		t.Setenv(common.EnvVarTLSDataPath, temppath)
   531  		certpath, err := GetCertBundlePathForRepository("127.0.0.1")
   532  		require.NoError(t, err)
   533  		assert.Empty(t, certpath)
   534  	})
   535  
   536  	t.Run("No valid cert in file", func(t *testing.T) {
   537  		temppath := t.TempDir()
   538  		err := os.WriteFile(path.Join(temppath, "127.0.0.1"), []byte("foobar"), 0o666)
   539  		if err != nil {
   540  			panic(err)
   541  		}
   542  		t.Setenv(common.EnvVarTLSDataPath, temppath)
   543  		certpath, err := GetCertBundlePathForRepository("127.0.0.1")
   544  		require.NoError(t, err)
   545  		assert.Empty(t, certpath)
   546  	})
   547  }