diff --git a/src/System.ServiceModel.Primitives/src/System/ServiceModel/X509CertificateEndpointIdentity.cs b/src/System.ServiceModel.Primitives/src/System/ServiceModel/X509CertificateEndpointIdentity.cs
index e7665da21c0..85775fe5a38 100644
--- a/src/System.ServiceModel.Primitives/src/System/ServiceModel/X509CertificateEndpointIdentity.cs
+++ b/src/System.ServiceModel.Primitives/src/System/ServiceModel/X509CertificateEndpointIdentity.cs
@@ -61,8 +61,7 @@ internal X509CertificateEndpointIdentity(XmlDictionaryReader reader)
reader.ReadStartElement(XD.XmlSignatureDictionary.X509Data, XD.XmlSignatureDictionary.Namespace);
while (reader.IsStartElement(XD.XmlSignatureDictionary.X509Certificate, XD.XmlSignatureDictionary.Namespace))
{
- reader.MoveToContent();
- X509Certificate2 certificate = new X509Certificate2(Convert.FromBase64String(reader.ReadContentAsString()));
+ X509Certificate2 certificate = new X509Certificate2(Convert.FromBase64String(reader.ReadElementString()));
if (Certificates.Count == 0)
{
// This is the first certificate. We assume this as the primary
diff --git a/src/System.ServiceModel.Primitives/tests/ServiceModel/X509CertificateEndpointIdentityTest.cs b/src/System.ServiceModel.Primitives/tests/ServiceModel/X509CertificateEndpointIdentityTest.cs
new file mode 100644
index 00000000000..31708d5f121
--- /dev/null
+++ b/src/System.ServiceModel.Primitives/tests/ServiceModel/X509CertificateEndpointIdentityTest.cs
@@ -0,0 +1,107 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.IO;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.ServiceModel;
+using System.Xml;
+using Infrastructure.Common;
+using Xunit;
+
+public class X509CertificateEndpointIdentityTest : ConditionalWcfTest
+{
+ [WcfFact]
+ [Issue(3572, OS = OSID.OSX)]
+ public static void X509Certificate_RoundTrip_Succeeds()
+ {
+ // Create a self-signed certificate for testing
+ X509Certificate2 certificate = CreateTestCertificate();
+
+ // Manually construct the XML that would be sent from the server
+ // This ensures we're testing deserialization independently of WriteContentsTo
+ string certificateBase64 = Convert.ToBase64String(certificate.RawData);
+ string xml = $@"
+
+
+ {certificateBase64}
+
+
+";
+
+ // Deserialize from XML
+ X509CertificateEndpointIdentity deserializedIdentity;
+ using (var reader = XmlReader.Create(new StringReader(xml)))
+ {
+ // This uses the internal constructor that reads from XmlDictionaryReader
+ // ReadIdentity expects to read the Identity element and its contents
+ deserializedIdentity = (X509CertificateEndpointIdentity)typeof(EndpointIdentity)
+ .GetMethod("ReadIdentity", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static)
+ .Invoke(null, new object[] { XmlDictionaryReader.CreateDictionaryReader(reader) });
+ }
+
+ // Verify the certificate was correctly deserialized
+ Assert.NotNull(deserializedIdentity);
+ X509Certificate2 deserializedCert = Assert.Single(deserializedIdentity.Certificates);
+ Assert.Equal(certificate.Thumbprint, deserializedCert.Thumbprint);
+ Assert.Equal(certificate.GetCertHash(), deserializedCert.GetCertHash());
+ }
+
+ [WcfFact]
+ [Issue(3572, OS = OSID.OSX)]
+ public static void X509Certificate_Multiple_RoundTrip_Succeeds()
+ {
+ // Create two test certificates
+ X509Certificate2 primaryCert = CreateTestCertificate();
+ X509Certificate2 supportingCert = CreateTestCertificate();
+
+ // Manually construct the XML that would be sent from the server with multiple certificates
+ // This ensures we're testing deserialization independently of WriteContentsTo
+ string primaryCertBase64 = Convert.ToBase64String(primaryCert.RawData);
+ string supportingCertBase64 = Convert.ToBase64String(supportingCert.RawData);
+ string xml = $@"
+
+
+ {primaryCertBase64}
+ {supportingCertBase64}
+
+
+";
+
+ // Deserialize from XML
+ X509CertificateEndpointIdentity deserializedIdentity;
+ using (var reader = XmlReader.Create(new StringReader(xml)))
+ {
+ // This uses the internal constructor that reads from XmlDictionaryReader
+ // ReadIdentity expects to read the Identity element and its contents
+ deserializedIdentity = (X509CertificateEndpointIdentity)typeof(EndpointIdentity)
+ .GetMethod("ReadIdentity", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static)
+ .Invoke(null, new object[] { XmlDictionaryReader.CreateDictionaryReader(reader) });
+ }
+
+ // Verify both certificates were correctly deserialized
+ Assert.NotNull(deserializedIdentity);
+ Assert.Equal(2, deserializedIdentity.Certificates.Count);
+ Assert.Equal(primaryCert.Thumbprint, deserializedIdentity.Certificates[0].Thumbprint);
+ Assert.Equal(supportingCert.Thumbprint, deserializedIdentity.Certificates[1].Thumbprint);
+ }
+
+ private static X509Certificate2 CreateTestCertificate()
+ {
+ // Create a simple self-signed certificate for testing
+ using (RSA rsa = RSA.Create(2048))
+ {
+ var request = new CertificateRequest(
+ "CN=Test Certificate",
+ rsa,
+ HashAlgorithmName.SHA256,
+ RSASignaturePadding.Pkcs1);
+
+ return request.CreateSelfSigned(
+ DateTimeOffset.UtcNow.AddDays(-1),
+ DateTimeOffset.UtcNow.AddDays(365));
+ }
+ }
+}