github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/pkg/pucontext/pucontext_test.go (about)

     1  // +build !windows
     2  
     3  package pucontext
     4  
     5  import (
     6  	"crypto/ecdsa"
     7  	"crypto/x509"
     8  	"testing"
     9  	"time"
    10  
    11  	. "github.com/smartystreets/goconvey/convey"
    12  	"go.aporeto.io/enforcerd/trireme-lib/controller/constants"
    13  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/nfqdatapath/tokenaccessor"
    14  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/utils/ephemeralkeys"
    15  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/claimsheader"
    16  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/pkiverifier"
    17  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/secrets"
    18  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/secrets/compactpki"
    19  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/tokens"
    20  	"go.aporeto.io/enforcerd/trireme-lib/policy"
    21  	"go.aporeto.io/enforcerd/trireme-lib/utils/crypto"
    22  	"go.aporeto.io/enforcerd/trireme-lib/utils/portspec"
    23  	"go.uber.org/zap"
    24  	"gotest.tools/assert"
    25  )
    26  
    27  func Test_NewPU(t *testing.T) {
    28  
    29  	Convey("When I call NewPU with proper data", t, func() {
    30  
    31  		fp := &policy.PUInfo{
    32  			Runtime: policy.NewPURuntimeWithDefaults(),
    33  			Policy:  policy.NewPUPolicy("", "/xyz", policy.AllowAll, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, nil, nil, []string{}, policy.EnforcerMapping, policy.Reject, policy.Reject),
    34  		}
    35  
    36  		pu, err := NewPU("pu1", fp, nil, 24*time.Hour)
    37  
    38  		Convey("I should not get error", func() {
    39  			So(pu, ShouldNotBeNil)
    40  			So(pu.HashID(), ShouldEqual, pu.hashID)
    41  			So(pu.ManagementNamespaceHash(), ShouldEqual, "JJ0iGN3c9I2d+bx4")
    42  			So(pu.Counters(), ShouldNotBeNil)
    43  			So(err, ShouldBeNil)
    44  		})
    45  	})
    46  }
    47  
    48  var (
    49  	keyPEM = `-----BEGIN EC PRIVATE KEY-----
    50  MHcCAQEEIPkiHqtH372JJdAG/IxJlE1gv03cdwa8Lhg2b3m/HmbyoAoGCCqGSM49
    51  AwEHoUQDQgAEAfAL+AfPj/DnxrU6tUkEyzEyCxnflOWxhouy1bdzhJ7vxMb1vQ31
    52  8ZbW/WvMN/ojIXqXYrEpISoojznj46w64w==
    53  -----END EC PRIVATE KEY-----`
    54  	caPool = `-----BEGIN CERTIFICATE-----
    55  MIIBhTCCASwCCQC8b53yGlcQazAKBggqhkjOPQQDAjBLMQswCQYDVQQGEwJVUzEL
    56  MAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NKQzEQMA4GA1UECgwHVHJpcmVtZTEPMA0G
    57  A1UEAwwGdWJ1bnR1MB4XDTE2MDkyNzIyNDkwMFoXDTI2MDkyNTIyNDkwMFowSzEL
    58  MAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTSkMxEDAOBgNVBAoM
    59  B1RyaXJlbWUxDzANBgNVBAMMBnVidW50dTBZMBMGByqGSM49AgEGCCqGSM49AwEH
    60  A0IABJxneTUqhbtgEIwpKUUzwz3h92SqcOdIw3mfQkMjg3Vobvr6JKlpXYe9xhsN
    61  rygJmLhMAN9gjF9qM9ybdbe+m3owCgYIKoZIzj0EAwIDRwAwRAIgC1fVMqdBy/o3
    62  jNUje/Hx0fZF9VDyUK4ld+K/wF3QdK4CID1ONj/Kqinrq2OpjYdkgIjEPuXoOoR1
    63  tCym8dnq4wtH
    64  -----END CERTIFICATE-----
    65  -----BEGIN CERTIFICATE-----
    66  MIIB3jCCAYOgAwIBAgIJALsW7pyC2ERQMAoGCCqGSM49BAMCMEsxCzAJBgNVBAYT
    67  AlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0pDMRAwDgYDVQQKDAdUcmlyZW1l
    68  MQ8wDQYDVQQDDAZ1YnVudHUwHhcNMTYwOTI3MjI0OTAwWhcNMjYwOTI1MjI0OTAw
    69  WjBLMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NKQzEQMA4G
    70  A1UECgwHVHJpcmVtZTEPMA0GA1UEAwwGdWJ1bnR1MFkwEwYHKoZIzj0CAQYIKoZI
    71  zj0DAQcDQgAE4c2Fd7XeIB1Vfs51fWwREfLLDa55J+NBalV12CH7YEAnEXjl47aV
    72  cmNqcAtdMUpf2oz9nFVI81bgO+OSudr3CqNQME4wHQYDVR0OBBYEFOBftuI09mmu
    73  rXjqDyIta1gT8lqvMB8GA1UdIwQYMBaAFOBftuI09mmurXjqDyIta1gT8lqvMAwG
    74  A1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAMylAHhbFA0KqhXIFiXNpEbH
    75  JKaELL6UXXdeQ5yup8q+AiEAh5laB9rbgTymjaANcZ2YzEZH4VFS3CKoSdVqgnwC
    76  dW4=
    77  -----END CERTIFICATE-----`
    78  
    79  	certPEM = `-----BEGIN CERTIFICATE-----
    80  MIIBhjCCASwCCQCPCdgp39gHJTAKBggqhkjOPQQDAjBLMQswCQYDVQQGEwJVUzEL
    81  MAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NKQzEQMA4GA1UECgwHVHJpcmVtZTEPMA0G
    82  A1UEAwwGdWJ1bnR1MB4XDTE2MDkyNzIyNDkwMFoXDTI2MDkyNTIyNDkwMFowSzEL
    83  MAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTSkMxEDAOBgNVBAoM
    84  B1RyaXJlbWUxDzANBgNVBAMMBnVidW50dTBZMBMGByqGSM49AgEGCCqGSM49AwEH
    85  A0IABAHwC/gHz4/w58a1OrVJBMsxMgsZ35TlsYaLstW3c4Se78TG9b0N9fGW1v1r
    86  zDf6IyF6l2KxKSEqKI854+OsOuMwCgYIKoZIzj0EAwIDSAAwRQIgQwQn0jnK/XvD
    87  KxgQd/0pW5FOAaB41cMcw4/XVlphO1oCIQDlGie+WlOMjCzrV0Xz+XqIIi1pIgPT
    88  IG7Nv+YlTVp5qA==
    89  -----END CERTIFICATE-----`
    90  )
    91  
    92  func createCompactPKISecrets(tags []string) (ephemeralkeys.KeyAccessor, *x509.Certificate, secrets.Secrets, error) { //nolint
    93  	txtKey, cert, _, err := crypto.LoadAndVerifyECSecrets([]byte(keyPEM), []byte(certPEM), []byte(caPool))
    94  	if err != nil {
    95  		return nil, nil, nil, err
    96  	}
    97  
    98  	issuer := pkiverifier.NewPKIIssuer(txtKey)
    99  	txtToken, err := issuer.CreateTokenFromCertificate(cert, tags)
   100  	if err != nil {
   101  		return nil, nil, nil, err
   102  	}
   103  
   104  	ControllerInfo := &secrets.ControllerInfo{
   105  		PublicKey: []byte(certPEM),
   106  	}
   107  
   108  	tokenKeyPEMs := []*secrets.ControllerInfo{ControllerInfo}
   109  
   110  	scrts, err := compactpki.NewCompactPKIWithTokenCA([]byte(keyPEM), []byte(certPEM), []byte(caPool), tokenKeyPEMs, txtToken, claimsheader.CompressionTypeV1)
   111  	if err != nil {
   112  		return nil, nil, nil, err
   113  	}
   114  	keyaccessor, _ := ephemeralkeys.New()
   115  	return keyaccessor, cert, scrts, nil
   116  }
   117  
   118  func Test_PUsTokenExchanges(t *testing.T) {
   119  	_, _, scrts, _ := createCompactPKISecrets([]string{"kDMRXWckV9k6mGuJ", "xyz", "eJ1s03u72o6i"})
   120  	ephemeralkeys.UpdateDatapathSecrets(scrts)
   121  
   122  	setup := func() (*PUContext, *PUContext) {
   123  
   124  		fp := &policy.PUInfo{
   125  			Runtime: policy.NewPURuntimeWithDefaults(),
   126  			Policy:  policy.NewPUPolicy("", "/xyz", policy.AllowAll, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, nil, nil, []string{}, policy.EnforcerMapping, policy.Reject, policy.Reject),
   127  		}
   128  		ta1, _ := tokenaccessor.New("pu1", 1*time.Hour, nil)
   129  		pu1, _ := NewPU("pu1", fp, ta1, 24*time.Hour)
   130  		pu1.managementID = "1newPU1"
   131  		tags1 := policy.NewTagStore()
   132  		tags1.AppendKeyValue("pu", "pu1")
   133  		pu1.compressedTags = tags1
   134  
   135  		ta2, _ := tokenaccessor.New("pu2", 1*time.Hour, nil)
   136  		pu2, _ := NewPU("pu2", fp, ta2, 24*time.Hour)
   137  		pu2.managementID = "1newPU2"
   138  		tags2 := policy.NewTagStore()
   139  		tags2.AppendKeyValue("pu", "pu2")
   140  		pu2.compressedTags = tags2
   141  
   142  		return pu1, pu2
   143  	}
   144  
   145  	pu1, pu2 := setup()
   146  	token := pu1.createSynToken(nil, claimsheader.NewClaimsHeader())
   147  
   148  	claimsOnSynRcvd := &tokens.ConnectionClaims{}
   149  	ka, _ := ephemeralkeys.New()
   150  	secretKey, _, _, remoteNonce, remoteContextID, _, err := pu2.tokenAccessor.ParsePacketToken(ka.PrivateKey(), token.token, scrts, claimsOnSynRcvd, false)
   151  
   152  	assert.Equal(t, err, nil, "ParsePacketToken should return nil")
   153  	assert.Equal(t, remoteContextID, pu1.managementID, "ParsePacketToken should get the correct remote contextID")
   154  	tags := claimsOnSynRcvd.CT.GetSlice()
   155  	assert.Equal(t, tags[0], "pu=pu1", "Receiver should receive correct tags")
   156  
   157  	ephKeySignV1, _ := pu2.tokenAccessor.Sign(ka.DecodingKeyV1(), scrts.EncodingKey().(*ecdsa.PrivateKey)) //nolint
   158  	ephKeySignV2, _ := pu2.tokenAccessor.Sign(ka.DecodingKeyV2(), scrts.EncodingKey().(*ecdsa.PrivateKey)) //nolint
   159  
   160  	claimsOnSynAckSend := &tokens.ConnectionClaims{
   161  		CT:       pu2.CompressedTags(),
   162  		LCL:      remoteNonce,
   163  		RMT:      remoteNonce,
   164  		DEKV1:    ka.DecodingKeyV1(),
   165  		DEKV2:    ka.DecodingKeyV2(),
   166  		SDEKV1:   ephKeySignV1,
   167  		SDEKV2:   ephKeySignV2,
   168  		ID:       pu2.ManagementID(),
   169  		RemoteID: pu1.managementID,
   170  	}
   171  
   172  	var encodedBuf [tokens.ClaimsEncodedBufSize]byte
   173  	tokenFromSynAck, _ := pu2.tokenAccessor.CreateSynAckPacketToken(false, claimsOnSynAckSend, encodedBuf[:], remoteNonce, claimsheader.NewClaimsHeader(), scrts, secretKey) //nolint
   174  
   175  	claimsOnSynAckRcvd := &tokens.ConnectionClaims{}
   176  	secretKey, _, _, remoteNonce, remoteContextID, _, err = pu1.tokenAccessor.ParsePacketToken(token.privateKey, tokenFromSynAck, scrts, claimsOnSynAckRcvd, true)
   177  
   178  	assert.Equal(t, err, nil, "ParsePacketToken should return nil")
   179  	assert.Equal(t, remoteContextID, pu2.managementID, "ParsePacketToken should get the correct remote contextID")
   180  	tags = claimsOnSynAckRcvd.CT.GetSlice()
   181  	assert.Equal(t, tags[0], "pu=pu2", "Receiver should receive correct tags")
   182  
   183  	claimsOnAckSend := &tokens.ConnectionClaims{
   184  		ID:       pu1.ManagementID(),
   185  		RMT:      remoteNonce,
   186  		RemoteID: remoteContextID,
   187  	}
   188  
   189  	ackToken, _ := pu1.tokenAccessor.CreateAckPacketToken(false, secretKey, claimsOnAckSend, encodedBuf[:])
   190  	claimsOnAckRcvd := &tokens.ConnectionClaims{}
   191  	err = pu2.tokenAccessor.ParseAckToken(false, secretKey, remoteNonce, ackToken, claimsOnAckRcvd)
   192  	assert.Equal(t, err, nil, "error should be nil")
   193  }
   194  
   195  func create314SynToken(p *PUContext, claimsHeader *claimsheader.ClaimsHeader) *synTokenInfo {
   196  
   197  	var datapathKeyPair ephemeralkeys.KeyAccessor
   198  	var err error
   199  	var nonce []byte
   200  
   201  	for {
   202  		datapathKeyPair, err = ephemeralkeys.New()
   203  
   204  		if err != nil {
   205  			// can generate errors only when the urandom io read buffer is full. retry till we succeed.
   206  			time.Sleep(10 * time.Millisecond)
   207  			continue
   208  		}
   209  
   210  		break
   211  	}
   212  
   213  	for {
   214  		// can generate errors only when the urandom io read buffer is full. retry till we succeed.
   215  		nonce, err = crypto.GenerateRandomBytes(16)
   216  		if err != nil {
   217  			continue
   218  		}
   219  
   220  		break
   221  	}
   222  
   223  	claims := &tokens.ConnectionClaims{
   224  		LCL: nonce,
   225  		CT:  p.CompressedTags(),
   226  		ID:  p.ManagementID(),
   227  	}
   228  
   229  	datapathSecret := ephemeralkeys.GetDatapathSecret()
   230  	var encodedBuf [tokens.ClaimsEncodedBufSize]byte
   231  
   232  	token, err := p.tokenAccessor.CreateSynPacketToken(claims, encodedBuf[:], nonce, claimsHeader, datapathSecret)
   233  	if err != nil {
   234  		zap.L().Error("Can not create syn packet token", zap.Error(err))
   235  		return nil
   236  	}
   237  
   238  	ephKeySignV1, err := p.tokenAccessor.Sign(datapathKeyPair.DecodingKeyV1(), datapathSecret.EncodingKey().(*ecdsa.PrivateKey))
   239  	if err != nil {
   240  		zap.L().Error("Can not sign the ephemeral public key", zap.Error(err))
   241  		return nil
   242  	}
   243  
   244  	ephKeySignV2, err := p.tokenAccessor.Sign(datapathKeyPair.DecodingKeyV2(), datapathSecret.EncodingKey().(*ecdsa.PrivateKey))
   245  
   246  	if err != nil {
   247  		zap.L().Error("Can not sign the ephemeral public key", zap.Error(err))
   248  		return nil
   249  	}
   250  
   251  	privateKey := datapathKeyPair.PrivateKey()
   252  	return &synTokenInfo{datapathSecret: datapathSecret,
   253  		privateKey:      privateKey,
   254  		publicKeyV1:     datapathKeyPair.DecodingKeyV1(),
   255  		publicKeyV2:     datapathKeyPair.DecodingKeyV2(),
   256  		publicKeySignV1: ephKeySignV1,
   257  		publicKeySignV2: ephKeySignV2,
   258  		token:           token}
   259  }
   260  
   261  func createV1SynToken(p *PUContext, claimsHeader *claimsheader.ClaimsHeader) *synTokenInfo {
   262  	var datapathKeyPair ephemeralkeys.KeyAccessor
   263  	var err error
   264  	var nonce []byte
   265  
   266  	for {
   267  		datapathKeyPair, err = ephemeralkeys.New()
   268  
   269  		if err != nil {
   270  			// can generate errors only when the urandom io read buffer is full. retry till we succeed.
   271  			time.Sleep(10 * time.Millisecond)
   272  			continue
   273  		}
   274  
   275  		break
   276  	}
   277  
   278  	for {
   279  		// can generate errors only when the urandom io read buffer is full. retry till we succeed.
   280  		nonce, err = crypto.GenerateRandomBytes(16)
   281  		if err != nil {
   282  			continue
   283  		}
   284  
   285  		break
   286  	}
   287  
   288  	claims := &tokens.ConnectionClaims{
   289  		LCL:   nonce,
   290  		DEKV1: datapathKeyPair.DecodingKeyV1(),
   291  		CT:    p.CompressedTags(),
   292  		ID:    p.ManagementID(),
   293  	}
   294  
   295  	datapathSecret := ephemeralkeys.GetDatapathSecret()
   296  	var encodedBuf [tokens.ClaimsEncodedBufSize]byte
   297  
   298  	token, err := p.tokenAccessor.CreateSynPacketToken(claims, encodedBuf[:], nonce, claimsHeader, datapathSecret)
   299  	if err != nil {
   300  		zap.L().Error("Can not create syn packet token", zap.Error(err))
   301  		return nil
   302  	}
   303  
   304  	ephKeySignV1, err := p.tokenAccessor.Sign(datapathKeyPair.DecodingKeyV1(), datapathSecret.EncodingKey().(*ecdsa.PrivateKey))
   305  	if err != nil {
   306  		zap.L().Error("Can not sign the ephemeral public key", zap.Error(err))
   307  		return nil
   308  	}
   309  
   310  	if err != nil {
   311  		zap.L().Error("Can not sign the ephemeral public key", zap.Error(err))
   312  		return nil
   313  	}
   314  
   315  	privateKey := datapathKeyPair.PrivateKey()
   316  	return &synTokenInfo{datapathSecret: datapathSecret,
   317  		privateKey:      privateKey,
   318  		publicKeyV1:     datapathKeyPair.DecodingKeyV1(),
   319  		publicKeySignV1: ephKeySignV1,
   320  		token:           token}
   321  }
   322  
   323  func Test_PUsFrom314To500(t *testing.T) {
   324  	_, _, scrts, _ := createCompactPKISecrets([]string{"kDMRXWckV9k6mGuJ", "xyz", "eJ1s03u72o6i"})
   325  	ephemeralkeys.UpdateDatapathSecrets(scrts)
   326  
   327  	setup := func() (*PUContext, *PUContext) {
   328  
   329  		fp := &policy.PUInfo{
   330  			Runtime: policy.NewPURuntimeWithDefaults(),
   331  			Policy:  policy.NewPUPolicy("", "/xyz", policy.AllowAll, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, nil, nil, []string{}, policy.EnforcerMapping, policy.Reject, policy.Reject),
   332  		}
   333  		ta1, _ := tokenaccessor.New("pu1", 1*time.Hour, nil)
   334  		pu1, _ := NewPU("pu1", fp, ta1, 24*time.Hour)
   335  		pu1.managementID = "2newPU1"
   336  		tags1 := policy.NewTagStore()
   337  		tags1.AppendKeyValue("pu", "pu1")
   338  		pu1.compressedTags = tags1
   339  
   340  		ta2, _ := tokenaccessor.New("pu2", 1*time.Hour, nil)
   341  		pu2, _ := NewPU("pu2", fp, ta2, 24*time.Hour)
   342  		pu2.managementID = "2newPU2"
   343  		tags2 := policy.NewTagStore()
   344  		tags2.AppendKeyValue("pu", "pu2")
   345  		pu2.compressedTags = tags2
   346  
   347  		return pu1, pu2
   348  	}
   349  
   350  	pu1, pu2 := setup()
   351  	token := create314SynToken(pu1, claimsheader.NewClaimsHeader())
   352  
   353  	claimsOnSynRcvd := &tokens.ConnectionClaims{}
   354  	ka, _ := ephemeralkeys.New()
   355  	secretKey, _, _, remoteNonce, remoteContextID, proto314, err := pu2.tokenAccessor.ParsePacketToken(ka.PrivateKey(), token.token, scrts, claimsOnSynRcvd, false)
   356  
   357  	assert.Equal(t, proto314, true, "protocol should be 314")
   358  	assert.Equal(t, err, nil, "ParsePacketToken should return nil")
   359  	assert.Equal(t, remoteContextID, pu1.managementID, "ParsePacketToken should get the correct remote contextID")
   360  	tags := claimsOnSynRcvd.CT.GetSlice()
   361  	assert.Equal(t, tags[0], "pu=pu1", "Receiver should receive correct tags")
   362  
   363  	claimsOnSynAckSend := &tokens.ConnectionClaims{
   364  		CT:       pu2.CompressedTags(),
   365  		LCL:      remoteNonce,
   366  		RMT:      remoteNonce,
   367  		ID:       pu2.ManagementID(),
   368  		RemoteID: pu1.managementID,
   369  	}
   370  
   371  	var encodedBuf [tokens.ClaimsEncodedBufSize]byte
   372  	tokenFromSynAck, _ := pu2.tokenAccessor.CreateSynAckPacketToken(true, claimsOnSynAckSend, encodedBuf[:], remoteNonce, claimsheader.NewClaimsHeader(), scrts, secretKey) //nolint
   373  
   374  	claimsOnSynAckRcvd := &tokens.ConnectionClaims{}
   375  	secretKey, _, _, remoteNonce, remoteContextID, proto314, err = pu1.tokenAccessor.ParsePacketToken(token.privateKey, tokenFromSynAck, scrts, claimsOnSynAckRcvd, true)
   376  
   377  	assert.Equal(t, proto314, true, "protocol should be 314")
   378  	assert.Equal(t, err, nil, "ParsePacketToken should return nil")
   379  	assert.Equal(t, remoteContextID, pu2.managementID, "ParsePacketToken should get the correct remote contextID")
   380  	tags = claimsOnSynAckRcvd.CT.GetSlice()
   381  	assert.Equal(t, tags[0], "pu=pu2", "Receiver should receive correct tags")
   382  
   383  	claimsOnAckSend := &tokens.ConnectionClaims{
   384  		ID:       pu1.ManagementID(),
   385  		RMT:      remoteNonce,
   386  		RemoteID: remoteContextID,
   387  	}
   388  
   389  	ackToken, _ := pu1.tokenAccessor.CreateAckPacketToken(true, secretKey, claimsOnAckSend, encodedBuf[:])
   390  	claimsOnAckRcvd := &tokens.ConnectionClaims{}
   391  	err = pu2.tokenAccessor.ParseAckToken(true, secretKey, remoteNonce, ackToken, claimsOnAckRcvd)
   392  	assert.Equal(t, err, nil, "error should be nil")
   393  }
   394  
   395  func Test_PUsFromV1ToV2(t *testing.T) {
   396  
   397  	_, _, scrts, _ := createCompactPKISecrets([]string{"kDMRXWckV9k6mGuJ", "xyz", "eJ1s03u72o6i"})
   398  	ephemeralkeys.UpdateDatapathSecrets(scrts)
   399  
   400  	setup := func() (*PUContext, *PUContext) {
   401  
   402  		fp := &policy.PUInfo{
   403  			Runtime: policy.NewPURuntimeWithDefaults(),
   404  			Policy:  policy.NewPUPolicy("", "/xyz", policy.AllowAll, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, nil, nil, []string{}, policy.EnforcerMapping, policy.Reject, policy.Reject),
   405  		}
   406  		ta1, _ := tokenaccessor.New("pu1", 1*time.Hour, nil)
   407  		pu1, _ := NewPU("pu1", fp, ta1, 24*time.Hour)
   408  		pu1.managementID = "newPU1"
   409  		tags1 := policy.NewTagStore()
   410  		tags1.AppendKeyValue("pu", "pu1")
   411  		pu1.compressedTags = tags1
   412  
   413  		ta2, _ := tokenaccessor.New("pu2", 1*time.Hour, nil)
   414  		pu2, _ := NewPU("pu2", fp, ta2, 24*time.Hour)
   415  		pu2.managementID = "newPU2"
   416  		tags2 := policy.NewTagStore()
   417  		tags2.AppendKeyValue("pu", "pu2")
   418  		pu2.compressedTags = tags2
   419  
   420  		return pu1, pu2
   421  	}
   422  
   423  	pu1, pu2 := setup()
   424  	token := createV1SynToken(pu1, claimsheader.NewClaimsHeader())
   425  
   426  	claimsOnSynRcvd := &tokens.ConnectionClaims{}
   427  	ka, _ := ephemeralkeys.New()
   428  	secretKey, _, _, remoteNonce, remoteContextID, _, err := pu2.tokenAccessor.ParsePacketToken(ka.PrivateKey(), token.token, scrts, claimsOnSynRcvd, false)
   429  
   430  	assert.Equal(t, err, nil, "ParsePacketToken should return nil")
   431  	assert.Equal(t, remoteContextID, pu1.managementID, "ParsePacketToken should get the correct remote contextID")
   432  	tags := claimsOnSynRcvd.CT.GetSlice()
   433  	assert.Equal(t, tags[0], "pu=pu1", "Receiver should receive correct tags")
   434  
   435  	ephKeySignV1, _ := pu2.tokenAccessor.Sign(ka.DecodingKeyV1(), scrts.EncodingKey().(*ecdsa.PrivateKey)) //nolint
   436  
   437  	claimsOnSynAckSend := &tokens.ConnectionClaims{
   438  		CT:       pu2.CompressedTags(),
   439  		LCL:      remoteNonce,
   440  		RMT:      remoteNonce,
   441  		DEKV1:    ka.DecodingKeyV1(),
   442  		SDEKV1:   ephKeySignV1,
   443  		ID:       pu2.ManagementID(),
   444  		RemoteID: pu1.managementID,
   445  	}
   446  
   447  	var encodedBuf [tokens.ClaimsEncodedBufSize]byte
   448  	tokenFromSynAck, _ := pu2.tokenAccessor.CreateSynAckPacketToken(false, claimsOnSynAckSend, encodedBuf[:], remoteNonce, claimsheader.NewClaimsHeader(), scrts, secretKey) //nolint
   449  
   450  	claimsOnSynAckRcvd := &tokens.ConnectionClaims{}
   451  	secretKey, _, _, remoteNonce, remoteContextID, _, err = pu1.tokenAccessor.ParsePacketToken(token.privateKey, tokenFromSynAck, scrts, claimsOnSynAckRcvd, true)
   452  
   453  	assert.Equal(t, err, nil, "ParsePacketToken should return nil")
   454  	assert.Equal(t, remoteContextID, pu2.managementID, "ParsePacketToken should get the correct remote contextID")
   455  	tags = claimsOnSynAckRcvd.CT.GetSlice()
   456  	assert.Equal(t, tags[0], "pu=pu2", "Receiver should receive correct tags")
   457  
   458  	claimsOnAckSend := &tokens.ConnectionClaims{
   459  		ID:       pu1.ManagementID(),
   460  		RMT:      remoteNonce,
   461  		RemoteID: remoteContextID,
   462  	}
   463  
   464  	ackToken, _ := pu1.tokenAccessor.CreateAckPacketToken(false, secretKey, claimsOnAckSend, encodedBuf[:])
   465  	claimsOnAckRcvd := &tokens.ConnectionClaims{}
   466  	err = pu2.tokenAccessor.ParseAckToken(false, secretKey, remoteNonce, ackToken, claimsOnAckRcvd)
   467  	assert.Equal(t, err, nil, "error should be nil")
   468  }
   469  
   470  func Test_PUSearch(t *testing.T) {
   471  
   472  	Convey("When I call PU Search", t, func() {
   473  
   474  		portRange80, _ := portspec.NewPortSpec(80, 85, nil)
   475  		portRange90, _ := portspec.NewPortSpec(90, 100, nil)
   476  
   477  		tagSelectorList := policy.TagSelectorList{
   478  			policy.TagSelector{
   479  				Clause: []policy.KeyValueOperator{
   480  					{
   481  						Key:      "app",
   482  						Value:    []string{"web"},
   483  						ID:       "asfasfasdasd",
   484  						Operator: policy.Equal,
   485  					},
   486  					{
   487  						Key:       "@sys:port",
   488  						Value:     []string{"TCP"},
   489  						ID:        "",
   490  						Operator:  policy.Equal,
   491  						PortRange: portRange80,
   492  					},
   493  				},
   494  				Policy: &policy.FlowPolicy{
   495  					PolicyID: "2",
   496  					Action:   policy.Accept,
   497  				},
   498  			},
   499  			policy.TagSelector{
   500  				Clause: []policy.KeyValueOperator{
   501  					{
   502  						Key:      "app",
   503  						Value:    []string{"web"},
   504  						ID:       "asfasfasdasd",
   505  						Operator: policy.Equal,
   506  					},
   507  					{
   508  						Key:       "@sys:port",
   509  						Value:     []string{"TCP"},
   510  						ID:        "",
   511  						Operator:  policy.Equal,
   512  						PortRange: portRange90,
   513  					},
   514  				},
   515  				Policy: &policy.FlowPolicy{
   516  					PolicyID: "2",
   517  					Action:   policy.Accept,
   518  				},
   519  			},
   520  		}
   521  
   522  		d := policy.NewPUPolicy(
   523  			"id",
   524  			"/abc",
   525  			policy.AllowAll,
   526  			nil,
   527  			nil,
   528  			nil,
   529  			nil,
   530  			tagSelectorList,
   531  			nil,
   532  			nil,
   533  			nil,
   534  			nil,
   535  			0,
   536  			0,
   537  			nil,
   538  			nil,
   539  			[]string{},
   540  			policy.EnforcerMapping,
   541  			policy.Reject|policy.Log,
   542  			policy.Reject|policy.Log,
   543  		)
   544  
   545  		fp := &policy.PUInfo{
   546  			Runtime: policy.NewPURuntimeWithDefaults(),
   547  			Policy:  d,
   548  		}
   549  
   550  		pu, _ := NewPU("pu1", fp, nil, 24*time.Hour)
   551  
   552  		tags := policy.NewTagStore()
   553  		tags.AppendKeyValue("app", "web")
   554  		tags.AppendKeyValue(constants.PortNumberLabelString, "TCP/85")
   555  
   556  		report, flow := pu.SearchRcvRules(tags)
   557  
   558  		Convey("The action should be Accept when port is 85", func() {
   559  			So(flow, ShouldNotBeNil)
   560  			So(report, ShouldNotBeNil)
   561  			So(flow.Action, ShouldEqual, policy.Accept)
   562  			So(report.Action, ShouldEqual, policy.Accept)
   563  			So(flow, ShouldNotBeNil)
   564  		})
   565  
   566  		tags = policy.NewTagStore()
   567  		tags.AppendKeyValue("app", "web")
   568  		tags.AppendKeyValue(constants.PortNumberLabelString, "TCP/98")
   569  
   570  		report, flow = pu.SearchRcvRules(tags)
   571  
   572  		Convey("The action should be Accept when port is 98", func() {
   573  			So(flow, ShouldNotBeNil)
   574  			So(report, ShouldNotBeNil)
   575  			So(flow.Action, ShouldEqual, policy.Accept)
   576  			So(report.Action, ShouldEqual, policy.Accept)
   577  			So(flow, ShouldNotBeNil)
   578  		})
   579  
   580  		tags = policy.NewTagStore()
   581  		tags.AppendKeyValue("app", "web")
   582  		tags.AppendKeyValue(constants.PortNumberLabelString, "TCP/101")
   583  
   584  		report, flow = pu.SearchRcvRules(tags)
   585  
   586  		Convey("The action should be Reject when port is 101", func() {
   587  			So(flow, ShouldNotBeNil)
   588  			So(report, ShouldNotBeNil)
   589  			So(flow.Action, ShouldEqual, policy.Reject|policy.Log)
   590  			So(report.Action, ShouldEqual, policy.Reject|policy.Log)
   591  			So(flow, ShouldNotBeNil)
   592  		})
   593  
   594  	})
   595  }