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

     1  // +build !windows
     2  
     3  package pkiverifier
     4  
     5  import (
     6  	"crypto/ecdsa"
     7  	"testing"
     8  	"time"
     9  
    10  	. "github.com/smartystreets/goconvey/convey"
    11  	"go.aporeto.io/enforcerd/trireme-lib/utils/crypto"
    12  )
    13  
    14  var (
    15  	keyPEM = `-----BEGIN EC PRIVATE KEY-----
    16  MHcCAQEEIPkiHqtH372JJdAG/IxJlE1gv03cdwa8Lhg2b3m/HmbyoAoGCCqGSM49
    17  AwEHoUQDQgAEAfAL+AfPj/DnxrU6tUkEyzEyCxnflOWxhouy1bdzhJ7vxMb1vQ31
    18  8ZbW/WvMN/ojIXqXYrEpISoojznj46w64w==
    19  -----END EC PRIVATE KEY-----`
    20  	caPool = `-----BEGIN CERTIFICATE-----
    21  MIIBhTCCASwCCQC8b53yGlcQazAKBggqhkjOPQQDAjBLMQswCQYDVQQGEwJVUzEL
    22  MAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NKQzEQMA4GA1UECgwHVHJpcmVtZTEPMA0G
    23  A1UEAwwGdWJ1bnR1MB4XDTE2MDkyNzIyNDkwMFoXDTI2MDkyNTIyNDkwMFowSzEL
    24  MAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTSkMxEDAOBgNVBAoM
    25  B1RyaXJlbWUxDzANBgNVBAMMBnVidW50dTBZMBMGByqGSM49AgEGCCqGSM49AwEH
    26  A0IABJxneTUqhbtgEIwpKUUzwz3h92SqcOdIw3mfQkMjg3Vobvr6JKlpXYe9xhsN
    27  rygJmLhMAN9gjF9qM9ybdbe+m3owCgYIKoZIzj0EAwIDRwAwRAIgC1fVMqdBy/o3
    28  jNUje/Hx0fZF9VDyUK4ld+K/wF3QdK4CID1ONj/Kqinrq2OpjYdkgIjEPuXoOoR1
    29  tCym8dnq4wtH
    30  -----END CERTIFICATE-----
    31  -----BEGIN CERTIFICATE-----
    32  MIIB3jCCAYOgAwIBAgIJALsW7pyC2ERQMAoGCCqGSM49BAMCMEsxCzAJBgNVBAYT
    33  AlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0pDMRAwDgYDVQQKDAdUcmlyZW1l
    34  MQ8wDQYDVQQDDAZ1YnVudHUwHhcNMTYwOTI3MjI0OTAwWhcNMjYwOTI1MjI0OTAw
    35  WjBLMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NKQzEQMA4G
    36  A1UECgwHVHJpcmVtZTEPMA0GA1UEAwwGdWJ1bnR1MFkwEwYHKoZIzj0CAQYIKoZI
    37  zj0DAQcDQgAE4c2Fd7XeIB1Vfs51fWwREfLLDa55J+NBalV12CH7YEAnEXjl47aV
    38  cmNqcAtdMUpf2oz9nFVI81bgO+OSudr3CqNQME4wHQYDVR0OBBYEFOBftuI09mmu
    39  rXjqDyIta1gT8lqvMB8GA1UdIwQYMBaAFOBftuI09mmurXjqDyIta1gT8lqvMAwG
    40  A1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAMylAHhbFA0KqhXIFiXNpEbH
    41  JKaELL6UXXdeQ5yup8q+AiEAh5laB9rbgTymjaANcZ2YzEZH4VFS3CKoSdVqgnwC
    42  dW4=
    43  -----END CERTIFICATE-----`
    44  
    45  	certPEM = `-----BEGIN CERTIFICATE-----
    46  MIIBhjCCASwCCQCPCdgp39gHJTAKBggqhkjOPQQDAjBLMQswCQYDVQQGEwJVUzEL
    47  MAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NKQzEQMA4GA1UECgwHVHJpcmVtZTEPMA0G
    48  A1UEAwwGdWJ1bnR1MB4XDTE2MDkyNzIyNDkwMFoXDTI2MDkyNTIyNDkwMFowSzEL
    49  MAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTSkMxEDAOBgNVBAoM
    50  B1RyaXJlbWUxDzANBgNVBAMMBnVidW50dTBZMBMGByqGSM49AgEGCCqGSM49AwEH
    51  A0IABAHwC/gHz4/w58a1OrVJBMsxMgsZ35TlsYaLstW3c4Se78TG9b0N9fGW1v1r
    52  zDf6IyF6l2KxKSEqKI854+OsOuMwCgYIKoZIzj0EAwIDSAAwRQIgQwQn0jnK/XvD
    53  KxgQd/0pW5FOAaB41cMcw4/XVlphO1oCIQDlGie+WlOMjCzrV0Xz+XqIIi1pIgPT
    54  IG7Nv+YlTVp5qA==
    55  -----END CERTIFICATE-----`
    56  )
    57  
    58  func TestNewConfig(t *testing.T) {
    59  	Convey("When I create a new PKI configuration", t, func() {
    60  		key, cert, _, err := crypto.LoadAndVerifyECSecrets([]byte(keyPEM), []byte(certPEM), []byte(caPool))
    61  		So(err, ShouldBeNil)
    62  
    63  		Convey("When I use NewPKIIssuer with valid keys, it should succeed ", func() {
    64  			p := NewPKIIssuer(key).(*tokenManager)
    65  			So(p, ShouldNotBeNil)
    66  			So(p.validity, ShouldEqual, 0)
    67  			So(p.privateKey, ShouldEqual, key)
    68  			So(p.publicKeys, ShouldBeNil)
    69  		})
    70  
    71  		Convey("When I use NewPKIVerifier valid keys, it should succeed ", func() {
    72  			pkiPublicKey := &PKIPublicKey{PublicKey: cert.PublicKey.(*ecdsa.PublicKey)}
    73  			p := NewPKIVerifier([]*PKIPublicKey{pkiPublicKey}, -1).(*tokenManager)
    74  			So(p, ShouldNotBeNil)
    75  			So(p.validity, ShouldEqual, defaultValidity*time.Second)
    76  			So(p.privateKey, ShouldBeNil)
    77  			So(p.publicKeys, ShouldResemble, []*PKIPublicKey{pkiPublicKey})
    78  		})
    79  		Convey("When I use NewPKIVerifier valid keys with a custom validity, it should succeed ", func() {
    80  			pkiPublicKey := &PKIPublicKey{PublicKey: cert.PublicKey.(*ecdsa.PublicKey)}
    81  			p := NewPKIVerifier([]*PKIPublicKey{pkiPublicKey}, 10*time.Second).(*tokenManager)
    82  			So(p, ShouldNotBeNil)
    83  			So(p.validity, ShouldEqual, 10*time.Second)
    84  			So(p.privateKey, ShouldBeNil)
    85  			So(p.publicKeys, ShouldResemble, []*PKIPublicKey{pkiPublicKey})
    86  		})
    87  	})
    88  }
    89  
    90  func TestCreateAndVerify(t *testing.T) {
    91  	Convey("Given a valid verifier", t, func() {
    92  		key, cert, _, err := crypto.LoadAndVerifyECSecrets([]byte(keyPEM), []byte(certPEM), []byte(caPool))
    93  		So(err, ShouldBeNil)
    94  		p := NewPKIIssuer(key)
    95  		pkiPublicKey := &PKIPublicKey{PublicKey: cert.PublicKey.(*ecdsa.PublicKey)}
    96  		v := NewPKIVerifier([]*PKIPublicKey{pkiPublicKey}, -1).(*tokenManager)
    97  		So(p, ShouldNotBeNil)
    98  		Convey("When I create a token", func() {
    99  			token, err1 := p.CreateTokenFromCertificate(cert, []string{"sometag"})
   100  			So(err1, ShouldBeNil)
   101  			rxtoken, err2 := v.Verify(token)
   102  			So(err2, ShouldBeNil)
   103  			So(*rxtoken.PublicKey.X, ShouldResemble, *cert.PublicKey.(*ecdsa.PublicKey).X)
   104  			So(*rxtoken.PublicKey.Y, ShouldResemble, *cert.PublicKey.(*ecdsa.PublicKey).Y)
   105  			So(rxtoken.PublicKey.Curve, ShouldResemble, cert.PublicKey.(*ecdsa.PublicKey).Curve)
   106  			So(rxtoken.Tags, ShouldResemble, []string{"sometag"})
   107  		})
   108  	})
   109  
   110  	Convey("Given a valid verifier", t, func() {
   111  		key, cert, _, err := crypto.LoadAndVerifyECSecrets([]byte(keyPEM), []byte(certPEM), []byte(caPool))
   112  		So(err, ShouldBeNil)
   113  		p := NewPKIIssuer(key)
   114  		pkiPublicKey := &PKIPublicKey{PublicKey: cert.PublicKey.(*ecdsa.PublicKey)}
   115  		v := NewPKIVerifier([]*PKIPublicKey{pkiPublicKey}, -1).(*tokenManager)
   116  		So(p, ShouldNotBeNil)
   117  		Convey("When I a receive a bad token, I should get an error", func() {
   118  			token, err1 := p.CreateTokenFromCertificate(cert, []string{})
   119  			So(err1, ShouldBeNil)
   120  			token = token[:len(token)-10]
   121  			_, err2 := v.Verify(token)
   122  			So(err2, ShouldNotBeNil)
   123  		})
   124  	})
   125  
   126  	Convey("Given an invalid verifier", t, func() {
   127  		key, cert, _, err := crypto.LoadAndVerifyECSecrets([]byte(keyPEM), []byte(certPEM), []byte(caPool))
   128  		So(err, ShouldBeNil)
   129  		p := NewPKIIssuer(key)
   130  		pkiPublicKey := &PKIPublicKey{PublicKey: nil}
   131  		v := NewPKIVerifier([]*PKIPublicKey{pkiPublicKey}, -1).(*tokenManager)
   132  		So(p, ShouldNotBeNil)
   133  		Convey("When I a receive a valid token, I should get an error", func() {
   134  			token, err1 := p.CreateTokenFromCertificate(cert, []string{})
   135  			So(err1, ShouldBeNil)
   136  			_, err2 := v.Verify(token)
   137  			So(err2, ShouldNotBeNil)
   138  		})
   139  	})
   140  }
   141  
   142  func TestCaching(t *testing.T) {
   143  	Convey("Given a valid verifier with a zero timer for the cache", t, func() {
   144  		key, cert, _, err := crypto.LoadAndVerifyECSecrets([]byte(keyPEM), []byte(certPEM), []byte(caPool))
   145  		So(err, ShouldBeNil)
   146  		p := NewPKIIssuer(key)
   147  		pkiPublicKey := &PKIPublicKey{PublicKey: cert.PublicKey.(*ecdsa.PublicKey)}
   148  		v := NewPKIVerifier([]*PKIPublicKey{pkiPublicKey}, 1*time.Second).(*tokenManager)
   149  
   150  		So(p, ShouldNotBeNil)
   151  
   152  		Convey("When I receive a token", func() {
   153  			token, err1 := p.CreateTokenFromCertificate(cert, []string{})
   154  			So(err1, ShouldBeNil)
   155  			_, err2 := v.Verify(token)
   156  			So(err2, ShouldBeNil)
   157  
   158  			Convey("The cache should have the token ", func() {
   159  				_, err := v.keycache.Get(string(token))
   160  				So(err, ShouldBeNil)
   161  				_, err2 := v.Verify(token)
   162  				So(err2, ShouldBeNil)
   163  			})
   164  
   165  			Convey("The cache should not have the token after 2 seconds ", func() {
   166  				time.Sleep(2 * time.Second)
   167  				_, err := v.keycache.Get(string(token))
   168  				So(err, ShouldNotBeNil)
   169  			})
   170  		})
   171  	})
   172  }