github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/internal/enforcer/applicationproxy/tcp/verifier/verifier_test.go (about)

     1  package verifier
     2  
     3  import (
     4  	"crypto/x509"
     5  	"encoding/pem"
     6  	"io/ioutil"
     7  	"testing"
     8  
     9  	"go.aporeto.io/enforcerd/trireme-lib/collector"
    10  	"go.aporeto.io/enforcerd/trireme-lib/policy"
    11  )
    12  
    13  func Test_verifier_TrustCAs(t *testing.T) {
    14  	type fields struct {
    15  		trustedCAPool *x509.CertPool
    16  	}
    17  	type args struct {
    18  		caPool *x509.CertPool
    19  	}
    20  	sysPool, err := x509.SystemCertPool()
    21  	if err != nil {
    22  		t.Errorf("unable to get system certs")
    23  	}
    24  	tests := []struct {
    25  		name   string
    26  		fields fields
    27  		args   args
    28  	}{
    29  		{
    30  			"basic nil",
    31  			fields{
    32  				trustedCAPool: nil,
    33  			},
    34  			args{
    35  				caPool: nil,
    36  			},
    37  		},
    38  		{
    39  			"basic valid",
    40  			fields{
    41  				trustedCAPool: sysPool,
    42  			},
    43  			args{
    44  				caPool: sysPool,
    45  			},
    46  		},
    47  	}
    48  	for _, tt := range tests {
    49  		t.Run(tt.name, func(t *testing.T) {
    50  			v := &verifier{
    51  				trustedCAPool: tt.fields.trustedCAPool,
    52  			}
    53  			v.TrustCAs(tt.args.caPool)
    54  			if v.trustedCAPool != tt.args.caPool {
    55  				t.Errorf("ca pool not appropriately setup")
    56  			}
    57  		})
    58  	}
    59  }
    60  
    61  // Dummy PolicyLookup implementer to test
    62  type policyReporter struct {
    63  	ip    int
    64  	ipret bool
    65  	id    int
    66  	idret bool
    67  }
    68  
    69  func (p *policyReporter) IDLookup(remoteController, remotePUID string, tags *policy.TagStore) bool {
    70  	p.id++
    71  	return p.idret
    72  }
    73  func (p *policyReporter) IPLookup() bool {
    74  	p.ip++
    75  	return p.ipret
    76  }
    77  
    78  func (p *policyReporter) ReportStats(remoteType collector.EndPointType, remoteController string, remotePUID string, mode string, report *policy.FlowPolicy, packet *policy.FlowPolicy, accept bool) {
    79  
    80  }
    81  
    82  func (p *policyReporter) Policy(tags *policy.TagStore) (*policy.FlowPolicy, *policy.FlowPolicy) {
    83  	return nil, nil
    84  }
    85  
    86  func Test_verifier_VerifyPeerCertificate(t *testing.T) {
    87  	type fields struct {
    88  		trustedCAs *x509.CertPool
    89  	}
    90  	type args struct {
    91  		rawCerts             [][]byte
    92  		verifiedChains       [][]*x509.Certificate
    93  		policyReporter       *policyReporter
    94  		mustHaveClientIDCert bool
    95  	}
    96  	type want struct {
    97  		err     bool
    98  		ipCount int
    99  		idCount int
   100  	}
   101  
   102  	// Aporeto CA Root
   103  	certs, err := ioutil.ReadFile("./testdata/myca-cert.pem")
   104  	if err != nil {
   105  		panic("unable to load CA")
   106  	}
   107  	block, _ := pem.Decode(certs)
   108  	if block == nil {
   109  		panic("failed to parse certificate PEM")
   110  	}
   111  	aporetoCertRoot, err := x509.ParseCertificate(block.Bytes)
   112  	if err != nil {
   113  		panic("failed to parse certificate: " + err.Error())
   114  	}
   115  	aporetoCAPool := x509.NewCertPool()
   116  	if ok := aporetoCAPool.AppendCertsFromPEM(certs); !ok {
   117  		panic("unable to append CA to root")
   118  	}
   119  
   120  	// Aporeto Client Bad Cert Leaf with Tags
   121  	certs, err = ioutil.ReadFile("./testdata/myclient-bad-cert.pem")
   122  	if err != nil {
   123  		panic("unable to load client bad cert")
   124  	}
   125  	block, _ = pem.Decode(certs)
   126  	if block == nil {
   127  		panic("failed to parse client bad certificate PEM")
   128  	}
   129  	aporetoClientBadCertWithExtension, err := x509.ParseCertificate(block.Bytes)
   130  	if err != nil {
   131  		panic("failed to parse client bad certificate: " + err.Error())
   132  	}
   133  
   134  	// Aporeto Client IP Cert Leaf with Tags
   135  	certs, err = ioutil.ReadFile("./testdata/myclient-ip-cert.pem")
   136  	if err != nil {
   137  		panic("unable to load client ip cert")
   138  	}
   139  	block, _ = pem.Decode(certs)
   140  	if block == nil {
   141  		panic("failed to parse client ip certificate PEM")
   142  	}
   143  	aporetoClientIPCertWithExtension, err := x509.ParseCertificate(block.Bytes)
   144  	if err != nil {
   145  		panic("failed to parse client ip certificate: " + err.Error())
   146  	}
   147  
   148  	// Aporeto Client DNS Cert Leaf with Tags
   149  	certs, err = ioutil.ReadFile("./testdata/myclient-dns-cert.pem")
   150  	if err != nil {
   151  		panic("unable to load client dns cert")
   152  	}
   153  	block, _ = pem.Decode(certs)
   154  	if block == nil {
   155  		panic("failed to parse client dns certificate PEM")
   156  	}
   157  	aporetoClientDNSCertWithExtension, err := x509.ParseCertificate(block.Bytes)
   158  	if err != nil {
   159  		panic("failed to parse client dns certificate: " + err.Error())
   160  	}
   161  
   162  	// Aporeto Server Cert Leaf with Tags
   163  	certs, err = ioutil.ReadFile("./testdata/myserver-cert.pem")
   164  	if err != nil {
   165  		panic("unable to load server cert")
   166  	}
   167  	block, _ = pem.Decode(certs)
   168  	if block == nil {
   169  		panic("failed to parse server certificate PEM")
   170  	}
   171  	aporetoServerCertWithExtension, err := x509.ParseCertificate(block.Bytes)
   172  	if err != nil {
   173  		panic("failed to parse server certificate: " + err.Error())
   174  	}
   175  	tests := []struct {
   176  		name   string
   177  		fields fields
   178  		args   args
   179  		want   want
   180  	}{
   181  		{
   182  			name:   "ip lookup - success (no aporeto tags)",
   183  			fields: fields{},
   184  			args: args{
   185  				policyReporter: &policyReporter{
   186  					ipret: true,
   187  					idret: true,
   188  				},
   189  			},
   190  			want: want{
   191  				err:     false,
   192  				ipCount: 1,
   193  				idCount: 0,
   194  			},
   195  		},
   196  		{
   197  			name:   "ip lookup - failure (no aporeto tags)",
   198  			fields: fields{},
   199  			args: args{
   200  				policyReporter: &policyReporter{
   201  					ipret: false,
   202  					idret: false,
   203  				},
   204  			},
   205  			want: want{
   206  				err:     true,
   207  				ipCount: 1,
   208  				idCount: 0,
   209  			},
   210  		},
   211  		{
   212  			name: "ip lookup - success (no trusted CAs)",
   213  			fields: fields{
   214  				trustedCAs: x509.NewCertPool(),
   215  			},
   216  			args: args{
   217  				verifiedChains: [][]*x509.Certificate{
   218  					{
   219  						aporetoClientIPCertWithExtension,
   220  						aporetoCertRoot,
   221  					},
   222  				},
   223  				policyReporter: &policyReporter{
   224  					ipret: true,
   225  					idret: true,
   226  				},
   227  			},
   228  			want: want{
   229  				err:     false,
   230  				ipCount: 1,
   231  				idCount: 0,
   232  			},
   233  		},
   234  		{
   235  			name:   "ip lookup - success (missing chain in trusted CAs)",
   236  			fields: fields{},
   237  			args: args{
   238  				verifiedChains: [][]*x509.Certificate{
   239  					{
   240  						aporetoClientIPCertWithExtension,
   241  					},
   242  				},
   243  				policyReporter: &policyReporter{
   244  					ipret: true,
   245  					idret: true,
   246  				},
   247  			},
   248  			want: want{
   249  				err:     false,
   250  				ipCount: 1,
   251  				idCount: 0,
   252  			},
   253  		},
   254  		{
   255  			name: "ip lookup - success (missing aporeto tags in verified chain)",
   256  			fields: fields{
   257  				trustedCAs: aporetoCAPool,
   258  			},
   259  			args: args{
   260  				verifiedChains: [][]*x509.Certificate{
   261  					{
   262  						aporetoCertRoot,
   263  					},
   264  				},
   265  				policyReporter: &policyReporter{
   266  					ipret: true,
   267  					idret: true,
   268  				},
   269  			},
   270  			want: want{
   271  				err:     false,
   272  				ipCount: 1,
   273  				idCount: 0,
   274  			},
   275  		},
   276  		{
   277  			name: "id lookup (client Bad) - failure",
   278  			fields: fields{
   279  				trustedCAs: aporetoCAPool,
   280  			},
   281  			args: args{
   282  				verifiedChains: [][]*x509.Certificate{
   283  					{
   284  						aporetoClientBadCertWithExtension,
   285  						aporetoCertRoot,
   286  					},
   287  				},
   288  				policyReporter: &policyReporter{
   289  					ipret: true,
   290  					idret: true,
   291  				},
   292  				mustHaveClientIDCert: true,
   293  			},
   294  			want: want{
   295  				err:     true,
   296  				ipCount: 0,
   297  				idCount: 0,
   298  			},
   299  		},
   300  		{
   301  			name: "id lookup (client IP) - success",
   302  			fields: fields{
   303  				trustedCAs: aporetoCAPool,
   304  			},
   305  			args: args{
   306  				verifiedChains: [][]*x509.Certificate{
   307  					{
   308  						aporetoClientIPCertWithExtension,
   309  						aporetoCertRoot,
   310  					},
   311  				},
   312  				policyReporter: &policyReporter{
   313  					ipret: true,
   314  					idret: true,
   315  				},
   316  			},
   317  			want: want{
   318  				err:     false,
   319  				ipCount: 0,
   320  				idCount: 1,
   321  			},
   322  		},
   323  		{
   324  			name: "id lookup (client DNS) - success",
   325  			fields: fields{
   326  				trustedCAs: aporetoCAPool,
   327  			},
   328  			args: args{
   329  				verifiedChains: [][]*x509.Certificate{
   330  					{
   331  						aporetoClientDNSCertWithExtension,
   332  						aporetoCertRoot,
   333  					},
   334  				},
   335  				policyReporter: &policyReporter{
   336  					ipret: true,
   337  					idret: true,
   338  				},
   339  			},
   340  			want: want{
   341  				err:     false,
   342  				ipCount: 0,
   343  				idCount: 1,
   344  			},
   345  		},
   346  		{
   347  			name: "id lookup (server) - success",
   348  			fields: fields{
   349  				trustedCAs: aporetoCAPool,
   350  			},
   351  			args: args{
   352  				verifiedChains: [][]*x509.Certificate{
   353  					{
   354  						aporetoServerCertWithExtension,
   355  						aporetoCertRoot,
   356  					},
   357  				},
   358  				policyReporter: &policyReporter{
   359  					ipret: true,
   360  					idret: true,
   361  				},
   362  			},
   363  			want: want{
   364  				err:     false,
   365  				ipCount: 0,
   366  				idCount: 1,
   367  			},
   368  		},
   369  		{
   370  			name: "id lookup (server) - must have client id - failure",
   371  			fields: fields{
   372  				trustedCAs: aporetoCAPool,
   373  			},
   374  			args: args{
   375  				policyReporter: &policyReporter{
   376  					ipret: true,
   377  					idret: true,
   378  				},
   379  				mustHaveClientIDCert: true,
   380  			},
   381  			want: want{
   382  				err:     true,
   383  				ipCount: 0,
   384  				idCount: 0,
   385  			},
   386  		},
   387  	}
   388  	for _, tt := range tests {
   389  		t.Run(tt.name, func(t *testing.T) {
   390  			v := New(tt.fields.trustedCAs)
   391  			err := v.VerifyPeerCertificate(tt.args.rawCerts, tt.args.verifiedChains, tt.args.policyReporter, tt.args.mustHaveClientIDCert)
   392  			if (err != nil) != tt.want.err {
   393  				t.Errorf("verifier.VerifyPeerCertificate() error = %v, want.err %v", err, tt.want.err)
   394  				return
   395  			}
   396  			if tt.args.policyReporter.id != tt.want.idCount {
   397  				t.Errorf("verifier.VerifyPeerCertificate() id have = %v, want %v", tt.args.policyReporter.id, tt.want.idCount)
   398  				return
   399  			}
   400  			if tt.args.policyReporter.ip != tt.want.ipCount {
   401  				t.Errorf("verifier.VerifyPeerCertificate() ip have = %v, want %v", tt.args.policyReporter.ip, tt.want.ipCount)
   402  				return
   403  			}
   404  		})
   405  	}
   406  }