Class: Iodine::TLS
- Inherits:
-
Data
- Object
- Data
- Iodine::TLS
- Defined in:
- lib/iodine/tls.rb,
ext/iodine/iodine_tls.c
Overview
Iodine's TLS instances hold SSL/TLS settings for secure connections.
This allows both secure client connections and secure server connections to be established.
tls = Iodine::TLS.new "localhost" # self-signed certificate
Iodine.listen service: "http", handler: APP, tls: tls
Iodine abstracts away the underlying SSL/TLS library to minimize the risk of misuse and insecure settings.
Calling TLS methods when no SSL/TLS library is available should result in iodine crashing. This is expected behavior.
At the moment, only OpenSSL is supported. BearSSL support is planned.
Instance Method Summary collapse
-
#initialize(*args) ⇒ Object
constructor
Loads the mustache template found in
:filename
. -
#on_protocol(protocol_name) ⇒ Object
Adds an ALPN protocol callback for the named protocol, the required block must return the handler for that protocol.
-
#trust(certificate) ⇒ Object
Adds a certificate PEM file to the list of trusted certificates and enforces peer verification.
-
#use_certificate(*args) ⇒ Object
Assigns the TLS context a public sertificate, allowing remote parties to validate the connection's identity.
Constructor Details
#initialize(*args) ⇒ Object
Loads the mustache template found in :filename
. If :template
is provided
it will be used instead of reading the file's content.
Iodine::Mustache.new(filename, template = nil)
When template data is provided, filename (if any) will only be used for partial template path resolution and the template data will be used for the template's content. This allows, for example, for front matter to be extracted before parsing the template.
Once a template was loaded, it could be rendered using render.
Accepts named arguments as well:
Iodine::Mustache.new(filename: "foo.mustache", template: "{{ bar }}")
228 229 230 231 232 233 |
# File 'ext/iodine/iodine_tls.c', line 228
static VALUE iodine_tls_new(int argc, VALUE *argv, VALUE self) {
if (argc) {
iodine_tls_use_certificate(argc, argv, self);
}
return self;
}
|
Instance Method Details
#on_protocol(protocol_name) ⇒ Object
Adds an ALPN protocol callback for the named protocol, the required block must return the handler for that protocol.
The first protocol added will be the default protocol in cases where ALPN failed.
i.e.:
tls.on_protocol("http/1.1") { HTTPConnection.new }
When implementing TLS clients, this identifies the protocol(s) that should be requested by the client.
When implementing TLS servers, this identifies the protocol(s) offered by the server.
More than a single protocol can be set, but iodine doesn't offer, at this moment, a way to handle these changes or to detect which protocol was selected except by assigning a different callback per protocol.
This is implemented using the ALPN extension to TLS.
198 199 200 201 202 203 204 205 206 207 208 |
# File 'ext/iodine/iodine_tls.c', line 198
static VALUE iodine_tls_alpn(VALUE self, VALUE protocol_name) {
Check_Type(protocol_name, T_STRING);
rb_need_block();
fio_tls_s *t = iodine_tls2c(self);
char *prname =
(protocol_name == Qnil ? NULL : IODINE_RSTRINFO(protocol_name).data);
VALUE block = IodineStore.add(rb_block_proc());
fio_tls_alpn_add(t, prname, iodine_tls_alpn_cb, (void *)block,
(void (*)(void *))IodineStore.remove);
return self;
}
|
#trust(certificate) ⇒ Object
Adds a certificate PEM file to the list of trusted certificates and enforces peer verification.
This is extremely important when using Iodine::TLS for client connections, since adding the target server's
It is enough to add the Certificate Authority's (CA) certificate, there's no need to add each client or server certificate.
When #trust is used on a server TLS, only trusted clients will be allowed to connect.
Since TLS setup is crucial for security, a missing file will result in Iodine crashing with an error message. This is expected behavior.
166 167 168 169 170 171 172 173 |
# File 'ext/iodine/iodine_tls.c', line 166
static VALUE iodine_tls_trust(VALUE self, VALUE certificate) {
Check_Type(certificate, T_STRING);
fio_tls_s *t = iodine_tls2c(self);
char *pubcert =
(certificate == Qnil ? NULL : IODINE_RSTRINFO(certificate).data);
fio_tls_trust(t, pubcert);
return self;
}
|
#use_certificate(*args) ⇒ Object
Assigns the TLS context a public sertificate, allowing remote parties to validate the connection's identity.
A self signed certificate is automatically created if the server_name
argument
is specified and either (or both) of the certificate
or private_ket
arguments are missing.
Some implementations allow servers to have more than a single certificate, which will be selected using the SNI extension. I believe the existing OpenSSL implementation supports this option (untested).
Iodine::TLS#use_certificate(server_name,
certificate = nil,
private_key = nil,
password = nil)
Certificates and keys should be String objects leading to a PEM file.
This method also accepts named arguments. i.e.:
tls = Iodine::TLS.new
tls.use_certificate server_name: "example.com"
tls.use_certificate certificate: "my_cert.pem", private_key: "my_key.pem"
Since TLS setup is crucial for security, a missing file will result in Iodine crashing with an error message. This is expected behavior.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'ext/iodine/iodine_tls.c', line 109
static VALUE iodine_tls_use_certificate(int argc, VALUE *argv, VALUE self) {
VALUE server_name = Qnil, certificate = Qnil, private_key = Qnil,
password = Qnil;
if (argc == 1 && RB_TYPE_P(argv[0], T_HASH)) {
/* named arguments */
server_name = rb_hash_aref(argv[0], server_name_sym);
certificate = rb_hash_aref(argv[0], certificate_sym);
private_key = rb_hash_aref(argv[0], private_key_sym);
password = rb_hash_aref(argv[0], password_sym);
} else {
/* regular arguments */
switch (argc) {
case 4: /* overflow */
password = argv[3];
Check_Type(password, T_STRING);
case 3: /* overflow */
private_key = argv[1];
Check_Type(private_key, T_STRING);
case 2: /* overflow */
certificate = argv[2];
Check_Type(certificate, T_STRING);
case 1: /* overflow */
server_name = argv[0];
Check_Type(server_name, T_STRING);
break;
default:
rb_raise(rb_eArgError, "expecting 1..4 arguments or named arguments.");
return self;
}
}
fio_tls_s *t = iodine_tls2c(self);
char *srvname = (server_name == Qnil ? NULL : StringValueCStr(server_name));
char *pubcert = (certificate == Qnil ? NULL : StringValueCStr(certificate));
char *prvkey = (private_key == Qnil ? NULL : StringValueCStr(private_key));
char *pass = (password == Qnil ? NULL : StringValueCStr(password));
fio_tls_cert_add(t, srvname, pubcert, prvkey, pass);
return self;
}
|