Fl4m3Ph03n1x

Fl4m3Ph03n1x

Cannot compile ssl_verify_fun in Windows 11 for Elixir

Background

I have a phoenix application in Windows 11. Unfortunately for me, I cannot compile the application because of a dependency error in Windows.

What I tried

First I tried the downloading Erlang from the official website (Downloads - Erlang/OTP), and Elixir
1.15.4 for OTP 26 (Installing Elixir - The Elixir programming language)

Unfortunately for me, I was greeted with an error when running mix phx.server.

$ mix deps.compile ssl_verify_fun
==> ssl_verify_fun
Compiling 7 files (.erl)
src/ssl_verify_hostname.erl:16: can't find include lib "public_key/include/public_key.hrl"

So, this lead me into this Elixir thread where the same issue happens for Ubuntu:

The solution found was for the user to install a special erlang package for Ubuntu, erlang-dev. However, since I am on Windows, I don’t really have that option.

So I removed both Erlang and Elixir and installed them using scoop, hoping the older versions of both Elixir and Erlang available there would be free of this issue.

With scoop I am now using:

elixir 1.15.4   main   2023-07-27 10:27:04
erlang 25.3.2.4 main   2023-07-27 10:10:31

Error

However, this still does not fix the issue, as I am greeted with a barrage of errors:

==> ssl_verify_fun
Compiling 7 files (.erl)
src/ssl_verify_fingerprint.erl:15:14: can't find include lib "public_key/include/public_key.hrl"
%   15| -include_lib("public_key/include/public_key.hrl").
%     |              ^

src/ssl_verify_pk.erl:14:14: can't find include lib "public_key/include/public_key.hrl"
%   14| -include_lib("public_key/include/public_key.hrl").
%     |              ^

src/ssl_verify_fun_cert_helpers.erl:13:14: can't find include lib "public_key/include/public_key.hrl"
%   13| -include_lib("public_key/include/public_key.hrl").
%     |              ^

src/ssl_verify_fingerprint.erl:27:26: record 'OTPCertificate' undefined
%   27| -spec verify_fun(Cert :: #'OTPCertificate'{},
%     |                          ^

src/ssl_verify_pk.erl:26:26: record 'OTPCertificate' undefined
%   26| -spec verify_fun(Cert :: #'OTPCertificate'{},
%     |                          ^

src/ssl_verify_fun_cert_helpers.erl:23:34: undefined macro 'id-ce-subjectAltName'
%   23|   AltSubject = select_extension(?'id-ce-subjectAltName', Extensions),
%     |                                  ^

src/ssl_verify_fingerprint.erl:29:39: record 'Extension' undefined
%   29|                           {extension, #'Extension'{}}, InitialUserState :: term()) ->
%     |                                       ^

src/ssl_verify_pk.erl:28:39: record 'Extension' undefined
%   28|                           {extension, #'Extension'{}}, InitialUserState :: term()) ->
%     |                                       ^

src/ssl_verify_hostname.erl:16:14: can't find include lib "public_key/include/public_key.hrl"
%   16| -include_lib("public_key/include/public_key.hrl").
%     |              ^

src/ssl_verify_fun_cert_helpers.erl:9:2: function extract_dns_names/1 undefined
%    9| -export([extract_dns_names/1,
%     |  ^

src/ssl_verify_fingerprint.erl:52:39: record 'OTPCertificate' undefined
%   52| -spec verify_cert_fingerprint(Cert :: #'OTPCertificate'{}, Fingerprint :: fingerprint()) ->
%     |                                       ^

src/ssl_verify_pk.erl:51:30: record 'OTPCertificate' undefined
%   51| -spec verify_cert_pk(Cert :: #'OTPCertificate'{}, Pk :: pk()) ->
%     |                              ^

src/ssl_verify_hostname.erl:28:26: record 'OTPCertificate' undefined
%   28| -spec verify_fun(Cert :: #'OTPCertificate'{},
%     |                          ^

src/ssl_verify_fun_cert_helpers.erl:19:2: spec for undefined function extract_dns_names/1
%   19| -spec extract_dns_names(Cert :: #'OTPCertificate'{}) -> [] | [string()].
%     |  ^

src/ssl_verify_hostname.erl:30:39: record 'Extension' undefined
%   30|                           {extension, #'Extension'{}}, InitialUserState :: term()) ->
%     |                                       ^

src/ssl_verify_fun_cert_helpers.erl:19:33: record 'OTPCertificate' undefined
%   19| -spec extract_dns_names(Cert :: #'OTPCertificate'{}) -> [] | [string()].
%     |                                 ^

src/ssl_verify_hostname.erl:46:36: record 'OTPCertificate' undefined
%   46| -spec verify_cert_hostname(Cert :: #'OTPCertificate'{}, Hostname :: hostname()) ->
%     |                                    ^

src/ssl_verify_fun_cert_helpers.erl:32:26: record 'OTPCertificate' undefined
%   32| -spec extract_cn(Cert :: #'OTPCertificate'{}) -> {error, no_common_name} | {ok, string()} | {error, invalid}.
%     |                          ^

src/ssl_verify_hostname.erl:76:38: record 'OTPCertificate' undefined
%   76|                              Cert :: #'OTPCertificate'{},
%     |                                      ^

src/ssl_verify_fun_cert_helpers.erl:34:17: record 'OTPCertificate' undefined
%   34|   TBSCert = Cert#'OTPCertificate'.tbsCertificate,
%     |                 ^

src/ssl_verify_fun_cert_helpers.erl:35:32: record 'OTPTBSCertificate' undefined
%   35|   {rdnSequence, List} = TBSCert#'OTPTBSCertificate'.subject,
%     |                                ^

src/ssl_verify_fun_cert_helpers.erl:38:26: record 'OTPCertificate' undefined
%   38| -spec extract_pk(Cert :: #'OTPCertificate'{}) -> {error, no_common_name} | #'SubjectPublicKeyInfo'{}.
%     |                          ^

src/ssl_verify_fun_cert_helpers.erl:38:76: record 'SubjectPublicKeyInfo' undefined
%   38| -spec extract_pk(Cert :: #'OTPCertificate'{}) -> {error, no_common_name} | #'SubjectPublicKeyInfo'{}.
%     |                                                                            ^

src/ssl_verify_fun_cert_helpers.erl:40:17: record 'OTPCertificate' undefined
%   40|   TBSCert = Cert#'OTPCertificate'.tbsCertificate,
%     |                 ^

src/ssl_verify_fun_cert_helpers.erl:41:26: record 'OTPTBSCertificate' undefined
%   41|   PublicKeyInfo = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo,
%     |                          ^

src/ssl_verify_fun_cert_helpers.erl:42:16: record 'OTPSubjectPublicKeyInfo' undefined
%   42|   PublicKeyInfo#'OTPSubjectPublicKeyInfo'.subjectPublicKey.
%     |                ^

src/ssl_verify_fun_cert_helpers.erl:48:24: record 'Extension' undefined
%   48| -spec extensions_list([#'Extension'{}] | asn1_NOVALUE) -> [] | [#'Extension'{}].
ean it with "mix deps.clean ssl_verify_fun"n, "mix compile" failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile ssl_verify_fun --force", update it with "mix deps.update ssl_verify_fun" or cl%     |                        ^
src/ssl_verify_fun_cert_helpers.erl:48:65: record 'Extension' undefined
%   48| -spec extensions_list([#'Extension'{}] | asn1_NOVALUE) -> [] | [#'Extension'{}].
%     |                                                                 ^

src/ssl_verify_fun_cert_helpers.erl:55:39: record 'Extension' undefined
%   55| -spec select_extension(Id :: term(), [#'Extension'{}]) -> undefined | #'Extension'{}.
%     |                                       ^

src/ssl_verify_fun_cert_helpers.erl:55:71: record 'Extension' undefined
%   55| -spec select_extension(Id :: term(), [#'Extension'{}]) -> undefined | #'Extension'{}.
%     |                                                                       ^

src/ssl_verify_fun_cert_helpers.erl:57:28: record 'Extension' undefined
%   57|   Matching = [Extension || #'Extension'{extnID = ExtId} = Extension <- Extensions, ExtId =:= Id],
%     |                            ^

src/ssl_verify_fun_cert_helpers.erl:57:84: variable 'ExtId' is unbound
%   57|   Matching = [Extension || #'Extension'{extnID = ExtId} = Extension <- Extensions, ExtId =:= Id],
%     |                                                                                    ^

src/ssl_verify_fun_cert_helpers.erl:75:15: record 'AttributeTypeAndValue' undefined
%   75| extract_cn2([[#'AttributeTypeAndValue'{type={2, 5, 4, 3},
%     |               ^

src/ssl_verify_fun_cert_helpers.erl:77:39: variable 'CN' is unbound
%   77|   ssl_verify_fun_encodings:get_string(CN);
%     |                                       ^

src/ssl_verify_fun_cert_helpers.erl:49:1: Warning: function extensions_list/1 is unused
%   49| extensions_list(E) ->
%     | ^

src/ssl_verify_fun_cert_helpers.erl:56:1: Warning: function select_extension/2 is unused
%   56| select_extension(Id, Extensions) ->
%     | ^

src/ssl_verify_fun_cert_helpers.erl:64:1: Warning: function extract_dns_names_from_alt_names/2 is unused
%   64| extract_dns_names_from_alt_names([ExtValue | Rest], Acc) ->
%     | ^

At this point, given my setup is on Windows, I don’t know what else to try.

Question

How can I fix this issue?

Marked As Solved

Fl4m3Ph03n1x

Fl4m3Ph03n1x

Answer

After some more digging I found out this issue:

Which represents my problem. Basically Elixir does not check the correct paths for the missing file:

Now, there is a possible workaround for this issue. By forcing your application to use a more updated version of the dependency in question (ssl_verify_fun), you can add this to your mix.exs file:

{:ssl_verify_fun, “~> 1.1.7”, manager: :rebar3, override: true}

However, I don’t really like this. If tomorrow the same thing happens, you have to overwrite again. And when overwrites start conflicting with each other, then you really have a problem.

In my case, I found which application was using the old version of ssl_verify_fun by looking at mix.lock. It was hackney.

However, instead of going through every dependency and trying to fix it, I took the more nuclear approach. I deleted my mix.lock and then run mix deps.update --all.

This forced some older dependencies to update. After that a simple mix deps.get fixed the issue and mix phx.server worked.

You can find more information in the Elixir Forum thread:

Also Liked

kokolegorille

kokolegorille

Sometime removing mix.lock and _build, deps folders is helping in dev.

But it might not be recommended otherwise :slight_smile:

Glad You find a solution to your problem.

Where Next?

Popular Backend topics Top

dimitarvp
As a part of my new job I’ll have to learn to manage a local k8s cluster. The tools used are microk8s, tilt and helm. I’ll appreciate an...
New
Kurisu
Hello and happy new year! I would like to buy a Ruby On Rails ebook for learning purpose. What would be the ROR equivalent of “Programm...
New
Jsdr3398
Are there any databases that require no setup (can be shipped in a small zip together with the project)?
New
New
GermaVinsmoke
Reading Programming Elixir 1.6 book, I’ve completed part 1 of the book. Now I’m thinking of reading Elixir in Action. What do you all sug...
New
New
Fl4m3Ph03n1x
Background While playing around with dialyzer, typespecs and currying, I was able to create an example of a false positive in dialyzer. ...
New
osbre
Hello everyone I’m trying to implement a “magic link” or “one-time login link” functionality I wonder what a secure way to implement it...
New
harwind
I have a large SQL database with millions of records, and I’ve identified duplicate entries. What’s the most efficient way to find and re...
New
Fl4m3Ph03n1x
Background I have an umbrella app where I use a dependecy called ETS. This dependency has a type called set_options that I use in some of...
New

Other popular topics Top

PragmaticBookshelf
Free and open source software is the default choice for the technologies that run our world, and it’s built and maintained by people like...
New
brentjanderson
Bought the Moonlander mechanical keyboard. Cherry Brown MX switches. Arms and wrists have been hurting enough that it’s time I did someth...
New
New
AstonJ
I ended up cancelling my Moonlander order as I think it’s just going to be a bit too bulky for me. I think the Planck and the Preonic (o...
New
PragmaticBookshelf
Learn different ways of writing concurrent code in Elixir and increase your application's performance, without sacrificing scalability or...
New
PragmaticBookshelf
Create efficient, elegant software tests in pytest, Python's most powerful testing framework. Brian Okken @brianokken Edited by Kat...
New
PragmaticBookshelf
Build efficient applications that exploit the unique benefits of a pure functional language, learning from an engineer who uses Haskell t...
New
PragmaticBookshelf
Build modern server-driven web applications using htmx. Whatever programming language you use, you’ll write less (and cleaner) code. ...
New
NewsBot
Node.js v22.14.0 has been released. Link: Release 2025-02-11, Version 22.14.0 'Jod' (LTS), @aduh95 · nodejs/node · GitHub
New
PragmaticBookshelf
Fight complexity and reclaim the original spirit of agility by learning to simplify how you develop software. The result: a more humane a...
New