github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/utils/crypto/crypto_test.go (about)

     1  // +build !windows
     2  
     3  package crypto
     4  
     5  import (
     6  	"errors"
     7  	"testing"
     8  
     9  	. "github.com/smartystreets/goconvey/convey"
    10  )
    11  
    12  const (
    13  	caPool = `-----BEGIN CERTIFICATE-----
    14  MIIBhTCCASwCCQC8b53yGlcQazAKBggqhkjOPQQDAjBLMQswCQYDVQQGEwJVUzEL
    15  MAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NKQzEQMA4GA1UECgwHVHJpcmVtZTEPMA0G
    16  A1UEAwwGdWJ1bnR1MB4XDTE2MDkyNzIyNDkwMFoXDTI2MDkyNTIyNDkwMFowSzEL
    17  MAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTSkMxEDAOBgNVBAoM
    18  B1RyaXJlbWUxDzANBgNVBAMMBnVidW50dTBZMBMGByqGSM49AgEGCCqGSM49AwEH
    19  A0IABJxneTUqhbtgEIwpKUUzwz3h92SqcOdIw3mfQkMjg3Vobvr6JKlpXYe9xhsN
    20  rygJmLhMAN9gjF9qM9ybdbe+m3owCgYIKoZIzj0EAwIDRwAwRAIgC1fVMqdBy/o3
    21  jNUje/Hx0fZF9VDyUK4ld+K/wF3QdK4CID1ONj/Kqinrq2OpjYdkgIjEPuXoOoR1
    22  tCym8dnq4wtH
    23  -----END CERTIFICATE-----
    24  -----BEGIN CERTIFICATE-----
    25  MIIB3jCCAYOgAwIBAgIJALsW7pyC2ERQMAoGCCqGSM49BAMCMEsxCzAJBgNVBAYT
    26  AlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0pDMRAwDgYDVQQKDAdUcmlyZW1l
    27  MQ8wDQYDVQQDDAZ1YnVudHUwHhcNMTYwOTI3MjI0OTAwWhcNMjYwOTI1MjI0OTAw
    28  WjBLMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NKQzEQMA4G
    29  A1UECgwHVHJpcmVtZTEPMA0GA1UEAwwGdWJ1bnR1MFkwEwYHKoZIzj0CAQYIKoZI
    30  zj0DAQcDQgAE4c2Fd7XeIB1Vfs51fWwREfLLDa55J+NBalV12CH7YEAnEXjl47aV
    31  cmNqcAtdMUpf2oz9nFVI81bgO+OSudr3CqNQME4wHQYDVR0OBBYEFOBftuI09mmu
    32  rXjqDyIta1gT8lqvMB8GA1UdIwQYMBaAFOBftuI09mmurXjqDyIta1gT8lqvMAwG
    33  A1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAMylAHhbFA0KqhXIFiXNpEbH
    34  JKaELL6UXXdeQ5yup8q+AiEAh5laB9rbgTymjaANcZ2YzEZH4VFS3CKoSdVqgnwC
    35  dW4=
    36  -----END CERTIFICATE-----`
    37  	certPEM = `-----BEGIN CERTIFICATE-----
    38  MIIBhjCCASwCCQCPCdgp39gHJTAKBggqhkjOPQQDAjBLMQswCQYDVQQGEwJVUzEL
    39  MAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NKQzEQMA4GA1UECgwHVHJpcmVtZTEPMA0G
    40  A1UEAwwGdWJ1bnR1MB4XDTE2MDkyNzIyNDkwMFoXDTI2MDkyNTIyNDkwMFowSzEL
    41  MAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTSkMxEDAOBgNVBAoM
    42  B1RyaXJlbWUxDzANBgNVBAMMBnVidW50dTBZMBMGByqGSM49AgEGCCqGSM49AwEH
    43  A0IABAHwC/gHz4/w58a1OrVJBMsxMgsZ35TlsYaLstW3c4Se78TG9b0N9fGW1v1r
    44  zDf6IyF6l2KxKSEqKI854+OsOuMwCgYIKoZIzj0EAwIDSAAwRQIgQwQn0jnK/XvD
    45  KxgQd/0pW5FOAaB41cMcw4/XVlphO1oCIQDlGie+WlOMjCzrV0Xz+XqIIi1pIgPT
    46  IG7Nv+YlTVp5qA==
    47  -----END CERTIFICATE-----`
    48  )
    49  
    50  // TestComputeVerifyHMAC tests the compute and verify of HMAC functions
    51  func TestComputeVerifyHMAC(t *testing.T) {
    52  	Convey("Given a token and a key", t, func() {
    53  
    54  		token := make([]byte, 256)
    55  		for i := uint8(0); i < 255; i++ {
    56  			token[i] = i
    57  		}
    58  
    59  		key := make([]byte, 32)
    60  		for i := uint8(0); i < 32; i++ {
    61  			key[i] = i
    62  		}
    63  
    64  		Convey("When I sign the token with the key", func() {
    65  			expectedMac, err := ComputeHmac256(token, key)
    66  			So(err, ShouldBeNil)
    67  			So(expectedMac, ShouldNotBeNil)
    68  
    69  			Convey("I should be able to verify the token with the same key", func() {
    70  				verified := VerifyHmac(token, expectedMac, key)
    71  				So(verified, ShouldBeTrue)
    72  			})
    73  
    74  			Convey("If I provide the worng key, I should fail verification", func() {
    75  				fakeKey := make([]byte, 32)
    76  				verified := VerifyHmac(token, expectedMac, fakeKey)
    77  				So(verified, ShouldBeFalse)
    78  			})
    79  
    80  			Convey("If I provide the wright key, but I havae the wrong signature, I should fail verification", func() {
    81  				failedMac := make([]byte, 32)
    82  				verified := VerifyHmac(token, failedMac, key)
    83  				So(verified, ShouldBeFalse)
    84  			})
    85  		})
    86  	})
    87  }
    88  
    89  // TestRandomString tests the random string generation function and the random byte generation
    90  func TestRandomString(t *testing.T) {
    91  	Convey("Given a string length of 16", t, func() {
    92  		length := 16
    93  		Convey("I should be able to generate two random strings that are not equal", func() {
    94  			string1, err1 := GenerateRandomString(length)
    95  			string2, err2 := GenerateRandomString(length)
    96  			So(err1, ShouldBeNil)
    97  			So(err2, ShouldBeNil)
    98  			So(string1, ShouldNotEqual, string2)
    99  		})
   100  	})
   101  	Convey("Given a string length of 32", t, func() {
   102  		length := 16
   103  		Convey("I should be able to generate two random strings that are not equal", func() {
   104  			string1, err1 := GenerateRandomString(length)
   105  			string2, err2 := GenerateRandomString(length)
   106  			So(err1, ShouldBeNil)
   107  			So(err2, ShouldBeNil)
   108  			So(string1, ShouldNotEqual, string2)
   109  		})
   110  	})
   111  }
   112  
   113  // TestFuncLoadEllipticCurve
   114  func TestFuncLoadEllipticCurve(t *testing.T) {
   115  	Convey("Given a valid EC key", t, func() {
   116  		keyPEM := `-----BEGIN EC PRIVATE KEY-----
   117  MHcCAQEEIPkiHqtH372JJdAG/IxJlE1gv03cdwa8Lhg2b3m/HmbyoAoGCCqGSM49
   118  AwEHoUQDQgAEAfAL+AfPj/DnxrU6tUkEyzEyCxnflOWxhouy1bdzhJ7vxMb1vQ31
   119  8ZbW/WvMN/ojIXqXYrEpISoojznj46w64w==
   120  -----END EC PRIVATE KEY-----`
   121  		Convey("I should be able to load the key", func() {
   122  			key, err := LoadEllipticCurveKey([]byte(keyPEM))
   123  			So(key, ShouldNotBeNil)
   124  			So(err, ShouldBeNil)
   125  		})
   126  	})
   127  
   128  	Convey("Given an invalid PEM BLOCK", t, func() {
   129  		keyPEM := ""
   130  		Convey("I should get an error", func() {
   131  			_, err := LoadEllipticCurveKey([]byte(keyPEM))
   132  			So(err, ShouldNotBeNil)
   133  		})
   134  	})
   135  
   136  	Convey("Given an invalid Key file", t, func() {
   137  		keyPEM := `-----BEGIN EC PRIVATE KEY-----
   138  -----END EC PRIVATE KEY-----`
   139  		Convey("I should get an error", func() {
   140  			_, err := LoadEllipticCurveKey([]byte(keyPEM))
   141  			So(err, ShouldNotBeNil)
   142  		})
   143  	})
   144  }
   145  
   146  // TestFuncLoadRootCertificates test the loading of root certs in a cert pool
   147  func TestFuncLoadRootCertificates(t *testing.T) {
   148  	Convey("Given a valid certificate chain", t, func() {
   149  
   150  		Convey("I should be able to get a valid certificate chain", func() {
   151  			roots := LoadRootCertificates([]byte(caPool))
   152  			So(roots, ShouldNotBeNil)
   153  			So(len(roots.Subjects()), ShouldEqual, 2)
   154  		})
   155  	})
   156  }
   157  
   158  // TestFuncLoadAndVerifyCertificate
   159  func TestLoadAndVerifyCertificate(t *testing.T) {
   160  	Convey("Given a valid certificate chain", t, func() {
   161  		roots := LoadRootCertificates([]byte(caPool))
   162  		So(roots, ShouldNotBeNil)
   163  		So(len(roots.Subjects()), ShouldEqual, 2)
   164  
   165  		Convey("Given a certificate signed by the intermediatery", func() {
   166  			Convey("I should be able to load and verify the certificate", func() {
   167  				cert, err := LoadAndVerifyCertificate([]byte(certPEM), roots)
   168  				So(cert, ShouldNotBeNil)
   169  				So(err, ShouldBeNil)
   170  			})
   171  		})
   172  	})
   173  
   174  	Convey("Given the root CA certificate only ", t, func() {
   175  		rootCA := `
   176  -----BEGIN CERTIFICATE-----
   177  MIIB3jCCAYOgAwIBAgIJALsW7pyC2ERQMAoGCCqGSM49BAMCMEsxCzAJBgNVBAYT
   178  AlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0pDMRAwDgYDVQQKDAdUcmlyZW1l
   179  MQ8wDQYDVQQDDAZ1YnVudHUwHhcNMTYwOTI3MjI0OTAwWhcNMjYwOTI1MjI0OTAw
   180  WjBLMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NKQzEQMA4G
   181  A1UECgwHVHJpcmVtZTEPMA0GA1UEAwwGdWJ1bnR1MFkwEwYHKoZIzj0CAQYIKoZI
   182  zj0DAQcDQgAE4c2Fd7XeIB1Vfs51fWwREfLLDa55J+NBalV12CH7YEAnEXjl47aV
   183  cmNqcAtdMUpf2oz9nFVI81bgO+OSudr3CqNQME4wHQYDVR0OBBYEFOBftuI09mmu
   184  rXjqDyIta1gT8lqvMB8GA1UdIwQYMBaAFOBftuI09mmurXjqDyIta1gT8lqvMAwG
   185  A1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAMylAHhbFA0KqhXIFiXNpEbH
   186  JKaELL6UXXdeQ5yup8q+AiEAh5laB9rbgTymjaANcZ2YzEZH4VFS3CKoSdVqgnwC
   187  dW4=
   188  -----END CERTIFICATE-----`
   189  		roots := LoadRootCertificates([]byte(rootCA))
   190  		So(roots, ShouldNotBeNil)
   191  		So(len(roots.Subjects()), ShouldEqual, 1)
   192  
   193  		Convey("Given a certificate signed by the intermediatery", func() {
   194  			Convey("I should be able to fail to verify the certificate ", func() {
   195  				cert, err := LoadAndVerifyCertificate([]byte(certPEM), roots)
   196  				So(cert, ShouldBeNil)
   197  				So(err, ShouldNotBeNil)
   198  			})
   199  		})
   200  	})
   201  
   202  	Convey("Given a good CA ", t, func() {
   203  		goodCA := `-----BEGIN CERTIFICATE-----
   204  MIIBhTCCASwCCQC8b53yGlcQazAKBggqhkjOPQQDAjBLMQswCQYDVQQGEwJVUzEL
   205  MAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NKQzEQMA4GA1UECgwHVHJpcmVtZTEPMA0G
   206  A1UEAwwGdWJ1bnR1MB4XDTE2MDkyNzIyNDkwMFoXDTI2MDkyNTIyNDkwMFowSzEL
   207  MAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTSkMxEDAOBgNVBAoM
   208  B1RyaXJlbWUxDzANBgNVBAMMBnVidW50dTBZMBMGByqGSM49AgEGCCqGSM49AwEH
   209  A0IABJxneTUqhbtgEIwpKUUzwz3h92SqcOdIw3mfQkMjg3Vobvr6JKlpXYe9xhsN
   210  rygJmLhMAN9gjF9qM9ybdbe+m3owCgYIKoZIzj0EAwIDRwAwRAIgC1fVMqdBy/o3
   211  jNUje/Hx0fZF9VDyUK4ld+K/wF3QdK4CID1ONj/Kqinrq2OpjYdkgIjEPuXoOoR1
   212  tCym8dnq4wtH
   213  -----END CERTIFICATE-----`
   214  
   215  		roots := LoadRootCertificates([]byte(goodCA))
   216  		So(roots, ShouldNotBeNil)
   217  		So(len(roots.Subjects()), ShouldEqual, 1)
   218  
   219  		Convey("Given a bad certificate ", func() {
   220  			badCA := `-----BEGIN CERTIFICATE-----
   221  MAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NKQzEQMA4GA1UECgwHVHJpcmVtZTEPMA0G
   222  A1UEAwwGdWJ1bnR1MB4XDTE2MDkyNzIyNDkwMFoXDTI2MDkyNTIyNDkwMFowSzEL
   223  MAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTSkMxEDAOBgNVBAoM
   224  B1RyaXJlbWUxDzANBgNVBAMMBnVidW50dTBZMBMGByqGSM49AgEGCCqGSM49AwEH
   225  A0IABAHwC/gHz4/w58a1OrVJBMsxMgsZ35TlsYaLstW3c4Se78TG9b0N9fGW1v1r
   226  zDf6IyF6l2KxKSEqKI854+OsOuMwCgYIKoZIzj0EAwIDSAAwRQIgQwQn0jnK/XvD
   227  KxgQd/0pW5FOAaB41cMcw4/XVlphO1oCIQDlGie+WlOMjCzrV0Xz+XqIIi1pIgPT
   228  IG7Nv+YlTVp5qA==
   229  -----END CERTIFICATE-----`
   230  			Convey("I should be able to fail to verify the certificate ", func() {
   231  				cert, err := LoadAndVerifyCertificate([]byte(badCA), roots)
   232  				So(cert, ShouldBeNil)
   233  				So(err, ShouldNotBeNil)
   234  			})
   235  		})
   236  	})
   237  
   238  	Convey("Given bad certificate   ", t, func() {
   239  
   240  		Convey("Where the certificate block is bad  ", func() {
   241  			emptyCA := ``
   242  			Convey("I should be able to fail to verify the certificate ", func() {
   243  				cert, err := LoadAndVerifyCertificate([]byte(emptyCA), nil)
   244  				So(cert, ShouldBeNil)
   245  				So(err, ShouldNotBeNil)
   246  			})
   247  		})
   248  	})
   249  }
   250  
   251  // TestLoadAndVerifyECSecrets
   252  func TestLoadAndVerifyECSecrets(t *testing.T) {
   253  
   254  	Convey("Given a valid EC key", t, func() {
   255  		keyPEM := `-----BEGIN EC PRIVATE KEY-----
   256  MHcCAQEEIPkiHqtH372JJdAG/IxJlE1gv03cdwa8Lhg2b3m/HmbyoAoGCCqGSM49
   257  AwEHoUQDQgAEAfAL+AfPj/DnxrU6tUkEyzEyCxnflOWxhouy1bdzhJ7vxMb1vQ31
   258  8ZbW/WvMN/ojIXqXYrEpISoojznj46w64w==
   259  -----END EC PRIVATE KEY-----`
   260  		Convey("I should be able to load the key", func() {
   261  			key, err := LoadEllipticCurveKey([]byte(keyPEM))
   262  			So(key, ShouldNotBeNil)
   263  			So(err, ShouldBeNil)
   264  		})
   265  
   266  		Convey("Given a valid certificate chain", func() {
   267  			roots := LoadRootCertificates([]byte(caPool))
   268  			So(roots, ShouldNotBeNil)
   269  			So(len(roots.Subjects()), ShouldEqual, 2)
   270  
   271  			Convey("Given a certificate signed by the intermediatery", func() {
   272  				Convey("I should be able to load and verify the certificate", func() {
   273  					cert, err := LoadAndVerifyCertificate([]byte(certPEM), roots)
   274  					So(cert, ShouldNotBeNil)
   275  					So(err, ShouldBeNil)
   276  				})
   277  
   278  				Convey("Given I have valid EC key, certificate chain and signed certificate", func() {
   279  					key, cert, certPool, err := LoadAndVerifyECSecrets([]byte(keyPEM), []byte(certPEM), []byte(caPool))
   280  
   281  					Convey("I should be able to load and verify all the certificates and keys in the right data structures", func() {
   282  						So(key, ShouldNotBeNil)
   283  						So(cert, ShouldNotBeNil)
   284  						So(certPool, ShouldNotBeNil)
   285  						So(err, ShouldBeNil)
   286  					})
   287  				})
   288  
   289  				Convey("Given I have invalid EC key, valid certificate chain and signed certificate", func() {
   290  					invalidKeyPEM := `-----BEGIN EC PRIVATE KEY-----
   291  			-----END EC PRIVATE KEY-----`
   292  					key, cert, certPool, err := LoadAndVerifyECSecrets([]byte(invalidKeyPEM), []byte(certPEM), []byte(caPool))
   293  
   294  					Convey("I should be able to fail verifying the EC key", func() {
   295  						So(key, ShouldBeNil)
   296  						So(cert, ShouldBeNil)
   297  						So(certPool, ShouldBeNil)
   298  						So(err, ShouldResemble, errors.New("LoadElliticCurveKey bad pem block: -----BEGIN EC PRIVATE KEY-----\n\t\t\t-----END EC PRIVATE KEY-----"))
   299  					})
   300  				})
   301  
   302  				Convey("Given I have valid EC key, invalid certificate chain and valid signed certificate", func() {
   303  					invalidCaPool := `-----BEGIN CERTIFICATE-----
   304  			-----END CERTIFICATE-----`
   305  					key, cert, certPool, err := LoadAndVerifyECSecrets([]byte(keyPEM), []byte(certPEM), []byte(invalidCaPool))
   306  
   307  					Convey("I should be able to fail loading the certificate pool", func() {
   308  						So(key, ShouldBeNil)
   309  						So(cert, ShouldBeNil)
   310  						So(certPool, ShouldBeNil)
   311  						So(err, ShouldResemble, errors.New("unable to load root certificate pool"))
   312  					})
   313  				})
   314  
   315  				Convey("Given I have valid EC key, certificate chain and invalid signed certificate", func() {
   316  					invalidCertPEM := `-----BEGIN CERTIFICATE-----
   317  		-----END CERTIFICATE-----`
   318  					key, cert, certPool, err := LoadAndVerifyECSecrets([]byte(keyPEM), []byte(invalidCertPEM), []byte(caPool))
   319  
   320  					Convey("I should be able to fail verifying certificate (bad certificate)", func() {
   321  						So(key, ShouldBeNil)
   322  						So(cert, ShouldBeNil)
   323  						So(certPool, ShouldBeNil)
   324  						So(err, ShouldResemble, errors.New("unable to parse pem block: -----BEGIN CERTIFICATE-----\n\t\t-----END CERTIFICATE-----"))
   325  					})
   326  				})
   327  			})
   328  		})
   329  	})
   330  }
   331  
   332  // func TestPublicKeyEncDec(t *testing.T) {
   333  
   334  // 	privateKey1, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   335  // 	encPub1 := EncodePublicKey(&privateKey1.PublicKey)
   336  // 	decPub1, _ := DecodePublicKey(encPub1)
   337  
   338  // 	pubKeyEq1 := reflect.DeepEqual(privateKey1.PublicKey, *decPub1)
   339  
   340  // 	assert.Equal(t, pubKeyEq1, true, "public key1 should be equal")
   341  // }