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

Rainer
Is there somewhere a good introduction to rust for experienced programmers (with years of C++/C#/Java experience)? Wanted to give it a t...
New
mrmurphy
I’ve run into a situation where I’ve got a list of posts inside of a container that uses phx-update=“prepend”, and the posts on the socke...
New
bsek43
Hello everyone, I’ve started learning Elixir and Phoenix few months ago and while I mostly grasped Elixir’s functional concepts and Phoe...
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
JimmyCarterSon
I am confused about the Schema setup, I am setting up a new application and I want to seed files in it as well. I tried to mix to create...
New
Fl4m3Ph03n1x
Background I have to queries that return a colossal amount of data on their own. I cannot use Repo.all as doing so would materialize thes...
New
sona11
I wrote this code to calculate Fibonacci numbers by specifying the size. The results are correct, however the one thing that concerns me ...
New
New
pillaiindu
What is the difference between using :references and :belongs_to in the following command? bin/rails generate scaffold LineItem product:...
New
yamuna
Hi everyone, I’m trying to run deepseek-coder:6.7b-instruct-q4_K_M in Docker using Ollama to create an LLM that will be used by CrewAI a...
New

Other popular topics Top

Devtalk
Hello Devtalk World! Please let us know a little about who you are and where you’re from :nerd_face:
New
DevotionGeo
I know that these benchmarks might not be the exact picture of real-world scenario, but still I expect a Rust web framework performing a ...
New
Rainer
My first contact with Erlang was about 2 years ago when I used RabbitMQ, which is written in Erlang, for my job. This made me curious and...
New
PragmaticBookshelf
From finance to artificial intelligence, genetic algorithms are a powerful tool with a wide array of applications. But you don't need an ...
New
AstonJ
This looks like a stunning keycap set :orange_heart: A LEGENDARY KEYBOARD LIVES ON When you bought an Apple Macintosh computer in the e...
New
PragmaticBookshelf
Learn different ways of writing concurrent code in Elixir and increase your application's performance, without sacrificing scalability or...
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
25 puzzles that will make you a better C programmer by challenging your knowledge of the language, and explaining the technical details o...
New
PragmaticBookshelf
Quickly turn complex problems into simple, working solutions using functional programming, safe concurrency, and the expressive tools of ...
New
CommunityNews
Open-source implementation of the classic GTA engine now running directly in your browser. Experience the reVC technology demo on DOS.Zon...
New