codtls 0.0.1.alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +12 -0
- data/.yardopts +4 -0
- data/Gemfile +12 -0
- data/LICENSE +21 -0
- data/README.md +78 -0
- data/Rakefile +29 -0
- data/lib/codtls.rb +186 -0
- data/lib/codtls/abstract_session.rb +179 -0
- data/lib/codtls/alert.rb +64 -0
- data/lib/codtls/decrypt.rb +72 -0
- data/lib/codtls/ecc.rb +26 -0
- data/lib/codtls/encrypt.rb +29 -0
- data/lib/codtls/h_changecipherspec.rb +25 -0
- data/lib/codtls/h_chello.rb +79 -0
- data/lib/codtls/h_content.rb +57 -0
- data/lib/codtls/h_finished.rb +30 -0
- data/lib/codtls/h_keyexchange.rb +131 -0
- data/lib/codtls/h_shello.rb +51 -0
- data/lib/codtls/h_shellodone.rb +22 -0
- data/lib/codtls/h_type.rb +22 -0
- data/lib/codtls/h_verify.rb +30 -0
- data/lib/codtls/handshake.rb +173 -0
- data/lib/codtls/models/codtls_connection.rb +3 -0
- data/lib/codtls/models/codtls_device.rb +3 -0
- data/lib/codtls/prf.rb +40 -0
- data/lib/codtls/pskdb.rb +104 -0
- data/lib/codtls/ram_session.rb +214 -0
- data/lib/codtls/rampskdb.rb +87 -0
- data/lib/codtls/record.rb +202 -0
- data/lib/codtls/session.rb +284 -0
- data/lib/codtls/version.rb +3 -0
- data/lib/generators/codtls/codtls_generator.rb +56 -0
- data/lib/generators/codtls/templates/create_codtls_connections.rb +15 -0
- data/lib/generators/codtls/templates/create_codtls_devices.rb +11 -0
- data/test/test_codtls.rb +75 -0
- data/test/test_ecc.rb +44 -0
- data/test/test_h_chello.rb +40 -0
- data/test/test_h_content.rb +59 -0
- data/test/test_h_keyexchange.rb +36 -0
- data/test/test_helper.rb +3 -0
- data/test/test_pskdb.rb +37 -0
- data/test/test_ram_session.rb +131 -0
- data/test/test_rampskdb.rb +26 -0
- data/test/test_record.rb +128 -0
- data/test/test_send_recv.rb +178 -0
- data/test/test_session.rb +164 -0
- metadata +303 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e2634fecc2fa34a90ab5b3941f174d49bf41c995
|
4
|
+
data.tar.gz: 904c426baa0e2fba87e187f14cff90b8fda13ed2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bf8ec5ec61ccffd47cdd5e5793af715b5c10793292165ef4cfece54430ef51dbe9513f1458fcd83b76a3deef2f4fd3d68aa347ff00ef8998e22556d069761985
|
7
|
+
data.tar.gz: 8ff6425ca7d37b55a3b69a8ec8a592580b69ef994656310ed737e5dc5fe8f40522b73ebda83c9e869993eea70759b2fef4487eb5e6b0548ba83390dd14d00c1c
|
data/.rubocop.yml
ADDED
data/.yardopts
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'coap'
|
4
|
+
gem 'openssl-ccm', '>=1.1.1'
|
5
|
+
gem 'openssl-cmac', '>=2.0.0'
|
6
|
+
gem 'sqlite3', '>=1.3.9'
|
7
|
+
gem 'activerecord', '>=4.0.0'
|
8
|
+
gem 'rake', '>=10.2.2'
|
9
|
+
gem 'rdoc', '>=4.1.1'
|
10
|
+
gem 'yard', '>=0.8.7.3'
|
11
|
+
gem 'rubocop', '>=0.18.1'
|
12
|
+
gem 'coveralls', '>=00.7.0'
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 SmallLars
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
[](http://badge.fury.io/rb/codtls)
|
2
|
+
[](https://gemnasium.com/SmallLars/codtls)
|
3
|
+
[](https://travis-ci.org/SmallLars/codtls)
|
4
|
+
[](https://coveralls.io/r/SmallLars/codtls)
|
5
|
+
[](https://codeclimate.com/github/SmallLars/codtls)
|
6
|
+
[](http://inch-pages.github.io/github/smalllars/codtls)
|
7
|
+
|
8
|
+
|
9
|
+
# Gem CoDTLS
|
10
|
+
|
11
|
+
Ruby Gem for RFC XXXX - CoDTLS: DTLS handshakes over CoAP
|
12
|
+
|
13
|
+
WORK IN PROGRESS - ITS NOT SECURE - THERE IS MANY WORK TO DO
|
14
|
+
|
15
|
+
## Introduction
|
16
|
+
|
17
|
+
This gem is an implementation of CoDTLS. CoDTLS is a protocol, which utlilizes CoAP and CoAP ressources for DTLS. See http://www.ietf.org/internet-drafts/draft-schmertmann-dice-codtls-00.txt for further details.
|
18
|
+
|
19
|
+
## How to install the gem
|
20
|
+
|
21
|
+
Add this line to your application's Gemfile:
|
22
|
+
|
23
|
+
gem 'openssl-ccm'
|
24
|
+
|
25
|
+
And then execute:
|
26
|
+
|
27
|
+
$ bundle
|
28
|
+
|
29
|
+
Or install it yourself as:
|
30
|
+
|
31
|
+
$ gem install openssl-ccm
|
32
|
+
|
33
|
+
When the gem is installed you have to call its generator to generate the needed ActiveRecord Migrations in your db/migrate folder
|
34
|
+
|
35
|
+
rails g codtls
|
36
|
+
|
37
|
+
You now have apply these migrations to your database with
|
38
|
+
|
39
|
+
rake db:migrate
|
40
|
+
|
41
|
+
Your Rails project should now be able to use this ruby gem.
|
42
|
+
|
43
|
+
## How to use the gem
|
44
|
+
|
45
|
+
You have to require the gem in the file you are using with
|
46
|
+
|
47
|
+
require 'codtls'
|
48
|
+
|
49
|
+
Now you can create a SecureSocket object and use it like any other socket.
|
50
|
+
|
51
|
+
# example for a server application
|
52
|
+
ssocket = CoDTLS::SecureSocket.new
|
53
|
+
ssocket.bind('AAAA::1', 5555)
|
54
|
+
ssocket.listen
|
55
|
+
new_connection = ssocket.accept
|
56
|
+
|
57
|
+
# example for a client application
|
58
|
+
ssocket = CoDTLS::SecureSocket.new
|
59
|
+
ssocket.sendto('AAAA::1', 'Test message')
|
60
|
+
answer = ssocket.recvfrom('AAAA::1')
|
61
|
+
|
62
|
+
## Used sources
|
63
|
+
|
64
|
+
http://guides.rubygems.org/make-your-own-gem/
|
65
|
+
|
66
|
+
http://www.medihack.org/2011/03/15/intend-to-extend/
|
67
|
+
|
68
|
+
http://rubydoc.info/gems/yard/file/docs/GettingStarted.md
|
69
|
+
|
70
|
+
http://openbook.galileocomputing.de/ruby_on_rails/ruby_on_rails_04_001.htm
|
71
|
+
|
72
|
+
http://blog.bigbinary.com/2011/07/20/ruby-pack-unpack.html
|
73
|
+
|
74
|
+
http://ruby-doc.org/stdlib-2.0.0/libdoc/socket/rdoc/IPSocket.html
|
75
|
+
http://ruby-doc.org/stdlib-2.0.0/libdoc/socket/rdoc/UDPSocket.html
|
76
|
+
http://www.ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html
|
77
|
+
|
78
|
+
http://bundler.io/
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
task :default => :build
|
5
|
+
|
6
|
+
desc "Run tests"
|
7
|
+
Rake::TestTask.new do |t|
|
8
|
+
t.libs << 'test'
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Create documentation"
|
12
|
+
task :doc do
|
13
|
+
sh "gem rdoc --rdoc openssl-ccm"
|
14
|
+
sh "yardoc"
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Uninstall and clean documentation"
|
18
|
+
task :clean do
|
19
|
+
sh "gem uninstall codtls"
|
20
|
+
begin; sh "rm -R ./.yardoc"; rescue; end
|
21
|
+
begin; sh "rm -R ./doc"; rescue; end
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "Development Dependencies"
|
25
|
+
task (:devinst) { sh "gem install --dev ./codtls-0.0.1.gem" }
|
26
|
+
|
27
|
+
desc "Bundle install"
|
28
|
+
task (:bundle) { sh "bundle install" }
|
29
|
+
|
data/lib/codtls.rb
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
require 'codtls/encrypt'
|
5
|
+
require 'codtls/decrypt'
|
6
|
+
require 'codtls/handshake'
|
7
|
+
require 'codtls/record'
|
8
|
+
require 'codtls/session'
|
9
|
+
|
10
|
+
# laber
|
11
|
+
module CoDTLS
|
12
|
+
LOG_LEVEL = Logger::ERROR # UNKNOWN,FATAL,ERROR,WARN,INFO,DEBUG
|
13
|
+
|
14
|
+
# TODO
|
15
|
+
class SecureSocketError < StandardError
|
16
|
+
end
|
17
|
+
|
18
|
+
# Secure UDP-Socket based on a CoAP using handshake
|
19
|
+
#
|
20
|
+
# Usage of SecureSocket ist the same as of UDPSocket.
|
21
|
+
# There are two additional class methods:
|
22
|
+
#
|
23
|
+
# set_psk(uuid, psk) to save PSK for specified UUID
|
24
|
+
#
|
25
|
+
# add_new_node_listener(listener) to enable autohandshake
|
26
|
+
# when a new node was found.
|
27
|
+
class SecureSocket
|
28
|
+
# Creates a new CoDTLS Socket. Behavior is like UDPSocket.
|
29
|
+
#
|
30
|
+
# @param address_family [Symbol] the address family of the socket,
|
31
|
+
# `Socket::AF_INET` or `Socket::AF_INET6`
|
32
|
+
# @return [Object] the new CoDTLS socket object
|
33
|
+
def initialize(address_family = nil)
|
34
|
+
if address_family.nil?
|
35
|
+
@socket = UDPSocket.new
|
36
|
+
else
|
37
|
+
@socket = UDPSocket.new(address_family)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Binds codtlssocket to host:port.
|
42
|
+
#
|
43
|
+
# @param host [IP] the address of the local machine
|
44
|
+
# @param port [Number] the port of the local machine
|
45
|
+
# @return [Number] 0 if bind succeed
|
46
|
+
def bind(host, port)
|
47
|
+
@socket.bind(host, port)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Connects codtlssocket to host:port.
|
51
|
+
#
|
52
|
+
# @param host [IP] the address of the remote machine
|
53
|
+
# @param port [Number] the port of the remote machine
|
54
|
+
# @return [Number] 0 if bind succeed
|
55
|
+
def connect(host, port)
|
56
|
+
@socket.connect(host, port)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Recieves message via secure UDP-Socket. Blocks until data is recieved.
|
60
|
+
#
|
61
|
+
# @param maxlen [Number] the number of bytes to receive from the socket
|
62
|
+
# @param flags [Number] should be a bitwise OR of Socket::MSG_* constants
|
63
|
+
# @return [Array] mesg, (address_family, port, hostname, numeric_address).
|
64
|
+
# mesg is empty, if recieved data is corrupt
|
65
|
+
def recvfrom(maxlen, flags = nil)
|
66
|
+
if flags.nil?
|
67
|
+
mesg = @socket.recvfrom(maxlen + 23)
|
68
|
+
else
|
69
|
+
mesg = @socket.recvfrom(maxlen + 23, flags)
|
70
|
+
end
|
71
|
+
CoDTLS::RecordLayer.decrypt(mesg, maxlen)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Recieves message via secure UDP-Socket.
|
75
|
+
#
|
76
|
+
# @param maxlen [Number] the number of bytes to receive from the socket
|
77
|
+
# @param flags [Number] should be a bitwise OR of Socket::MSG_* constants
|
78
|
+
# @return [Array] mesg, (address_family, port, hostname, numeric_address).
|
79
|
+
# message is empty, if data there is no data or data is corrupt
|
80
|
+
def recvfrom_nonblock(maxlen, flags = nil)
|
81
|
+
if flags.nil?
|
82
|
+
mesg = @socket.recvfrom_nonblock(maxlen + 23)
|
83
|
+
else
|
84
|
+
mesg = @socket.recvfrom_nonblock(maxlen + 23, flags)
|
85
|
+
end
|
86
|
+
CoDTLS::RecordLayer.decrypt(mesg, maxlen)
|
87
|
+
end
|
88
|
+
|
89
|
+
# === Usage:
|
90
|
+
# * send(mesg, flags, host, port)
|
91
|
+
# * send(mesg, flags, sockaddr_to)
|
92
|
+
# * send(mesg, flags)
|
93
|
+
#
|
94
|
+
# Sends message via secure UDP-Socket.
|
95
|
+
#
|
96
|
+
# @param mesg [String] the message to send
|
97
|
+
# @param flags [Number] should be a bitwise OR of Socket::MSG_* constants
|
98
|
+
# @param host_or_sockaddr_to [String] the hostname or sockaddr of the
|
99
|
+
# remote machine
|
100
|
+
# @param port [Number] the port of the remote machine
|
101
|
+
# @return [Number] the number of bytes sent.
|
102
|
+
# If mesg.length > 0 && return value == 0 an error happend
|
103
|
+
def send(mesg, flags, *argv)
|
104
|
+
return 0 if mesg.length <= 0
|
105
|
+
if argv.length > 2
|
106
|
+
fail ArgumentError, 'wrong number of arguments ' \
|
107
|
+
"(#{2 + argv.length} for 2-4)"
|
108
|
+
end
|
109
|
+
|
110
|
+
secure_mesg = case argv.length
|
111
|
+
when 0
|
112
|
+
CoDTLS::RecordLayer.encrypt(
|
113
|
+
mesg,
|
114
|
+
@socket.peeraddr(:numeric)[3])
|
115
|
+
when 1
|
116
|
+
CoDTLS::RecordLayer.encrypt(
|
117
|
+
mesg,
|
118
|
+
Socket.unpack_sockaddr_in(argv[0])[1])
|
119
|
+
when 2
|
120
|
+
CoDTLS::RecordLayer.encrypt(
|
121
|
+
mesg,
|
122
|
+
IPSocket.getaddress(argv[0]))
|
123
|
+
end
|
124
|
+
@socket.send(secure_mesg, flags, *argv)
|
125
|
+
mesg.length
|
126
|
+
end
|
127
|
+
|
128
|
+
# Disallows further read and write using shutdown system call.
|
129
|
+
def close
|
130
|
+
@socket.close
|
131
|
+
end
|
132
|
+
|
133
|
+
# Sets pre-shared key for the device with the specified uuid.
|
134
|
+
#
|
135
|
+
# @param uuid [Binary] the UUID of the device in 16 byte binary form
|
136
|
+
# @param psk [String] the 16 byte long pre-shared key of the device
|
137
|
+
# @param desc [String] Optional Description of the device
|
138
|
+
def self.add_psk(uuid, psk, desc = '')
|
139
|
+
CoDTLS::PSKDB.set_psk(uuid, psk, desc)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns all known devices as an Array.
|
143
|
+
#
|
144
|
+
# @return [Array] of {uuid: A, psk: B, desc: C}
|
145
|
+
def self.psks
|
146
|
+
CoDTLS::PSKDB.all_registered
|
147
|
+
# [{ uuid: ['a9d984d1fe2b4c06afe8da98d8924005'].pack('H*'),
|
148
|
+
# psk: 'ABCDEFGHIJKLMNOP', desc: 'Temperaturgeraet 1' },
|
149
|
+
# { uuid: ['9425f01d39034295ad9447161e13251b'].pack('H*'),
|
150
|
+
# psk: 'abcdefghijklmnop', desc: 'Rolladen Nummer 5' }]
|
151
|
+
end
|
152
|
+
|
153
|
+
# Deletes the entry of the specified uuid.
|
154
|
+
#
|
155
|
+
# @param uuid [Binary] the UUID of the device to delete
|
156
|
+
# @return [Bool] true if uuid was found and deleted, else false
|
157
|
+
def self.del_psk(uuid)
|
158
|
+
CoDTLS::PSKDB.del_psk!(uuid)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Starts a listening thread on port 5684. If HelloRequest is recieved,
|
162
|
+
# listener.info(numeric_address, code) is called, after a handshake.
|
163
|
+
# numeric_address contains the ip of the remote and code == 0 if
|
164
|
+
# handshake succeed. Code == 1 if handshake failed or PSK is missing.
|
165
|
+
def self.add_new_node_listener(listener)
|
166
|
+
Thread.new do
|
167
|
+
s = UDPSocket.new(Socket::AF_INET6)
|
168
|
+
s.bind('::0', 5684)
|
169
|
+
loop do
|
170
|
+
packet = s.recvfrom(3)
|
171
|
+
|
172
|
+
logger = Logger.new(STDOUT)
|
173
|
+
logger.level = CoDTLS::LOG_LEVEL
|
174
|
+
logger.debug(packet.inspect)
|
175
|
+
|
176
|
+
if packet[0] == "\x50\x03\x00"
|
177
|
+
logger.debug("HelloRequest erhalten")
|
178
|
+
numeric_address = packet[1][3]
|
179
|
+
listener.info(numeric_address,
|
180
|
+
CoDTLS::Handshake.handshake(numeric_address))
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
module CoDTLS
|
2
|
+
# Error class for wrong data inputs (for exampe keyblock)
|
3
|
+
class SessionError < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
# Storage class for a CoDTLS-Session with the following Fields:
|
7
|
+
#
|
8
|
+
# TABLE 1
|
9
|
+
# Type | Name | Standard-Value
|
10
|
+
# -------------------------------------------------------
|
11
|
+
# uint8_t | uuid[16]; | uuid - couldnt be empty
|
12
|
+
# uint8_t | psk[16]; | psk - couldnt be empty
|
13
|
+
# uint8_t | psk_new[16]; | empty
|
14
|
+
#
|
15
|
+
# TABLE 2
|
16
|
+
# Type | Name | Standard-Value
|
17
|
+
# -------------------------------------------------------
|
18
|
+
# uint8_t | ip[16]; | Given IP
|
19
|
+
# uint8_t | id[8]; | empty
|
20
|
+
# uint16_t | epoch; | 0
|
21
|
+
# uint48_t | seq_num_r; | depends on implementation (-1, 0 or 1)
|
22
|
+
# uint48_t | seq_num_w; | depends on implementation (-1, 0 or 1)
|
23
|
+
# uint8_t | key_block[40]; | empty
|
24
|
+
# uint8_t | key_block_new[40]; | empty
|
25
|
+
# uint8_t | handshake; | 0
|
26
|
+
class AbstractSession
|
27
|
+
# Creates a database connection if necessary
|
28
|
+
def self.establish_connection
|
29
|
+
fail 'SYSTEM ERROR: method missing'
|
30
|
+
end
|
31
|
+
|
32
|
+
# Sets PSK for the specified UUID. If PSK for UUID is already set,
|
33
|
+
# PSK ist saved into PSK_new. So PSK is set one time, while PSK_new
|
34
|
+
# maybe gets overwritten more times. Other values are set to standard.
|
35
|
+
#
|
36
|
+
# @param uuid [Binary] the UUID of the device in 16 byte binary form
|
37
|
+
# @param psk [String] the 16 byte long pre-shared key of the device
|
38
|
+
def self.set_psk(uuid, psk, desc = '')
|
39
|
+
fail 'SYSTEM ERROR: method missing'
|
40
|
+
end
|
41
|
+
|
42
|
+
# Gets PSK for the specified UUID. If PSK_new is set, the return value
|
43
|
+
# is PSK_new, else PSK is return value. If UUID is not existing
|
44
|
+
# nil will be returned.
|
45
|
+
#
|
46
|
+
# @param uuid [Binary] the UUID of the device in 16 byte binary form
|
47
|
+
# @return [String] the 16 byte long pre-shared key for the UUID
|
48
|
+
def self.get_psk(uuid)
|
49
|
+
fail 'SYSTEM ERROR: method missing'
|
50
|
+
end
|
51
|
+
|
52
|
+
# Deletes the PSK for the provided UUID. Handle with care, PSK_new and PSK
|
53
|
+
# are lost after this.
|
54
|
+
#
|
55
|
+
# @param uuid [Binary] the UUID of the device in 16 byte binary form
|
56
|
+
def self.del_psk!(uuid)
|
57
|
+
fail 'SYSTEM ERROR: method missing'
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns an array of all registered UUIDs.
|
61
|
+
#
|
62
|
+
# @return [Array] of {uuid: A, psk: B, desc: C}
|
63
|
+
def self.all_registered
|
64
|
+
fail 'SYSTEM ERROR: method missing'
|
65
|
+
end
|
66
|
+
|
67
|
+
# Removes the all entrys from database in TABLE 2.
|
68
|
+
def self.clear_all
|
69
|
+
fail 'SYSTEM ERROR: method missing'
|
70
|
+
end
|
71
|
+
|
72
|
+
# Constructor to create a new session for the given ip. When only ip is
|
73
|
+
# given, its the value for searching in database. When its not found, a
|
74
|
+
# new database entry with standard values will be created. When id is
|
75
|
+
# also given, id is the first value for searching in database. When its
|
76
|
+
# found, ip will be updated and other values are unchanged. In the other
|
77
|
+
# case, when id isnt found, its the same behavior as without id but with
|
78
|
+
# additional storing of the id. Throws excpetion if ip == nil.
|
79
|
+
#
|
80
|
+
# @param ip [IP] IP for this Session
|
81
|
+
# @param id [String] Session-Id for this Session
|
82
|
+
def initialize(ip, id = nil)
|
83
|
+
fail 'SYSTEM ERROR: method missing'
|
84
|
+
end
|
85
|
+
|
86
|
+
# Sets the ID of the current session.
|
87
|
+
#
|
88
|
+
# @param id [String] the Session-Id
|
89
|
+
def id=(id)
|
90
|
+
fail 'SYSTEM ERROR: method missing'
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns the ID of the current session.
|
94
|
+
#
|
95
|
+
# @return [String] the Session-ID. nil if Session-ID is unknown
|
96
|
+
def id
|
97
|
+
fail 'SYSTEM ERROR: method missing'
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns the Epoch of the session for the specified IP.
|
101
|
+
#
|
102
|
+
# @return [Number] the Epoch
|
103
|
+
def epoch
|
104
|
+
fail 'SYSTEM ERROR: method missing'
|
105
|
+
end
|
106
|
+
|
107
|
+
# Increases the Epoch of the session by 1.
|
108
|
+
# Also copy key_block_new to key_block and sets key_block_new to empty.
|
109
|
+
# seq_num_r and seq_num_w are set back to standard value.
|
110
|
+
# Throws excpetion if keyblock is not 40 bytes long.
|
111
|
+
def increase_epoch
|
112
|
+
fail 'SYSTEM ERROR: method missing'
|
113
|
+
end
|
114
|
+
|
115
|
+
# Checks the sequenze number of an incoming paket. Valid number is
|
116
|
+
# -10 ... + 100 of the expected number.
|
117
|
+
# The inital LAST number is 0, so the next expected is 1.
|
118
|
+
#
|
119
|
+
# @param num [Number] the recieved sequence number
|
120
|
+
# @return [Bool] true if the number is valid. false if invalid
|
121
|
+
def check_seq(num)
|
122
|
+
fail 'SYSTEM ERROR: method missing'
|
123
|
+
end
|
124
|
+
|
125
|
+
# Sets the sequence number of the last received paket.
|
126
|
+
#
|
127
|
+
# @param num [Number] the new sequence number
|
128
|
+
def seq=(num)
|
129
|
+
fail 'SYSTEM ERROR: method missing'
|
130
|
+
end
|
131
|
+
|
132
|
+
# Returns the sequence number for the next outgoing paket.
|
133
|
+
# The inital sequence number is 1. Every return value needs
|
134
|
+
# to be last value + 1.
|
135
|
+
#
|
136
|
+
# @return [Number] the sequence number for the next outgoing paket
|
137
|
+
def seq
|
138
|
+
fail 'SYSTEM ERROR: method missing'
|
139
|
+
end
|
140
|
+
|
141
|
+
# Inserts a new keyblock to key_block_new. Throws excpetion if
|
142
|
+
# keyblock is not 40 bytes long.
|
143
|
+
#
|
144
|
+
# @param keyBlock [String] the 40 byte long new keyblock to be inserted
|
145
|
+
def key_block=(keyBlock)
|
146
|
+
fail 'SYSTEM ERROR: method missing'
|
147
|
+
end
|
148
|
+
|
149
|
+
# Returns the active keyblock (key_block) for the specified IP.
|
150
|
+
# If keyblock is empty, nil will be returned.
|
151
|
+
#
|
152
|
+
# @return [String] the 40 byte long keyblock or nil if empty
|
153
|
+
def key_block
|
154
|
+
fail 'SYSTEM ERROR: method missing'
|
155
|
+
end
|
156
|
+
|
157
|
+
# Causes the next messages to be send as handshake messages.
|
158
|
+
def enable_handshake
|
159
|
+
fail 'SYSTEM ERROR: method missing'
|
160
|
+
end
|
161
|
+
|
162
|
+
# Causes the next messages to not be send as handshake messages.
|
163
|
+
def disable_handshake
|
164
|
+
fail 'SYSTEM ERROR: method missing'
|
165
|
+
end
|
166
|
+
|
167
|
+
# Checks if the next message should be send as a handshake message.
|
168
|
+
#
|
169
|
+
# @return [Bool] true if the next messages are handshake messages
|
170
|
+
def handshake?
|
171
|
+
fail 'SYSTEM ERROR: method missing'
|
172
|
+
end
|
173
|
+
|
174
|
+
# Removes the hole entry from database.
|
175
|
+
def clear
|
176
|
+
fail 'SYSTEM ERROR: method missing'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|