Deno World
Published in

Deno World

3 ways of accepting self-signed certificates in Deno

Introduction

Hypertext Transfer Protocol Secure (HTTPS) is an extension of the Hypertext Transfer Protocol (HTTP). It is used for secure communication over a computer network, and is widely used on the Internet. HTTPS is even more important since the advent of HTTP/2 as most of the implementations don’t support unsecure (plaintext) HTTP/2.

In cryptography, a certificate authority or certification authority (CA) is an entity that issues digital certificates. A digital certificate certifies the ownership of a public key by the named subject of the certificate. This allows others to rely upon signatures or on assertions made about the private key that corresponds to the certified public key. A CA acts as a trusted third party — trusted both by the subject (owner) of the certificate and by the party relying upon the certificate.

One particularly common use for certificate authorities is to sign certificates used in HTTPS. A certificate signed by a trusted CA costs money. A self-signed certificate is a certificate that their users issue on their own behalf, as opposed to a certificate authority (CA) issuing them. These certificates are easy to make and do not cost money. However, they do not provide any trust value.

While the self-signed certificates do not provide a programmatic trust, it might be required to use them in situations like development testing, local servers in the org network/data center, and public servers that are trusted but do not have a CA backed certificate.

Issue with self-signed certificate

By default, Deno rejects a self-signed certificate. In other words, by default, Deno doesn’t trust a server that can’t provide a CA backed certificate.

Let’s say an HTTPS service is running on localhost:8100. A fetch request to that server would result in error:

await fetch("https://localhost:8100"); error: Uncaught (in promise) TypeError: error sending request for url (https://localhost:8100/): error trying to connect: invalid peer certificate contents: invalid peer certificate: UnknownIssuer

A TypeError is raised whenever Deno encounters an untrusted certificate. This default behavior is right. But, as mentioned above, there are cases when it’s okay to selectively trust some self-signed certificates.

Let’s go over the 3 ways of accepting a self-signed certificate.

Here is the app.ts file that’ll be used for all the examples:

//app.tsconst res=await fetch("https://localhost:8100");
console.log(await res.text());

Trust all / Trust hosts

The first and easiest option is to choose the trusted hosts from which all kind of certificates would be accepted.

Deno comes with a command line option to either trust all self-signed certificates or trust from particular hosts.

Trusting all hosts should never be done in production

The command line option is called — unsafely-ignore-certificate-error. If no host names are provided, then all self-signed certificates are trusted. Deno prints a warning at startup to indicate that the application is running at risk.

$ deno run --allow-net --unsafely-ignore-certificate-errors app.ts
DANGER: TLS certificate validation is disabled for all hostnames
Hello World

As we can see, Deno proceeds with the HTTP connection by accepting the self-signed certificate. This can be confirmed with the ‘Hello World’ log line.

The same command line option can be used with specify host names from which the self-signed certificate would be accepted. All other unsafe hosts would still raise error.

$ deno run --allow-net --unsafely-ignore-certificate-errors=localhost app.ts
DANGER: TLS certificate validation is disabled for: localhost
Hello world

This is much better than accepting self-signed certificates from everywhere.

Use cert from command-line

The second option is to use — cert command-line option to supply a self-signed certificate at application startup. Deno would allow HTTP connection to the servers using this particular certificate.

Let’s say ca.pem is the certificate provided by a fake authority (server itself) that has signed the server’s certificate. The certificate authority is not a trusted one.

$ deno run --allow-net --cert ./ca.pem app.ts
Hello world

The requests to servers using different certificates would still fail. In the following example, the server running on localhost:8100 is using a different certificate.

$ deno run --allow-net --cert ./ca.pem app.ts
Sending fatal alert BadCertificate
error: Uncaught (in promise) TypeError: error sending request for url (https://localhost:8100/): error trying to connect: invalid peer certificate contents: invalid peer certificate: UnsupportedCertVersion

Use cert from store

The third and the last option is to place/use the self-signed certificate in/from the system’s certificate store. There are three steps involved:

  • Add the self-signed certificate to the system’s certificate store

On Mac, this requires adding ca.pem to keychain access app

  • Once ca.pem is added to system’s store, it needs to be marked as trusted

On Mac, this requires opening the self-signed certificate and choosing the option of always trust

  • An environment variable called DENO_TLS_CA_STORE needs to be set to system:
export DENO_TLS_CA_STORE=system

Once all the above is done, the Deno application can be executed without any additional command-line options:

$ deno run --allow-net app.ts
Hello world

This story is a part of the exclusive medium publication on Deno: Deno World.

--

--

--

The one and only exclusive medium magazine with 200+ articles on Deno

Recommended from Medium

React & Docker for Development and Production

Ace Your First AWS Certification in 10 Days

CS373 Spring 2022: An Vi Nguyen

How to manipulate gpx files using python

Implementing Acceptance Test-Driven Development (ATDD)

Docker Basic Commands. PS Cheat Sheet Ep-01

Cloud Journey: Starting with Enterprise Scale — Part 3

Dynamic Form Builder With a “Stateless Client”.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mayank Choubey

Mayank Choubey

Deno, Node.js, etc.

More from Medium

HTTP echo server in Deno

Deno nuggets: Write raw data on console

Deno nuggets: TCP client

Deno by example: Content server — Part 2 Formatting & linting