Rebex Graph

.NET client library for MS Graph API (Exchange Online)

Download 30-day free trial Buy from $199
More .NET libraries

Back to feature list...

TLS/SSL core

TLS/SSL is a cryptographic communication protocol providing a way of securing protocols such as FTP, HTTP, SMTP, IMAP, POP3, Telnet or Syslog.

TLS and SSL are different versions of the same protocol. TLS 1.0 is a name for what was supposed to be SSL 3.1. When we use the terms "SSL" or "TLS", we generally mean "TLS or SSL".

Validating and examining server certificate 

When connecting securely, you should ensure you are really connected to the desired server. TLS/SSL provides it with a security certificate of the server. On the client side you should just verify that the server certificate of the current connection really comes from the server you want to connect to. There are following ways, how to do it using the Rebex Graph:

  • By default, the server certificate is validated against Windows certificate infrastructure.
  • If you cannot rely on the built-in certificate verifier, you can write your own certificate validation.
  • The certificate validation can be simply skipped by setting the SslAcceptAllCertificates property:
    // create client instance
    // ...
    
    // skip certificate validation (don't do this in production environment!)
    client.Settings.SslAcceptAllCertificates = true;
    
    // connect securely (SslMode.Explicit or SslMode.Implicit)
    client.Connect(hostname, SslMode.Explicit);
    
    ' create client instance
    ' ...
    
    ' let skip certificate validation (don't do this in production environment!)
    client.Settings.SslAcceptAllCertificates = True
    
    ' connect securely (SslMode.Explicit or SslMode.Implicit)
    client.Connect(hostname, SslMode.Explicit)
    
Tip: For more detailed information read the Introduction to Public Key Certificates article.

Built-in certificate verifier 

When calling the Connect method and no custom validation is configured, the server certificate is validated using Windows CryptoAPI.

See what to do when a server certificate is not trusted.

Legacy Windows CE platforms don't natively support certificates signed using algorithms based on SHA-2 hashes. As a workaround for this major OS limitation, we introduced a built-in certificate validator in the 2016 R3 release.

Custom certificate validation 

If you cannot relay on the certificate can be trusted by the Windows certificate infrastructure, you can implement your own validation:

Register an event handler before calling the Connect method

// create client instance
// ...

// register custom validation event handler
client.ValidatingCertificate += client_ValidatingCertificate;

// connect securely (SslMode.Explicit or SslMode.Implicit)
client.Connect(hostname, SslMode.Explicit);
' create client instance
' ...

' register custom validation event handler
AddHandler client.ValidatingCertificate, AddressOf client_ValidatingCertificate

' connect securely (SslMode.Explicit or SslMode.Implicit)
client.Connect(hostname, SslMode.Explicit)

Implement the custom validation within the event handler

public void client_ValidatingCertificate(object sender, SslCertificateValidationEventArgs e)
{
    // first try to use the default validation (against the Windows certificate store)
    ValidationResult res = e.CertificateChain.Validate(e.ServerName, 0);
    if (res.Valid)
    {
        e.Accept();
        return;
    }

    // get server certificate of the current connection
    Certificate cert = e.CertificateChain[0];

    // check the certificate is already known
    if (trustedThumbprints.Contains(cert.Thumbprint))
    {
        e.Accept();
        return;
    }

    // the certificate is not know yet - show it to user
    Console.WriteLine("Do you trust to the following certificate?");
    Console.WriteLine(" Common name: {0}", cert.GetCommonName());
    Console.WriteLine(" Thumbprint:  {0}", cert.Thumbprint);
    Console.WriteLine(" Expires on:  {0:d}", cert.GetExpirationDate());

    // ask user for the answer
    // ...

    // accept or reject the certificate
    if (userAnswer)
    {
        e.Accept();
        // OPTIONALY store the current certificate as trusted
        trustedThumbprints.Add(cert.Thumbprint);
    }
    else
    {
        e.Reject();
    }
}
Public Sub client_ValidatingCertificate(sender As Object, e As SslCertificateValidationEventArgs)
    ' first try to use the default validation (against the Windows certificate store)
    Dim res = e.CertificateChain.Validate(e.ServerName, 0)
    If res.Valid Then
        e.Accept()
        Return
    End If

    ' get server certificate of the current connection
    Dim cert As Certificate = e.CertificateChain(0)

    ' check the certificate is already known
    If trustedThumbprints.Contains(cert.Thumbprint) Then
        e.Accept()
        Return
    End If

    ' the certificate is not know yet - show it to user
    Console.WriteLine("Do you trust to the following certificate?")
    Console.WriteLine(" Common name: {0}", cert.GetCommonName())
    Console.WriteLine(" Thumbprint:  {0}", cert.Thumbprint)
    Console.WriteLine(" Expires on:  {0:d}", cert.GetExpirationDate())

    ' ask user for the answer
    ' ...

    ' accept or reject the certificate
    If userAnswer Then
        e.Accept()
        ' OPTIONALY store the current certificate as trusted
        trustedThumbprints.Add(cert.Thumbprint)
    Else
        e.Reject()
    End If
End Sub

Overriding SSL server name 

Server certificate's common name should specify the server hostname - this ensures that the server presents a certificate that actually belongs to it. If the names are mismatched, you can still work around it.

Security settings and algorithms 

When connecting with Rebex Graph via TLS/SSL, you can easily configure desired TLS versions, cipher suites, elliptic curves and other parameters.

TLS/SSL protocol versions

Use Settings.SslAllowedVersions property (on client object) to enable or disable specific versions of the TLS/SSL protocol. Supported versions:

  • TLS 1.3 (not available on .NET Compact Framework)
  • TLS 1.2
  • TLS 1.1
  • TLS 1.0
  • SSL 3.0

Note: TLS 1.3 is still a very new protocol and some legacy servers have issues communicating with clients that support TLS 1.3 in addition to earlier versions. Therefore, to prevent interoperability issues, TLS 1.3 support is not enabled in Rebex Graph by default. To enable it:

  • C#: client.Settings.SslAllowedVersions |= TlsVersion.TLS13;
  • VB.NET: client.Settings.SslAllowedVersions = client.Settings.SslAllowedVersions Or TlsVersion.TLS13

Note: SSL 3.0 is no longer considered secure and it's disabled by default. To enable it:

  • C#: client.Settings.SslAllowedVersions |= TlsVersion.SSL30;
  • VB.NET: client.Settings.SslAllowedVersions = client.Settings.SslAllowedVersions Or TlsVersion.SSL30

TLS 1.3 cipher suites

The following TLS 1.3 ciphers are supported:

  • TLS_AES_128_GCM_SHA256 (AES/GCM with 128-bit key)
  • TLS_AES_256_GCM_SHA384 (AES/GCM with 256-bit key)
  • TLS_CHACHA20_POLY1305_SHA256 (ChaCha20-Poly1305 AEAD cipher)

Use Settings.SetSymmetricCipherSuites(...) method (on the client object) to specify a list of allowed TLS 1.3 symmetric cipher suites, and Settings.GetSymmetricCipherSuites() method to retrieve the current setting.

Note: TLS_CHACHA20_POLY1305_SHA256 cipher is not enabled by default. It uses a managed implementation that is slower than AES/GCM alternatives on mainstream Windows platforms.

TLS 1.3 key exchange algorithms

The following TLS 1.3 key exchange algorithms are supported:

  • secp256r1 (ECDH with NIST P-256 curve)
  • secp384r1 (ECDH with NIST P-384 curve)
  • secp521r1 (ECDH with NIST P-521 curve)
  • X25519 (ECDH with Curve25519; needs a plugin on Windows 8.1 / Windows Server 2012 or earlier and on non-Windows platforms)

TLS 1.3 signature algorithms

The following TLS 1.3 signature algorithms are supported:

  • ecdsa_secp256r1_sha256 (ECDSA with NIST P-256 curve and SHA-256)
  • ecdsa_secp384r1_sha384 (ECDSA with NIST P-384 curve and SHA-384)
  • ecdsa_secp521r1_sha512 (ECDSA with NIST P-521 curve and SHA-512)
  • rsa_pss_rsae_sha256 (RSA with RSASSA-PSS scheme and SHA-256)
  • rsa_pss_rsae_sha384 (RSA with RSASSA-PSS scheme and SHA-384)
  • rsa_pss_rsae_sha512 (RSA with RSASSA-PSS scheme and SHA-512)
  • ed25519 (EdDSA with edwards25519 curve and SHA-512)

In TLS 1.3, certificates signed by the following signature algorithms are supported:

  • ECDSA with SHA-256, SHA-384 or SHA-512 (corresponds to TLS 1.3 ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384 and ecdsa_secp521r1_sha512 algorithms)
  • ECDSA with SHA-1 (legacy certificates; corresponds to TLS 1.3 ecdsa_sha1 algorithm)
  • RSASSA-PSS with SHA-256, SHA-384 or SHA-512 (corresponds to TLS 1.3 rsa_pss_rsae_sha256, rsa_pss_rsae_sha384 and rsa_pss_rsae_sha512 algorithms)
  • RSASSA-PKCS1-v1_5 with SHA-256, SHA-384 or SHA-512 (corresponds to TLS 1.3 rsa_pkcs1_sha256, rsa_pkcs1_sha384 and rsa_pkcs1_sha512 algorithms)
  • RSASSA-PKCS1-v1_5 with SHA-1 (legacy certificates; corresponds to TLS 1.3 rsa_pkcs1_sha1 algorithm)
  • EdDSA with edwards25519 curve and SHA-512 (corresponds to TLS 1.3 ed25519; needs a custom certificate verifier)
Note: On Xamarin, Mono and older Windows platforms, elliptic curve algorithms (ECDH and ECDSA) are only available with an external plugins.

TLS 1.2/1.1/1.0 cipher suites

The Settings.SslAllowedSuites property (on the client object) makes it possible to specify a combination of following algorithms:

Cipher ID Certificate Key Algorithm Key Exchange Algorithm Encryption Algorithm MAC Alg.
RSA_WITH_​AES_128_GCM_SHA256 RSA RSA AES/GCM AEAD
RSA_WITH_​AES_256_GCM_SHA384 AES/GCM AEAD
RSA_WITH_​AES_128_CBC_SHA256 AES/CBC SHA-256
RSA_WITH_​AES_256_CBC_SHA256 AES/CBC SHA-256
RSA_EXPORT_WITH_​RC4_40_MD5 RC4 MD5
RSA_WITH_​RC4_128_MD5 RC4 MD5
RSA_WITH_​RC4_128_SHA RC4 SHA-1
RSA_EXPORT_WITH_​RC2_CBC_40_MD5 RC2/CBC MD5
RSA_EXPORT_WITH_​DES40_CBC_SHA DES/CBC SHA-1
RSA_WITH_​DES_CBC_SHA DES/CBC SHA-1
RSA_WITH_​3DES_EDE_CBC_SHA 3DES/CBC SHA-1
RSA_EXPORT1024_WITH_​DES_CBC_SHA DES/CBC SHA-1
RSA_EXPORT1024_WITH_​RC4_56_SHA RC4 SHA-1
RSA_WITH_​AES_128_CBC_SHA AES/CBC SHA-1
RSA_WITH_​AES_256_CBC_SHA AES/CBC SHA-1
ECDHE_RSA_WITH_​AES_128_GCM_SHA256 RSA Elliptic Curve Diffie-Hellman AES/GCM AEAD
ECDHE_RSA_WITH_​AES_256_GCM_SHA384 AES/GCM AEAD
ECDHE_RSA_WITH_​CHACHA20_POLY1305_SHA256 ChaCha20-Poly1305 AEAD
ECDHE_RSA_WITH_​AES_128_CBC_SHA256 AES/CBC SHA-256
ECDHE_RSA_WITH_​AES_256_CBC_SHA384 AES/CBC SHA-384
ECDHE_RSA_WITH_​AES_128_CBC_SHA AES/CBC SHA-1
ECDHE_RSA_WITH_​AES_256_CBC_SHA AES/CBC SHA-1
ECDHE_RSA_WITH_​3DES_EDE_CBC_SHA 3DES/CBC SHA-1
ECDHE_RSA_WITH_​RC4_128_SHA RC4 SHA-1
ECDHE_ECDSA_WITH_​AES_128_GCM_SHA256 Elliptic Curve DSA Elliptic Curve Diffie-Hellman AES/GCM AEAD
ECDHE_ECDSA_WITH_​AES_256_GCM_SHA384 AES/GCM AEAD
ECDHE_ECDSA_WITH_​CHACHA20_POLY1305_SHA256 ChaCha20-Poly1305 AEAD
ECDHE_ECDSA_WITH_​AES_128_CBC_SHA256 AES/CBC SHA-256
ECDHE_ECDSA_WITH_​AES_256_CBC_SHA384 AES/CBC SHA-384
ECDHE_ECDSA_WITH_​AES_128_CBC_SHA AES/CBC SHA-1
ECDHE_ECDSA_WITH_​AES_256_CBC_SHA AES/CBC SHA-1
ECDHE_ECDSA_WITH_​3DES_EDE_CBC_SHA 3DES/CBC SHA-1
ECDHE_ECDSA_WITH_​RC4_128_SHA RC4 SHA-1
DHE_RSA_WITH_​AES_128_GCM_SHA256 RSA Diffie-Hellman AES/GCM AEAD
DHE_RSA_WITH_​AES_256_GCM_SHA384 AES/GCM AEAD
DHE_RSA_WITH_​CHACHA20_POLY1305_SHA256 ChaCha20-Poly1305 AEAD
DHE_RSA_WITH_​AES_128_CBC_SHA256 AES/CBC SHA-256
DHE_RSA_WITH_​AES_256_CBC_SHA256 AES/CBC SHA-256
DHE_RSA_EXPORT_WITH_​DES40_CBC_SHA DES/CBC SHA-1
DHE_RSA_WITH_​DES_CBC_SHA DES/CBC SHA-1
DHE_RSA_WITH_​3DES_EDE_CBC_SHA 3DES/CBC SHA-1
DHE_RSA_WITH_​AES_128_CBC_SHA AES/CBC SHA-1
DHE_RSA_WITH_​AES_256_CBC_SHA AES/CBC SHA-1
DHE_DSS_WITH_​AES_128_GCM_SHA256 DSS Diffie-Hellman AES/GCM AEAD
DHE_DSS_WITH_​AES_256_GCM_SHA384 AES/GCM AEAD
DHE_DSS_WITH_​AES_128_CBC_SHA256 AES/CBC SHA-256
DHE_DSS_WITH_​AES_256_CBC_SHA256 AES/CBC SHA-256
DHE_DSS_EXPORT_WITH_​DES40_CBC_SHA DES/CBC SHA-1
DHE_DSS_WITH_​DES_CBC_SHA DES/CBC SHA-1
DHE_DSS_WITH_​3DES_EDE_CBC_SHA 3DES/CBC SHA-1
DHE_DSS_WITH_​AES_128_CBC_SHA AES/CBC SHA-1
DHE_DSS_WITH_​AES_256_CBC_SHA AES/CBC SHA-1
DHE_DSS_EXPORT1024_WITH_​DES_CBC_SHA DES/CBC SHA-1
DHE_DSS_EXPORT1024_WITH_​RC4_56_SHA RC4 SHA-1
DHE_DSS_WITH_​RC4_128_SHA RC4 SHA-1
DH_anon_WITH_​AES_256_CBC_SHA256 no certificate Diffie-Hellman AES/CBC SHA-256
DH_anon_WITH_​AES_128_CBC_SHA256 AES/CBC SHA-256
DH_anon_WITH_​AES_256_CBC_SHA AES/CBC SHA-1
DH_anon_WITH_​AES_128_CBC_SHA AES/CBC SHA-1
DH_anon_WITH_​RC4_128_MD5 RC4 MD5
DH_anon_WITH_​3DES_EDE_CBC_SHA 3DES/CBC SHA-1
DH_anon_WITH_​DES_CBC_SHA DES/CBC SHA-1
Note: Vulnerable cipher suites are switched off by default. To enable them, set Settings.SslAllowVulnerableSuites to true. However, this is strongly discouraged.
Note: CHACHA20_POLY1305 ciphers are not enabled by default. They use a managed implementation that is slower than AES/GCM alternatives on mainstream Windows platforms.
Ciphers based on modular Diffie-Hellman algorithm (those with "DHE_" prefix) are known to be very slow on legacy hardware. To only enable ciphers that are fast and also sufficiently secure, use TlsCipherSuite.Fast enum value.

TLS/SSL extensions

Rebex Graph supports Server Name Identification (SNI) extension and Renegotiation Indication extension.

TLS/SSL elliptic curves

The Settings.SslAllowedCurves property (on client object) makes it possible to specify a set of enabled elliptic curves used by ECDHE ciphers above. Supported elliptic curves:

Curve ID Curve Name
NistP256* NIST P-256 curve
NistP384* NIST P-384 curve
NistP521* NIST P-521 curve
BrainpoolP256R1** Brainpool P-256 R1 curve
BrainpoolP384R1** Brainpool P-384 R1 curve
BrainpoolP512R1** Brainpool P-512 R1 curve
Curve25519*** X25519 curve

* These curves require a plugin on Xamarin, Mono, and legacy Windows platforms.

** These curves require a plugin on Xamarin, Mono, and Windows earlier than Windows 10 / Windows Server 2016.

*** These curves require a plugin on non-Windows platforms and on Windows earlier than Windows 10 / Windows Server 2016.

Certificate validation options

Use Settings.SslServerCertificateValidationOptions property to specify various options for the build-in certificate verifier. For example:

  • IgnoreCnNotMatch (Ignore common name mismatch)
  • SkipRevocationCheck (Skip revocation check)
  • IgnoreCnNotMatch (Ignore invalid common name)
  • IgnoreWrongUsage (Ignore wrong usage)
  • IgnoreTimeNotNested (Ignore improperly nested validity periods)
  • AllowUnknownCa (Allow unknown certification authority)
Note: Please make sure you understand the implications of these options when using them in production environments.

Back to feature list...