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