Skip to content

Commit 65530b8

Browse files
author
madblobfish
committed
ssl: enable generating keying material from SSL sessions
Add OpenSSL::SSL::SSLSocket#export_keying_material to support RFC 5705
1 parent 1955728 commit 65530b8

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

ext/openssl/ossl_ssl.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2429,6 +2429,49 @@ ossl_ssl_alpn_protocol(VALUE self)
24292429
return rb_str_new((const char *) out, outlen);
24302430
}
24312431

2432+
/*
2433+
* call-seq:
2434+
* session.export_keying_material(label, length) -> String
2435+
*
2436+
* Enables use of shared session key material in accordance with RFC 5705.
2437+
*/
2438+
static VALUE
2439+
ossl_ssl_export_keying_material(int argc, VALUE *argv, VALUE self)
2440+
{
2441+
SSL *ssl;
2442+
VALUE str;
2443+
VALUE label;
2444+
VALUE length;
2445+
VALUE context;
2446+
unsigned char *p;
2447+
size_t len;
2448+
int use_ctx = 0;
2449+
unsigned char *ctx;
2450+
size_t ctx_len = 0;
2451+
int ret;
2452+
2453+
rb_scan_args(argc, argv, "21", &label, &length, &context);
2454+
StringValue(label);
2455+
2456+
GetSSL(self, ssl);
2457+
2458+
len = (size_t)NUM2LONG(length);
2459+
str = rb_str_new(0, len);
2460+
p = (unsigned char *)RSTRING_PTR(str);
2461+
if (!NIL_P(context)) {
2462+
use_ctx = 1;
2463+
StringValue(context);
2464+
ctx = (unsigned char *)RSTRING_PTR(context);
2465+
ctx_len = RSTRING_LEN(context);
2466+
}
2467+
ret = SSL_export_keying_material(ssl, p, len, (char *)RSTRING_PTR(label),
2468+
RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
2469+
if (ret == 0 || ret == -1) {
2470+
ossl_raise(eSSLError, "SSL_export_keying_material");
2471+
}
2472+
return str;
2473+
}
2474+
24322475
/*
24332476
* call-seq:
24342477
* ssl.tmp_key => PKey or nil
@@ -2856,6 +2899,7 @@ Init_ossl_ssl(void)
28562899
rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
28572900
rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
28582901
rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
2902+
rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1);
28592903
# ifndef OPENSSL_NO_NEXTPROTONEG
28602904
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
28612905
# endif

test/openssl/test_ssl.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,6 +1817,19 @@ def test_fileno
18171817
sock2.close
18181818
end
18191819

1820+
def test_export_keying_material
1821+
start_server do |port|
1822+
cli_ctx = OpenSSL::SSL::SSLContext.new
1823+
server_connect(port, cli_ctx) do |ssl|
1824+
assert_instance_of(String, ssl.export_keying_material('ttls keying material', 64))
1825+
assert_operator(64, :==, ssl.export_keying_material('ttls keying material', 64).b.length)
1826+
assert_operator(8, :==, ssl.export_keying_material('ttls keying material', 8).b.length)
1827+
assert_operator(5, :==, ssl.export_keying_material('test', 5, 'context').b.length)
1828+
ssl.puts "abc"; ssl.gets # workaround to make tests work on windows
1829+
end
1830+
end
1831+
end
1832+
18201833
private
18211834

18221835
def start_server_version(version, ctx_proc = nil,

0 commit comments

Comments
 (0)