@@ -301,6 +301,49 @@ public bool HighIntegrity
301301 /// <param name="issuerCertificatePath">The file system path to find the certificate at.</param>
302302 public void TrustIssuer ( string issuerCertificatePath ) => CertificateValidationCallback = TrustIssuerCallback ( issuerCertificatePath ) ;
303303
304+ #if NET5_0_OR_GREATER
305+ /// <summary>
306+ /// Supply a user certificate from a PEM file pair and enable TLS.
307+ /// </summary>
308+ /// <param name="userCertificatePath">The path for the the user certificate (commonly a .crt file).</param>
309+ /// <param name="userKeyPath">The path for the the user key (commonly a .key file).</param>
310+ public void SetUserPemCertificate ( string userCertificatePath , string userKeyPath )
311+ {
312+ CertificateSelectionCallback = CreatePemUserCertificateCallback ( userCertificatePath , userKeyPath ) ;
313+ Ssl = true ;
314+ }
315+ #endif
316+
317+ /// <summary>
318+ /// Supply a user certificate from a PFX file and optional password and enable TLS.
319+ /// </summary>
320+ /// <param name="userCertificatePath">The path for the the user certificate (commonly a .pfx file).</param>
321+ /// <param name="password">The password for the certificate file.</param>
322+ public void SetUserPfxCertificate ( string userCertificatePath , string ? password = null )
323+ {
324+ CertificateSelectionCallback = CreatePfxUserCertificateCallback ( userCertificatePath , password ) ;
325+ Ssl = true ;
326+ }
327+
328+ #if NET5_0_OR_GREATER
329+ internal static LocalCertificateSelectionCallback CreatePemUserCertificateCallback ( string userCertificatePath , string userKeyPath )
330+ {
331+ // PEM handshakes not universally supported and causes a runtime error about ephemeral certificates; to avoid, export as PFX
332+ using var pem = X509Certificate2 . CreateFromPemFile ( userCertificatePath , userKeyPath ) ;
333+ #pragma warning disable SYSLIB0057 // Type or member is obsolete
334+ var pfx = new X509Certificate2 ( pem . Export ( X509ContentType . Pfx ) ) ;
335+ #pragma warning restore SYSLIB0057 // Type or member is obsolete
336+
337+ return ( sender , targetHost , localCertificates , remoteCertificate , acceptableIssuers ) => pfx ;
338+ }
339+ #endif
340+
341+ internal static LocalCertificateSelectionCallback CreatePfxUserCertificateCallback ( string userCertificatePath , string ? password , X509KeyStorageFlags storageFlags = X509KeyStorageFlags . DefaultKeySet )
342+ {
343+ var pfx = new X509Certificate2 ( userCertificatePath , password ?? "" , storageFlags ) ;
344+ return ( sender , targetHost , localCertificates , remoteCertificate , acceptableIssuers ) => pfx ;
345+ }
346+
304347 /// <summary>
305348 /// Create a certificate validation check that checks against the supplied issuer even when not known by the machine.
306349 /// </summary>
0 commit comments