Answer After some more digging I found out this issue:
opened 03:19PM - 12 Jun 23 UTC
closed 05:20PM - 12 Jun 23 UTC
### Elixir and Erlang/OTP versions Erlang/OTP 25 [erts-13.2] [source] [64-bit] … [smp:10:10] [ds:10:10:10] [async-threads:1] [jit] Elixir 1.15.0-rc.2 (9a9cf41) (compiled with Erlang/OTP 25) ### Operating system macOS Ventura 13.4 ### Current behavior When compiling a project with `ssl_verify_fun` as a dependency, running `mix deps.compile` fails when using Elixir 1.15.0-rc.2. ``` > mix deps.compile ssl_verify_fun --force ==> ssl_verify_fun Compiling 7 files (.erl) 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_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_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_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_hostname.erl:28:26: record 'OTPCertificate' undefined % 28| -spec verify_fun(Cert :: #'OTPCertificate'{}, % | ^ src/ssl_verify_pk.erl:26:26: record 'OTPCertificate' undefined % 26| -spec verify_fun(Cert :: #'OTPCertificate'{}, % | ^ src/ssl_verify_fingerprint.erl:27:26: record 'OTPCertificate' undefined % 27| -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_hostname.erl:30:39: record 'Extension' undefined % 30| {extension, #'Extension'{}}, InitialUserState :: term()) -> % | ^ src/ssl_verify_pk.erl:28:39: record 'Extension' undefined % 28| {extension, #'Extension'{}}, InitialUserState :: term()) -> % | ^ src/ssl_verify_fingerprint.erl:29:39: record 'Extension' undefined % 29| {extension, #'Extension'{}}, InitialUserState :: term()) -> % | ^ src/ssl_verify_fun_cert_helpers.erl:9:2: function extract_dns_names/1 undefined % 9| -export([extract_dns_names/1, % | ^ src/ssl_verify_hostname.erl:46:36: record 'OTPCertificate' undefined % 46| -spec verify_cert_hostname(Cert :: #'OTPCertificate'{}, Hostname :: hostname()) -> % | ^ src/ssl_verify_pk.erl:51:30: record 'OTPCertificate' undefined % 51| -spec verify_cert_pk(Cert :: #'OTPCertificate'{}, Pk :: pk()) -> % | ^ src/ssl_verify_fingerprint.erl:52:39: record 'OTPCertificate' undefined % 52| -spec verify_cert_fingerprint(Cert :: #'OTPCertificate'{}, Fingerprint :: fingerprint()) -> % | ^ 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:76:38: record 'OTPCertificate' undefined % 76| Cert :: #'OTPCertificate'{}, % | ^ src/ssl_verify_fun_cert_helpers.erl:19:33: record 'OTPCertificate' undefined % 19| -spec extract_dns_names(Cert :: #'OTPCertificate'{}) -> [] | [string()]. % | ^ 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_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'{}]. % | ^ 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) -> % | ^ ``` ### Expected behavior `ssl_verify_fun` should compile like it does in other Elixir versions.
Which represents my problem. Basically Elixir does not check the correct paths for the missing file:
opened 02:14AM - 20 Jun 23 UTC
closed 05:10PM - 14 Jul 23 UTC
Note:Open for guidance
### Elixir and Erlang/OTP versions ``` Erlang/OTP 26 [erts-14.0] [source] [64-… bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit] Elixir 1.15.0 (compiled with Erlang/OTP 26) ``` ### Operating system macOS 13.4 ### Current behavior `public_key/include/public_key.hrl` header cannot be found. To reproduce: ``` git clone https://github.com/deadtrickster/ssl_verify_fun.erl.git && cd ssl_verify_fun.erl && mix compile ``` Output: ```erlang 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_fingerprint.erl:27:26: record 'OTPCertificate' undefined % 27| -spec verify_fun(Cert :: #'OTPCertificate'{}, % | ^ 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_fingerprint.erl:29:39: record 'Extension' undefined % 29| {extension, #'Extension'{}}, InitialUserState :: term()) -> % | ^ src/ssl_verify_hostname.erl:28:26: record 'OTPCertificate' undefined % 28| -spec verify_fun(Cert :: #'OTPCertificate'{}, % | ^ src/ssl_verify_fingerprint.erl:44:39: record 'OTPCertificate' undefined % 44| -spec verify_cert_fingerprint(Cert :: #'OTPCertificate'{}, Fingerprint :: fingerprint()) -> % | ^ src/ssl_verify_hostname.erl:30:39: record 'Extension' undefined % 30| {extension, #'Extension'{}}, InitialUserState :: term()) -> % | ^ 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_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_hostname.erl:46:36: record 'OTPCertificate' undefined % 46| -spec verify_cert_hostname(Cert :: #'OTPCertificate'{}, Hostname :: hostname()) -> % | ^ 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_pk.erl:26:26: record 'OTPCertificate' undefined % 26| -spec verify_fun(Cert :: #'OTPCertificate'{}, % | ^ src/ssl_verify_hostname.erl:76:38: record 'OTPCertificate' undefined % 76| Cert :: #'OTPCertificate'{}, % | ^ src/ssl_verify_fun_cert_helpers.erl:9:2: function extract_dns_names/1 undefined % 9| -export([extract_dns_names/1, % | ^ src/ssl_verify_pk.erl:28:39: record 'Extension' undefined % 28| {extension, #'Extension'{}}, InitialUserState :: term()) -> % | ^ 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_pk.erl:51:30: record 'OTPCertificate' undefined % 51| -spec verify_cert_pk(Cert :: #'OTPCertificate'{}, Pk :: pk()) -> % | ^ src/ssl_verify_fun_cert_helpers.erl:19:33: record 'OTPCertificate' undefined % 19| -spec extract_dns_names(Cert :: #'OTPCertificate'{}) -> [] | [string()]. % | ^ 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_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'{}]. % | ^ 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) -> % | ^ ``` ### Expected behavior Compiles as expected with Elixir `1.14.5`. Output: ```erlang Compiling 7 files (.erl) Generated ssl_verify_fun app ```
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:
I develop in Windows because my application is for Windows users. I literally have no other choice if I want to use Elixir. Besides, given my investigation, I have reason to believe this is not a Windows specific issue, even though I admit I have...
1 Like