libtls 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.yardopts +3 -0
- data/Gemfile +4 -0
- data/LICENSE +13 -0
- data/README.md +279 -0
- data/Rakefile +9 -0
- data/lib/libtls.rb +9 -0
- data/lib/libtls/client.rb +195 -0
- data/lib/libtls/config.rb +112 -0
- data/lib/libtls/exn.rb +22 -0
- data/lib/libtls/raw.rb +759 -0
- data/lib/libtls/server.rb +128 -0
- data/lib/libtls/version.rb +8 -0
- data/libtls.gemspec +30 -0
- data/spec/fixtures/mike-burns.pem +116 -0
- data/spec/fixtures/theca.pem +13 -0
- data/spec/fixtures/thecert.crt +13 -0
- data/spec/fixtures/thecsr.csr +11 -0
- data/spec/fixtures/thekey.key +15 -0
- data/spec/fixtures/thekey.key.protected +18 -0
- data/spec/oo/client_spec.rb +28 -0
- data/spec/oo/server_spec.rb +75 -0
- data/spec/support/fixtures.rb +10 -0
- metadata +135 -0
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'libtls/config'
|
2
|
+
require 'libtls/raw'
|
3
|
+
require 'libtls/exn'
|
4
|
+
|
5
|
+
module LibTLS
|
6
|
+
##
|
7
|
+
# Represent a server that communicates over TLS
|
8
|
+
#
|
9
|
+
# This class handles the details on using an existing instance of Socket to
|
10
|
+
# communicate with clients. It knows how to configure the TLS settings and
|
11
|
+
# negotiate the TLS handshake.
|
12
|
+
#
|
13
|
+
# Here is an example method that echos a response over an encrypted channel.
|
14
|
+
# Note that the issues around creating and maintaining a socket are dealt
|
15
|
+
# with elsewhere.
|
16
|
+
#
|
17
|
+
# def echo_server(socket)
|
18
|
+
# config = {
|
19
|
+
# key_file: "thekey.key",
|
20
|
+
# cert_file: "thecert.crt"
|
21
|
+
# }
|
22
|
+
#
|
23
|
+
# LibTLS::Server.new(configure: config) do |server|
|
24
|
+
# client_socket, _ = socket.accept
|
25
|
+
#
|
26
|
+
# server.accept(client_socket) do |client|
|
27
|
+
# str = client.read
|
28
|
+
# client.write(str)
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
class Server
|
33
|
+
##
|
34
|
+
# The FFI wrapper around the struct tls object
|
35
|
+
#
|
36
|
+
# This is only useful for calling any of the {LibTLS::Raw} methods.
|
37
|
+
attr :ctx
|
38
|
+
|
39
|
+
##
|
40
|
+
# Instantiate and configure a TLS server
|
41
|
+
#
|
42
|
+
# Once constructed, a {Server} instance must be freed with the {#finish}
|
43
|
+
# method. If you pass a block to the constructor it will handle this for you.
|
44
|
+
#
|
45
|
+
# @param configure [Hash] a mapping from setting name to value. The setting
|
46
|
+
# name is any of {LibTLS::Config::VALID_SET_CONFIGS}; the value is either a
|
47
|
+
# scalar value passed through to the C function, or an array of values. For
|
48
|
+
# example:
|
49
|
+
# { ca_file: 'ca.pem', key_mem: [key_ptr, 48] }
|
50
|
+
# @yieldparam [Server] self an initialized and configured instance of self
|
51
|
+
# @raise [LibTLS::UnknownCError] if +tls_init+ or +tls_server+ fail
|
52
|
+
# @raise [LibTLS::CError] if +tls_configure+ fails
|
53
|
+
def initialize(configure:, &block)
|
54
|
+
if LibTLS::Raw.tls_init < 0
|
55
|
+
raise LibTLS::UnknownCError, "tls_init"
|
56
|
+
end
|
57
|
+
|
58
|
+
@config = Config.new(configure)
|
59
|
+
|
60
|
+
if (@ctx = LibTLS::Raw.tls_server) == nil
|
61
|
+
raise LibTLS::UnknownCError, "tls_server"
|
62
|
+
end
|
63
|
+
|
64
|
+
if LibTLS::Raw::tls_configure(ctx, @config.as_raw) < 0
|
65
|
+
raise LibTLS::CError, "tls_configure: #{LibTLS::Raw.tls_error(ctx)}"
|
66
|
+
end
|
67
|
+
|
68
|
+
if block
|
69
|
+
begin
|
70
|
+
block.call(self)
|
71
|
+
ensure
|
72
|
+
self.finish
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# Negotiate a TLS handshake on an existing socket
|
79
|
+
#
|
80
|
+
# The client socket is assumed to already have an active connection; for
|
81
|
+
# example, +IO.select+ or +Socket#accept+ has been called.
|
82
|
+
#
|
83
|
+
# The block is run on a connection opened for the client. Once the block
|
84
|
+
# finishes, the connection is closed automatically.
|
85
|
+
#
|
86
|
+
# @param client_socket [Socket] a connected socket
|
87
|
+
# @yieldparam [OpenedClient] client the connected client
|
88
|
+
# @raise [LibTLS::CError] if +tls_accept_socket+ fails
|
89
|
+
# @return the result of the block
|
90
|
+
def accept(client_socket, &block)
|
91
|
+
cctx_ptr = FFI::MemoryPointer.new(:pointer)
|
92
|
+
|
93
|
+
if tls_accept(cctx_ptr, client_socket) == -1
|
94
|
+
raise LibTLS::CError, "tls_accept_socket: #{LibTLS::Raw.tls_error(ctx)}"
|
95
|
+
end
|
96
|
+
|
97
|
+
cctx = cctx_ptr.read_pointer
|
98
|
+
|
99
|
+
opened_client = OpenedClient.new(cctx)
|
100
|
+
block.call(opened_client)
|
101
|
+
ensure
|
102
|
+
opened_client && opened_client.close
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
# Release any memory held on to by the C library
|
107
|
+
#
|
108
|
+
# This method must be called either implicitly by passing a block to
|
109
|
+
# {#initialize}, or explicitly by you.
|
110
|
+
def finish
|
111
|
+
@config.free
|
112
|
+
LibTLS::Raw.tls_free(ctx)
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def tls_accept(cctx_ptr, client_sock)
|
118
|
+
ret = LibTLS::Raw.tls_accept_socket(
|
119
|
+
ctx, cctx_ptr, client_sock.fileno)
|
120
|
+
|
121
|
+
if [LibTLS::Raw::TLS_READ_AGAIN, LibTLS::Raw::TLS_WRITE_AGAIN].include?(ret)
|
122
|
+
tls_accept(cctx_ptr, client_sock)
|
123
|
+
else
|
124
|
+
ret
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/libtls.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'libtls/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "libtls"
|
8
|
+
spec.version = LibTLS::VERSION
|
9
|
+
spec.authors = ["Mike Burns"]
|
10
|
+
spec.email = ["mike@mike-burns.com"]
|
11
|
+
spec.summary = %q{Bindings for libtls (libressl)}
|
12
|
+
spec.description = %q{
|
13
|
+
This is a set of libtls bindings for Ruby, plus a nice object-oriented layer
|
14
|
+
atop the bindings.
|
15
|
+
}
|
16
|
+
spec.homepage = "https://github.com/mike-burns/libtls.rb"
|
17
|
+
spec.license = "ISC"
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0")
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_dependency "ffi", "~> 1.2"
|
25
|
+
spec.requirements << 'libtls'
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
spec.add_development_dependency "rspec", "~> 2"
|
30
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIGRjCCBS6gAwIBAgIDFAInMA0GCSqGSIb3DQEBCwUAMIGMMQswCQYDVQQGEwJJ
|
3
|
+
TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0
|
4
|
+
YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3Mg
|
5
|
+
MSBQcmltYXJ5IEludGVybWVkaWF0ZSBTZXJ2ZXIgQ0EwHhcNMTQxMTAxMDUyMDI1
|
6
|
+
WhcNMTUxMTAxMTk1ODM5WjBTMQswCQYDVQQGEwJTRTEbMBkGA1UEAxMSd3d3Lm1p
|
7
|
+
a2UtYnVybnMuY29tMScwJQYJKoZIhvcNAQkBFhh3ZWJtYXN0ZXJAbWlrZS1idXJu
|
8
|
+
cy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQjCP4Sx7ObtxJ
|
9
|
+
/1cRJ+2wDnEZtVk4MByVKeZwWO94JnsUWejRCUqFl8al2tKkYWDeju2qAMbC7Wmq
|
10
|
+
5UiPyiXd5gdrb2Sjn+Z5K7s5B9B5DF2u3bllGU4EqhpgYOYkWFMwalDWSYoBy0WH
|
11
|
+
9Av3GpQXx71ueF1HbLd/UrPxeEWvAytKQpbmydd+eohRvmjKU4URoT/gnY1A+39Q
|
12
|
+
9MvyAVwnI4EtyMMW1t7jDBD1IGyY1MhxPYtaAFKEoEMzMnhZln4DohMWfmfL8LqF
|
13
|
+
GD5FcPBDmlLDLPCsLmq5NVd/x1S9irK5fpGc3ovv/cq99XfdPfkIjMC84H8eaawr
|
14
|
+
WThteTdzAgMBAAGjggLnMIIC4zAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDATBgNV
|
15
|
+
HSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQUxnbSAvGSoA1sDTBCMWZyRwNs47Ew
|
16
|
+
HwYDVR0jBBgwFoAU60I00Jiwq5/0G2sI98xkLu8OLEUwLQYDVR0RBCYwJIISd3d3
|
17
|
+
Lm1pa2UtYnVybnMuY29tgg5taWtlLWJ1cm5zLmNvbTCCAVYGA1UdIASCAU0wggFJ
|
18
|
+
MAgGBmeBDAECATCCATsGCysGAQQBgbU3AQIDMIIBKjAuBggrBgEFBQcCARYiaHR0
|
19
|
+
cDovL3d3dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjCB9wYIKwYBBQUHAgIwgeow
|
20
|
+
JxYgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwAwIBARqBvlRoaXMg
|
21
|
+
Y2VydGlmaWNhdGUgd2FzIGlzc3VlZCBhY2NvcmRpbmcgdG8gdGhlIENsYXNzIDEg
|
22
|
+
VmFsaWRhdGlvbiByZXF1aXJlbWVudHMgb2YgdGhlIFN0YXJ0Q29tIENBIHBvbGlj
|
23
|
+
eSwgcmVsaWFuY2Ugb25seSBmb3IgdGhlIGludGVuZGVkIHB1cnBvc2UgaW4gY29t
|
24
|
+
cGxpYW5jZSBvZiB0aGUgcmVseWluZyBwYXJ0eSBvYmxpZ2F0aW9ucy4wNQYDVR0f
|
25
|
+
BC4wLDAqoCigJoYkaHR0cDovL2NybC5zdGFydHNzbC5jb20vY3J0MS1jcmwuY3Js
|
26
|
+
MIGOBggrBgEFBQcBAQSBgTB/MDkGCCsGAQUFBzABhi1odHRwOi8vb2NzcC5zdGFy
|
27
|
+
dHNzbC5jb20vc3ViL2NsYXNzMS9zZXJ2ZXIvY2EwQgYIKwYBBQUHMAKGNmh0dHA6
|
28
|
+
Ly9haWEuc3RhcnRzc2wuY29tL2NlcnRzL3N1Yi5jbGFzczEuc2VydmVyLmNhLmNy
|
29
|
+
dDAjBgNVHRIEHDAahhhodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS8wDQYJKoZIhvcN
|
30
|
+
AQELBQADggEBAI35NGd8yJUPBm0Yc/nFLvdow2hpBot7Yw/h5XADT84TZmTwE+D2
|
31
|
+
PiI7MoTKieL70L7jL7k4SNxTlaN/Y9TJ5Vqj9oAIxzlOrIAc4KzxyO3tyFTRWhVw
|
32
|
+
WUvvEGobRuoXZVtbGOxDPcVdB1/+bNsG/mY8KrnuJmDunOYg2FA3BZWVV3xRIfEW
|
33
|
+
rCTJwF0qT0GQfv25aM5huTFdEU+QzSUGjqaCq4doD+zFRdLj5WPP+zaEWtPC2S+F
|
34
|
+
8v1+U4BP1MS0rVF9r+4ulvAZWZ+hrlB4kcGHEHy73hX3zy63LFxkIni15c2OE2c0
|
35
|
+
RF2xeweSzapCmlJDtQpMqaFnaKeN+yC/W+M=
|
36
|
+
-----END CERTIFICATE-----
|
37
|
+
-----BEGIN CERTIFICATE-----
|
38
|
+
MIIGNDCCBBygAwIBAgIBGDANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
|
39
|
+
MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
|
40
|
+
Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
|
41
|
+
dGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjA1NDE3WhcNMTcxMDI0MjA1NDE3WjCB
|
42
|
+
jDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsT
|
43
|
+
IlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNVBAMTL1N0
|
44
|
+
YXJ0Q29tIENsYXNzIDEgUHJpbWFyeSBJbnRlcm1lZGlhdGUgU2VydmVyIENBMIIB
|
45
|
+
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtonGrO8JUngHrJJj0PREGBiE
|
46
|
+
gFYfka7hh/oyULTTRwbw5gdfcA4Q9x3AzhA2NIVaD5Ksg8asWFI/ujjo/OenJOJA
|
47
|
+
pgh2wJJuniptTT9uYSAK21ne0n1jsz5G/vohURjXzTCm7QduO3CHtPn66+6CPAVv
|
48
|
+
kvek3AowHpNz/gfK11+AnSJYUq4G2ouHI2mw5CrY6oPSvfNx23BaKA+vWjhwRRI/
|
49
|
+
ME3NO68X5Q/LoKldSKqxYVDLNM08XMML6BDAjJvwAwNi/rJsPnIO7hxDKslIDlc5
|
50
|
+
xDEhyBDBLIf+VJVSH1I8MRKbf+fAoKVZ1eKPPvDVqOHXcDGpxLPPr21TLwb0pwID
|
51
|
+
AQABo4IBrTCCAakwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
|
52
|
+
VR0OBBYEFOtCNNCYsKuf9BtrCPfMZC7vDixFMB8GA1UdIwQYMBaAFE4L7xqkQFul
|
53
|
+
F2mHMMo0aEPQQa7yMGYGCCsGAQUFBwEBBFowWDAnBggrBgEFBQcwAYYbaHR0cDov
|
54
|
+
L29jc3Auc3RhcnRzc2wuY29tL2NhMC0GCCsGAQUFBzAChiFodHRwOi8vd3d3LnN0
|
55
|
+
YXJ0c3NsLmNvbS9zZnNjYS5jcnQwWwYDVR0fBFQwUjAnoCWgI4YhaHR0cDovL3d3
|
56
|
+
dy5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0
|
57
|
+
c3NsLmNvbS9zZnNjYS5jcmwwgYAGA1UdIAR5MHcwdQYLKwYBBAGBtTcBAgEwZjAu
|
58
|
+
BggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjA0
|
59
|
+
BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50ZXJtZWRpYXRl
|
60
|
+
LnBkZjANBgkqhkiG9w0BAQUFAAOCAgEAIQlJPqWIbuALi0jaMU2P91ZXouHTYlfp
|
61
|
+
tVbzhUV1O+VQHwSL5qBaPucAroXQ+/8gA2TLrQLhxpFy+KNN1t7ozD+hiqLjfDen
|
62
|
+
xk+PNdb01m4Ge90h2c9W/8swIkn+iQTzheWq8ecf6HWQTd35RvdCNPdFWAwRDYSw
|
63
|
+
xtpdPvkBnufh2lWVvnQce/xNFE+sflVHfXv0pQ1JHpXo9xLBzP92piVH0PN1Nb6X
|
64
|
+
t1gW66pceG/sUzCv6gRNzKkC4/C2BBL2MLERPZBOVmTX3DxDX3M570uvh+v2/miI
|
65
|
+
RHLq0gfGabDBoYvvF0nXYbFFSF87ICHpW7LM9NfpMfULFWE7epTj69m8f5SuauNi
|
66
|
+
YpaoZHy4h/OZMn6SolK+u/hlz8nyMPyLwcKmltdfieFcNID1j0cHL7SRv7Gifl9L
|
67
|
+
WtBbnySGBVFaaQNlQ0lxxeBvlDRr9hvYqbBMflPrj0jfyjO1SPo2ShpTpjMM0InN
|
68
|
+
SRXNiTE8kMBy12VLUjWKRhFEuT2OKGWmPnmeXAhEKa2wNREuIU640ucQPl2Eg7PD
|
69
|
+
wuTSxv0JS3QJ3fGz0xk+gA2iCxnwOOfFwq/iI9th4p1cbiCJSS4jarJiwUW0n6+L
|
70
|
+
p/EiO/h94pDQehn7Skzj0n1fSoMD7SfWI55rjbRZotnvbIIp3XUZPD9MEI3vu3Un
|
71
|
+
0q6Dp6jOW6c=
|
72
|
+
-----END CERTIFICATE-----
|
73
|
+
-----BEGIN CERTIFICATE-----
|
74
|
+
MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
|
75
|
+
MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
|
76
|
+
Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
|
77
|
+
dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
|
78
|
+
MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
|
79
|
+
U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
|
80
|
+
cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
|
81
|
+
A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
|
82
|
+
pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
|
83
|
+
OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
|
84
|
+
Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
|
85
|
+
Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
|
86
|
+
HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
|
87
|
+
Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
|
88
|
+
+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
|
89
|
+
Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
|
90
|
+
Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
|
91
|
+
26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
|
92
|
+
AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
|
93
|
+
FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
|
94
|
+
ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
|
95
|
+
LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
|
96
|
+
BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
|
97
|
+
Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
|
98
|
+
dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
|
99
|
+
cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
|
100
|
+
YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
|
101
|
+
dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
|
102
|
+
bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
|
103
|
+
YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
|
104
|
+
TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
|
105
|
+
9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
|
106
|
+
jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
|
107
|
+
FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
|
108
|
+
ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
|
109
|
+
ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
|
110
|
+
EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
|
111
|
+
L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
|
112
|
+
yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
|
113
|
+
O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
|
114
|
+
um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
|
115
|
+
NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
|
116
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,13 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIICCTCCAXICCQC0VuaH4rQBXTANBgkqhkiG9w0BAQsFADBJMQswCQYDVQQGEwJT
|
3
|
+
RTESMBAGA1UECAwJU3RvY2tob2xtMRIwEAYDVQQHDAlTdG9ja2hvbG0xEjAQBgNV
|
4
|
+
BAMMCWxvY2FsaG9zdDAeFw0xNTA0MTQxOTA5MjhaFw0xNjA0MTMxOTA5MjhaMEkx
|
5
|
+
CzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAcMCVN0b2Nr
|
6
|
+
aG9sbTESMBAGA1UEAwwJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
|
7
|
+
iQKBgQCoPanBU4m8XMicKm9g+4tNDpd7PjJwQXT9ybleuZaqR0RDBPYra3Pk+djB
|
8
|
+
eTJcCOmTpSV+3GoiUKUImkSmlAZ/z7/QckzutYq4SczSexSLyecxNIlbDpDoj9pY
|
9
|
+
a0q3QGd20cO4bWCkslldt5YMvLWsuNZn8SWIjZniy58Q4W/fSwIDAQABMA0GCSqG
|
10
|
+
SIb3DQEBCwUAA4GBAE2Zdyvdtpp5vvNztLUPM0JMUJLgmR1Z7z0XYdSelBWs7b0F
|
11
|
+
Hbno1Ft1kWpPhYhYkokmI4wYQ/PiI0dgKxIs7adcZNpvCzk6kvfNUhiPRNsk/oIJ
|
12
|
+
Z1tfxKDbpClQgAshvX8zcepJnxK5JdPk8joOmBdMshEkmg30UW20EOVvhl45
|
13
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,13 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIICCTCCAXICCQC0VuaH4rQBXTANBgkqhkiG9w0BAQsFADBJMQswCQYDVQQGEwJT
|
3
|
+
RTESMBAGA1UECAwJU3RvY2tob2xtMRIwEAYDVQQHDAlTdG9ja2hvbG0xEjAQBgNV
|
4
|
+
BAMMCWxvY2FsaG9zdDAeFw0xNTA0MTQxOTA5MjhaFw0xNjA0MTMxOTA5MjhaMEkx
|
5
|
+
CzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAcMCVN0b2Nr
|
6
|
+
aG9sbTESMBAGA1UEAwwJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
|
7
|
+
iQKBgQCoPanBU4m8XMicKm9g+4tNDpd7PjJwQXT9ybleuZaqR0RDBPYra3Pk+djB
|
8
|
+
eTJcCOmTpSV+3GoiUKUImkSmlAZ/z7/QckzutYq4SczSexSLyecxNIlbDpDoj9pY
|
9
|
+
a0q3QGd20cO4bWCkslldt5YMvLWsuNZn8SWIjZniy58Q4W/fSwIDAQABMA0GCSqG
|
10
|
+
SIb3DQEBCwUAA4GBAE2Zdyvdtpp5vvNztLUPM0JMUJLgmR1Z7z0XYdSelBWs7b0F
|
11
|
+
Hbno1Ft1kWpPhYhYkokmI4wYQ/PiI0dgKxIs7adcZNpvCzk6kvfNUhiPRNsk/oIJ
|
12
|
+
Z1tfxKDbpClQgAshvX8zcepJnxK5JdPk8joOmBdMshEkmg30UW20EOVvhl45
|
13
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,11 @@
|
|
1
|
+
-----BEGIN CERTIFICATE REQUEST-----
|
2
|
+
MIIBiDCB8gIBADBJMQswCQYDVQQGEwJTRTESMBAGA1UECAwJU3RvY2tob2xtMRIw
|
3
|
+
EAYDVQQHDAlTdG9ja2hvbG0xEjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG
|
4
|
+
9w0BAQEFAAOBjQAwgYkCgYEAqD2pwVOJvFzInCpvYPuLTQ6Xez4ycEF0/cm5XrmW
|
5
|
+
qkdEQwT2K2tz5PnYwXkyXAjpk6UlftxqIlClCJpEppQGf8+/0HJM7rWKuEnM0nsU
|
6
|
+
i8nnMTSJWw6Q6I/aWGtKt0BndtHDuG1gpLJZXbeWDLy1rLjWZ/EliI2Z4sufEOFv
|
7
|
+
30sCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBAD7rnHFehiIhj6zXWGyKnVvBBT64
|
8
|
+
0M/yRdEfADH2sA5viUxDX2E9r+zZJMwTWNhH+nPeNU4aJbgjULkq6VIOWVHafkFS
|
9
|
+
hmk4KQMnDMy0wzyY88ozZ2m/g3vpm+MH/wJF4AZ7YCywyuiI+J87pwAmATkEjcqR
|
10
|
+
/uoYUH9EyLi4BO3Y
|
11
|
+
-----END CERTIFICATE REQUEST-----
|
@@ -0,0 +1,15 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIICXQIBAAKBgQCoPanBU4m8XMicKm9g+4tNDpd7PjJwQXT9ybleuZaqR0RDBPYr
|
3
|
+
a3Pk+djBeTJcCOmTpSV+3GoiUKUImkSmlAZ/z7/QckzutYq4SczSexSLyecxNIlb
|
4
|
+
DpDoj9pYa0q3QGd20cO4bWCkslldt5YMvLWsuNZn8SWIjZniy58Q4W/fSwIDAQAB
|
5
|
+
AoGAIDT9xFa7rWWNueedvtEoz62VbjBv83F0dgkiBXI914chGDtg7Nr7KsBxsEgF
|
6
|
+
Tf0eyfb5gJmtb7hEf6sYrVL1Ez8yoAjHo3su2Yh9EhL8FNJITaWANgpvJFpBBRcV
|
7
|
+
aDz3foxbc0pGISWl4NwIxuStZdY1en96LgSXlD9CE8TqgIECQQDVdKlZ5OMfw2Cn
|
8
|
+
dOqgSYvcT/ToYE5Mg4TfH5xnyWNseAQ8k8kI2GIOxZIH3PAl5VwuVxpr8Bbza97v
|
9
|
+
4mYgHptrAkEAycX3Ewa1YMKNjrOYB47kDCzYhYBFD/mUojbE05WVPQatoznRfBdk
|
10
|
+
ZKsg5iu6P6NU6moROYiVauOu6oDmhXGjoQJBAMHaBwrKobHw/9BUj9gtssTMIIEB
|
11
|
+
JVq7fmocDTD8ZjzV6hMRq9tKmBMOPobBkZ7443R6SlaIXm+HIZn9o/27ji0CQQC6
|
12
|
+
MQ/6YqplC6MNF/UmpFkUUx3Ks78HKsxZlCi1BsecdNkuUmBZHkzqCHBnddp8dwAZ
|
13
|
+
AJ+8c6lN5aS3iRMv+NmBAkAnJKyhAjpxKe4JcTex5WyQg/GPffjMakQm8J5ppUnX
|
14
|
+
jxSjvPKee0PYgztZwwCWgakynwvCk+GbK0h3oCssDAmP
|
15
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,18 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
Proc-Type: 4,ENCRYPTED
|
3
|
+
DEK-Info: DES-EDE3-CBC,0EDD0A67E5CDB391
|
4
|
+
|
5
|
+
HIEDTe8y51xjvG/R9FbDgEQ3bzUbQYAAqimxdpJoOFvWMOgJl9HlWNAUk5yf8evD
|
6
|
+
rU+t1fvn0GUL0OHnR6A8edI8U+9GPL3Bt4vis5unpkGg68MyvQna4qDXnqAW3cVI
|
7
|
+
OXpt+v/xaQUazChCg6b9mt4G4vd7mKWB4i9tg078+d+hyWxWOMqU2CdWt7hDRtkw
|
8
|
+
wIwHf1Gbn9q3gXReuDHmq2SHg1FkjfMqQ7rY7jySGSzapdAj/wh/h04kZ2Vdkooa
|
9
|
+
jIp1hShqJh6fRij9R5PuJyAvVcioxFcdT7iE2u2diBVcehJWlHOTOoBTJpB4ExeC
|
10
|
+
cHdeA3tuE1rTfK4Ix65UDPbk6xXXwuIyiTLD7Bw0Q5uw7093+ZaoFctmE6CCkiMK
|
11
|
+
vHByPKmsrsNuac+Dq3QsL0WDkHwYvRSji8wVnorlCMOVqa4xHMo27gtgIufEGJzs
|
12
|
+
wWTIiIqPy8iMLODtt+uWbGRkLHXfOwS7F4PvmeQB8xEnjVlIBJ1qpYpXzzMgs5x9
|
13
|
+
N69d+xTY4AVBF+a87kQIkx41AjqiNt2sBS7gYkGnnd1W6v3IqdQuTLzfZh/WLiaW
|
14
|
+
RGhP/f8gRWprVoso07qTBdWM/rx9op+F6C5LYlGGAKvtSXcwsklT3qL2AEzc6Tvi
|
15
|
+
P7iyD+n6wdtFsIFwzp4D2l7oE5alN+a9o7laV18MwLFVhfdSjRVM6VDA2nBDva4T
|
16
|
+
G063CrMiRUv4G5nbqvgOSOmx2nHArYcSjyfc7fyobxeAyuzt8E+ayLSgAML//BTS
|
17
|
+
rlOIkY84kUvgHxsjw1Ia5fg9oTyPaSJVDJwN1QNTvCX872/z+ELWDw==
|
18
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'libtls'
|
3
|
+
require 'support/fixtures'
|
4
|
+
|
5
|
+
describe 'a libtls client' do
|
6
|
+
it 'reads data via a TLS connection' do
|
7
|
+
config = {
|
8
|
+
protocols: LibTLS::Raw::TLS_PROTOCOL_TLSv1_2,
|
9
|
+
ca_file: fixture_filename('mike-burns.pem')
|
10
|
+
}
|
11
|
+
|
12
|
+
content = nil
|
13
|
+
LibTLS::Client.new(configure: config) do |client|
|
14
|
+
content = client.connect("mike-burns.com", 443) do |c|
|
15
|
+
c.write(http_get("mike-burns.com"))
|
16
|
+
c.read
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
expect(content[0..14]).to eq "HTTP/1.1 200 OK"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def http_get(hostname)
|
26
|
+
"GET / HTTP/1.1\r\nUser-Agent: libtls.rb/0.1\r\nHost: #{hostname}\r\n\r\n"
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'socket'
|
3
|
+
require 'libtls'
|
4
|
+
require 'support/fixtures'
|
5
|
+
|
6
|
+
describe 'a libtls server' do
|
7
|
+
before :each do
|
8
|
+
@socket = create_socket_for_client(hostname, port)
|
9
|
+
end
|
10
|
+
|
11
|
+
after :each do
|
12
|
+
@client_socket && @client_socket.close
|
13
|
+
@socket && @socket.close
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'sends data via a TLS connection' do
|
17
|
+
config = {
|
18
|
+
key_file: key_file,
|
19
|
+
cert_file: cert_file
|
20
|
+
}
|
21
|
+
|
22
|
+
fork do
|
23
|
+
@client_socket, _ = @socket.accept
|
24
|
+
|
25
|
+
LibTLS::Server.new(configure: config) do |server|
|
26
|
+
server.accept(@client_socket) do |c|
|
27
|
+
str = c.read
|
28
|
+
c.write(str)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
sleep 1
|
33
|
+
|
34
|
+
content = echo_client(msg)
|
35
|
+
|
36
|
+
expect(content).to eq (msg)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
let(:hostname) { "localhost" }
|
42
|
+
let(:port) { "3334" }
|
43
|
+
let(:key_file) { fixture_filename("thekey.key") }
|
44
|
+
let(:cert_file) { fixture_filename("thecert.crt") }
|
45
|
+
let(:ca_file) { fixture_filename("theca.pem") }
|
46
|
+
let(:msg) { "hello\r\n" }
|
47
|
+
|
48
|
+
def echo_client(str)
|
49
|
+
content = ""
|
50
|
+
config = {
|
51
|
+
protocols: LibTLS::Raw::TLS_PROTOCOLS_ALL,
|
52
|
+
ca_file: ca_file
|
53
|
+
}
|
54
|
+
|
55
|
+
LibTLS::Client.new(configure: config) do |client|
|
56
|
+
begin
|
57
|
+
content = client.connect(hostname, port) do |c|
|
58
|
+
c.write(str)
|
59
|
+
c.read
|
60
|
+
end
|
61
|
+
rescue LibTLS::CError
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
content
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_socket_for_client(hostname, port)
|
69
|
+
sin = Addrinfo.tcp(hostname, port)
|
70
|
+
sock = sin.bind()
|
71
|
+
sock.listen(1)
|
72
|
+
|
73
|
+
sock
|
74
|
+
end
|
75
|
+
end
|