Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SSL support to mug #10

Open
wants to merge 65 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
c123d06
fix typo in doc comment
arnu515 Nov 12, 2024
a5052f2
bump gleam version to 1.0
arnu515 Nov 12, 2024
4abf89e
Add a script to generate SSL certificates
arnu515 Nov 12, 2024
4e1e050
Ignore generated certs
arnu515 Nov 12, 2024
fec4fa2
Start an echo SSL server along with the TCP server
arnu515 Nov 12, 2024
5ccd275
Add SSL support
arnu515 Nov 12, 2024
9519343
Generate keys before running tests
arnu515 Nov 12, 2024
82720ab
Add a function (unimplemented) to support certs_keys
arnu515 Nov 12, 2024
61b0e38
Update README.md to showcase SSL support
arnu515 Nov 12, 2024
aa09fb5
Remove unused imports
arnu515 Nov 14, 2024
b1589a4
Migrate the exact receive tests over to SSL
arnu515 Nov 14, 2024
c83c0a4
Add the ability to upgrade a TCP socket to a TLS socket
arnu515 Nov 14, 2024
74abcd1
fix typo in README
arnu515 Nov 14, 2024
e3db634
Add an example on upgrading a TCP connection to TLS in the README
arnu515 Nov 14, 2024
49ba4f8
Add better examples!
arnu515 Nov 14, 2024
ab550b8
Add doc comments to the upgrade functions
arnu515 Nov 14, 2024
862b8db
Rename `SSLConnectionOptions` to `SslConnectionOptions`
arnu515 Nov 15, 2024
bd26e77
Remove `upgrade` and rename `upgrade3` to `upgrade`
arnu515 Nov 15, 2024
6a4971a
Remove unnecessary comment
arnu515 Nov 15, 2024
a57eb02
Add label
arnu515 Nov 16, 2024
e9943f9
Added certs_keys support (tests are still pending!)
arnu515 Nov 16, 2024
6eabd97
Use an erlang function to add the certs_keys option
arnu515 Nov 16, 2024
eb7fe4f
Add types for SSL-specific errors
arnu515 Nov 16, 2024
ee2b61a
Add `new()` method to SSL
arnu515 Nov 16, 2024
ded407a
Update README to reflect new functions
arnu515 Nov 16, 2024
cc1bc4a
Fix imports
arnu515 Nov 16, 2024
4b7a2bc
Expose start() and stop() methods
arnu515 Nov 16, 2024
44f5f07
Normalise TlsAlert Errors
arnu515 Nov 17, 2024
f61b185
Rework how certificates are passed
arnu515 Nov 17, 2024
b77ae74
Add downgrade example
arnu515 Nov 17, 2024
1b7d266
Ask user to depend on SSL application in README
arnu515 Nov 17, 2024
6fee6b9
Rename the `ssl` module to `tls`
arnu515 Nov 17, 2024
ca5d020
Add ability to disable using system cacerts
arnu515 Nov 17, 2024
bc199ff
Rename `mug_ssl_test` to `mug_tls_test`
arnu515 Nov 27, 2024
600d8c9
Remove io import
arnu515 Nov 27, 2024
2ca1290
Convert gleam strings to erlang strings
arnu515 Dec 2, 2024
f7c1751
Rewrite tests
arnu515 Dec 2, 2024
bbc2fea
Properly generate certs
arnu515 Dec 2, 2024
8bbd59d
Fix
arnu515 Dec 2, 2024
1e30f80
Fix deprecations warnings from stdlib
GearsDatapacks Dec 3, 2024
50567eb
v1.2.0
lpil Dec 4, 2024
93dd8fb
Use gleam version 1.4.0
arnu515 Dec 4, 2024
3772094
Fix stdlib deprecations
arnu515 Dec 4, 2024
306797f
Merge branch 'lpil:main' into main
arnu515 Dec 5, 2024
e97b1a1
fix: instruct user to depend on the `ssl` app
arnu515 Dec 5, 2024
79f3a8b
No piping into functions
arnu515 Dec 5, 2024
fbe5e30
Rename the Certificates type to VerificationMethod
arnu515 Dec 5, 2024
9db1219
Remove failing testcase
arnu515 Dec 5, 2024
91e6ad3
Rename NoVerification to DangerouslyDisableVerification
arnu515 Dec 6, 2024
516f176
Call rescue on cacerts_get and return error to caller
arnu515 Dec 7, 2024
9cd7691
Add
arnu515 Dec 22, 2024
ffb9429
Merge into one file
arnu515 Dec 22, 2024
d10d434
Add `ssl` to `extra_applications`
arnu515 Dec 22, 2024
ddc9842
Detect if running in CI
arnu515 Dec 25, 2024
d1941c3
Exit if not running in project root
arnu515 Dec 25, 2024
bf61854
Replace `pushd` and `popd` with `cd`
arnu515 Dec 25, 2024
38fab38
Update error message
arnu515 Dec 25, 2024
7881f15
feat: add testing instructions
arnu515 Jan 23, 2025
387fda9
fix: remove io.debug
arnu515 Jan 23, 2025
aa413df
Update comment explaining the `sleep` call
arnu515 Jan 23, 2025
1e989d5
Fix test to use system CAs
arnu515 Jan 23, 2025
2811bc2
Make Socket constructors opaque
arnu515 Jan 23, 2025
9fd6da7
Remove SslNotStarted error
arnu515 Jan 23, 2025
c460079
feat: don't use erlang.rescue
arnu515 Mar 9, 2025
654f371
format
arnu515 Mar 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ jobs:
rebar3-version: "3"
- run: gleam format --check src test
- run: gleam deps download
- run: ./test/certs/gencerts.sh
- run: gleam test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
*.ez
build
erl_crash.dump
test/certs/*
!test/certs/gencerts.sh
95 changes: 95 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,99 @@ pub fn main() {
It also includes support for receiving packages as Erlang messages, enabling
TCP sockets to be used within OTP actors.

It also has SSL (TLS) support!

```gleam
// Make sure you depend on the `ssl` application in `gleam.toml`!
// This can be done by adding `ssl` to the list of `extra_applications` under the
// erlang key in the `gleam.toml` file.
// More info here: https://gleam.run/writing-gleam/gleam-toml/

import mug/tls as mug

pub fn main() {
// Form a connection to a TCP+TLS server
let assert Ok(socket) =
mug.new("example.com", port: 443) // HTTPS port!
|> mug.timeout(milliseconds: 5000)
|> mug.connect()

// Talk over an encrypted connection!
let assert Ok(Nil) =
mug.send(socket, <<"HEAD / HTTP/1.1\r\nHost: example.com\r\n\r\n":utf8>>)
let assert Ok(data) = mug.receive(socket, 5000)
let assert Ok(data) = bit_array.to_string(data)
let assert "HTTP/1.1 200 OK\r\n" <> _ = data
}
```

You can also upgrade an existing TCP connection to TLS! This can be useful for
applications which negotiate over plain TCP first, and then upgrade to an
encrypted connection (for example SMTP).

```gleam
import gleam/option.{Some}
import mug
import mug/tls

pub fn main() {
// Form a connection to a TCP server
let assert Ok(tcp_socket) =
mug.new("erlang-the-movie-2.example.com", port: 12345)
|> mug.timeout(milliseconds: 500)
|> mug.connect()

// Talk over plain text!
let assert Ok(Nil) = mug.send(socket, <<"Let's upgrade!\n":utf8>>)
let assert Ok(_) = mug.receive(socket, timeout_milliseconds: 100)

// Now upgrade the connection
let assert Ok(socket) = tls.upgrade(
tcp_socket,
// Do not check certificates (Do not use in prod!!)
tls.NoVerification,
// Timeout after 1000 millis
milliseconds: 1000
)

// Talk over an encrypted connection!
let assert Ok(Nil) =
tls.send(socket, <<"Hello, Joe!\n":utf8>>)
let assert Ok(_) = tls.receive(socket, 5000)

// Downgrade to an unencrypted connection
case tls.downgrade(socket, milliseconds: 1000) {
Error(tls.Closed) -> {
// Downgrade failed, so the connection was closed.
Nil
}
Ok(#(tcp_socket, data)) -> {
// `data` is the first piece of data received (if any)
// after downgrade
let assert Some(_) = data
let assert Ok(Nil) = mug.send(socket, <<"Scary unencrypted connection!\n":utf8>>)
}
Error(_) -> {
// Downgrade failed for other reasons
Nil
}
}
}
```

Documentation can be found at <https://hexdocs.pm/mug>.

## Testing the library

Some tests testing the TLS capabilities of `mug` require there to be a CA
certificate and a regular certificate and their keys to be present in the
`test/certs` folder. These certs can be generated if you have OpenSSL installed
by running the `./test/certs/gencerts.sh` script from the project's root
directory. If these certificates are not present, you will get a
`Pattern match failed` error on most tests in the `mug_tls_test.gleam` file.

```bash
$ ./test/certs/gencerts.sh # Run this first if you haven't already!

$ gleam test
```
3 changes: 3 additions & 0 deletions gleam.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ licences = ["Apache-2.0"]
repository = { type = "github", user = "lpil", repo = "mug" }
links = [{ title = "Website", href = "https://gleam.run" }]

[erlang]
extra_applications = ["ssl"]

[dependencies]
gleam_stdlib = ">= 0.44.0 and < 2.0.0"
gleam_erlang = ">= 0.22.0 and < 1.0.0"
Expand Down
Loading