istio.io/istio@v0.0.0-20240520182934-d79c90f27776/security/pkg/pki/util/crypto_test.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package util 16 17 import ( 18 "crypto" 19 "crypto/ecdsa" 20 "crypto/ed25519" 21 "crypto/elliptic" 22 "crypto/rand" 23 "crypto/rsa" 24 "crypto/x509" 25 "reflect" 26 "strings" 27 "testing" 28 ) 29 30 const ( 31 csr = ` 32 -----BEGIN CERTIFICATE REQUEST----- 33 MIIBoTCCAQoCAQAwEzERMA8GA1UEChMISnVqdSBvcmcwgZ8wDQYJKoZIhvcNAQEB 34 BQADgY0AMIGJAoGBANFf06eqiDx0+qD/xBAR5aMwwgaBOn6TPfSy96vOxLTsfkTg 35 ir/vb8UG+F5hO6yxF+z2BgzD8LwcbKnxahoPq/aWGLw3Umcqm4wxgWKHxvtYSQDG 36 w4zpmKOqgkagxbx32JXDlMpi6adUVHNvB838CiUys6IkVB0obGHnre8zmCLdAgMB 37 AAGgTjBMBgkqhkiG9w0BCQ4xPzA9MDsGA1UdEQQ0MDKGMHNwaWZmZTovL3Rlc3Qu 38 Y29tL25hbWVzcGFjZS9ucy9zZXJ2aWNlYWNjb3VudC9zYTANBgkqhkiG9w0BAQsF 39 AAOBgQCw9dL6xRQSjdYKt7exqlTJliuNEhw/xDVGlNUbDZnT0uL3zXI//Z8tsejn 40 8IFzrDtm0Z2j4BmBzNMvYBKL/4JPZ8DFywOyQqTYnGtHIkt41CNjGfqJRk8pIqVC 41 hKldzzeCKNgztEvsUKVqltFZ3ZYnkj/8/Cg8zUtTkOhHOjvuig== 42 -----END CERTIFICATE REQUEST-----` 43 44 keyRSA = ` 45 -----BEGIN RSA PRIVATE KEY----- 46 MIIEowIBAAKCAQEAw/OBAAhDu58f0HkJlJBtb42Jp9EECC+WYEOVEdM/Y9fqcoSF 47 b19NxztVqy0r/aW8pCO3DZ2EYIA3Y9pYasDfhsIl9lhQkvEwk/05iL6oNrZ45Bgs 48 iSK+R5OlO9pXtj6HF948qFTDYbYVqki3rAWSSYeGpQ+/s/xcIIIKH5ozKs7DTqR8 49 svQ6t7Hxg0vYSUCHfJo25yIvoo8XGZxrFWOZDXfHHC22q8kuuxT82bdQo7KzYhgn 50 uujyzIZYqgG9BuUmB6UYdvuDRRDz4HDfERSFFxZbTAaMPNgCRvQnkPS0DJO0XZW2 51 T9m3bQvaqTgFI/capuhhgRcP0UrStJKZO7LVHQIDAQABAoIBAFLw0v2Mgf78j57S 52 XLfBmlDJfCbIVgiQ+/mrIYH2BLLiRZ5LcZ9+m5FlEBHwgNpQONTROT5OGiYun0No 53 vFwTX4nOy/rFzvUjmghJ+vxilxjxi6IgiVlSl2/8ksgO12mQdeYob0xg9IJ7bBgz 54 x2rMwOrWrqtXSzGH9AbehCJ0RowrUUjTujnow8WrDVS0cjPIl9c1eQDIDlHCUskC 55 iGMYYfJtB1nkdw1Kkp1YVmCYqwzVENi6+Hx66j/oOtGteTelwFmclc7JIK7liKEZ 56 xnDbgVTkIp9nSszpHStWikwh/srCWI7trC/k0viViZQLOd/64CyJ/sf8uZDzsG7f 57 hoiK3pECgYEAxF/d7QcDWaXCBkw4yC8ozqp6KTcA8thVuBK0Adtpzuf9t8h+B7V2 58 wlkSEs4A3YiUnxolEh1XOT+0u3uGfawlhFgXxEEHeBq+Lz6PIbWuVSl4PiWo8vtj 59 9MoBYRPtJelhHkBfjunqqaFwdRQQvXjmCsQfx4UAhBxdXvc2kTR/y08CgYEA/3K8 60 DKXldQliScqkG+Acj6nNgugecLYjCHgmAglHX6jwDuTVqNF3cv3DF5bZ4/nIbDsk 61 WooVhS4AEFYWceqmTveGsJNuDMoRSWNwDFRBu5Iq6LxneKiXp9vuZ4U4xZNejrgx 62 la7w1hQs92qCloY4Jxw9Ls3zKub4vC26CfJwzdMCgYBGw0T1ZNGQPGruWgkcGeJa 63 lpPuxiNRXyOEcTjscmRuaqrCzzybCokA/5fDrvgg3Fax/nndTTVhK9O0u457Os1K 64 I3RtBAHtBbYC0EhDnXR0u7zYqDl5VZ1vWFum38dVIgQdIpVMqn4lIkej6Ncfb7F1 65 r7bD7umAsbfzwKGpMYHbgQKBgQDL03vzR6hIc71mjffWekOv6lieXKJ1Yw+fIWeK 66 dmbqEH3EFJnbg5AhRBSYTPj9bICcw7AlQksbonHQlzB/ozEij2V8nZbRQ6b5fQuZ 67 +t0cUuxEGpkhcLzZ5qZbGbUMCaQIkzaVbiqjVyPuI6Ghg+VoZ6L2JsUh9XyBgqcQ 68 as/RmwKBgGPB8PHYHyz0km8LxM/GPstcoO4Ls5coS3MX2EBDKGqWOIOtLKz0azc7 69 R4beF5BJE6ulhLig4fkOWH4CIvw2Y1/22GJE/fYjUTRMD57ZdYuKqSyMNxwqiolw 70 xGSDfnFvR13RCqeUdlQofVYpolqrSobOyOVfQv2ksnPPsC87NISM 71 -----END RSA PRIVATE KEY-----` 72 73 keyInvalidRSA = ` 74 -----BEGIN RSA PRIVATE KEY----- 75 -----END RSA PRIVATE KEY-----` 76 77 keyECDSA = ` 78 -----BEGIN EC PRIVATE KEY----- 79 MGgCAQEEHBMUyVWFKTW4TwtwCmIAxdpsBFn0MV7tGeSA32CgBwYFK4EEACGhPAM6 80 AATCkAx7whb2k3xWm+UjlFWFiV11oYmIdYgXqiAQkiz7fEq6QFhsjjCizeGzAlhT 81 TmngRSxv/dSvGA== 82 -----END EC PRIVATE KEY-----` 83 84 keyInvalidECDSA = ` 85 -----BEGIN EC PRIVATE KEY----- 86 -----END EC PRIVATE KEY-----` 87 88 keyPKCS8RSA = ` 89 -----BEGIN PRIVATE KEY----- 90 MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC5iMw+Cvt0ZAnj 91 l5piKgyoFIlCAD2FeKd0CQaUA9sHk7XuWAXUAHWQrNXRIG/d9uZBedOwFQ/D8GCR 92 m5uQTTZC/4cww6pXvrVvX3DYe7H3hF8g3cDsHoYuR51LHzFR1lAe/y0XFaRw18Vm 93 WNFLnUozEeq1nT0CAyw0iXGa22ptZA3M1G9JJjDrENT6adI/N/19XH9fMiQOOOrT 94 zerC9DRVouXgxDsXUz2H25XT3YWu7nVs/ic57BRc3JU4JfYbVR8Br2+lAgPFvLFs 95 /HfX2BuvHC64sseIOVfXL7a/EaOVQhD9NKL7K+5faX21JAfN40f+qwfNLJrrUjHu 96 7UMpZbJVAgMBAAECggEBAJQ6RarfzUuMzRXGvjHlFF2IoqxXUs96uJYMy/OfLPNd 97 wIEeU/GvOD4Qx3afqqA0LHttIIHSIdlSB2TtZBiih1J5ogGEoWge1geXwalDEckF 98 OZchc4txS5RX5MPqtNWEGljZV6XUxZ7d1DjThssZa/lnPBRC/kXIUR3cHSYyXFHt 99 vA4vY4tVmH1TDUY51A64qKO5dg/Jupn1AHVnoU8eGGD31pISmlZdy64rBMdx9Ac5 100 u30rGP4RWR9YCSZRFtoxL2d0VoEdKAx1qN0/rPYPNUK1EIFO8kW4voNlUfyGDTLX 101 TdYBX5Stmm3ws6MAoJJKdpBLWmiJgqOjaiYlf/7y+zUCgYEA5mogVNiba2KRP85O 102 QOH2ugY1dPiiJLm6QTub7Aygy8lc6WQGa2TXBUpqGYp4rs0wjBnkhtIoErZM8cxu 103 ENj8dGBikfEJq95NcOMx6wsQYKRWX9JwDzNrLyUCtKK+B3kO8daHzHWTPB7mNkHF 104 Y91PZLmzSCdAsqxI5VHo0mzStMsCgYEAziLizDE4Q+IpNvzpGo+TxOJILTYdf1HC 105 OdoaWMKU1Hl6TyWGXon0/ZfAI+jxjT9sI4/Slr5ED86FT0iaIOcSgvl8PmbcvMrM 106 m3Nj/ZVM3EPzo8EW/LNFlZreheIuvuSwUvnzlWaWZdWJ5/z0M7Is05NsF2v5QlON 107 OVd/b3pVcV8CgYEAhIDTRvepqP9t9/t0FOvdLu0TIMk6tVP5QDo/WGeKsKaDv9O9 108 vVSoMmqwyS9QZ3WoTWk2ejGwydH8PbEKOrYNt/8VsEelACk+74Q32KrsKCdZZJFn 109 z9YJ9XqbK7XLAhEj/v8X6QRUP2aljN4V3XAPkCUabIvmMNnSsc2AzkG2ijECgYB6 110 BtTTo9928A8N6jHj81K6nmmzufFESZX8wUwPd0C7dx4cdE5S8MACzy6DE4bK4tyV 111 QLKdYgzQfqUUBhqXl7KxrhcKqcHKURNGgsySdSuGyQMV0VxWQ5nRslhAUWDyyFZJ 112 CIZVzuEBb6OvnWLCp5s5tG+sfdKUnPlhFJbv2y9xaQKBgCp1g3NtljkH1Olk+kFF 113 LwxpTxIxS/8jZIM6MpfcmLPyZVRrpUORgkphXvLVXub+anNqGbK0Cbc30KQGnFKD 114 PFsekZAmhgetPqL16MQSEZbXRSnGiklqQtew79S/yQDwZVCer8n1ABp5eZ2wsLgu 115 92ik2sTgTEhef6AgLeHcT5ne 116 -----END PRIVATE KEY-----` 117 118 keyInvalidPKCS8 = ` 119 -----BEGIN PRIVATE KEY----- 120 -----END PRIVATE KEY-----` 121 122 certRSA = ` 123 -----BEGIN CERTIFICATE----- 124 MIIC+zCCAeOgAwIBAgIQQ0vFSayWg4FQBBr1EpI5rzANBgkqhkiG9w0BAQsFADAT 125 MREwDwYDVQQKEwhKdWp1IG9yZzAeFw0xNzAzMTEwNjA0MDJaFw0xODAzMTEwNjA0 126 MDJaMBMxETAPBgNVBAoTCEp1anUgb3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A 127 MIIBCgKCAQEAw/OBAAhDu58f0HkJlJBtb42Jp9EECC+WYEOVEdM/Y9fqcoSFb19N 128 xztVqy0r/aW8pCO3DZ2EYIA3Y9pYasDfhsIl9lhQkvEwk/05iL6oNrZ45BgsiSK+ 129 R5OlO9pXtj6HF948qFTDYbYVqki3rAWSSYeGpQ+/s/xcIIIKH5ozKs7DTqR8svQ6 130 t7Hxg0vYSUCHfJo25yIvoo8XGZxrFWOZDXfHHC22q8kuuxT82bdQo7KzYhgnuujy 131 zIZYqgG9BuUmB6UYdvuDRRDz4HDfERSFFxZbTAaMPNgCRvQnkPS0DJO0XZW2T9m3 132 bQvaqTgFI/capuhhgRcP0UrStJKZO7LVHQIDAQABo0swSTAOBgNVHQ8BAf8EBAMC 133 BaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAUBgNVHREEDTAL 134 gglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAITDuqOhN1jwiA72qSWzOwuy 135 bMHPkUTUw2JfICtPS0AlfNNVJXREUi4KoX81ju126PGQeOTApWvS5Kkd6PbNqVH9 136 g3myAKrkyjewTfFtK5OOOQGzQT6lCEhKdZJusdqfAMl1heFJGnZ6GAi38ftdz2Z8 137 0LPyyIaVBvexNnTPrqoBqdtWyzjYIdMnsSNWJnldmWjwA76sW+vvlLvTONiT4unM 138 8ia4GGIw7GK4E/7qxl27q6pXdZkZgG53XItYiUJGAKeBJ2nQfXq0qSmtpHkF17Cu 139 hw25X3FJpzRq62JxTx5q6+M2c07g4dkbfMDp/TO7vF4SWruU6JBZj5MVDYn4PEA= 140 -----END CERTIFICATE-----` 141 142 certECDSA = ` 143 -----BEGIN CERTIFICATE----- 144 MIIBSzCB+qADAgECAhAzJszEACNBOHrsfSUJMPsHMAoGCCqGSM49BAMCMAsxCTAH 145 BgNVBAoTADAeFw0xNzAzMTMwNTE2NThaFw0xNzAzMTMwNTE2NThaMAsxCTAHBgNV 146 BAoTADBOMBAGByqGSM49AgEGBSuBBAAhAzoABMKQDHvCFvaTfFab5SOUVYWJXXWh 147 iYh1iBeqIBCSLPt8SrpAWGyOMKLN4bMCWFNOaeBFLG/91K8Yo0swSTAOBgNVHQ8B 148 Af8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAUBgNV 149 HREEDTALgglsb2NhbGhvc3QwCgYIKoZIzj0EAwIDQAAwPQIcY8lgBAAtFWtxmk9k 150 BB6nORpwdv4LVt/BFgLwWQIdAKvHn7cxBJ+aAC25rIumRNKDzP7PkV0HDbxtX+M= 151 -----END CERTIFICATE-----` 152 ) 153 154 var certChainValid = loadPEMFile("../testdata/cert-chain.pem") 155 156 func TestParsePemEncodedCertificate(t *testing.T) { 157 testCases := map[string]struct { 158 errMsg string 159 pem string 160 publicKeyAlgo x509.PublicKeyAlgorithm 161 }{ 162 "Invalid PEM string": { 163 errMsg: "invalid PEM encoded certificate", 164 pem: "invalid pem string", 165 }, 166 "Invalid certificate string": { 167 errMsg: "failed to parse X.509 certificate", 168 pem: keyECDSA, 169 }, 170 "Parse RSA certificate": { 171 publicKeyAlgo: x509.RSA, 172 pem: certRSA, 173 }, 174 "Parse ECDSA certificate": { 175 publicKeyAlgo: x509.ECDSA, 176 pem: certECDSA, 177 }, 178 } 179 180 for id, c := range testCases { 181 cert, err := ParsePemEncodedCertificate([]byte(c.pem)) 182 if c.errMsg != "" { 183 if err == nil { 184 t.Errorf("%s: no error is returned", id) 185 } else if c.errMsg != err.Error() { 186 t.Errorf(`%s: Unexpected error message: expected "%s" but got "%s"`, id, c.errMsg, err.Error()) 187 } 188 } else if cert.PublicKeyAlgorithm != c.publicKeyAlgo { 189 t.Errorf("%s: Unexpected public key algorithm: want %d but got %d", id, c.publicKeyAlgo, cert.PublicKeyAlgorithm) 190 } 191 } 192 } 193 194 func TestParsePemEncodedCertificateChain(t *testing.T) { 195 testCases := map[string]struct { 196 errMsg string 197 pem string 198 }{ 199 "Parse Certificate Chain": { 200 pem: certChainValid, 201 }, 202 "Invalid PEM string": { 203 pem: "Invalid PEM string", 204 errMsg: "invalid PEM encoded certificate", 205 }, 206 "Invalid certificate string": { 207 pem: keyRSA, 208 errMsg: "failed to parse X.509 certificate", 209 }, 210 } 211 212 for id, c := range testCases { 213 _, rootCertByte, err := ParsePemEncodedCertificateChain([]byte(c.pem)) 214 if c.errMsg != "" { 215 if err == nil { 216 t.Errorf("%s: no error is returned", id) 217 } else if c.errMsg != err.Error() { 218 t.Errorf(`%s: Unexpected error message: expected "%s" but got "%s"`, id, c.errMsg, err.Error()) 219 } 220 } else if len(rootCertByte) == 0 { 221 t.Errorf("%s: rootCertByte is nil", id) 222 } 223 } 224 } 225 226 func TestParsePemEncodedCSR(t *testing.T) { 227 testCases := map[string]struct { 228 algo x509.PublicKeyAlgorithm 229 errMsg string 230 pem string 231 }{ 232 "Invalid PEM string": { 233 errMsg: "certificate signing request is not properly encoded", 234 pem: "bad pem string", 235 }, 236 "Invalid CSR string": { 237 errMsg: "failed to parse X.509 certificate signing request", 238 pem: certECDSA, 239 }, 240 "Parse CSR": { 241 algo: x509.RSA, 242 pem: csr, 243 }, 244 } 245 246 for id, c := range testCases { 247 _, err := ParsePemEncodedCSR([]byte(c.pem)) 248 if c.errMsg != "" { 249 if err == nil { 250 t.Errorf(`%s: no error is returned, expected "%s"`, id, c.errMsg) 251 } else if c.errMsg != err.Error() { 252 t.Errorf(`%s: Unexpected error message: want "%s" but got "%s"`, id, c.errMsg, err.Error()) 253 } 254 } else if err != nil { 255 t.Errorf(`%s: Unexpected error: "%s"`, id, err) 256 } 257 } 258 } 259 260 func TestParsePemEncodedKey(t *testing.T) { 261 testCases := map[string]struct { 262 pem string 263 keyType reflect.Type 264 errMsg string 265 }{ 266 "Invalid PEM string": { 267 pem: "Invalid PEM string", 268 errMsg: "invalid PEM-encoded key", 269 }, 270 "Invalid PEM block type": { 271 pem: certRSA, 272 errMsg: "unsupported PEM block type for a private key: CERTIFICATE", 273 }, 274 "Parse RSA key": { 275 pem: keyRSA, 276 keyType: reflect.TypeOf(&rsa.PrivateKey{}), 277 }, 278 "Parse invalid RSA key": { 279 pem: keyInvalidRSA, 280 errMsg: "failed to parse the RSA private key", 281 }, 282 "Parse ECDSA key": { 283 pem: keyECDSA, 284 keyType: reflect.TypeOf(&ecdsa.PrivateKey{}), 285 }, 286 "Parse invalid ECDSA key": { 287 pem: keyInvalidECDSA, 288 errMsg: "failed to parse the ECDSA private key", 289 }, 290 "Parse PKCS8 key using RSA algorithm": { 291 pem: keyPKCS8RSA, 292 keyType: reflect.TypeOf(&rsa.PrivateKey{}), 293 }, 294 "Parse invalid PKCS8 key": { 295 pem: keyInvalidPKCS8, 296 errMsg: "failed to parse the PKCS8 private key", 297 }, 298 } 299 300 for id, c := range testCases { 301 key, err := ParsePemEncodedKey([]byte(c.pem)) 302 if c.errMsg != "" { 303 if err == nil { 304 t.Errorf(`%s: no error is returned, expected "%s"`, id, c.errMsg) 305 } else if !strings.HasPrefix(err.Error(), c.errMsg) { 306 t.Errorf(`%s: Unexpected error message: expected "%s" but got "%s"`, id, c.errMsg, err.Error()) 307 } 308 } else if err != nil { 309 t.Errorf(`%s: Unexpected error: "%s"`, id, err) 310 } else if keyType := reflect.TypeOf(key); keyType != c.keyType { 311 t.Errorf(`%s: Unmatched key type: expected "%v" but got "%v"`, id, c.keyType, keyType) 312 } 313 } 314 } 315 316 func TestGetRSAKeySize(t *testing.T) { 317 testCases := map[string]struct { 318 pem string 319 size int 320 errMsg string 321 }{ 322 "Success with RSA key": { 323 pem: keyRSA, 324 size: 2048, 325 }, 326 "Success with PKCS8RSA key": { 327 pem: keyPKCS8RSA, 328 size: 2048, 329 }, 330 "Failure with non-RSA key": { 331 pem: keyECDSA, 332 errMsg: "key type is not RSA: *ecdsa.PrivateKey", 333 }, 334 } 335 336 for id, c := range testCases { 337 key, err := ParsePemEncodedKey([]byte(c.pem)) 338 if err != nil { 339 t.Errorf("%s: failed to parse the Pem key.", id) 340 } 341 size, err := GetRSAKeySize(key) 342 if c.errMsg != "" { 343 if err == nil { 344 t.Errorf(`%s: no error is returned, expected error: "%s"`, id, c.errMsg) 345 } else if c.errMsg != err.Error() { 346 t.Errorf(`%s: Unexpected error message: expected "%s" but got "%s"`, id, c.errMsg, err.Error()) 347 } 348 } else if err != nil { 349 t.Errorf(`%s: Unexpected error: "%s"`, id, err) 350 } else if size != c.size { 351 t.Errorf(`%s: Unmatched key size: expected %v but got "%v"`, id, c.size, size) 352 } 353 } 354 } 355 356 func TestIsSupportedECPrivateKey(t *testing.T) { 357 _, ed25519PrivKey, _ := ed25519.GenerateKey(nil) 358 ecdsaPrivKeyP224, _ := ecdsa.GenerateKey(elliptic.P224(), rand.Reader) 359 ecdsaPrivKeyP256, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 360 ecdsaPrivKeyP384, _ := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) 361 ecdsaPrivKeyP521, _ := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) 362 363 cases := map[string]struct { 364 key crypto.PrivateKey 365 isErr bool 366 expectedCurve elliptic.Curve 367 }{ 368 "ECDSA-P224": { 369 key: ecdsaPrivKeyP224, 370 isErr: false, 371 expectedCurve: elliptic.P256(), 372 }, 373 "ECDSA-P256": { 374 key: ecdsaPrivKeyP256, 375 isErr: false, 376 expectedCurve: elliptic.P256(), 377 }, 378 "ECDSA-P384": { 379 key: ecdsaPrivKeyP384, 380 isErr: false, 381 expectedCurve: elliptic.P384(), 382 }, 383 "ECDSA-P512": { 384 key: ecdsaPrivKeyP521, 385 isErr: false, 386 expectedCurve: elliptic.P256(), 387 }, 388 "ED25519": { 389 key: ed25519PrivKey, 390 isErr: true, 391 expectedCurve: nil, 392 }, 393 } 394 395 for id, tc := range cases { 396 curve, err := GetEllipticCurve(&tc.key) 397 if tc.expectedCurve != curve { 398 t.Errorf("expected (%v) but received (%v)", tc.expectedCurve, curve) 399 } 400 if err != nil { 401 if !tc.isErr { 402 t.Errorf("%s: should be supported, but is failing", id) 403 } 404 } 405 } 406 } 407 408 func TestPemCertBytestoString(t *testing.T) { 409 // empty check 410 if len(PemCertBytestoString([]byte{})) != 0 { 411 t.Errorf("Empty call fails!") 412 } 413 414 certBytes := []byte(certECDSA) 415 certBytes = AppendCertByte(certBytes, []byte(certRSA)) 416 result := PemCertBytestoString(certBytes) 417 cert1 := strings.TrimSuffix(strings.TrimPrefix(certECDSA, "\n"), "\n") 418 cert2 := strings.TrimSuffix(strings.TrimPrefix(certRSA, "\n"), "\n") 419 if !reflect.DeepEqual(result, []string{cert1, cert2}) { 420 t.Errorf("Basic comparison fails!") 421 } 422 423 // check only first string passed if second is bogus 424 certBytes = []byte(certRSA) 425 certBytes = AppendCertByte(certBytes, []byte("Bogus")) 426 result = PemCertBytestoString(certBytes) 427 cert1 = strings.TrimSuffix(strings.TrimPrefix(certRSA, "\n"), "\n") 428 if !reflect.DeepEqual(result, []string{cert1}) { 429 t.Errorf("Bogus comparison fails!") 430 } 431 }