CompileNotes
13 min readPasindu Ekanayake

How HTTPS and TLS Certificates Work: CAs, Certificate Chains, and Trust

A practical guide to HTTPS, TLS certificates, Certificate Authorities, root and intermediate certificates, certificate chains, and how a client decides whether to trust a server.

  • HTTPS
  • TLS
  • SSL Certificates
  • Security
On this page

If you have worked with web apps, backend APIs, infrastructure, desktop clients, or mobile apps, you have probably seen terms like SSL certificate, TLS, Certificate Authority, root certificate, or certificate chain.

They tend to appear when something goes wrong.

Maybe an API suddenly starts returning an SSL error. Maybe a browser refuses to load a page. Maybe a service-to-service call fails after a certificate rotation. Maybe you need to add certificate or public-key pinning to an application. Or maybe somebody sends you a .cer, .crt, or .pem file and expects you to know what to do with it.

It is easy to know that HTTPS is secure and that certificates are involved, but still not have a clear picture of how all the pieces connect.

So before getting into topics like SSL pinning, it helps to understand the normal HTTPS trust process first.

First: SSL vs TLS

People still commonly say SSL certificate, but modern HTTPS connections use TLS, not the old SSL protocols.

SSL came first. TLS replaced it.

So when someone says:

"The SSL certificate is expiring next month."

they usually mean the certificate being used by the server for its TLS connection.

In this article, I will mostly use TLS certificate, but you will still see the term SSL certificate everywhere in hosting dashboards, documentation, support tickets, and everyday engineering conversations.

What HTTPS Actually Gives Us

Suppose a client calls this API:

https://api.example.com

HTTPS gives us three closely related protections.

First, the traffic between the client and the server is encrypted, so someone observing the connection should not be able to read the application data.

Second, TLS protects the integrity of that traffic, so modification in transit can be detected.

Third, the client gets a way to verify that it is actually talking to the server it expects.

Those protections work together, but they solve different parts of the problem.

Imagine that an application sends:

{
  "username": "pasindu",
  "password": "example-password"
}

We obviously do not want someone sitting between the client and the server to read that request.

TLS protects that traffic.

But encryption alone is not enough.

An attacker could theoretically say:

"Sure, I can give you an encrypted connection. Encrypt your data with me."

That would still be a problem.

The client also needs to know:

"Am I really connected to api.example.com?"

That is where certificates and the trust system become important.

What Is a TLS Certificate?

A TLS certificate is a digital document that connects an identity, such as a domain name, with a public key.

A simplified certificate might contain information like:

Domain:
api.example.com
 
Public Key:
<server public key>
 
Issuer:
DigiCert
 
Valid From:
January 1, 2026
 
Valid Until:
January 1, 2027
 
Digital Signature:
<issuer signature>

Real certificates contain more information than this, but this is enough to understand the basic idea.

The important pieces are:

  • who the certificate belongs to
  • the public key
  • who issued the certificate
  • when it is valid
  • a digital signature proving that the certificate was issued by the claimed issuer

Public Key and Private Key

Certificates make more sense once we understand the basic public/private key relationship.

The server has a key pair:

Private Key
Public Key

The private key must remain secret on the server.

The public key can be shared.

The TLS certificate contains the public key, or more precisely the public-key information associated with the server.

A very simplified view looks like this:

Server
│
├── Private Key
│   └── Secret
│
└── TLS Certificate
    └── Contains public-key information

The private key is important because possessing it allows the server to prove during the TLS handshake that it really owns the certificate being presented.

One important point is that HTTPS does not simply encrypt every request directly with the certificate's public key.

Modern TLS uses the handshake to establish shared symmetric session keys, and those session keys are then used to encrypt the actual application traffic.

So conceptually:

TLS handshake
  (certificate authentication + key agreement)
        ↓
Shared traffic keys derived
        ↓
Protected HTTP traffic

Symmetric cryptography is much more efficient for protecting large amounts of application data.

But Who Says the Certificate Is Trustworthy?

This is the next question.

Anybody can create a certificate.

I could create one on my laptop claiming:

Domain: google.com

That does not mean your browser, operating system, or runtime should trust it.

We need another party to verify identities and sign certificates.

That is the role of a Certificate Authority, usually shortened to CA.

What Is a Certificate Authority?

A Certificate Authority is an organization trusted to issue certificates.

Examples you may have seen include:

  • DigiCert
  • Let's Encrypt
  • Sectigo
  • GlobalSign

When a CA issues a certificate, it digitally signs it.

That signature allows a client to verify that the certificate was issued by a trusted party and has not simply been created by somebody pretending to own the domain.

A simplified relationship looks like this:

Certificate Authority
        ↓ signs
api.example.com certificate

But there is another question.

Why should your browser, operating system, or runtime trust DigiCert, Let's Encrypt, Sectigo, or GlobalSign in the first place?

That brings us to the trust store.

The Trust Store

A client needs some set of trust anchors that it already accepts.

These are typically root certificates belonging to Certificate Authorities.

Depending on the environment, that trust may come from the operating system, a browser, a runtime, an application-specific configuration, or a combination of these.

This collection of trusted certificates is commonly referred to as a trust store.

Very roughly:

Client Trust Store
│
├── Trusted Root CA A
├── Trusted Root CA B
├── Trusted Root CA C
└── ...

You normally do not add every website certificate manually to your browser, laptop, phone, or server runtime.

Instead, the client environment trusts a set of root Certificate Authorities.

Those trusted roots can then establish trust for other certificates.

This is what allows a client to connect securely to millions of HTTPS services without storing every individual server certificate permanently.

Root Certificates

A root certificate sits at the top of a certificate trust hierarchy.

For example, a root CA might have a certificate representing its root identity.

Conceptually:

Trusted Root Certificate

The client environment trusts this certificate directly because it exists as a trust anchor in the trust store being used for validation.

Root certificates are especially sensitive because they can be used to establish trust for certificates below them.

For that reason, root private keys are generally protected very carefully.

Certificate Authorities usually do not use a root certificate directly to issue every website certificate.

Instead, they normally introduce another layer.

Intermediate Certificates

Between the root certificate and the website certificate, there is usually one or more intermediate certificates.

The root signs an intermediate certificate.

The intermediate then signs certificates used by actual servers.

For example:

Root Certificate
      ↓ signs
Intermediate Certificate
      ↓ signs
api.example.com Certificate

This structure provides better operational security.

The root key can stay heavily protected, while intermediate certificates handle day-to-day certificate issuance.

If an intermediate certificate ever needs to be revoked or replaced, the root certificate does not necessarily need to change.

Leaf Certificates

The certificate used directly by a website or API server is often called the leaf certificate or end-entity certificate.

In our example:

api.example.com

would have the leaf certificate.

So we now have three useful terms:

Root
  ↓
Intermediate
  ↓
Leaf

or:

Root CA Certificate
        ↓
Intermediate CA Certificate
        ↓
api.example.com Certificate

This relationship is called a certificate chain.

What Is a Certificate Chain?

When a server presents its certificate, the client needs to determine whether that certificate can eventually be connected to something the client already trusts.

Suppose the server gives the client:

api.example.com certificate
Intermediate CA certificate

The client can then build a trust path:

api.example.com
      ↓ signed by
Intermediate CA
      ↓ signed by
Trusted Root CA

The root certificate normally already exists in the trust store used by the client, so the server usually does not need to send it.

This is why you sometimes see certificate information described as:

Leaf certificate
Intermediate certificate
Root certificate

Understanding this chain becomes extremely important later when we discuss SSL pinning.

A More Realistic Example

Imagine our API is:

https://api.mybank.example

The server may present a certificate chain conceptually similar to:

api.mybank.example
        ↓
DigiCert Intermediate CA
        ↓
DigiCert Root CA

The exact names will depend on the real certificates being used, but the idea is the same.

The client does not necessarily need to have the api.mybank.example certificate permanently stored.

Instead, it verifies that the certificate can be traced back through a valid chain to a trusted root.

What Happens When a Client Makes an HTTPS Request?

Now let's connect everything to an actual request.

An application might ask for a resource like this:

https://api.example.com/user/profile

At the application layer, this may look like a simple browser navigation, a fetch call, an HTTP client request, or a backend service calling another backend service.

But underneath that simple request, much more is happening.

A simplified flow is:

Application code
        ↓
Application/networking API
        ↓
Networking stack
        ↓
TLS handshake
        ↓
Server sends certificate chain
        ↓
Certificate validation
        ↓
Encrypted connection established
        ↓
HTTP request sent

Different platforms hide this work behind different layers.

Browsers have their own networking stack and certificate handling behavior.

Android applications commonly use networking clients such as OkHttp.

iOS applications commonly use Apple's URL loading and networking APIs, such as URLSession.

React Native or Flutter code may expose a simple JavaScript or Dart API, while the actual TLS work happens deeper in the underlying platform and networking stack.

The important point is the same across these environments:

The application code may only show one simple request, but certificate exchange and validation happen lower in the networking stack.

What Does the Client Validate?

When the server presents its certificate, the client does not simply check:

"Does this certificate exist?"

Several checks are involved.

Is the certificate currently valid?

Certificates have validity periods.

For example:

Valid From: 2026-01-01
Valid Until: 2027-01-01

If the certificate has expired, validation should fail.

Does the domain match?

If the client connects to:

api.example.com

the certificate must be valid for that hostname.

A certificate for:

another-example.com

should not be accepted just because it was issued by a trusted CA.

Is the certificate chain valid?

The client verifies signatures through the certificate chain.

Conceptually:

Leaf certificate
      ↓
Intermediate CA
      ↓
Trusted Root CA

The chain should eventually lead to a trusted root.

Is the issuer trusted?

If the chain cannot terminate at a root trusted by the client environment, normal certificate validation should fail.

Has something else made the certificate invalid?

There are other parts of certificate and TLS validation as well, including certificate extensions, usage constraints, signature algorithms, and potentially revocation-related checks depending on the platform and configuration.

We do not need all of those details yet.

The main point is that HTTPS certificate validation is much more than checking whether a server happens to have a certificate.

What Happens If the Certificate Is Self-Signed?

Developers often encounter self-signed certificates in development environments.

A self-signed certificate is signed by its own private key rather than being part of a normal public CA chain.

For example:

Development Server Certificate
        │
        └── signed by itself

Your development machine may trust it if you install the certificate manually or explicitly configure the relevant environment to trust it.

But another machine, browser, server runtime, or mobile device will not automatically trust that certificate just because it exists.

This is why development servers using self-signed certificates often produce errors such as:

SSLHandshakeException
certificate verify failed
unable to get local issuer certificate

The exact error depends on the platform and networking library.

What Happens When a Certificate Expires?

Certificates are intentionally temporary.

A leaf certificate might be valid for months rather than many years.

Eventually it needs to be renewed or replaced.

Imagine this:

Client
    ↓
api.example.com
    ↓
Certificate expired yesterday

The TLS validation fails before the application can safely communicate with the API.

From the application's perspective, this can look like a network failure even though:

  • the internet connection is working
  • the server is running
  • the API code itself is healthy

The TLS connection fails before the normal HTTP request can complete.

This is one reason certificate expiry dates matter so much in production systems.

It becomes even more important when SSL pinning is involved.

Where SSL Pinning Enters the Picture

Normal HTTPS essentially asks:

"Can this server certificate be validated through the trust system that this client accepts?"

SSL pinning introduces another restriction.

Instead of trusting every certificate that passes normal validation, the application can say:

"I also expect a particular certificate or public key."

Conceptually:

Normal TLS validation
        ↓
Certificate trusted?
        ↓ Yes
Pin validation
        ↓
Expected certificate/public key?
      Yes   No
       │     │
       ↓     ↓
  Continue  Reject

That additional check is the foundation of certificate and public-key pinning.

But pinning also introduces new problems:

  • What happens when the leaf certificate is renewed?
  • Should we pin the leaf certificate or an intermediate?
  • Should we pin the whole certificate or only its public key?
  • Should pinning happen in application code, platform networking code, or both?
  • How do browsers, server runtimes, Android, and iOS networking stacks handle it?
  • How do we confirm that pinning is actually being enforced?

Those are easier to reason about once the TLS connection itself is less of a black box.

A Mental Model Worth Remembering

If you forget most of the terminology later, this is the part worth remembering:

Server
  ↓
Leaf Certificate
  ↓ signed by
Intermediate Certificate
  ↓ signed by
Root Certificate
  ↓
Already trusted by the client's trust store

The client checks whether it can build a valid path from the server certificate to a root it trusts.

If it can, and the other certificate checks pass, TLS can continue.

SSL pinning adds another layer by narrowing that trust even further.

Final Notes

You do not need to memorize every field inside an X.509 certificate before working with HTTPS.

What matters initially is understanding the relationship:

HTTPS
+
TLS
+
Certificates
+
Certificate Authorities
+
Certificate Chain
+
Trust Store

Once that picture is clear, the next useful step is How the TLS Handshake Actually Works.

That means looking at what happens while a TLS connection is being established: how the client and server negotiate the connection, where certificates are exchanged, how certificate validation fits into the process, and how both sides arrive at the keys used to protect application traffic.

After that foundation is clear, topics like SSL pinning, public-key pinning, certificate rotation, OkHttp CertificatePinner, iOS trust evaluation, and other platform-specific security implementations become much easier to reason about.