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-----`