vitess.io/vitess@v0.16.2/go/vt/vtgr/ssl/ssl_test.go (about) 1 package ssl_test 2 3 import ( 4 "crypto/tls" 5 "crypto/x509" 6 "encoding/pem" 7 "fmt" 8 nethttp "net/http" 9 "os" 10 "reflect" 11 "strings" 12 "syscall" 13 "testing" 14 15 "vitess.io/vitess/go/vt/vtgr/config" 16 "vitess.io/vitess/go/vt/vtgr/ssl" 17 ) 18 19 /* 20 This file has been copied over from VTOrc package 21 */ 22 23 func TestHasString(t *testing.T) { 24 elem := "foo" 25 a1 := []string{"bar", "foo", "baz"} 26 a2 := []string{"bar", "fuu", "baz"} 27 good := ssl.HasString(elem, a1) 28 if !good { 29 t.Errorf("Didn't find %s in array %s", elem, strings.Join(a1, ", ")) 30 } 31 bad := ssl.HasString(elem, a2) 32 if bad { 33 t.Errorf("Unexpectedly found %s in array %s", elem, strings.Join(a2, ", ")) 34 } 35 } 36 37 // TODO: Build a fake CA and make sure it loads up 38 func TestNewTLSConfig(t *testing.T) { 39 fakeCA := writeFakeFile(pemCertificate) 40 defer syscall.Unlink(fakeCA) 41 42 conf, err := ssl.NewTLSConfig(fakeCA, true) 43 if err != nil { 44 t.Errorf("Could not create new TLS config: %s", err) 45 } 46 if conf.ClientAuth != tls.VerifyClientCertIfGiven { 47 t.Errorf("Client certificate verification was not enabled") 48 } 49 if conf.ClientCAs == nil { 50 t.Errorf("ClientCA empty even though cert provided") 51 } 52 53 conf, err = ssl.NewTLSConfig("", false) 54 if err != nil { 55 t.Errorf("Could not create new TLS config: %s", err) 56 } 57 if conf.ClientAuth == tls.VerifyClientCertIfGiven { 58 t.Errorf("Client certificate verification was enabled unexpectedly") 59 } 60 if conf.ClientCAs != nil { 61 t.Errorf("Filling in ClientCA somehow without a cert") 62 } 63 } 64 65 func TestStatus(t *testing.T) { 66 var validOUs []string 67 url := fmt.Sprintf("http://example.com%s", config.Config.StatusEndpoint) 68 69 req, err := nethttp.NewRequest("GET", url, nil) 70 if err != nil { 71 t.Fatal(err) 72 } 73 config.Config.StatusOUVerify = false 74 if err := ssl.Verify(req, validOUs); err != nil { 75 t.Errorf("Failed even with verification off") 76 } 77 config.Config.StatusOUVerify = true 78 if err := ssl.Verify(req, validOUs); err == nil { 79 t.Errorf("Did not fail on with bad verification") 80 } 81 } 82 83 func TestVerify(t *testing.T) { 84 var validOUs []string 85 86 req, err := nethttp.NewRequest("GET", "http://example.com/foo", nil) 87 if err != nil { 88 t.Fatal(err) 89 } 90 91 if err := ssl.Verify(req, validOUs); err == nil { 92 t.Errorf("Did not fail on lack of TLS config") 93 } 94 95 pemBlock, _ := pem.Decode([]byte(pemCertificate)) 96 cert, err := x509.ParseCertificate(pemBlock.Bytes) 97 if err != nil { 98 t.Fatal(err) 99 } 100 101 var tcs tls.ConnectionState 102 req.TLS = &tcs 103 104 if err := ssl.Verify(req, validOUs); err == nil { 105 t.Errorf("Found a valid OU without any being available") 106 } 107 108 // Set a fake OU 109 cert.Subject.OrganizationalUnit = []string{"testing"} 110 111 // Pretend our request had a certificate 112 req.TLS.PeerCertificates = []*x509.Certificate{cert} 113 req.TLS.VerifiedChains = [][]*x509.Certificate{req.TLS.PeerCertificates} 114 115 // Look for fake OU 116 validOUs = []string{"testing"} 117 118 if err := ssl.Verify(req, validOUs); err != nil { 119 t.Errorf("Failed to verify certificate OU") 120 } 121 } 122 123 func TestReadPEMData(t *testing.T) { 124 pemCertFile := writeFakeFile(pemCertificate) 125 defer syscall.Unlink(pemCertFile) 126 pemPKFile := writeFakeFile(pemPrivateKey) 127 defer syscall.Unlink(pemPKFile) 128 pemPKWPFile := writeFakeFile(pemPrivateKeyWithPass) 129 defer syscall.Unlink(pemPKWPFile) 130 _, err := ssl.ReadPEMData(pemCertFile, []byte{}) 131 if err != nil { 132 t.Errorf("Failed to decode certificate: %s", err) 133 } 134 pemNoPassBytes, err := ssl.ReadPEMData(pemPKFile, []byte{}) 135 if err != nil { 136 t.Errorf("Failed to decode private key: %s", err) 137 } 138 pemPassBytes, err := ssl.ReadPEMData(pemPKWPFile, []byte("testing")) 139 if err != nil { 140 t.Errorf("Failed to decode private key with password: %s", err) 141 } 142 if reflect.DeepEqual(pemPassBytes, pemNoPassBytes) { 143 t.Errorf("PEM encoding failed after password removal") 144 } 145 } 146 147 func TestAppendKeyPair(t *testing.T) { 148 c, err := ssl.NewTLSConfig("", false) 149 if err != nil { 150 t.Fatal(err) 151 } 152 pemCertFile := writeFakeFile(pemCertificate) 153 defer syscall.Unlink(pemCertFile) 154 pemPKFile := writeFakeFile(pemPrivateKey) 155 defer syscall.Unlink(pemPKFile) 156 157 if err := ssl.AppendKeyPair(c, pemCertFile, pemPKFile); err != nil { 158 t.Errorf("Failed to append certificate and key to tls config: %s", err) 159 } 160 } 161 162 func TestAppendKeyPairWithPassword(t *testing.T) { 163 c, err := ssl.NewTLSConfig("", false) 164 if err != nil { 165 t.Fatal(err) 166 } 167 pemCertFile := writeFakeFile(pemCertificate) 168 defer syscall.Unlink(pemCertFile) 169 pemPKFile := writeFakeFile(pemPrivateKeyWithPass) 170 defer syscall.Unlink(pemPKFile) 171 172 if err := ssl.AppendKeyPairWithPassword(c, pemCertFile, pemPKFile, []byte("testing")); err != nil { 173 t.Errorf("Failed to append certificate and key to tls config: %s", err) 174 } 175 } 176 177 func TestIsEncryptedPEM(t *testing.T) { 178 pemPKFile := writeFakeFile(pemPrivateKey) 179 defer syscall.Unlink(pemPKFile) 180 pemPKWPFile := writeFakeFile(pemPrivateKeyWithPass) 181 defer syscall.Unlink(pemPKWPFile) 182 if ssl.IsEncryptedPEM(pemPKFile) { 183 t.Errorf("Incorrectly identified unencrypted PEM as encrypted") 184 } 185 if !ssl.IsEncryptedPEM(pemPKWPFile) { 186 t.Errorf("Incorrectly identified encrypted PEM as unencrypted") 187 } 188 } 189 190 func writeFakeFile(content string) string { 191 f, err := os.CreateTemp("", "ssl_test") 192 if err != nil { 193 return "" 194 } 195 os.WriteFile(f.Name(), []byte(content), 0644) 196 return f.Name() 197 } 198 199 const pemCertificate = `-----BEGIN CERTIFICATE----- 200 MIIDtTCCAp2gAwIBAgIJAOxKC7FsJelrMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV 201 BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 202 aWRnaXRzIFB0eSBMdGQwHhcNMTcwODEwMTQ0MjM3WhcNMTgwODEwMTQ0MjM3WjBF 203 MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 204 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 205 CgKCAQEA12vHV3gYy5zd1lujA7prEhCSkAszE6E37mViWhLQ63CuedZfyYaTAHQK 206 HYDZi4K1MNAySUfZRMcICSSsxlRIz6mzXrFsowaJgwx4cbMDIvXE03KstuXoTYJh 207 +xmXB+5yEVEtIyP2DvPqfCmwCZb3k94Y/VY1nAQDxIxciXrAxT9zT1oYd0YWr2yp 208 J2mgsfnY4c3zg7W5WgvOTmYz7Ey7GJjpUjGdayx+P1CilKzSWH1xZuVQFNLSHvcH 209 WXkEoCMVc0tW5mO5eEO1aNHo9MSjPF386l1rq+pz5OwjqCEZq2b1YxesyLnbF+8+ 210 iYGfYmFaDLFwG7zVDwialuI4TzIIOQIDAQABo4GnMIGkMB0GA1UdDgQWBBQ1ubGx 211 Yvn3wN5VXyoR0lOD7ARzVTB1BgNVHSMEbjBsgBQ1ubGxYvn3wN5VXyoR0lOD7ARz 212 VaFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV 213 BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAOxKC7FsJelrMAwGA1UdEwQF 214 MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBALmm4Zw/4jLKDJciUGUYOcr5Xe9TP/Cs 215 afH7IWvaFUDfV3W6yAm9jgNfIy9aDLpuu2CdEb+0qL2hdmGLV7IM3y62Ve0UTdGV 216 BGsm1zMmIguew2wGbAwGr5LmIcUseatVUKAAAfDrBNwotEAdM8kmGekUZfOM+J9D 217 FoNQ62C0buRHGugtu6zWAcZNOe6CI7HdhaAdxZlgn8y7dfJQMacoK0NcWeUVQwii 218 6D4mgaqUGM2O+WcquD1vEMuBPYVcKhi43019E0+6LI5QB6w80bARY8K7tkTdRD7U 219 y1/C7iIqyuBVL45OdSabb37TfGlHZIPIwLaGw3i4Mr0+F0jQT8rZtTQ= 220 -----END CERTIFICATE-----` 221 222 const pemPrivateKey = `-----BEGIN RSA PRIVATE KEY----- 223 MIIEpAIBAAKCAQEA12vHV3gYy5zd1lujA7prEhCSkAszE6E37mViWhLQ63CuedZf 224 yYaTAHQKHYDZi4K1MNAySUfZRMcICSSsxlRIz6mzXrFsowaJgwx4cbMDIvXE03Ks 225 tuXoTYJh+xmXB+5yEVEtIyP2DvPqfCmwCZb3k94Y/VY1nAQDxIxciXrAxT9zT1oY 226 d0YWr2ypJ2mgsfnY4c3zg7W5WgvOTmYz7Ey7GJjpUjGdayx+P1CilKzSWH1xZuVQ 227 FNLSHvcHWXkEoCMVc0tW5mO5eEO1aNHo9MSjPF386l1rq+pz5OwjqCEZq2b1Yxes 228 yLnbF+8+iYGfYmFaDLFwG7zVDwialuI4TzIIOQIDAQABAoIBAHLf4pleTbqmmBWr 229 IC7oxhgIBmAR2Nbq7eyO2/e0ePxURnZqPwI0ZUekmZBKGbgvp3e0TlyNl+r5R+u4 230 RvosD/fNQv2IF6qH3eSoTcIz98Q40xD+4eNWjp5mnOFOMB/mo6VgaHWIw7oNkElN 231 4bX7b2LG2QSfaE8eRPQW9XHKp+mGhYFbxgPYxUmlIXuYZF61hVwxysDA6DP3LOi8 232 yUL6E64x6NqN9xtg/VoN+f6N0MOvsr4yb5+uvni1LVRFI7tNqIN4Y6P6trgKfnRR 233 EpZeAUu8scqyxE4NeqnnjK/wBuXxaeh3e9mN1V2SzT629c1InmmQasZ5slcCJQB+ 234 38cswgECgYEA+esaLKwHXT4+sOqMYemi7TrhxtNC2f5OAGUiSRVmTnum2gl4wOB+ 235 h5oLZAuG5nBEIoqbMEbI35vfuHqIe390IJtPdQlz4TGDsPufYj/gnnBBFy/c8f+n 236 f/CdRDRYrpnpKGwvUntLRB2pFbe2hlqqq+4YUqiHauJMOCJnPbOo1lECgYEA3KnF 237 VOXyY0fKD45G7ttfAcpw8ZI2gY99sCRwtBQGsbO61bvw5sl/3j7AmYosz+n6f7hb 238 uHmitIuPv4z3r1yfVysh80tTGIM3wDkpr3fLYRxpVOZU4hgxMQV9yyaSA/Hfqn48 239 vIK/NC4bERqpofNNdrIqNaGWkd87ZycvpRfa0WkCgYBztbVVr4RtWG9gLAg5IRot 240 KhD0pEWUdpiYuDpqifznI3r6Al6lNot+rwTNGkUoFhyFvZTigjNozFuFpz3fqAAV 241 RLNCJdFAF1O4spd1vst5r9GDMcbjSJG9u6KkvHO+y0XXUFeMoccUT4NEqd1ZUUsp 242 9T/PrXWdOA9AAjW4rKDkMQKBgQC9R4NVR8mbD8Frhoeh69qbFqO7E8hdalBN/3QN 243 hAAZ/imNnSEPVliwsvNSwQufbPzLAcDrhKrkY7JyhOERM0oa44zDvSESLbxszpvL 244 P97c9hoEEW9OYaIQgr1cvUES0S8ieBZxPVX11HazPUO0/5a68ijyyCD4D5xM53gf 245 DU9NwQKBgQCmVthQi65xcc4mgCIwXtBZWXeaPv5x0dLEXIC5EoN6eXLK9iW//7cE 246 hhawtJtl+J6laB+TkEGQsyhc4v85WcywdisyR7LR7CUqFYJMKeE/VtTVKnYbfq54 247 rHoQS9YotByBwPtRx0V93gkc+KWBOGmSBBxKj7lrBkYkcWAiRfpJjg== 248 -----END RSA PRIVATE KEY-----` 249 250 const pemPrivateKeyWithPass = `-----BEGIN RSA PRIVATE KEY----- 251 Proc-Type: 4,ENCRYPTED 252 DEK-Info: DES-EDE3-CBC,3EABF60A784F9065 253 254 IDGYvdRJXvBt5vEDI9caEYJ2vvVmoqmxTKvheNX0aLSXUl/p8hIZ25kd/4mpmI3m 255 irQdEe2JuNh4/fPDe6Agg6mX6mYCVbiupfXdFKkqJzndW/O5nEQ4yuRgi0fO4wcH 256 OM/kTS8/7UaKfCuWFa71ywh1WeStFDBwsMQqLdFFeuQ/JC6g2tZW6xzCBE0BVIkq 257 6OWXmWumXMufhOdpb9sNoc3lbdOi037V886o0cIRQp4qPepElhhhplrhaJZBSxiP 258 TUldExbtYCN1APhrgUp1RpxIWHNLezjhUYLGooxb6SqinpLd9ia2uFotwNDeX7/T 259 dMPQPtgdFwvoCtWn9oVWp+regdZPacABLsvtTD4NS8h13BKzBmAqtYfHJk44u/Tv 260 6PcCb9xHI7+YpNJznrHiCtALWkfG56mDjp0SP+OKjsYMjo317D+x892i2XT79k2T 261 0IM0OUPizVkN5c7uDQBHqxmE9JVQT7QFMy1P57nWPsmG5o7e9Y/klaPQzi04FWEh 262 YAEZrU5/FQlFziu3/Jw6WwQnm3IqJP6iMlnR9Y5iZCZQnLhcJNIxxOJ/+cVH4dVD 263 jIHztasHgbfld045Ua7nk91VyFP5pWRPFacJ74D+xm/1IjF/+9Uj3NQX88Swig0Q 264 Fi7+eJ1XtCI0YdUqiUdp8QaS1GnFzibSIcXCbLLEn0Cgh/3CFXUyh92M4GIgvmcI 265 /hi4nUDa3nLYDHyOZubFLERb+Zr3EFzNXX4Ga3fcNH0deluxW4tda+QCk0ud6k9N 266 y2bCcAVnvbB+yX2s7CSVq+eaT/4JLIJY5AlrISRwYtG57SR/DN9HuU99dD30k581 267 PmarIt4VAakjXo/Zqd1AMh+ofbC/Qm7jBwbPGPZAM/FjpnVsvaXsdChI19Az72v3 268 wiLOKEw8M23vV4/E7QwW3Pp/RPyUZk6HAlBuLXbcyZHOOV4WPsKrI46BBXL8Qf4X 269 5kpRITFFUaFu3aaO7mloVAoneEKusKJgKOAwWifRI3jf6fH9B8qDA0jQpWRNpLs4 270 3A2qrOyHQ9SMoBr7ya8Vs2BMdfqAmOyiUdVzLr2EjnRxa7f3/7/sdzD1aaIJa2TM 271 kjpKgFMq5B/FRVmuAvKyEF52A/b6L9EpinyB53DzWnIw9W5zdjjRkuxmGmv1R94A 272 gJvbONh955cinHft0rm0hdKo77wDvXZdX5ZeITjOwJ0d/VBHYDGUonDVgnAVLcz+ 273 n1BS+oOS1xLG/EJOGqtNYihVuCkbIwwdAVhc7pKo3nIbLyrKFKFyh/Br11PPBris 274 nlWo8BWSoFv7gKOftkulHJFAVekisaXe4OIcYMATeLvDfAnBDJrNHZn0HcyHI51L 275 3EhCCPJrrmfNv+QMdPk6LTts5YIdhNRSV5PR2X8ZshChod7atyrw+Wm+LCcy3h1G 276 xIVNracpnna+Ic5M8EIJZgLOH7IjDFS1EcPjz5em0rVqGGsLDvxmRo2ZJTPSHlpM 277 8q6VJEIso5sfoauf+fX+y7xk1CpFG8NkXSplbiYmZXdB1zepV1a/ZiW2uU7hEAV7 278 oMEzoBEIw3wTuRasixjH7Z6i8PvF3eUKXCIt0UiwTmWdCCW37c5eqjguyp9aLDtc 279 -----END RSA PRIVATE KEY-----`