@@ -43,6 +43,13 @@ public sealed class X509IdentityTokenHandler : IUserIdentityTokenHandler
4343 public X509IdentityTokenHandler ( X509IdentityToken token )
4444 {
4545 m_token = token ;
46+
47+ if ( m_token . CertificateData != null )
48+ {
49+ m_certificate = CertificateFactory . Create ( m_token . CertificateData ) ;
50+ }
51+
52+ m_ownsCertificate = true ;
4653 }
4754
4855 /// <summary>
@@ -66,12 +73,29 @@ public X509IdentityTokenHandler(X509Certificate2 certificate)
6673 }
6774
6875 Certificate = certificate ;
76+ m_ownsCertificate = true ;
6977 m_token = new X509IdentityToken
7078 {
7179 CertificateData = certificate . RawData
7280 } ;
7381 }
7482
83+ /// <summary>
84+ /// Private constructor for <see cref="Clone"/>. The cloned handler
85+ /// shares the certificate reference but does not own it, so it will
86+ /// not dispose the certificate. This is necessary because the
87+ /// certificate's private key may reside in protected storage and
88+ /// cannot be deep-copied.
89+ /// </summary>
90+ private X509IdentityTokenHandler (
91+ X509IdentityToken token ,
92+ X509Certificate2 certificate )
93+ {
94+ m_token = token ;
95+ m_certificate = certificate ;
96+ m_ownsCertificate = false ;
97+ }
98+
7599 /// <summary>
76100 /// The certificate associated with the token.
77101 /// </summary>
@@ -134,16 +158,13 @@ public SignatureData Sign(
134158 byte [ ] dataToSign ,
135159 string securityPolicyUri )
136160 {
137- X509Certificate2 certificate = Certificate ??
138- CertificateFactory . Create ( m_token . CertificateData ) ;
161+ var info = SecurityPolicies . GetInfo ( securityPolicyUri ) ;
139162
140- SignatureData signatureData = SecurityPolicies . CreateSignatureData (
141- securityPolicyUri ,
142- certificate ,
163+ var signatureData = SecurityPolicies . CreateSignatureData (
164+ info ,
165+ m_certificate ,
143166 dataToSign ) ;
144167
145- m_token . CertificateData = certificate . RawData ;
146-
147168 return signatureData ;
148169 }
149170
@@ -155,17 +176,14 @@ public bool Verify(
155176 {
156177 try
157178 {
158- X509Certificate2 certificate = Certificate ??
159- CertificateFactory . Create ( m_token . CertificateData ) ;
179+ var info = SecurityPolicies . GetInfo ( securityPolicyUri ) ;
160180
161181 bool valid = SecurityPolicies . VerifySignatureData (
162182 signatureData ,
163- securityPolicyUri ,
164- certificate ,
183+ info ,
184+ m_certificate ,
165185 dataToVerify ) ;
166186
167- m_token . CertificateData = certificate . RawData ;
168-
169187 return valid ;
170188 }
171189 catch ( Exception e )
@@ -180,19 +198,19 @@ public bool Verify(
180198 /// <inheritdoc/>
181199 public void Dispose ( )
182200 {
183- // TODOL Utils.SilentDispose(m_certificate);
201+ if ( m_ownsCertificate )
202+ {
203+ Utils . SilentDispose ( m_certificate ) ;
204+ }
184205 m_certificate = null ;
185206 }
186207
187208 /// <inheritdoc/>
188209 public object Clone ( )
189210 {
190- return new X509IdentityTokenHandler ( Utils . Clone ( m_token ) )
191- {
192- // Keep the in-memory certificate instance so private key operations
193- // continue to work when cloned handlers are used for signing.
194- Certificate = m_certificate
195- } ;
211+ return new X509IdentityTokenHandler (
212+ Utils . Clone ( m_token ) ,
213+ m_certificate ) ;
196214 }
197215
198216 /// <inheritdoc/>
@@ -206,6 +224,7 @@ public bool Equals(IUserIdentityTokenHandler other)
206224 }
207225
208226 private readonly X509IdentityToken m_token ;
227+ private readonly bool m_ownsCertificate ;
209228 private X509Certificate2 m_certificate ;
210229 }
211230}
0 commit comments