github.com/Venafi/vcert/v5@v5.10.2/pkg/certificate/certificate_test.go (about) 1 /* 2 * Copyright 2018 Venafi, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package certificate 18 19 import ( 20 "crypto" 21 "crypto/rand" 22 "crypto/rsa" 23 "crypto/x509" 24 "crypto/x509/pkix" 25 "encoding/asn1" 26 "encoding/pem" 27 "math/big" 28 "net" 29 "os" 30 "reflect" 31 "strings" 32 "testing" 33 "time" 34 35 "github.com/Venafi/vcert/v5/pkg/util" 36 ) 37 38 func getCertificateRequestForTest() *Request { 39 req := Request{} 40 req.Subject.CommonName = "vcert.test.vfidev.com" 41 req.Subject.Organization = []string{"Venafi, Inc."} 42 req.Subject.OrganizationalUnit = []string{"Engineering", "Automated Tests"} 43 req.Subject.Country = []string{"US"} 44 req.Subject.Locality = []string{"SLC"} 45 req.Subject.Province = []string{"Utah"} 46 47 host, _ := os.Hostname() 48 req.DNSNames = []string{host} 49 50 addrs, _ := net.InterfaceAddrs() 51 var ips []net.IP 52 for _, add := range addrs { 53 ip, _, _ := net.ParseCIDR(add.String()) 54 v4 := ip.To4() 55 if v4 != nil && !v4.IsLoopback() { 56 ips = append(ips, ip) 57 } 58 59 } 60 req.IPAddresses = ips 61 62 req.ExtKeyUsages = *NewExtKeyUsageSlice("ServerAuth") 63 64 return &req 65 } 66 67 func generateTestCertificate() (*x509.Certificate, crypto.Signer, error) { 68 req := getCertificateRequestForTest() 69 70 priv, err := GenerateECDSAPrivateKey(EllipticCurveP384) 71 if err != nil { 72 return nil, nil, err 73 } 74 75 certBytes, err := generateSelfSigned(req, x509.KeyUsageKeyEncipherment|x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, priv) 76 if err != nil { 77 return nil, nil, err 78 } 79 80 cert, err := x509.ParseCertificate(certBytes) 81 if err != nil { 82 return nil, nil, err 83 } 84 85 return cert, priv, nil 86 } 87 88 func generateSelfSigned(request *Request, ku x509.KeyUsage, eku []x509.ExtKeyUsage, privateKey crypto.Signer) ([]byte, error) { 89 notBefore := time.Now() 90 limit := new(big.Int).Lsh(big.NewInt(1), 128) 91 serial, _ := rand.Int(rand.Reader, limit) 92 93 certRequest := x509.Certificate{ 94 SerialNumber: serial, 95 } 96 certRequest.Subject = request.Subject 97 certRequest.DNSNames = request.DNSNames 98 certRequest.EmailAddresses = request.EmailAddresses 99 certRequest.IPAddresses = request.IPAddresses 100 certRequest.SignatureAlgorithm = request.SignatureAlgorithm 101 certRequest.ExtKeyUsage = eku 102 certRequest.NotBefore = notBefore.UTC() 103 if ku&x509.KeyUsageCertSign != x509.KeyUsageCertSign { 104 certRequest.NotAfter = certRequest.NotBefore.AddDate(0, 0, 90) 105 certRequest.IsCA = false 106 } else { 107 certRequest.NotAfter = certRequest.NotBefore.AddDate(0, 0, 180) 108 certRequest.IsCA = true 109 } 110 certRequest.BasicConstraintsValid = true 111 112 pub := publicKey(privateKey) 113 114 cert, err := x509.CreateCertificate(rand.Reader, &certRequest, &certRequest, pub, privateKey) 115 if err != nil { 116 cert = nil 117 } 118 119 return cert, err 120 } 121 122 func TestGenerateRSAPrivateKey(t *testing.T) { 123 priv, err := GenerateRSAPrivateKey(512) 124 if err != nil { 125 t.Fatalf("Error generating RSA Private Key\nError: %s", err) 126 } 127 128 err = priv.Validate() 129 if err != nil { 130 t.Fatalf("Error validating RSA Private Key\nError: %s", err) 131 } 132 } 133 134 func TestGenerateECDSAPrivateKey(t *testing.T) { 135 ellipticCurves := []EllipticCurve{EllipticCurveP256, EllipticCurveP384, EllipticCurveP521} 136 for _, curve := range ellipticCurves { 137 _, err := GenerateECDSAPrivateKey(curve) 138 if err != nil { 139 t.Fatalf("Error generating ECDSA Private Key\nError: %s", err) 140 } 141 } 142 } 143 144 func TestGenerateCertificateRequestWithRSAKey(t *testing.T) { 145 req := getCertificateRequestForTest() 146 var err error 147 req.PrivateKey, err = GenerateRSAPrivateKey(512) 148 if err != nil { 149 t.Fatalf("Error generating RSA Private Key\nError: %s", err) 150 } 151 152 err = req.GenerateCSR() 153 if err != nil { 154 t.Fatalf("Error generating Certificate Request\nError: %s", err) 155 } 156 157 pemBlock, _ := pem.Decode(req.GetCSR()) 158 if pemBlock == nil { 159 t.Fatalf("Failed to decode CSR as PEM") 160 } 161 162 parsedReq, err := x509.ParseCertificateRequest(pemBlock.Bytes) 163 if err != nil { 164 t.Fatalf("Error parsing generated Certificate Request\nError: %s", err) 165 } 166 167 err = parsedReq.CheckSignature() 168 if err != nil { 169 t.Fatalf("Error checking signature of generated Certificate Request\nError: %s", err) 170 } 171 172 validateExtendedKeyUsage(t, parsedReq) 173 } 174 175 func TestGenerateCertificateRequestWithECDSAKey(t *testing.T) { 176 req := getCertificateRequestForTest() 177 var err error 178 req.PrivateKey, err = GenerateECDSAPrivateKey(EllipticCurveP521) 179 if err != nil { 180 t.Fatalf("Error generating RSA Private Key\nError: %s", err) 181 } 182 183 err = req.GenerateCSR() 184 if err != nil { 185 t.Fatalf("Error generating Certificate Request\nError: %s", err) 186 } 187 188 pemBlock, _ := pem.Decode(req.GetCSR()) 189 if pemBlock == nil { 190 t.Fatalf("Failed to decode CSR as PEM") 191 } 192 193 parsedReq, err := x509.ParseCertificateRequest(pemBlock.Bytes) 194 if err != nil { 195 t.Fatalf("Error parsing generated Certificate Request\nError: %s", err) 196 } 197 198 err = parsedReq.CheckSignature() 199 if err != nil { 200 t.Fatalf("Error checking signature of generated Certificate Request\nError: %s", err) 201 } 202 } 203 204 func TestGenerateCertificateRequestWithED25519Key(t *testing.T) { 205 req := getCertificateRequestForTest() 206 var err error 207 req.PrivateKey, err = GenerateED25519PrivateKey() 208 if err != nil { 209 t.Fatalf("Error generating RSA Private Key\nError: %s", err) 210 } 211 212 err = req.GenerateCSR() 213 if err != nil { 214 t.Fatalf("Error generating Certificate Request\nError: %s", err) 215 } 216 217 pemBlock, _ := pem.Decode(req.GetCSR()) 218 if pemBlock == nil { 219 t.Fatalf("Failed to decode CSR as PEM") 220 } 221 222 parsedReq, err := x509.ParseCertificateRequest(pemBlock.Bytes) 223 if err != nil { 224 t.Fatalf("Error parsing generated Certificate Request\nError: %s", err) 225 } 226 227 err = parsedReq.CheckSignature() 228 if err != nil { 229 t.Fatalf("Error checking signature of generated Certificate Request\nError: %s", err) 230 } 231 } 232 233 func validateExtendedKeyUsage(t *testing.T, parsedReq *x509.CertificateRequest) { 234 if parsedReq.Extensions == nil { 235 t.Fatalf("No extensions found in generated Certificate Request") 236 } 237 238 var extKeyUsages pkix.Extension 239 for _, extension := range parsedReq.Extensions { 240 if extension.Id.Equal(ExtensionExtKeyUsageOid) { 241 extKeyUsages = extension 242 break 243 } 244 } 245 246 if extKeyUsages.Id == nil { 247 t.Fatalf("No extension Extended Key Usages found in generated Certificate Request") 248 } 249 250 var b []asn1.ObjectIdentifier 251 _, err := asn1.Unmarshal(extKeyUsages.Value, &b) 252 if err != nil { 253 panic(err) 254 } 255 256 if len(b) != 1 { 257 t.Fatalf("Invalid extension Extended Key Usages found in generated Certificate Request. It was expected only one but it was gotten %q", len(b)) 258 } 259 260 if !b[0].Equal(ExtKeyUsageServerAuthOid) { 261 t.Fatalf("Invalid extension Extended Key Usages found in generated Certificate Request. It was expected %q but it was gotten %q", ExtKeyUsageServerAuthOid, b[0]) 262 } 263 } 264 265 func TestEllipticCurveString(t *testing.T) { 266 curve := EllipticCurveP521 267 stringCurve := curve.String() 268 if stringCurve != "P521" { 269 t.Fatalf("Unexpected string value was returned. Expected: P521 Actual: %s", stringCurve) 270 } 271 curve = EllipticCurveP384 272 stringCurve = curve.String() 273 if stringCurve != "P384" { 274 t.Fatalf("Unexpected string value was returned. Expected: P384 Actual: %s", stringCurve) 275 } 276 curve = EllipticCurveP256 277 stringCurve = curve.String() 278 if stringCurve != "P256" { 279 t.Fatalf("Unexpected string value was returned. Expected: P256 Actual: %s", stringCurve) 280 } 281 } 282 283 func TestEllipticCurveSetByString(t *testing.T) { 284 curve := EllipticCurveDefault 285 curve.Set("P521") 286 if curve != EllipticCurveP521 { 287 t.Fatalf("Unexpected string value was returned. Expected: P521 Actual: %s", curve.String()) 288 } 289 curve.Set("P384") 290 if curve != EllipticCurveP384 { 291 t.Fatalf("Unexpected string value was returned. Expected: P384 Actual: %s", curve.String()) 292 } 293 curve.Set("P256") 294 if curve != EllipticCurveP256 { 295 t.Fatalf("Unexpected string value was returned. Expected: P256 Actual: %s", curve.String()) 296 } 297 curve.Set("p521") 298 if curve != EllipticCurveP521 { 299 t.Fatalf("Unexpected string value was returned. Expected: p521 Actual: %s", curve.String()) 300 } 301 curve.Set("p384") 302 if curve != EllipticCurveP384 { 303 t.Fatalf("Unexpected string value was returned. Expected: p384 Actual: %s", curve.String()) 304 } 305 curve.Set("p256") 306 if curve != EllipticCurveP256 { 307 t.Fatalf("Unexpected string value was returned. Expected: p256 Actual: %s", curve.String()) 308 } 309 } 310 311 func TestKeyTypeString(t *testing.T) { 312 keyType := KeyTypeECDSA 313 s := keyType.String() 314 if s != "ECDSA" { 315 t.Fatalf("Unexpected string value was returned. Expected: ECDSA Actual: %s", s) 316 } 317 keyType = KeyTypeRSA 318 s = keyType.String() 319 if s != "RSA" { 320 t.Fatalf("Unexpected string value was returned. Expected: RSA Actual: %s", s) 321 } 322 keyType = 5 323 s = keyType.String() 324 if s != "" { 325 t.Fatalf("Unexpected string value was returned. Expected: \"\" Actual: %s", s) 326 } 327 } 328 329 func TestKeyTypeSetByString(t *testing.T) { 330 keyType := KeyTypeRSA 331 keyType.Set("rsa", "") 332 if keyType != KeyTypeRSA { 333 t.Fatalf("Unexpected string value was returned. Expected: RSA Actual: %s", keyType.String()) 334 } 335 keyType.Set("RSA", "") 336 if keyType != KeyTypeRSA { 337 t.Fatalf("Unexpected string value was returned. Expected: RSA Actual: %s", keyType.String()) 338 } 339 keyType.Set("ecdsa", "") 340 if keyType != KeyTypeECDSA { 341 t.Fatalf("Unexpected string value was returned. Expected: ECDSA Actual: %s", keyType.String()) 342 } 343 keyType.Set("ECDSA", "p384") 344 if keyType != KeyTypeECDSA { 345 t.Fatalf("Unexpected string value was returned. Expected: ECDSA Actual: %s", keyType.String()) 346 } 347 keyType.Set("ECDSA", "p384") 348 if keyType != KeyTypeECDSA { 349 t.Fatalf("Unexpected string value was returned. Expected: ECDSA Actual: %s", keyType.String()) 350 } 351 keyType.Set("EC", "p384") 352 if keyType != KeyTypeECDSA { 353 t.Fatalf("Unexpected string value was returned. Expected: ECDSA Actual: %s", keyType.String()) 354 } 355 keyType.Set("EC", "ed25519") 356 if keyType != KeyTypeED25519 { 357 t.Fatalf("Unexpected string value was returned. Expected: ED25519 Actual: %s", keyType.String()) 358 } 359 } 360 361 func TestGetPrivateKeyPEMBock(t *testing.T) { 362 var priv crypto.Signer 363 priv, err := GenerateRSAPrivateKey(512) 364 if err != nil { 365 t.Fatalf("Error generating RSA Private Key\nError: %s", err) 366 } 367 368 p, err := GetPrivateKeyPEMBock(priv) 369 if err != nil { 370 t.Fatalf("Error: %s", err) 371 } 372 if p == nil { 373 t.Fatalf("GetPrivateKeyPEMBock returned nil for RSA key") 374 } 375 376 ellipticCurves := []EllipticCurve{EllipticCurveP256, EllipticCurveP384, EllipticCurveP521} 377 for _, curve := range ellipticCurves { 378 priv, err = GenerateECDSAPrivateKey(curve) 379 if err != nil { 380 t.Fatalf("Error generating ECDSA Private Key\nError: %s", err) 381 } 382 383 p, err = GetPrivateKeyPEMBock(priv) 384 if err != nil { 385 t.Fatalf("Error: %s", err) 386 } 387 if p == nil { 388 t.Fatalf("GetPrivateKeyPEMBock returned nil for ECDSA key") 389 } 390 } 391 } 392 393 func TestGetEncryptedPrivateKeyPEMBock(t *testing.T) { 394 var priv crypto.Signer 395 priv, err := GenerateRSAPrivateKey(512) 396 if err != nil { 397 t.Fatalf("Error generating RSA Private Key\nError: %s", err) 398 } 399 400 p, err := GetEncryptedPrivateKeyPEMBock(priv, []byte("something")) 401 if err != nil { 402 t.Fatalf("Error: %s", err) 403 } 404 if p == nil { 405 t.Fatalf("GetPrivateKeyPEMBock returned nil for RSA key") 406 } 407 408 encoded := pem.EncodeToMemory(p) 409 str, err := util.DecryptPkcs8PrivateKey(string(encoded), "something") 410 if err != nil { 411 t.Fatalf("Error: %s", err) 412 } 413 414 p, _ = pem.Decode([]byte(str)) 415 if p == nil { 416 t.Fatalf("missing private key PEM") 417 } 418 419 _, err = x509.ParsePKCS8PrivateKey(p.Bytes) 420 if err != nil { 421 t.Fatalf("Error: %s", err) 422 } 423 424 ellipticCurves := []EllipticCurve{EllipticCurveP256, EllipticCurveP384, EllipticCurveP521} 425 for _, curve := range ellipticCurves { 426 priv, err = GenerateECDSAPrivateKey(curve) 427 if err != nil { 428 t.Fatalf("Error generating ECDSA Private Key\nError: %s", err) 429 } 430 431 p, err = GetEncryptedPrivateKeyPEMBock(priv, []byte("something")) 432 if err != nil { 433 t.Fatalf("Error: %s", err) 434 } 435 if p == nil { 436 t.Fatalf("GetPrivateKeyPEMBock returned nil for ECDSA key") 437 } 438 439 strPem := string(pem.EncodeToMemory(p)) 440 441 decryptedKey, err := util.DecryptPkcs8PrivateKey(strPem, "something") 442 if err != nil { 443 t.Fatalf("Error: %s", err) 444 } 445 p, _ = pem.Decode([]byte(decryptedKey)) 446 _, err = x509.ParsePKCS8PrivateKey(p.Bytes) 447 if err != nil { 448 t.Fatalf("Error: %s", err) 449 } 450 } 451 } 452 453 func TestGetCertificatePEMBlock(t *testing.T) { 454 cert, _, err := generateTestCertificate() 455 if err != nil { 456 t.Fatalf("Error generating test certificate\nError: %s", err) 457 } 458 certPem := GetCertificatePEMBlock(cert.Raw) 459 if certPem == nil { 460 t.Fatalf("GetCertificatePEMBlock returned nil pem block") 461 } 462 } 463 464 func TestGetCertificateRequestPEMBlock(t *testing.T) { 465 certRequest := getCertificateRequestForTest() 466 var priv crypto.Signer 467 priv, err := GenerateRSAPrivateKey(512) 468 if err != nil { 469 t.Fatalf("Error generating RSA Private Key\nError: %s", err) 470 } 471 err = GenerateRequest(certRequest, priv) 472 if err != nil { 473 t.Fatalf("Error generating request\nError: %s", err) 474 } 475 csrPem := GetCertificateRequestPEMBlock(certRequest.GetCSR()) 476 if csrPem == nil { 477 t.Fatalf("GetCertificateRequestPEMBlock returned nil pem block") 478 } 479 } 480 481 func TestPublicKey(t *testing.T) { 482 priv, _ := GenerateRSAPrivateKey(512) 483 pub := PublicKey(priv) 484 if pub == nil { 485 t.Fatal("should return public key") 486 } 487 } 488 489 const ( 490 checkCertificatePrivateKeyRSAvalid = ` 491 -----BEGIN PRIVATE KEY----- 492 MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAKiD4hrY58XqeYEB 493 yIg14R6R2Ia/53cBSkNhzRn7Q9wDIzA8qJUkGNu8Oz0nE2V3LhDXsNM7B+IgO1LB 494 YRBgegCKHpQVsYlnNUmETbJSILEsbEZZLCaMBXC/xONKpJi9E3qyNr6vNvYxd12O 495 l9RN3tTl6NJG5gS8BAf8Z6X7r6bdAgMBAAECgYEAjpLGgiByOCkhk9yGZXfwd4S9 496 xYQnubAFvOzKMuk7iLG+29j2aPiZb4/aLusYpggnmWhj2tNe4BqVFnc2QDzf+qTO 497 fEmDm1mBnc0V+k0Rt99Wq9KPVMAm2EJBFrUGK7VGQ3H4B02kS+ywz6z25mebCzBT 498 JlA7m3jaUdGJQEEPXgECQQDcVwlQrTPOxkG6UX3wfqtSgby0nVPH1N7h+aIVRbZY 499 wfdXFsJEIv9ePly0S8MFLpxBNczR4Dqpm6ViEGkUEM+tAkEAw8mt5TAw9//38x0n 500 ZyeYhGrM0qOMHHLw5XhnaJPiJ4NyU96aspr+Ppv4Z550f+Z3dIGSKnDinQly1jL1 501 f21Z8QJBAKrR7y7UmG2d1icUNobULQ3x9tIvhlxN891NIxNK0GtPNOoXgtRALapq 502 voQomDDUSd9kTj4HkHMdb8Hu5wffYKECQA5NBfGusnT68m6Em6MyRjat4mYkYhCV 503 6LiqMct2udcvB8POh7gyEA4csGlJLrNE70bITBfjhPn5fbTdpgb3wtECQQC4dQBg 504 335myMx7IDWT/I6R7i0Rx+WY7XZ84PkTwTd0q78yIhRS/42rgwEBMkkxlSg5X2sb 505 Xjw3nEoRoeTEToar 506 -----END PRIVATE KEY----- 507 ` 508 checkCertificatePrivateKeyRSAinvalid = ` 509 -----BEGIN PRIVATE KEY----- 510 MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKOZvVaHHImhKD+r 511 RZXJYV8busd0g0uWBGMeK+VltyG8H/h/neyPmHoEh62P/3FG3UP7oOAAGfz3/yCW 512 hf7fHmNz1d6/HyCdQvD4kz/e9E6ty+k1iM5X6pGS97xPsObgHfyOgLn1/YdKvq81 513 yG+O/mtfqQEI2izYUAbhUtq3qbctAgMBAAECgYAumTzH56YmQYQAVp10Y67bcz+J 514 TlOTdQB85vwj1AwMjNQiaN8noWMR5jZrJmfg8QlXMtYI156PYmgF9Tnndc/mmVlg 515 ow9mqEWjXZoBLCP++EkAbQ8dwmuGJB9WzIWFvj6bnKUOJAqQpsXv/wOqcrO7RZb0 516 h2Wt/08tpuMZSYnUtQJBANIOKhCxJGjRbPgiczPFauuPi/kqSl1tLFbJfK0XBOvg 517 Dezwz4YZpkhj1ttM6JB8QcDHEOMZ3XJMu+m8TqAB4cMCQQDHYmL7FzFg8QGeeeUe 518 a4EVFSxmN45y2qSq2KyN0eaeuuV+fHjiLFyi+rZ+gA9xnyQFWcwTH+tFvcbi5aI7 519 WgRPAkAC2XBWo6CDz3tz7juz0xS9N0hFy/4QQF/emYMYcfx+Gp71vNqDzitERh5v 520 AR8Sfq0BqXGgMwSe/U17QTOr1fqzAkAFiwixbl2jElA3NbBW/ioiieooFVdSfh2h 521 2lBByRoeQ5fpwlAiCZWxukKkla7YO9Jmi66OwY5q6/HBkRzHhaMlAkAEeP1wnnnQ 522 F3iRLaRPmLtKf8sO1onEkSaQAq5p8/RFvNNwwqMh1t9wu9UYIefICoFsK0wAza9j 523 4qQY8qM+To1X 524 -----END PRIVATE KEY----- 525 ` 526 checkCertificateCSRRSA = ` 527 -----BEGIN CERTIFICATE REQUEST----- 528 MIIBrDCCARUCAQAwbDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxEjAQBgNV 529 BAcMCVNhbHQgTGFrZTEPMA0GA1UECgwGVmVuYWZpMQ8wDQYDVQQLDAZEZXZPcHMx 530 GDAWBgNVBAMMD3Rlc3QudmVuZGV2LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw 531 gYkCgYEAqIPiGtjnxep5gQHIiDXhHpHYhr/ndwFKQ2HNGftD3AMjMDyolSQY27w7 532 PScTZXcuENew0zsH4iA7UsFhEGB6AIoelBWxiWc1SYRNslIgsSxsRlksJowFcL/E 533 40qkmL0TerI2vq829jF3XY6X1E3e1OXo0kbmBLwEB/xnpfuvpt0CAwEAAaAAMA0G 534 CSqGSIb3DQEBCwUAA4GBAGsKm5fJ8Zm/j9XMPXhPYmOdiDj+9QlcFq7uRRqwpxo7 535 C507RR5Pj2zBRZRLJcc/bNTQFqnW92kIcvJ+YvrQl/GkEMKM2wds/RyMXRHtOJvZ 536 YQt6JtkAeQOMECJ7RRHrZiG+m2by2YAB2krthK2gJGSr80xWzZWzrgdwdTe2sxUG 537 -----END CERTIFICATE REQUEST----- 538 ` 539 chechCertificateRSACert = ` 540 -----BEGIN CERTIFICATE----- 541 MIICyjCCAbICCQDtS0qAZisbTTANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJV 542 UzENMAsGA1UECAwEVXRhaDESMBAGA1UEBwwJU2FsdCBMYWtlMQ8wDQYDVQQKDAZW 543 ZW5hZmkxDzANBgNVBAsMBkRldk9wczESMBAGA1UEAwwJVmVuYWZpIENBMB4XDTE5 544 MDMxNDE1MjAzMloXDTE5MDQxMzE1MjAzMlowbDELMAkGA1UEBhMCVVMxDTALBgNV 545 BAgMBFV0YWgxEjAQBgNVBAcMCVNhbHQgTGFrZTEPMA0GA1UECgwGVmVuYWZpMQ8w 546 DQYDVQQLDAZEZXZPcHMxGDAWBgNVBAMMD3Rlc3QudmVuZGV2LmNvbTCBnzANBgkq 547 hkiG9w0BAQEFAAOBjQAwgYkCgYEAqIPiGtjnxep5gQHIiDXhHpHYhr/ndwFKQ2HN 548 GftD3AMjMDyolSQY27w7PScTZXcuENew0zsH4iA7UsFhEGB6AIoelBWxiWc1SYRN 549 slIgsSxsRlksJowFcL/E40qkmL0TerI2vq829jF3XY6X1E3e1OXo0kbmBLwEB/xn 550 pfuvpt0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAMsuZogw+GE3ACQpULxxC3GFP 551 +3N91g79V5PBP9flBuMuNoC5sQdEFaRBYA7VAUc/0kwT9hbQsm6GO/PnuhDljkqB 552 2toPXTW5Okg93r0ZlTKrNWamsj3b5JQOB/dvjBx2c4VDzaD7lO0WMPaNbc0DV1Mm 553 5UGslmj7iZIMRmyV4Cvdq/1u3/GjjO8q7qglltYtCP79xAw78dCbhtbdFzCixJ+g 554 wNesasf48fL5jiH4gCwpzNij0ryhR0zglz+TsHRGVMef2CNFOw0PfkinQoaDI/Y+ 555 e/0CZ8Cg2oudlSulDRWzFJBwiCapeRfwkLkhO/pjd0ILvBk8DFzjwCFTpi2SpQ== 556 -----END CERTIFICATE----- 557 ` 558 chechCertificateRSACert2 = ` 559 -----BEGIN CERTIFICATE----- 560 MIICyjCCAbICCQDtS0qAZisbTjANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJV 561 UzENMAsGA1UECAwEVXRhaDESMBAGA1UEBwwJU2FsdCBMYWtlMQ8wDQYDVQQKDAZW 562 ZW5hZmkxDzANBgNVBAsMBkRldk9wczESMBAGA1UEAwwJVmVuYWZpIENBMB4XDTE5 563 MDMxNDE4MDMwMVoXDTE5MDQxMzE4MDMwMVowbDELMAkGA1UEBhMCVVMxDTALBgNV 564 BAgMBFV0YWgxEjAQBgNVBAcMCVNhbHQgTGFrZTEPMA0GA1UECgwGVmVuYWZpMQ8w 565 DQYDVQQLDAZEZXZPcHMxGDAWBgNVBAMMD3Rlc3QudmVuZGV2LmNvbTCBnzANBgkq 566 hkiG9w0BAQEFAAOBjQAwgYkCgYEAo5m9VocciaEoP6tFlclhXxu6x3SDS5YEYx4r 567 5WW3Ibwf+H+d7I+YegSHrY//cUbdQ/ug4AAZ/Pf/IJaF/t8eY3PV3r8fIJ1C8PiT 568 P970Tq3L6TWIzlfqkZL3vE+w5uAd/I6AufX9h0q+rzXIb47+a1+pAQjaLNhQBuFS 569 2repty0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAfb5V/rcEEsZ68rRaEerkvPCk 570 EiBMepUAzGrUFQyENiA2qoRuqKnOjhyzZ4uFiXFamiqCK0kjzUVraAYjzhGkH6AU 571 AxUKXh5fa9tkt0XsZCS1aTjuDYAPO2Ug62OejUoZtRjy+nGUM7dYku9syzhmQ+hK 572 AHu1RG+ZOtT13j3SAH0nkjEADzzsZhZWj/m5HtGQUY9ehAQhbTqn/M+aeGPxOdPt 573 Ys0kiIJWXXW4JpJLfwKE9VFERQdHVum0+j8dUfOfyo0clJLPcesBFQ4RRkituxnG 574 vDm5x5eZ/dsjYa8CcADBe/2KJBnldZW02o1/OqJ67m2Q1Y74hRTV5MGybpYx/w== 575 -----END CERTIFICATE----- 576 ` 577 ) 578 579 func TestRequest_CheckCertificate(t *testing.T) { 580 rsaPrivKeyInvalid := pemRSADecode(checkCertificatePrivateKeyRSAinvalid) 581 rsaPrivKeyValid := pemRSADecode(checkCertificatePrivateKeyRSAvalid) 582 583 cases := []struct { 584 name string 585 request Request 586 cert string 587 valid bool 588 errorMessage string 589 }{ 590 {"valid req", Request{KeyType: KeyTypeRSA, PrivateKey: rsaPrivKeyValid}, chechCertificateRSACert, true, ""}, 591 {"mismatched key type", Request{KeyType: KeyTypeECDSA, PrivateKey: rsaPrivKeyValid}, chechCertificateRSACert, false, "key type"}, 592 {"mismatched keys", Request{KeyType: KeyTypeRSA, PrivateKey: rsaPrivKeyInvalid}, chechCertificateRSACert, false, "key modulus"}, 593 {"valid csr", Request{csr: []byte(checkCertificateCSRRSA)}, chechCertificateRSACert, true, ""}, 594 {"csr mismatched keys", Request{csr: []byte(checkCertificateCSRRSA)}, chechCertificateRSACert2, false, "key modulus"}, 595 } 596 for i := range cases { 597 c := cases[i] 598 t.Run(c.name, func(t *testing.T) { 599 err := c.request.CheckCertificate(c.cert) 600 if c.valid && err != nil { 601 t.Fatalf("cert should be valid but checker found error: %s", err) 602 } 603 if !c.valid && err == nil { 604 t.Fatalf("certificate should failed but check returns that its valid") 605 } 606 if !c.valid && !strings.Contains(err.Error(), c.errorMessage) { 607 t.Fatalf("unexpected error '%s' (should conatins %s)", err.Error(), c.errorMessage) 608 } 609 }) 610 } 611 } 612 613 func Test_NewRequest(t *testing.T) { 614 rsaPk, err := GenerateRSAPrivateKey(512) 615 if err != nil { 616 t.Fatalf("Error generating RSA Private Key\nError: %s", err) 617 } 618 619 ecdsaPk, err := GenerateECDSAPrivateKey(EllipticCurveP256) 620 if err != nil { 621 t.Fatalf("Error generating ECDSA Private Key\nError: %s", err) 622 } 623 624 ed25519Pk, err := GenerateED25519PrivateKey() 625 if err != nil { 626 t.Fatalf("Error generating ECDSA Private Key\nError: %s", err) 627 } 628 629 cases := []struct { 630 name string 631 certificate *x509.Certificate 632 expRequest Request 633 }{ 634 { 635 name: "rsa key", 636 certificate: &x509.Certificate{ 637 PublicKey: rsaPk.Public(), 638 }, 639 expRequest: Request{KeyType: KeyTypeRSA, KeyLength: 512}, 640 }, 641 { 642 name: "ecdsa key", 643 certificate: &x509.Certificate{ 644 PublicKey: ecdsaPk.Public(), 645 }, 646 expRequest: Request{KeyType: KeyTypeECDSA, KeyCurve: EllipticCurveP256}, 647 }, 648 { 649 name: "ed25519 key", 650 certificate: &x509.Certificate{ 651 PublicKey: ed25519Pk.Public(), 652 }, 653 expRequest: Request{KeyType: KeyTypeED25519, KeyCurve: EllipticCurveED25519}, 654 }, 655 } 656 for _, c := range cases { 657 c := c 658 t.Run(c.name, func(t *testing.T) { 659 req := NewRequest(c.certificate) 660 if !reflect.DeepEqual(req, &c.expRequest) { 661 t.Fatalf("expected request to be %v, got %v", c.expRequest, req) 662 } 663 }) 664 } 665 } 666 667 func TestRequest_SetCSR_and_GetCSR(t *testing.T) { 668 checkCN := "setcsr.example.com" 669 certificateRequest := x509.CertificateRequest{} 670 certificateRequest.Subject.CommonName = checkCN 671 pk, err := GenerateRSAPrivateKey(512) 672 if err != nil { 673 t.Fatalf("Error generating RSA Private Key\nError: %s", err) 674 } 675 676 csr, err := x509.CreateCertificateRequest(rand.Reader, &certificateRequest, pk) 677 if err != nil { 678 csr = nil 679 } 680 681 rawCsr := csr 682 683 pemCsr := pem.EncodeToMemory(GetCertificateRequestPEMBlock(csr)) 684 r := Request{} 685 686 csrs := [][]byte{rawCsr, pemCsr} 687 for _, csr := range csrs { 688 err = r.SetCSR(csr) 689 if err != nil { 690 t.Fatal(err) 691 } 692 gotCsr := r.GetCSR() 693 block, _ := pem.Decode(gotCsr) 694 cert, err := x509.ParseCertificateRequest(block.Bytes) 695 if err != nil { 696 t.Fatal(err) 697 } 698 if cert.Subject.CommonName != checkCN { 699 t.Fatalf("%s =! %s", cert.Subject.CommonName, checkCN) 700 } 701 err = r.SetCSR(pemCsr) 702 if err != nil { 703 t.Fatal(err) 704 } 705 t.Logf("Got cn %s from csr %s", cert.Subject.CommonName, gotCsr) 706 } 707 708 } 709 710 func pemRSADecode(priv string) *rsa.PrivateKey { 711 privPem, _ := pem.Decode([]byte(priv)) 712 713 parsedKey, err := x509.ParsePKCS8PrivateKey(privPem.Bytes) 714 if err != nil { 715 panic(err) 716 } 717 return parsedKey.(*rsa.PrivateKey) 718 } 719 720 type FindNewestCertificateWithSansMock struct { 721 // testCase name 722 name string 723 // expected returned certificate 724 expected *CertificateInfo 725 // sans argument passed to FindNewestCertificateWithSans function 726 sans *Sans 727 } 728 729 func createTimeMock(t *testing.T, s string) time.Time { 730 time, err := time.Parse(time.RFC3339, s) 731 732 if err != nil { 733 t.Error(err) 734 t.Fatalf("error parsing time string %q", s) 735 } 736 737 return time 738 } 739 740 func TestFindNewestCertificateWithSans(t *testing.T) { 741 // create a list of certificates where we will try to find according to our 742 // testCases, we are not interested in any other field but the `SANS.DNS`, 743 // and `ValidTo` which are the ones used to match in the 744 // `FindNewestCertificateWithSans` function 745 certificates := []*CertificateInfo{ 746 { 747 SANS: Sans{ 748 DNS: []string{ 749 "one.vfidev.com", 750 }, 751 }, 752 ValidTo: createTimeMock(t, "2022-08-22T00:00:00.000+00:00"), 753 }, 754 { 755 SANS: Sans{ 756 DNS: []string{ 757 "one.vfidev.com", 758 "two.vfidev.com", 759 }, 760 }, 761 ValidTo: createTimeMock(t, "2022-08-22T00:00:00.000+00:00"), 762 }, 763 { 764 SANS: Sans{ 765 DNS: []string{ 766 "one.vfidev.com", 767 "two.vfidev.com", 768 }, 769 }, 770 ValidTo: createTimeMock(t, "2030-01-01T00:00:00.000+00:00"), 771 }, 772 { 773 SANS: Sans{ 774 DNS: []string{ 775 "1.vfidev.com", 776 "2.vfidev.com", 777 "3.vfidev.com", 778 }, 779 }, 780 ValidTo: createTimeMock(t, "2022-08-22T00:00:00.000+00:00"), 781 }, 782 } 783 784 testCases := []FindNewestCertificateWithSansMock{ 785 // should not return any certificate 786 { 787 name: "Empty SANS", 788 expected: nil, 789 sans: nil, 790 }, 791 // should return the only existing certificate 792 { 793 name: "Simple", 794 expected: &CertificateInfo{ 795 SANS: Sans{ 796 DNS: []string{ 797 "one.vfidev.com", 798 }, 799 }, 800 ValidTo: createTimeMock(t, "2022-08-22T00:00:00.000+00:00"), 801 }, 802 sans: &Sans{DNS: []string{"one.vfidev.com"}}, 803 }, 804 //should return the newest certificate 805 { 806 name: "Newest", 807 expected: &CertificateInfo{ 808 SANS: Sans{ 809 DNS: []string{ 810 "one.vfidev.com", 811 "two.vfidev.com", 812 }, 813 }, 814 ValidTo: createTimeMock(t, "2030-01-01T00:00:00.000+00:00"), 815 }, 816 sans: &Sans{DNS: []string{"one.vfidev.com", "two.vfidev.com"}}, 817 }, 818 // should return the only existing certificate regardless of the order of 819 // the sans arguments 820 { 821 name: "Order of arguments", 822 expected: &CertificateInfo{ 823 SANS: Sans{ 824 DNS: []string{ 825 "1.vfidev.com", 826 "2.vfidev.com", 827 "3.vfidev.com", 828 }, 829 }, 830 ValidTo: createTimeMock(t, "2022-08-22T00:00:00.000+00:00"), 831 }, 832 sans: &Sans{DNS: []string{"3.vfidev.com", "2.vfidev.com", "1.vfidev.com"}}, 833 }, 834 } 835 836 for _, testCase := range testCases { 837 t.Run(testCase.name, func(t *testing.T) { 838 // ignore error, just use the certificate value as a sign of success 839 certificate, _ := FindNewestCertificateWithSans(certificates, testCase.sans) 840 841 // certificate should have been found but function returned no certificate 842 if testCase.expected != nil && certificate == nil { 843 t.Fatalf("certificate should have been found but function returned no certificate\nsans provided: %v\nexpected certificate: %v", util.GetJsonAsString(testCase.sans), util.GetJsonAsString(testCase.expected)) 844 } 845 846 // no certificate should have been found but function returned one 847 if testCase.expected == nil && certificate != nil { 848 t.Fatalf("no certificate should have been found but function returned one\nsans provided: %v\nreturned certificate: %v", util.GetJsonAsString(testCase.sans), util.GetJsonAsString(certificate)) 849 } 850 851 if !reflect.DeepEqual(testCase.expected, certificate) { 852 t.Fatalf("certificates did not match.\nexpected:\n%v\ngot:\n%v", util.GetJsonAsString(testCase.expected), util.GetJsonAsString(certificate)) 853 } 854 }) 855 } 856 }