/learn_you_some_ssl.ex Secret
Last active
January 3, 2021 15:36
Star
You must be signed in to star a gist
Code snippets from 'Learn you some :ssl' talk at ElixirConf EU 2019
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
iex(1)> :httpc.request('https://elixir-lang.org') | |
** (exit) exited in: :gen_server.call(:httpc_manager, {:request, # ... | |
** (EXIT) no process: the process is not alive or there's no process | |
currently associated with the given name, possibly because its | |
application isn't started | |
# ... | |
iex(2)> :inets.start() | |
:ok | |
iex(3)> :ssl.start() | |
:ok | |
iex(4)> :httpc.request('https://elixir-lang.org') | |
{:ok, | |
{{'HTTP/1.1', 200, 'OK'}, | |
# ... | |
iex(5)> :httpc.request(:get, {'https://elixir-lang.org', []}, | |
...(5)> [], []) | |
{:ok, | |
{{'HTTP/1.1', 200, 'OK'}, | |
# ... | |
iex(6)> :httpc.request(:get, {'https://selfsigned.voltone.net', []}, | |
...(6)> [], []) | |
{:ok, | |
{{'HTTP/1.1', 200, 'OK'}, | |
# ... | |
iex(7)> :httpc.request(:get, {'https://selfsigned.voltone.net', []}, | |
...(7)> [ssl: [verify: :verify_peer]], []) | |
{:ok, | |
{{'HTTP/1.1', 200, 'OK'}, | |
# ... | |
### Scratching my head for a minute... | |
iex(8)> :httpc.request(:get, {'https://selfsigned.voltone.net', []}, | |
...(8)> [ssl: [verify: :verify_peer]], []) | |
{:error, | |
{:failed_connect, | |
[ | |
{:to_address, {'selfsigned.voltone.net', 443}}, | |
{:inet, [:inet], {:options, {:cacertfile, []}}} | |
]}} | |
iex(9)> h = [{'Connection', 'close'}] | |
[{'Connection', 'close'}] | |
iex(10)> :httpc.request(:get, {'https://selfsigned.voltone.net', h}, | |
...(10)> [ssl: [verify: :verify_peer]], []) | |
{:error, | |
{:failed_connect, | |
[ | |
{:to_address, {'selfsigned.voltone.net', 443}}, | |
{:inet, [:inet], {:options, {:cacertfile, []}}} | |
]}} | |
iex(11)> :httpc.request(:get, {'https://selfsigned.voltone.net', h}, | |
...(11)> [ssl: [ | |
...(11)> verify: :verify_peer, | |
...(11)> cacertfile: '/dev/null' # Essentially an empty file | |
...(11)> ]], []) | |
{:ok, | |
{{'HTTP/1.1', 200, 'OK'}, | |
# ... | |
iex(12)> :httpc.request(:get, {'https://selfsigned.voltone.net', h}, | |
...(12)> [ssl: [ | |
...(12)> verify: :verify_peer, | |
...(12)> cacertfile: '/dev/null', | |
...(12)> reuse_sessions: false | |
...(12)> ]], []) | |
{:error, | |
{:failed_connect, | |
[ | |
{:to_address, {'selfsigned.voltone.net', 443}}, | |
{:inet, [:inet], {:tls_alert, 'bad certificate'}} | |
]}} | |
iex(13)> :httpc.request(:get, {'https://selfsigned.voltone.net', h}, | |
...(13)> [ssl: [ | |
...(13)> verify: :verify_peer, | |
...(13)> cacertfile: '/etc/ssl/certs/ca-certificates.crt', | |
...(13)> reuse_sessions: false | |
...(13)> ]], []) | |
{:error, | |
{:failed_connect, | |
[ | |
{:to_address, {'selfsigned.voltone.net', 443}}, | |
{:inet, [:inet], {:tls_alert, 'bad certificate'}} | |
]}} | |
iex(14)> :httpc.request(:get, {'https://elixir-lang.org/', h}, | |
...(14)> [ssl: [ | |
...(14)> verify: :verify_peer, | |
...(14)> cacertfile: '/etc/ssl/certs/ca-certificates.crt', | |
...(14)> reuse_sessions: false | |
...(14)> ]], []) | |
{:ok, | |
{{'HTTP/1.1', 200, 'OK'}, | |
# ... | |
iex(15)> :httpc.request(:get, {'https://sha256.badssl.com/', h}, | |
...(15)> [ssl: [ | |
...(15)> verify: :verify_peer, | |
...(15)> cacertfile: '/etc/ssl/certs/ca-certificates.crt', | |
...(15)> reuse_sessions: false | |
...(15)> ]], []) | |
{:error, | |
{:failed_connect, | |
[ | |
{:to_address, {'sha256.badssl.com', 443}}, | |
{:inet, [:inet], {:tls_alert, 'handshake failure'}} | |
]}} | |
# Log message: TLS client: In state certify at ssl_handshake.erl:1380 | |
# generated CLIENT ALERT: Fatal - Handshake Failure - | |
# {bad_cert,hostname_check_failed} | |
iex(16)> :httpc.request(:get, {'https://sha256.badssl.com/', h}, | |
...(16)> [ssl: [ | |
...(16)> verify: :verify_peer, | |
...(16)> cacertfile: '/etc/ssl/certs/ca-certificates.crt', | |
...(16)> customize_hostname_check: [ | |
...(16)> match_fun: | |
...(16)> :public_key.pkix_verify_hostname_match_fun(:https) | |
...(16)> ], | |
...(16)> reuse_sessions: false | |
...(16)> ]], []) | |
{:ok, | |
{{'HTTP/1.1', 200, 'OK'}, | |
# ... | |
# Assuming HTTPoison in deps and started, e.g. from `iex -S mix` | |
iex(17)> HTTPoison.get("https://elixir-lang.org") | |
{:ok, | |
%HTTPoison.Response{ | |
# ... | |
iex(19)> HTTPoison.get("https://selfsigned.voltone.net", [], | |
...(19)> ssl: [ | |
...(19)> versions: [:"tlsv1.2"] | |
...(19)> ]) | |
{:ok, | |
%HTTPoison.Response{ | |
# ... | |
iex(20)> :httpc.request(:get, {'https://revoked.badssl.com/', h}, | |
...(20)> [ssl: [ | |
...(20)> verify: :verify_peer, | |
...(20)> cacertfile: '/etc/ssl/certs/ca-certificates.crt', | |
...(20)> customize_hostname_check: [ | |
...(20)> match_fun: | |
...(20)> :public_key.pkix_verify_hostname_match_fun(:https) | |
...(20)> ], | |
...(20)> crl_check: true, | |
...(20)> crl_cache: {:ssl_crl_cache, {:internal, [http: 30000]}}, | |
...(20)> reuse_sessions: false | |
...(20)> ]], []) | |
{:error, | |
{:failed_connect, | |
[ | |
{:to_address, {'revoked.badssl.com', 443}}, | |
{:inet, [:inet], {:tls_alert, 'certificate revoked'}} | |
]}} | |
iex(21)> :ssl.cipher_suites(:default, :"tlsv1.2") |> | |
...(21)> :ssl.filter_cipher_suites( | |
...(21)> key_exchange: &(&1 == :ecdhe_rsa), | |
...(21)> mac: &(&1 == :aead) | |
...(21)> ) | |
[ | |
%{cipher: :aes_256_gcm, key_exchange: :ecdhe_rsa, mac: :aead, | |
prf: :sha384}, | |
%{cipher: :aes_128_gcm, key_exchange: :ecdhe_rsa, mac: :aead, | |
prf: :sha256} | |
] | |
# Alternatively... | |
# :ssl.cipher_suites(:default, :”tlsv1.2") |> | |
# Enum.filter(&match?(%{key_exchange: :ecdhe_rsa, mac: :aead}, &1)) | |
iex(22)> ciphers = :ssl.cipher_suites(:default, :"tlsv1.2") |> | |
...(22)> :ssl.filter_cipher_suites( | |
...(22)> cipher: &(&1 == :chacha20_poly1305) | |
...(22)> ) | |
[] | |
iex(23)> :ssl.listen(8443, ciphers: ciphers) | |
{:ok, | |
{:sslsocket, nil, | |
# ...snip... | |
[ | |
<<192, 44>>, # ECDHE-ECDSA-AES256-GCM-SHA384 | |
<<192, 48>>, # ECDHE-RSA-AES256-GCM-SHA384 | |
<<192, 36>>, # ECDHE-ECDSA-AES256-SHA384 | |
<<192, 40>>, # ECDHE-RSA-AES256-SHA384 | |
# ... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment