From 32f4b4b94001ab544839454b89767d035db32684 Mon Sep 17 00:00:00 2001 From: nitram509 Date: Thu, 24 Oct 2024 13:28:59 +0200 Subject: [PATCH] refactor tests using sttic files instead of base64 rework tests as table tests --- pkcs12_test.go | 327 +++++++++------------- test-data/ad_standalone_com_aescbc256.p12 | Bin 0 -> 2779 bytes test-data/example_com_aescbc128.p12 | Bin 0 -> 2874 bytes test-data/example_com_aescbc192.p12 | Bin 0 -> 4380 bytes test-data/testing_at_example_com.p12 | Bin 0 -> 2514 bytes test-data/windows_azure_tools.p12 | Bin 0 -> 2576 bytes 6 files changed, 137 insertions(+), 190 deletions(-) create mode 100644 test-data/ad_standalone_com_aescbc256.p12 create mode 100644 test-data/example_com_aescbc128.p12 create mode 100644 test-data/example_com_aescbc192.p12 create mode 100644 test-data/testing_at_example_com.p12 create mode 100644 test-data/windows_azure_tools.p12 diff --git a/pkcs12_test.go b/pkcs12_test.go index f563577..459ce20 100644 --- a/pkcs12_test.go +++ b/pkcs12_test.go @@ -9,213 +9,160 @@ import ( "crypto/rsa" "crypto/tls" "crypto/x509" - "encoding/base64" + _ "embed" "encoding/pem" "testing" ) -func TestPfx(t *testing.T) { - for commonName, base64P12 := range testdata { - p12, _ := base64.StdEncoding.DecodeString(base64P12) +//go:embed test-data/testing_at_example_com.p12 +var fileTestingAtExampleCom []byte - priv, cert, err := Decode(p12, "") - if err != nil { - t.Fatal(err) - } +//go:embed test-data/windows_azure_tools.p12 +var fileWindowsAzureTools []byte - if err := priv.(*rsa.PrivateKey).Validate(); err != nil { - t.Errorf("error while validating private key: %v", err) - } +var testdata = map[string][]byte{ + // 'null' password test case + "Windows Azure Tools": fileWindowsAzureTools, + // empty string password test case + "testing@example.com": fileTestingAtExampleCom, +} - if cert.Subject.CommonName != commonName { - t.Errorf("expected common name to be %q, but found %q", commonName, cert.Subject.CommonName) - } +func TestPfx(t *testing.T) { + for commonName, p12 := range testdata { + t.Run(commonName, func(t *testing.T) { + priv, cert, err := Decode(p12, "") + if err != nil { + t.Fatal(err) + } + + if err := priv.(*rsa.PrivateKey).Validate(); err != nil { + t.Errorf("error while validating private key: %v", err) + } + + if cert.Subject.CommonName != commonName { + t.Errorf("expected common name to be %q, but found %q", commonName, cert.Subject.CommonName) + } + }) } } func TestPEM(t *testing.T) { - for commonName, base64P12 := range testdata { - p12, _ := base64.StdEncoding.DecodeString(base64P12) - - blocks, err := ToPEM(p12, "") - if err != nil { - t.Fatalf("error while converting to PEM: %s", err) - } - - var pemData []byte - for _, b := range blocks { - pemData = append(pemData, pem.EncodeToMemory(b)...) - } - - cert, err := tls.X509KeyPair(pemData, pemData) - if err != nil { - t.Errorf("err while converting to key pair: %v", err) - } - config := tls.Config{ - Certificates: []tls.Certificate{cert}, - } - config.BuildNameToCertificate() - - if _, exists := config.NameToCertificate[commonName]; !exists { - t.Errorf("did not find our cert in PEM?: %v", config.NameToCertificate) - } + for commonName, p12 := range testdata { + t.Run(commonName, func(t *testing.T) { + blocks, err := ToPEM(p12, "") + if err != nil { + t.Fatalf("error while converting to PEM: %s", err) + } + + var pemData []byte + for _, b := range blocks { + pemData = append(pemData, pem.EncodeToMemory(b)...) + } + + cert, err := tls.X509KeyPair(pemData, pemData) + if err != nil { + t.Errorf("err while converting to key pair: %v", err) + } + config := tls.Config{ + Certificates: []tls.Certificate{cert}, + } + config.BuildNameToCertificate() + + if _, exists := config.NameToCertificate[commonName]; !exists { + t.Errorf("did not find our cert in PEM?: %v", config.NameToCertificate) + } + }) } } func TestTrustStore(t *testing.T) { - for commonName, base64P12 := range testdata { - p12, _ := base64.StdEncoding.DecodeString(base64P12) - - _, cert, err := Decode(p12, "") - if err != nil { - t.Fatal(err) - } - - pfxData, err := EncodeTrustStore(rand.Reader, []*x509.Certificate{cert}, "password") - if err != nil { - t.Fatal(err) - } - - decodedCerts, err := DecodeTrustStore(pfxData, "password") - if err != nil { - t.Fatal(err) - } - - if len(decodedCerts) != 1 { - t.Fatal("Unexpected number of certs") - } - - if decodedCerts[0].Subject.CommonName != commonName { - t.Errorf("expected common name to be %q, but found %q", commonName, decodedCerts[0].Subject.CommonName) - } - } -} - -func TestPBES2_AES256CBC(t *testing.T) { - // This P12 PDU is a self-signed certificate exported via Windows certmgr. - // It is encrypted with the following options (verified via openssl): PBES2, PBKDF2, AES-256-CBC, Iteration 2000, PRF hmacWithSHA256 - commonName := "*.ad.standalone.com" - base64P12 := `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` - p12, _ := base64.StdEncoding.DecodeString(base64P12) - pk, cert, caCerts, err := DecodeChain(p12, "password") - if err != nil { - t.Fatal(err) - } - - rsaPk, ok := pk.(*rsa.PrivateKey) - if !ok { - t.Error("could not cast to rsa private key") - } - if !rsaPk.PublicKey.Equal(cert.PublicKey) { - t.Error("public key embedded in private key not equal to public key of certificate") - } - if cert.Subject.CommonName != commonName { - t.Errorf("unexpected leaf cert common name, got %s, want %s", cert.Subject.CommonName, commonName) - } - if len(caCerts) != 0 { - t.Errorf("unexpected # of caCerts: got %d, want 0", len(caCerts)) - } -} - -func TestPBES2_AES128CBC(t *testing.T) { - //PKCS7 Encrypted data: PBES2, PBKDF2, AES-128-CBC, Iteration 2048, PRF hmacWithSHA256 - commonName := "example-com" - base64P12 := `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` - - p12, _ := base64.StdEncoding.DecodeString(base64P12) - pk, cert, caCerts, err := DecodeChain(p12, "rHyQTJsubhfxcpH5JttyilHE6BBsNoZp") - if err != nil { - t.Fatal(err) - } - - rsaPk, ok := pk.(*rsa.PrivateKey) - if !ok { - t.Error("could not cast to rsa private key") - } - if !rsaPk.PublicKey.Equal(cert.PublicKey) { - t.Error("public key embedded in private key not equal to public key of certificate") - } - if cert.Subject.CommonName != commonName { - t.Errorf("unexpected leaf cert common name, got %s, want %s", cert.Subject.CommonName, commonName) - } - if len(caCerts) != 0 { - t.Errorf("unexpected # of caCerts: got %d, want 0", len(caCerts)) + for commonName, p12 := range testdata { + t.Run(commonName, func(t *testing.T) { + _, cert, err := Decode(p12, "") + if err != nil { + t.Fatal(err) + } + + pfxData, err := EncodeTrustStore(rand.Reader, []*x509.Certificate{cert}, "password") + if err != nil { + t.Fatal(err) + } + + decodedCerts, err := DecodeTrustStore(pfxData, "password") + if err != nil { + t.Fatal(err) + } + + if len(decodedCerts) != 1 { + t.Fatal("Unexpected number of certs") + } + + if decodedCerts[0].Subject.CommonName != commonName { + t.Errorf("expected common name to be %q, but found %q", commonName, decodedCerts[0].Subject.CommonName) + } + }) } } -func TestPBES2_AES192CBC(t *testing.T) { - //PKCS7 Encrypted data: PBES2, PBKDF2, AES-192-CBC, Iteration 2048, PRF hmacWithSHA256 - commonName := "example-com" - base64P12 := `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` - - p12, _ := base64.StdEncoding.DecodeString(base64P12) - pk, cert, caCerts, err := DecodeChain(p12, "password") - if err != nil { - t.Fatal(err) - } - - rsaPk, ok := pk.(*rsa.PrivateKey) - if !ok { - t.Error("could not cast to rsa private key") - } - if !rsaPk.PublicKey.Equal(cert.PublicKey) { - t.Error("public key embedded in private key not equal to public key of certificate") - } - if cert.Subject.CommonName != commonName { - t.Errorf("unexpected leaf cert common name, got %s, want %s", cert.Subject.CommonName, commonName) - } - if len(caCerts) != 0 { - t.Errorf("unexpected # of caCerts: got %d, want 0", len(caCerts)) +//go:embed test-data/example_com_aescbc128.p12 +var fileExampleComAesCbc128 []byte + +//go:embed test-data/example_com_aescbc192.p12 +var fileExampleComAesCbc192 []byte + +//go:embed test-data/ad_standalone_com_aescbc256.p12 +var fileAdStandaloneComAesCbc256 []byte + +func Test_DecodeChain_PBES2(t *testing.T) { + tests := []struct { + testName string + storeData []byte + password string + commonName string + testDescription string + }{ + { + testName: "AES128CBC", + storeData: fileExampleComAesCbc128, + password: "rHyQTJsubhfxcpH5JttyilHE6BBsNoZp", + commonName: "example-com", + testDescription: "PKCS7 Encrypted data: PBES2, PBKDF2, AES-128-CBC, Iteration 2048, PRF hmacWithSHA256", + }, + { + testName: "AES192CBC", + storeData: fileExampleComAesCbc192, + password: "password", + commonName: "example-com", + testDescription: "PKCS7 Encrypted data: PBES2, PBKDF2, AES-192-CBC, Iteration 2048, PRF hmacWithSHA256", + }, + { + testName: "AES256CBC", + storeData: fileAdStandaloneComAesCbc256, + password: "password", + commonName: "*.ad.standalone.com", + testDescription: "This P12 PDU is a self-signed certificate exported via Windows certmgr. It is encrypted with the following options (verified via openssl): PBES2, PBKDF2, AES-256-CBC, Iteration 2000, PRF hmacWithSHA256", + }, + } + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + pk, cert, caCerts, err := DecodeChain(tt.storeData, tt.password) + if err != nil { + t.Fatal(err) + } + + rsaPk, ok := pk.(*rsa.PrivateKey) + if !ok { + t.Error("could not cast to rsa private key") + } + if !rsaPk.PublicKey.Equal(cert.PublicKey) { + t.Error("public key embedded in private key not equal to public key of certificate") + } + if cert.Subject.CommonName != tt.commonName { + t.Errorf("unexpected leaf cert common name, got %s, want %s", cert.Subject.CommonName, tt.commonName) + } + if len(caCerts) != 0 { + t.Errorf("unexpected # of caCerts: got %d, want 0", len(caCerts)) + } + }) } } - -var testdata = map[string]string{ - // 'null' password test case - "Windows Azure Tools": `MIIKDAIBAzCCCcwGCSqGSIb3DQEHAaCCCb0Eggm5MIIJtTCCBe4GCSqGSIb3DQEHAaCCBd8EggXbMIIF1zCCBdMGCyqGSIb3DQEMCgECoIIE7jCCBOowHAYKKoZIhvcNAQwBAzAOBAhStUNnlTGV+gICB9AEggTIJ81JIossF6boFWpPtkiQRPtI6DW6e9QD4/WvHAVrM2bKdpMzSMsCML5NyuddANTKHBVq00Jc9keqGNAqJPKkjhSUebzQFyhe0E1oI9T4zY5UKr/I8JclOeccH4QQnsySzYUG2SnniXnQ+JrG3juetli7EKth9h6jLc6xbubPadY5HMB3wL/eG/kJymiXwU2KQ9Mgd4X6jbcV+NNCE/8jbZHvSTCPeYTJIjxfeX61Sj5kFKUCzERbsnpyevhY3X0eYtEDezZQarvGmXtMMdzf8HJHkWRdk9VLDLgjk8uiJif/+X4FohZ37ig0CpgC2+dP4DGugaZZ51hb8tN9GeCKIsrmWogMXDIVd0OACBp/EjJVmFB6y0kUCXxUE0TZt0XA1tjAGJcjDUpBvTntZjPsnH/4ZySy+s2d9OOhJ6pzRQBRm360TzkFdSwk9DLiLdGfv4pwMMu/vNGBlqjP/1sQtj+jprJiD1sDbCl4AdQZVoMBQHadF2uSD4/o17XG/Ci0r2h6Htc2yvZMAbEY4zMjjIn2a+vqIxD6onexaek1R3zbkS9j19D6EN9EWn8xgz80YRCyW65znZk8xaIhhvlU/mg7sTxeyuqroBZNcq6uDaQTehDpyH7bY2l4zWRpoj10a6JfH2q5shYz8Y6UZC/kOTfuGqbZDNZWro/9pYquvNNW0M847E5t9bsf9VkAAMHRGBbWoVoU9VpI0UnoXSfvpOo+aXa2DSq5sHHUTVY7A9eov3z5IqT+pligx11xcs+YhDWcU8di3BTJisohKvv5Y8WSkm/rloiZd4ig269k0jTRk1olP/vCksPli4wKG2wdsd5o42nX1yL7mFfXocOANZbB+5qMkiwdyoQSk+Vq+C8nAZx2bbKhUq2MbrORGMzOe0Hh0x2a0PeObycN1Bpyv7Mp3ZI9h5hBnONKCnqMhtyQHUj/nNvbJUnDVYNfoOEqDiEqqEwB7YqWzAKz8KW0OIqdlM8uiQ4JqZZlFllnWJUfaiDrdFM3lYSnFQBkzeVlts6GpDOOBjCYd7dcCNS6kq6pZC6p6HN60Twu0JnurZD6RT7rrPkIGE8vAenFt4iGe/yF52fahCSY8Ws4K0UTwN7bAS+4xRHVCWvE8sMRZsRCHizb5laYsVrPZJhE6+hux6OBb6w8kwPYXc+ud5v6UxawUWgt6uPwl8mlAtU9Z7Miw4Nn/wtBkiLL/ke1UI1gqJtcQXgHxx6mzsjh41+nAgTvdbsSEyU6vfOmxGj3Rwc1eOrIhJUqn5YjOWfzzsz/D5DzWKmwXIwdspt1p+u+kol1N3f2wT9fKPnd/RGCb4g/1hc3Aju4DQYgGY782l89CEEdalpQ/35bQczMFk6Fje12HykakWEXd/bGm9Unh82gH84USiRpeOfQvBDYoqEyrY3zkFZzBjhDqa+jEcAj41tcGx47oSfDq3iVYCdL7HSIjtnyEktVXd7mISZLoMt20JACFcMw+mrbjlug+eU7o2GR7T+LwtOp/p4LZqyLa7oQJDwde1BNZtm3TCK2P1mW94QDL0nDUps5KLtr1DaZXEkRbjSJub2ZE9WqDHyU3KA8G84Tq/rN1IoNu/if45jacyPje1Npj9IftUZSP22nV7HMwZtwQ4P4MYHRMBMGCSqGSIb3DQEJFTEGBAQBAAAAMFsGCSqGSIb3DQEJFDFOHkwAewBCADQAQQA0AEYARQBCADAALQBBADEAOABBAC0ANAA0AEIAQgAtAEIANQBGADIALQA0ADkAMQBFAEYAMQA1ADIAQgBBADEANgB9MF0GCSsGAQQBgjcRATFQHk4ATQBpAGMAcgBvAHMAbwBmAHQAIABTAG8AZgB0AHcAYQByAGUAIABLAGUAeQAgAFMAdABvAHIAYQBnAGUAIABQAHIAbwB2AGkAZABlAHIwggO/BgkqhkiG9w0BBwagggOwMIIDrAIBADCCA6UGCSqGSIb3DQEHATAcBgoqhkiG9w0BDAEGMA4ECEBk5ZAYpu0WAgIH0ICCA3hik4mQFGpw9Ha8TQPtk+j2jwWdxfF0+sTk6S8PTsEfIhB7wPltjiCK92Uv2tCBQnodBUmatIfkpnRDEySmgmdglmOCzj204lWAMRs94PoALGn3JVBXbO1vIDCbAPOZ7Z0Hd0/1t2hmk8v3//QJGUg+qr59/4y/MuVfIg4qfkPcC2QSvYWcK3oTf6SFi5rv9B1IOWFgN5D0+C+x/9Lb/myPYX+rbOHrwtJ4W1fWKoz9g7wwmGFA9IJ2DYGuH8ifVFbDFT1Vcgsvs8arSX7oBsJVW0qrP7XkuDRe3EqCmKW7rBEwYrFznhxZcRDEpMwbFoSvgSIZ4XhFY9VKYglT+JpNH5iDceYEBOQL4vBLpxNUk3l5jKaBNxVa14AIBxq18bVHJ+STInhLhad4u10v/Xbx7wIL3f9DX1yLAkPrpBYbNHS2/ew6H/ySDJnoIDxkw2zZ4qJ+qUJZ1S0lbZVG+VT0OP5uF6tyOSpbMlcGkdl3z254n6MlCrTifcwkzscysDsgKXaYQw06rzrPW6RDub+t+hXzGny799fS9jhQMLDmOggaQ7+LA4oEZsfT89HLMWxJYDqjo3gIfjciV2mV54R684qLDS+AO09U49e6yEbwGlq8lpmO/pbXCbpGbB1b3EomcQbxdWxW2WEkkEd/VBn81K4M3obmywwXJkw+tPXDXfBmzzaqqCR+onMQ5ME1nMkY8ybnfoCc1bDIupjVWsEL2Wvq752RgI6KqzVNr1ew1IdqV5AWN2fOfek+0vi3Jd9FHF3hx8JMwjJL9dZsETV5kHtYJtE7wJ23J68BnCt2eI0GEuwXcCf5EdSKN/xXCTlIokc4Qk/gzRdIZsvcEJ6B1lGovKG54X4IohikqTjiepjbsMWj38yxDmK3mtENZ9ci8FPfbbvIEcOCZIinuY3qFUlRSbx7VUerEoV1IP3clUwexVQo4lHFee2jd7ocWsdSqSapW7OWUupBtDzRkqVhE7tGria+i1W2d6YLlJ21QTjyapWJehAMO637OdbJCCzDs1cXbodRRE7bsP492ocJy8OX66rKdhYbg8srSFNKdb3pF3UDNbN9jhI/t8iagRhNBhlQtTr1me2E/c86Q18qcRXl4bcXTt6acgCeffK6Y26LcVlrgjlD33AEYRRUeyC+rpxbT0aMjdFderlndKRIyG23mSp0HaUwNzAfMAcGBSsOAwIaBBRlviCbIyRrhIysg2dc/KbLFTc2vQQUg4rfwHMM4IKYRD/fsd1x6dda+wQ=`, - // empty string password test case - "testing@example.com": `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 -HQ8CAggA`, -} diff --git a/test-data/ad_standalone_com_aescbc256.p12 b/test-data/ad_standalone_com_aescbc256.p12 new file mode 100644 index 0000000000000000000000000000000000000000..a1f7bf9bbd24d5b2f076a31dfe1f56db00aea39a GIT binary patch literal 2779 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 Ie%%iL0Y=TuPyhe` literal 0 HcmV?d00001 diff --git a/test-data/example_com_aescbc128.p12 b/test-data/example_com_aescbc128.p12 new file mode 100644 index 0000000000000000000000000000000000000000..6088478768d9ca58466096ddf6b33769b37ab974 GIT binary patch literal 2874 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 literal 0 HcmV?d00001 diff --git a/test-data/example_com_aescbc192.p12 b/test-data/example_com_aescbc192.p12 new file mode 100644 index 0000000000000000000000000000000000000000..83cce79de7f07e909b1af73c09e577f83b1d2fa3 GIT binary patch literal 4380 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