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 // }