[ruby/openssl] ssl: enable generating keying material from SSL sessions
Add OpenSSL::SSL::SSLSocket#export_keying_material to support RFC 5705 https://github.com/ruby/openssl/commit/65530b887e
This commit is contained in:
parent
a98096349e
commit
79543b9a53
@ -2433,6 +2433,49 @@ ossl_ssl_alpn_protocol(VALUE self)
|
|||||||
return rb_str_new((const char *) out, outlen);
|
return rb_str_new((const char *) out, outlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* session.export_keying_material(label, length) -> String
|
||||||
|
*
|
||||||
|
* Enables use of shared session key material in accordance with RFC 5705.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
ossl_ssl_export_keying_material(int argc, VALUE *argv, VALUE self)
|
||||||
|
{
|
||||||
|
SSL *ssl;
|
||||||
|
VALUE str;
|
||||||
|
VALUE label;
|
||||||
|
VALUE length;
|
||||||
|
VALUE context;
|
||||||
|
unsigned char *p;
|
||||||
|
size_t len;
|
||||||
|
int use_ctx = 0;
|
||||||
|
unsigned char *ctx;
|
||||||
|
size_t ctx_len = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
rb_scan_args(argc, argv, "21", &label, &length, &context);
|
||||||
|
StringValue(label);
|
||||||
|
|
||||||
|
GetSSL(self, ssl);
|
||||||
|
|
||||||
|
len = (size_t)NUM2LONG(length);
|
||||||
|
str = rb_str_new(0, len);
|
||||||
|
p = (unsigned char *)RSTRING_PTR(str);
|
||||||
|
if (!NIL_P(context)) {
|
||||||
|
use_ctx = 1;
|
||||||
|
StringValue(context);
|
||||||
|
ctx = (unsigned char *)RSTRING_PTR(context);
|
||||||
|
ctx_len = RSTRING_LEN(context);
|
||||||
|
}
|
||||||
|
ret = SSL_export_keying_material(ssl, p, len, (char *)RSTRING_PTR(label),
|
||||||
|
RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
|
||||||
|
if (ret == 0 || ret == -1) {
|
||||||
|
ossl_raise(eSSLError, "SSL_export_keying_material");
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* ssl.tmp_key => PKey or nil
|
* ssl.tmp_key => PKey or nil
|
||||||
@ -2860,6 +2903,7 @@ Init_ossl_ssl(void)
|
|||||||
rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
|
rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
|
||||||
rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
|
rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
|
||||||
rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
|
rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
|
||||||
|
rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1);
|
||||||
# ifndef OPENSSL_NO_NEXTPROTONEG
|
# ifndef OPENSSL_NO_NEXTPROTONEG
|
||||||
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
|
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
|
||||||
# endif
|
# endif
|
||||||
|
@ -1817,6 +1817,19 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
|
|||||||
sock2.close
|
sock2.close
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_export_keying_material
|
||||||
|
start_server do |port|
|
||||||
|
cli_ctx = OpenSSL::SSL::SSLContext.new
|
||||||
|
server_connect(port, cli_ctx) do |ssl|
|
||||||
|
assert_instance_of(String, ssl.export_keying_material('ttls keying material', 64))
|
||||||
|
assert_operator(64, :==, ssl.export_keying_material('ttls keying material', 64).b.length)
|
||||||
|
assert_operator(8, :==, ssl.export_keying_material('ttls keying material', 8).b.length)
|
||||||
|
assert_operator(5, :==, ssl.export_keying_material('test', 5, 'context').b.length)
|
||||||
|
ssl.puts "abc"; ssl.gets # workaround to make tests work on windows
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def start_server_version(version, ctx_proc = nil,
|
def start_server_version(version, ctx_proc = nil,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user