raioquic 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.containerignore +4 -0
- data/.rubocop.yml +93 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Containerfile +6 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +113 -0
- data/LICENSE +28 -0
- data/README.md +48 -0
- data/Rakefile +16 -0
- data/Steepfile +8 -0
- data/example/curlcatcher.rb +18 -0
- data/example/interoperability/README.md +9 -0
- data/example/interoperability/aioquic/aioquic_client.py +47 -0
- data/example/interoperability/aioquic/aioquic_server.py +34 -0
- data/example/interoperability/key.pem +28 -0
- data/example/interoperability/localhost-unasuke-dev.crt +21 -0
- data/example/interoperability/quic-go/sample_server.go +61 -0
- data/example/interoperability/raioquic_client.rb +42 -0
- data/example/interoperability/raioquic_server.rb +43 -0
- data/example/parse_curl_example.rb +108 -0
- data/lib/raioquic/buffer.rb +202 -0
- data/lib/raioquic/core_ext.rb +54 -0
- data/lib/raioquic/crypto/README.md +5 -0
- data/lib/raioquic/crypto/aesgcm.rb +52 -0
- data/lib/raioquic/crypto/backend/aead.rb +52 -0
- data/lib/raioquic/crypto/backend.rb +12 -0
- data/lib/raioquic/crypto.rb +10 -0
- data/lib/raioquic/quic/configuration.rb +81 -0
- data/lib/raioquic/quic/connection.rb +2776 -0
- data/lib/raioquic/quic/crypto.rb +317 -0
- data/lib/raioquic/quic/event.rb +69 -0
- data/lib/raioquic/quic/logger.rb +272 -0
- data/lib/raioquic/quic/packet.rb +471 -0
- data/lib/raioquic/quic/packet_builder.rb +301 -0
- data/lib/raioquic/quic/rangeset.rb +113 -0
- data/lib/raioquic/quic/recovery.rb +528 -0
- data/lib/raioquic/quic/stream.rb +343 -0
- data/lib/raioquic/quic.rb +20 -0
- data/lib/raioquic/tls.rb +1659 -0
- data/lib/raioquic/version.rb +5 -0
- data/lib/raioquic.rb +12 -0
- data/misc/export_x25519.py +43 -0
- data/misc/gen_rfc8448_keypair.rb +90 -0
- data/raioquic.gemspec +37 -0
- data/sig/raioquic/buffer.rbs +37 -0
- data/sig/raioquic/core_ext.rbs +7 -0
- data/sig/raioquic/crypto/aesgcm.rbs +20 -0
- data/sig/raioquic/crypto/backend/aead.rbs +11 -0
- data/sig/raioquic/quic/configuration.rbs +34 -0
- data/sig/raioquic/quic/connection.rbs +277 -0
- data/sig/raioquic/quic/crypto.rbs +88 -0
- data/sig/raioquic/quic/event.rbs +51 -0
- data/sig/raioquic/quic/logger.rbs +57 -0
- data/sig/raioquic/quic/packet.rbs +157 -0
- data/sig/raioquic/quic/packet_builder.rbs +76 -0
- data/sig/raioquic/quic/rangeset.rbs +17 -0
- data/sig/raioquic/quic/recovery.rbs +142 -0
- data/sig/raioquic/quic/stream.rbs +87 -0
- data/sig/raioquic/tls.rbs +444 -0
- data/sig/raioquic.rbs +9 -0
- metadata +121 -0
data/lib/raioquic.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "raioquic/version"
|
4
|
+
require_relative "raioquic/buffer"
|
5
|
+
require_relative "raioquic/quic"
|
6
|
+
require_relative "raioquic/crypto"
|
7
|
+
|
8
|
+
module Raioquic
|
9
|
+
class Error < StandardError; end
|
10
|
+
# Your code goes here...
|
11
|
+
class ValueError < Error; end
|
12
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Create X25519 kay pair as PEM format it illustrated in RFC 8448.
|
2
|
+
|
3
|
+
from cryptography.hazmat.primitives import serialization
|
4
|
+
from cryptography.hazmat.primitives.asymmetric import x25519
|
5
|
+
import binascii
|
6
|
+
|
7
|
+
client_priv_key = x25519.X25519PrivateKey.from_private_bytes(
|
8
|
+
binascii.unhexlify("49af42ba7f7994852d713ef2784bcbcaa7911de26adc5642cb634540e7ea5005")
|
9
|
+
)
|
10
|
+
|
11
|
+
print(client_priv_key.private_bytes(
|
12
|
+
encoding=serialization.Encoding.PEM,
|
13
|
+
format=serialization.PrivateFormat.PKCS8,
|
14
|
+
encryption_algorithm=serialization.NoEncryption()
|
15
|
+
))
|
16
|
+
|
17
|
+
client_pub_key = x25519.X25519PublicKey.from_public_bytes(
|
18
|
+
binascii.unhexlify("99381de560e4bd43d23d8e435a7dbafeb3c06e51c13cae4d5413691e529aaf2c")
|
19
|
+
)
|
20
|
+
|
21
|
+
print(client_pub_key.public_bytes(
|
22
|
+
encoding=serialization.Encoding.PEM,
|
23
|
+
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
24
|
+
))
|
25
|
+
|
26
|
+
server_priv_key = x25519.X25519PrivateKey.from_private_bytes(
|
27
|
+
binascii.unhexlify("b1580eeadf6dd589b8ef4f2d5652578cc810e9980191ec8d058308cea216a21e")
|
28
|
+
)
|
29
|
+
|
30
|
+
print(server_priv_key.private_bytes(
|
31
|
+
encoding=serialization.Encoding.PEM,
|
32
|
+
format=serialization.PrivateFormat.PKCS8,
|
33
|
+
encryption_algorithm=serialization.NoEncryption()
|
34
|
+
))
|
35
|
+
|
36
|
+
server_pub_key = x25519.X25519PublicKey.from_public_bytes(
|
37
|
+
binascii.unhexlify("c9828876112095fe66762bdbf7c672e156d6cc253b833df1dd69b1b04e751f0f")
|
38
|
+
)
|
39
|
+
|
40
|
+
print(server_pub_key.public_bytes(
|
41
|
+
encoding=serialization.Encoding.PEM,
|
42
|
+
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
43
|
+
))
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "openssl"
|
4
|
+
|
5
|
+
# Generate key pair illustrated in RFC 8448.
|
6
|
+
# https://datatracker.ietf.org/doc/html/rfc8448
|
7
|
+
#
|
8
|
+
# In OpenSSL 3 environtment, openssl gem did not support OpenSSL::PKey::RSA#set_key, OpenSSL::PKey::RSA#set_factors,
|
9
|
+
# and OpenSSL::PKey::RSA#set_crt_params because PKey object made immutable from OpenSSL 3.
|
10
|
+
# Run this script in OpenSSL 1 env (like a container), get key pair with PEM format,
|
11
|
+
# then read in OpenSSL 3 env by OpenSSL::Pkey.read method and so on.
|
12
|
+
|
13
|
+
rfc8448_rsa_pkey_moduls = <<~MODULUS.split.map(&:hex).map(&:chr).join
|
14
|
+
b4 bb 49 8f 82 79 30 3d 98 08 36 39 9b 36 c6 98
|
15
|
+
8c 0c 68 de 55 e1 bd b8 26 d3 90 1a 24 61 ea fd
|
16
|
+
2d e4 9a 91 d0 15 ab bc 9a 95 13 7a ce 6c 1a f1
|
17
|
+
9e aa 6a f9 8c 7c ed 43 12 09 98 e1 87 a8 0e e0
|
18
|
+
cc b0 52 4b 1b 01 8c 3e 0b 63 26 4d 44 9a 6d 38
|
19
|
+
e2 2a 5f da 43 08 46 74 80 30 53 0e f0 46 1c 8c
|
20
|
+
a9 d9 ef bf ae 8e a6 d1 d0 3e 2b d1 93 ef f0 ab
|
21
|
+
9a 80 02 c4 74 28 a6 d3 5a 8d 88 d7 9f 7f 1e 3f
|
22
|
+
MODULUS
|
23
|
+
|
24
|
+
rfc8448_rsa_pkey_public_exponent = <<~EXPONENT.split.map(&:hex).map(&:chr).join
|
25
|
+
01 00 01
|
26
|
+
EXPONENT
|
27
|
+
|
28
|
+
rfc8448_rsa_pkey_private_exponent = <<~EXPONENT.split.map(&:hex).map(&:chr).join
|
29
|
+
04 de a7 05 d4 3a 6e a7 20 9d d8 07 21 11 a8 3c
|
30
|
+
81 e3 22 a5 92 78 b3 34 80 64 1e af 7c 0a 69 85
|
31
|
+
b8 e3 1c 44 f6 de 62 e1 b4 c2 30 9f 61 26 e7 7b
|
32
|
+
7c 41 e9 23 31 4b bf a3 88 13 05 dc 12 17 f1 6c
|
33
|
+
81 9c e5 38 e9 22 f3 69 82 8d 0e 57 19 5d 8c 84
|
34
|
+
88 46 02 07 b2 fa a7 26 bc f7 08 bb d7 db 7f 67
|
35
|
+
9f 89 34 92 fc 2a 62 2e 08 97 0a ac 44 1c e4 e0
|
36
|
+
c3 08 8d f2 5a e6 79 23 3d f8 a3 bd a2 ff 99 41
|
37
|
+
EXPONENT
|
38
|
+
|
39
|
+
rfc8448_rsa_pkey_prime1 = <<~PRIME1.split.map(&:hex).map(&:chr).join
|
40
|
+
e4 35 fb 7c c8 37 37 75 6d ac ea 96 ab 7f 59 a2
|
41
|
+
cc 10 69 db 7d eb 19 0e 17 e3 3a 53 2b 27 3f 30
|
42
|
+
a3 27 aa 0a aa bc 58 cd 67 46 6a f9 84 5f ad c6
|
43
|
+
75 fe 09 4a f9 2c 4b d1 f2 c1 bc 33 dd 2e 05 15
|
44
|
+
PRIME1
|
45
|
+
|
46
|
+
rfc8448_rsa_pkey_prime2 = <<~PRIME2.split.map(&:hex).map(&:chr).join
|
47
|
+
ca bd 3b c0 e0 43 86 64 c8 d4 cc 9f 99 97 7a 94
|
48
|
+
d9 bb fe ad 8e 43 87 0a ba e3 f7 eb 8b 4e 0e ee
|
49
|
+
8a f1 d9 b4 71 9b a6 19 6c f2 cb ba ee eb f8 b3
|
50
|
+
49 0a fe 9e 9f fa 74 a8 8a a5 1f c6 45 62 93 03
|
51
|
+
PRIME2
|
52
|
+
|
53
|
+
rfc8448_rsa_pkey_exponent1 = <<~EXPONENT1.split.map(&:hex).map(&:chr).join
|
54
|
+
3f 57 34 5c 27 fe 1b 68 7e 6e 76 16 27 b7 8b 1b
|
55
|
+
82 64 33 dd 76 0f a0 be a6 a6 ac f3 94 90 aa 1b
|
56
|
+
47 cd a4 86 9d 68 f5 84 dd 5b 50 29 bd 32 09 3b
|
57
|
+
82 58 66 1f e7 15 02 5e 5d 70 a4 5a 08 d3 d3 19
|
58
|
+
EXPONENT1
|
59
|
+
|
60
|
+
rfc8448_rsa_pkey_exponent2 = <<~EXPONENT2.split.map(&:hex).map(&:chr).join
|
61
|
+
18 3d a0 13 63 bd 2f 28 85 ca cb dc 99 64 bf 47
|
62
|
+
64 f1 51 76 36 f8 64 01 28 6f 71 89 3c 52 cc fe
|
63
|
+
40 a6 c2 3d 0d 08 6b 47 c6 fb 10 d8 fd 10 41 e0
|
64
|
+
4d ef 7e 9a 40 ce 95 7c 41 77 94 e1 04 12 d1 39
|
65
|
+
EXPONENT2
|
66
|
+
|
67
|
+
rfc8448_rsa_pkey_coefficient = <<~COEF.split.map(&:hex).map(&:chr).join
|
68
|
+
83 9c a9 a0 85 e4 28 6b 2c 90 e4 66 99 7a 2c 68
|
69
|
+
1f 21 33 9a a3 47 78 14 e4 de c1 18 33 05 0e d5
|
70
|
+
0d d1 3c c0 38 04 8a 43 c5 9b 2a cc 41 68 89 c0
|
71
|
+
37 66 5f e5 af a6 05 96 9f 8c 01 df a5 ca 96 9d
|
72
|
+
COEF
|
73
|
+
|
74
|
+
rsa_cert = OpenSSL::PKey::RSA.new
|
75
|
+
rsa_cert.set_key(
|
76
|
+
OpenSSL::BN.new(rfc8448_rsa_pkey_moduls, 2),
|
77
|
+
OpenSSL::BN.new(rfc8448_rsa_pkey_public_exponent, 2),
|
78
|
+
OpenSSL::BN.new(rfc8448_rsa_pkey_private_exponent, 2),
|
79
|
+
)
|
80
|
+
rsa_cert.set_factors(
|
81
|
+
OpenSSL::BN.new(rfc8448_rsa_pkey_prime1, 2),
|
82
|
+
OpenSSL::BN.new(rfc8448_rsa_pkey_prime2, 2),
|
83
|
+
)
|
84
|
+
rsa_cert.set_crt_params(
|
85
|
+
OpenSSL::BN.new(rfc8448_rsa_pkey_exponent1, 2),
|
86
|
+
OpenSSL::BN.new(rfc8448_rsa_pkey_exponent2, 2),
|
87
|
+
OpenSSL::BN.new(rfc8448_rsa_pkey_coefficient, 2),
|
88
|
+
)
|
89
|
+
|
90
|
+
File.write("rfc8448.pem", rsa_cert.to_pem)
|
data/raioquic.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/raioquic/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "raioquic"
|
7
|
+
spec.version = Raioquic::VERSION
|
8
|
+
spec.authors = ["Yusuke Nakamura"]
|
9
|
+
spec.email = ["yusuke1994525@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "Write a short summary, because RubyGems requires one."
|
12
|
+
spec.description = "Write a longer description or delete this line."
|
13
|
+
spec.homepage = "https://example.com"
|
14
|
+
spec.required_ruby_version = ">= 3.0.0"
|
15
|
+
|
16
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
17
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
18
|
+
spec.metadata["changelog_uri"] = spec.homepage
|
19
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
25
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
26
|
+
end
|
27
|
+
end
|
28
|
+
spec.bindir = "exe"
|
29
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
# Uncomment to register a new dependency of your gem
|
33
|
+
spec.add_dependency "tttls1.3"
|
34
|
+
|
35
|
+
# For more information and examples about making a new gem, check out our
|
36
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
37
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Raioquic
|
2
|
+
class Buffer
|
3
|
+
# extend Forwardable
|
4
|
+
|
5
|
+
UINT_VAR_MAX: ::Integer
|
6
|
+
UINT_VAR_MAX_SIZE: 8
|
7
|
+
|
8
|
+
class BufferReadError < StandardError
|
9
|
+
end
|
10
|
+
class BufferWriteError < StandardError
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.encode_uint_var: (Integer) -> String
|
14
|
+
def self.size_uint_var: (Integer) -> (1 | 2 | 4 | 8)
|
15
|
+
def initialize: (?capacity: Integer?, ?data: String) -> void
|
16
|
+
def dealloc: () -> nil
|
17
|
+
def data: () -> String
|
18
|
+
def tell: () -> ::Integer # delegated method
|
19
|
+
def seek: (Integer) -> void
|
20
|
+
def capacity: -> ::Integer
|
21
|
+
def data_slice: (start: Integer, ends: Integer) -> untyped
|
22
|
+
def pull_bytes: (Integer) -> String
|
23
|
+
def pull_uint8: () -> Integer
|
24
|
+
def pull_uint16: () -> Integer
|
25
|
+
def pull_uint32: () -> Integer
|
26
|
+
def pull_uint64: () -> Integer
|
27
|
+
def pull_uint_var: () -> Integer
|
28
|
+
def push_bytes: (String) -> void
|
29
|
+
def push_uint8: (Integer) -> void
|
30
|
+
def push_uint16: (Integer) -> void
|
31
|
+
def push_uint32: (Integer) -> void
|
32
|
+
def push_uint64: (Integer) -> void
|
33
|
+
def push_uint_var: (Integer) -> void
|
34
|
+
def encode_uint_var: (Integer) -> nil
|
35
|
+
private def check_read_bounds: (Integer) -> void
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Raioquic
|
2
|
+
module Crypto
|
3
|
+
class AESGCM
|
4
|
+
MAX_SIZE: Numeric
|
5
|
+
|
6
|
+
class OverflowError < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader key: ::String
|
10
|
+
|
11
|
+
def initialize: (String) -> void
|
12
|
+
def encrypt: (nonce: ::String, data: ::String, associated_data: ::String) -> ::String
|
13
|
+
| (nonce: ::String, data: ::String) -> ::String
|
14
|
+
def decrypt: (nonce: ::String, data: ::String, associated_data: ::String) -> ::String
|
15
|
+
| (nonce: ::String, data: ::String) -> ::String
|
16
|
+
def validate_length: (nonce: ::String, data: ::String) -> void
|
17
|
+
def check_nonce: (::String) -> void
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Raioquic
|
2
|
+
module Crypto
|
3
|
+
module Backend
|
4
|
+
class Aead
|
5
|
+
def self.aead_cipher_name: (::Raioquic::Crypto::AESGCM | untyped) -> String
|
6
|
+
def self.encrypt: (cipher: untyped, key: String, nonce: String, data: String, associated_data: Array[String?], tag_length: Integer) -> String
|
7
|
+
def self.decrypt: (cipher: untyped, key: String, nonce: String, data: String, associated_data: Array[String?], tag_length: Integer) -> String
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Raioquic
|
2
|
+
module Quic
|
3
|
+
module QuicConfiguration
|
4
|
+
attr_accessor alpn_protocols: ::Array[untyped]
|
5
|
+
attr_accessor connection_id_length: ::Integer
|
6
|
+
attr_accessor idle_timeout: ::Float
|
7
|
+
attr_accessor is_client: bool
|
8
|
+
attr_accessor max_data: ::Integer
|
9
|
+
attr_accessor max_stream_data: ::Integer
|
10
|
+
attr_accessor quic_logger: ::Raioquic::Quic::Logger::QuicLogger
|
11
|
+
attr_accessor secrets_log_file: untyped
|
12
|
+
attr_accessor server_name: ::String | nil
|
13
|
+
attr_accessor session_ticket: ::String | nil
|
14
|
+
attr_accessor cadata: ::String | nil
|
15
|
+
attr_accessor cafile: ::String | nil
|
16
|
+
attr_accessor capath: ::String | nil
|
17
|
+
attr_accessor certificate: untyped
|
18
|
+
attr_accessor certificate_chain: ::Array[untyped]
|
19
|
+
attr_accessor cipher_suites: ::Array[::Integer]
|
20
|
+
attr_accessor initial_rtt: ::Float
|
21
|
+
attr_accessor max_datagram_frame_size: ::Integer
|
22
|
+
attr_accessor private_key: untyped
|
23
|
+
attr_accessor quantam_readiness_test: bool
|
24
|
+
attr_accessor supported_versions: ::Array[::Integer]
|
25
|
+
attr_accessor verify_mode: ::Integer # OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER
|
26
|
+
|
27
|
+
def initialize: (untyped) -> void
|
28
|
+
def load_cert_chain: (::String certfile) -> void
|
29
|
+
| (::String certfile, ::String keyfile) -> void
|
30
|
+
| (::String certfile, ::String keyfile, ::String password) -> void
|
31
|
+
def load_verify_locations: (?cafile: ::String|nil, ?capath: ::String|nil, ?cadata: ::String|nil) -> void
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,277 @@
|
|
1
|
+
module Raioquic
|
2
|
+
module Quic
|
3
|
+
module Connection
|
4
|
+
CRYPTO_BUFFER_SIZE: ::Integer
|
5
|
+
EPOCH_SHORTCUTS: ::Hash[::String, ::Integer]
|
6
|
+
MAX_EARLY_DATA: ::Integer
|
7
|
+
SECRETS_LABELS: ::Array[::Array[::String | nil]]
|
8
|
+
STREAM_FLAGS: ::Integer
|
9
|
+
STREAM_COUNT_MAX: ::Integer
|
10
|
+
UDP_HEADER_SIZE: 8
|
11
|
+
ACK_FRAME_CAPACITY: ::Integer
|
12
|
+
APPLICATION_CLOSE_FRAME_CAPACITY: ::Integer
|
13
|
+
CONNECTION_LIMIT_FRAME_CAPACITY: ::Integer
|
14
|
+
HANDSHAKE_DONE_FRAME_CAPACITY: ::Integer
|
15
|
+
MAX_STREAM_DATA_FRAME_CAPACITY: ::Integer
|
16
|
+
NEW_CONNECTION_ID_FRAME_CAPACITY: ::Integer
|
17
|
+
PATH_CHALLENGE_FRAME_CAPACITY: ::Integer
|
18
|
+
PATH_RESPONSE_FRAME_CAPACITY: ::Integer
|
19
|
+
PING_FRAME_CAPACITY: ::Integer
|
20
|
+
RESET_STREAM_FRAME_CAPACITY: ::Integer
|
21
|
+
RETIRE_CONNECTION_ID_CAPACITY: ::Integer
|
22
|
+
STOP_SENDING_FRAME_CAPACITY: ::Integer
|
23
|
+
STREAMS_BLOCKED_CAPACITY: ::Integer
|
24
|
+
TRANSPORT_CLOSE_FLAME_CAPACITY: ::Integer
|
25
|
+
|
26
|
+
def self.epochs: (::String shortcut) -> ::Array[::Integer]
|
27
|
+
def self.dump_cid: (::String cid) -> ::String
|
28
|
+
def self.get_epoch: (::Integer packet_type) -> ::Integer
|
29
|
+
def self.get_transport_parameters_extension: (::Integer version) -> ::Integer
|
30
|
+
def self.stream_is_client_initialized: (::Integer stream_id) -> bool
|
31
|
+
def self.stream_is_unidirectional: (::Integer stream_id) -> bool
|
32
|
+
|
33
|
+
class Limit
|
34
|
+
@frame_type: ::Integer
|
35
|
+
@name: ::String
|
36
|
+
@sent: ::Integer
|
37
|
+
@used: ::Integer
|
38
|
+
@value: ::Integer
|
39
|
+
|
40
|
+
attr_reader frame_type: ::Integer
|
41
|
+
|
42
|
+
attr_accessor used: ::Integer
|
43
|
+
attr_accessor sent: ::Integer
|
44
|
+
attr_accessor value: ::Integer
|
45
|
+
|
46
|
+
def initialize: (frame_type: ::Integer, name: ::String, value: ::Integer) -> void
|
47
|
+
end
|
48
|
+
|
49
|
+
class QuicConnectionError < Error
|
50
|
+
@error_code: ::Integer
|
51
|
+
@frame_type: ::Integer
|
52
|
+
@reason_phrase: ::String
|
53
|
+
end
|
54
|
+
|
55
|
+
# TODO: QuicConnectionAdapter
|
56
|
+
|
57
|
+
class QuicConnectionId
|
58
|
+
attr_accessor cid: ::String
|
59
|
+
attr_accessor sequence_number: ::Integer
|
60
|
+
attr_accessor stateless_reset_token: ::String
|
61
|
+
attr_accessor was_sent: bool
|
62
|
+
end
|
63
|
+
|
64
|
+
class QuicConnectionState
|
65
|
+
FIRSTFLIGHT: 0
|
66
|
+
CONNECTED: 1
|
67
|
+
CLOSING: 2
|
68
|
+
DRAINING: 3
|
69
|
+
TERMINATED: 4
|
70
|
+
end
|
71
|
+
|
72
|
+
class QuicNetworkPath
|
73
|
+
attr_accessor addr: untyped
|
74
|
+
attr_accessor bytes_received: ::Integer
|
75
|
+
attr_accessor bytes_sent: ::Integer
|
76
|
+
attr_accessor is_validated: bool
|
77
|
+
attr_accessor local_challenge: ::String | nil
|
78
|
+
attr_accessor remote_challenge: ::String | nil
|
79
|
+
|
80
|
+
def can_send: (::Integer size) -> bool
|
81
|
+
end
|
82
|
+
|
83
|
+
class QuicReceiveContext
|
84
|
+
attr_accessor epoch: ::Integer
|
85
|
+
attr_accessor host_cid: ::String
|
86
|
+
attr_accessor network_path: QuicNetworkPath
|
87
|
+
attr_accessor quic_logger_frames: ::Array[untyped] | nil
|
88
|
+
attr_accessor time: ::Float
|
89
|
+
end
|
90
|
+
|
91
|
+
END_STATES: ::Array[::Integer]
|
92
|
+
|
93
|
+
|
94
|
+
class QuicConnection
|
95
|
+
attr_reader configuration: QuicConfiguration
|
96
|
+
attr_reader original_destination_connection_id: ::String
|
97
|
+
attr_reader loss: Quic::Recovery::QuicPacketRecovery
|
98
|
+
attr_reader tls: ::Raioquic::TLS::Context
|
99
|
+
attr_reader local_max_streams_bidi: Limit
|
100
|
+
|
101
|
+
attr_accessor ack_delay: ::Float
|
102
|
+
attr_accessor is_client: bool
|
103
|
+
|
104
|
+
@configuration: QuicConfiguration
|
105
|
+
@is_client: bool
|
106
|
+
@ack_delay: ::Float
|
107
|
+
@close_at: ::Float | nil
|
108
|
+
@close_event: untyped # TODO: events
|
109
|
+
@connect_called: bool
|
110
|
+
@cryptos: ::Hash[::Integer, ::Raioquic::Quic::Crypto::CryptoPair]
|
111
|
+
@crypto_buffers: ::Hash[::Integer, ::Raioquic::Buffer]
|
112
|
+
@crypto_retransmitted: bool
|
113
|
+
@crypto_streams: ::Hash[::Integer, ::Raioquic::Quic::Stream::QuicStream] # TODO: QuicStream
|
114
|
+
@events: untyped # TODO: deque?
|
115
|
+
@handshake_complete: bool
|
116
|
+
@handshake_confirmed: bool
|
117
|
+
@host_cids: ::Array[QuicConnectionId]
|
118
|
+
@host_cid: ::String
|
119
|
+
@host_cid_seq: ::Integer
|
120
|
+
@local_ack_delay_exponent: ::Integer
|
121
|
+
@local_active_connection_id_limit: ::Integer
|
122
|
+
@local_initial_source_connection_id: ::String
|
123
|
+
@local_max_data: Limit
|
124
|
+
@local_max_stream_data_bidi_local: ::Integer
|
125
|
+
@local_max_stream_data_bidi_remote: ::Integer
|
126
|
+
@local_max_stream_data_uni: ::Integer
|
127
|
+
@local_max_streams_bidi: Limit
|
128
|
+
@local_max_streams_uni: Limit
|
129
|
+
@loss_at: ::Float | nil
|
130
|
+
@network_paths: ::Array[QuicNetworkPath]
|
131
|
+
@pacing_at: ::Float | nil
|
132
|
+
@packet_number: ::Integer
|
133
|
+
@parameters_received: bool
|
134
|
+
@peer_cid: QuicConnectionId
|
135
|
+
@peer_cid_available: ::Array[QuicConnectionId]
|
136
|
+
@peer_cid_sequence_numbers: ::Array[::Integer] # TODO: set
|
137
|
+
@peer_token: ::String
|
138
|
+
@quic_logger: ::Raioquic::Quic::Logger::QuicLoggerTrace
|
139
|
+
@remote_ack_delay_exponent: ::Integer
|
140
|
+
@remote_active_connection_id_limit: ::Integer
|
141
|
+
@remote_initial_source_connection_id: ::String | nil
|
142
|
+
@remote_max_idle_timeout: ::Float
|
143
|
+
@remote_max_data: ::Integer
|
144
|
+
@remote_max_data_used: ::Integer
|
145
|
+
@remote_max_datagram_frame_size: ::Integer | nil
|
146
|
+
@remote_max_stream_data_bidi_local: ::Integer
|
147
|
+
@remote_max_stream_data_bidi_remote: ::Integer
|
148
|
+
@remote_max_stream_data_uni: ::Integer
|
149
|
+
@remote_max_streams_bidi: ::Integer
|
150
|
+
@remote_max_streams_uni: ::Integer
|
151
|
+
@retry_count: ::Integer
|
152
|
+
@retry_source_connection_id: ::String | nil
|
153
|
+
@spaces: ::Hash[::Integer, Quic::Recovery::QuicPacketSpace]
|
154
|
+
@spin_bit: bool
|
155
|
+
@spin_highest_pn: ::Integer
|
156
|
+
@state: ::Integer
|
157
|
+
@streams: ::Hash[::Integer, Quic::Stream::QuicStream] # TODO: QuicStream
|
158
|
+
@streams_blocked_bidi: ::Array[untyped] # TODO: QuicStream
|
159
|
+
@streams_blocked_uni: ::Array[untyped] # TODO: QuicStream
|
160
|
+
@streams_finished: ::Array[::Integer] # TODO: ::Set
|
161
|
+
@version: ::Integer | nil
|
162
|
+
@version_negotiation_count: ::Integer
|
163
|
+
@original_destination_connection_id: ::String
|
164
|
+
@logger: untyped
|
165
|
+
@loss: Quic::Recovery::QuicPacketRecovery
|
166
|
+
@close_pending: bool
|
167
|
+
@datagrams_pending: untyped # TODO: set
|
168
|
+
@handshake_done_pending: bool
|
169
|
+
@ping_pending: ::Array[::Integer]
|
170
|
+
@probe_pending: bool
|
171
|
+
@retire_connection_ids: ::Array[::Integer]
|
172
|
+
@streams_blocked_pending: bool
|
173
|
+
@session_ticket_fetcher: untyped
|
174
|
+
@session_ticket_handler: untyped
|
175
|
+
@frame_handlers: ::Hash[::Integer, [::Symbol, ::Array[::Integer]]]
|
176
|
+
@tls: ::Raioquic::TLS::Context
|
177
|
+
|
178
|
+
def intialize: (
|
179
|
+
configuration: QuicConfiguration,
|
180
|
+
?original_destination_connection_id: ::String,
|
181
|
+
?retry_source_connection_id: ::String,
|
182
|
+
?session_ticket_fetcher: untyped,
|
183
|
+
?session_ticket_handler: untyped,
|
184
|
+
) -> void
|
185
|
+
def change_connection_id: () -> void
|
186
|
+
def close: (?error_code: ::Integer, ?frame_type: ::Integer|nil, ?reason_phrase: ::String) -> void
|
187
|
+
def connect: (addr: untyped, now: ::Float) -> void # TODO: type of addr
|
188
|
+
def datagrams_to_send: (now: ::Float) -> ::Array[[::String, untyped]] # TODO: NetworkAddress
|
189
|
+
def get_next_available_stream_id: (?is_unidirectional: bool) -> ::Integer
|
190
|
+
def get_timer: () -> (::Float | nil)
|
191
|
+
def handle_timer: (now: ::Float) -> void
|
192
|
+
def next_event: () -> (::Raioquic::Quic::Event::QuicEvent | nil)
|
193
|
+
def receive_datagram: (data: ::String, addr: untyped, now: ::Float) -> void # TODO: NetworkAddress
|
194
|
+
def request_key_update: () -> void
|
195
|
+
def reset_stream: (stream_id: ::Integer, error_code: ::Integer) -> void
|
196
|
+
def send_ping: (::Integer uid) -> void
|
197
|
+
def send_datagram_frame: (:String data) -> void
|
198
|
+
def send_stream_data: (stream_id: ::Integer, data: ::String, ?end_stream: bool) -> void
|
199
|
+
def stop_stream: (stream_id: ::Integer, error_code: ::Integer) -> void
|
200
|
+
private def alpn_handler: (::String alpn_protocol) -> void
|
201
|
+
private def assert_stream_can_receive: (frame_type: ::Integer, stream_id: ::Integer) -> void
|
202
|
+
private def assert_stream_can_send: (frame_type: ::Integer, stream_id: ::Integer) -> void
|
203
|
+
private def consume_peer_cid: () -> void
|
204
|
+
private def close_begin: (is_initiator: bool, now: ::Float) -> void
|
205
|
+
private def close_end: () -> void
|
206
|
+
private def _connect: (now: ::Float) -> void
|
207
|
+
private def discard_epoch: (::Integer epoch) -> void
|
208
|
+
private def find_network_path: (untyped addr) -> QuicNetworkPath # TODO: NetworkAddress
|
209
|
+
private def get_or_create_stream: (frame_type: ::Integer, stream_id: ::Integer) -> ::Raioquic::Quic::Stream::QuicStream
|
210
|
+
private def get_or_create_stream_for_send: (::Integer stream_id) -> ::Raioquic::Quic::Stream::QuicStream
|
211
|
+
private def handle_session_ticket: (::Raioquic::TLS::SessionTicket session_ticket) -> void
|
212
|
+
private def initialize_connection: (::String peer_cid) -> void
|
213
|
+
private def handle_ack_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
214
|
+
private def handle_connection_close_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
215
|
+
private def handle_crypto_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
216
|
+
private def handle_data_blocked_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
217
|
+
private def handle_datagram_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
218
|
+
private def handle_handshake_done_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
219
|
+
private def handle_max_data_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
220
|
+
private def handle_max_stream_data_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
221
|
+
private def handle_max_streams_bidi_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
222
|
+
private def handle_max_streams_uni_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
223
|
+
private def handle_new_connection_id_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
224
|
+
private def handle_new_token_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
225
|
+
private def handle_padding_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
226
|
+
private def handle_path_challenge_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
227
|
+
private def handle_path_response_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
228
|
+
private def handle_ping_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
229
|
+
private def handle_reset_stream_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
230
|
+
private def handle_retire_connection_id_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
231
|
+
private def handle_stop_sending_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
232
|
+
private def handle_stream_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
233
|
+
private def handle_stream_data_blocked_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
234
|
+
private def handle_streams_blocked_frame: (context: QuicReceiveContext, frame_type: ::Integer, buf: ::Raioquic::Buffer) -> void
|
235
|
+
private def log_key_retired: (key_type: ::String, trigger: ::String) -> void
|
236
|
+
private def log_key_updated: (key_type: ::String, trigger: ::String) -> void
|
237
|
+
private def on_ack_delivery: (delivery: ::Integer, space: ::Raioquic::Quic::Recovery::QuicPacketSpace, highest_acked: ::Integer) -> void
|
238
|
+
private def on_connection_limit_delivery: (delivery: ::Integer, limit: Limit) -> void
|
239
|
+
private def on_handshake_done_delivery: (delivery: ::Integer) -> void
|
240
|
+
private def on_max_stream_data_delivery: (delivery: ::Integer, stream: ::Raioquic::Quic::Stream::QuicStream) -> void
|
241
|
+
private def on_new_connection_id_delivery: (delivery: ::Integer, connection_id: QuicConnectionId) -> void
|
242
|
+
private def on_ping_delivery: (delivery: ::Integer, uids: ::Array[::Integer]) -> void
|
243
|
+
private def on_retire_connection_id_delivery: (delivery: ::Integer, sequence_number: ::Integer) -> void
|
244
|
+
private def payload_received: (context: QuicReceiveContext, plain: ::String) -> [bool, bool]
|
245
|
+
private def replenish_connection_ids: () -> void
|
246
|
+
private def retire_peer_cid: (QuicConnectionId connection_id) -> void
|
247
|
+
private def push_crypto_data: () -> void
|
248
|
+
private def send_probe: () -> void
|
249
|
+
private def parse_transport_parameters: (data: ::String, ?from_session_ticket: bool) -> void
|
250
|
+
private def serialize_transport_parameters: () -> ::String
|
251
|
+
private def set_state: (::Integer quic_connection_state) -> void
|
252
|
+
private def stream_can_receive: (::Integer stream_id) -> bool
|
253
|
+
private def stream_can_send: (::Integer stream_id) -> bool
|
254
|
+
private def unblock_streams: (bool is_unidirectional) -> void
|
255
|
+
private def update_traffic_key: (direction: ::Integer, epoch: ::Integer, cipher_suite: ::Integer, secret: ::String) -> void
|
256
|
+
private def write_application: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, network_path: QuicNetworkPath, now: ::Float) -> void
|
257
|
+
private def write_handshake: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, epoch: ::Integer, now: ::Float) -> void
|
258
|
+
private def write_ack_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, space: ::Raioquic::Quic::Recovery::QuicPacketSpace, now: ::Float) -> void
|
259
|
+
private def write_connection_close_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, epoch: ::Integer, error_code: ::Integer, ?frame_type: ::Integer, reason_phrase: ::String) -> void
|
260
|
+
private def write_connection_limits: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, space: ::Raioquic::Quic::Recovery::QuicPacketSpace) -> void
|
261
|
+
private def write_crypto_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, space: ::Raioquic::Quic::Recovery::QuicPacketSpace, stream: ::Raioquic::Quic::Stream::QuicStream) -> bool
|
262
|
+
private def write_datagram_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, data: ::String, frame_type: ::Integer) -> bool
|
263
|
+
private def write_handshake_done_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder) -> void
|
264
|
+
private def write_new_connection_id_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, connection_id: QuicConnectionId) -> void
|
265
|
+
private def write_path_challenge_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, challenge: ::String) -> void
|
266
|
+
private def write_path_response_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, challenge: ::String) -> void
|
267
|
+
private def write_ping_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, ?uids: ::Array[::Integer], ?comment: ::String) -> void
|
268
|
+
private def write_reset_stream_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, stream: ::Raioquic::Quic::Stream::QuicStream) -> void
|
269
|
+
private def write_retire_connection_id_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, sequence_number: ::Integer) -> void
|
270
|
+
private def write_stop_sending_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, stream: ::Raioquic::Quic::Stream::QuicStream) -> void
|
271
|
+
private def write_stream_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, space: ::Raioquic::Quic::Recovery::QuicPacketSpace, stream: ::Raioquic::Quic::Stream::QuicStream, max_offset: ::Integer) -> ::Integer
|
272
|
+
private def write_stream_limits: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, space: ::Raioquic::Quic::Recovery::QuicPacketSpace, stream: ::Raioquic::Quic::Stream::QuicStream) -> void
|
273
|
+
private def write_streams_blocked_frame: (builder: ::Raioquic::Quic::PacketBuilder::QuicPacketBuilder, frame_type: ::Integer, limit: ::Integer) -> void
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Raioquic
|
2
|
+
module Quic
|
3
|
+
module Crypto
|
4
|
+
INITIAL_CIPHER_SUITE: untyped
|
5
|
+
AEAD_KEY_LENGTH_MAX: 32
|
6
|
+
AEAD_NONCE_LENGTH: 12
|
7
|
+
AEAD_TAG_LENGTH: 16
|
8
|
+
PACKET_LENGTH_MAX: 1500
|
9
|
+
PACKET_NUMBER_LENGTH_MAX: 4
|
10
|
+
SAMPLE_LENGTH: 16
|
11
|
+
INITIAL_SALT_VERSION_1: ::String
|
12
|
+
|
13
|
+
|
14
|
+
def self?.derive_key_iv_hp: (untyped, ::String) -> Array[::String]
|
15
|
+
def self?.xor_str: (::String, ::String) -> ::String
|
16
|
+
|
17
|
+
class CryptoError
|
18
|
+
end
|
19
|
+
|
20
|
+
class NoCallback
|
21
|
+
end
|
22
|
+
|
23
|
+
class CryptoContext
|
24
|
+
attr_reader aead: untyped
|
25
|
+
attr_reader key_phase: 0 | 1
|
26
|
+
attr_reader secret: nil | ::String
|
27
|
+
@aead: nil | AEAD
|
28
|
+
@cipher_suite: untyped # TODO: ?
|
29
|
+
@key_phase: 0 | 1
|
30
|
+
@secret: nil | ::String
|
31
|
+
@version: untyped # TODO: ::Raioquic::Quic::Packet::QuicProtocolVersion::VERSION_1
|
32
|
+
@setup_cb: NoCallback | untyped
|
33
|
+
@teardown_cb: NoCallback | untyped
|
34
|
+
@hp: HeaderProtection|nil
|
35
|
+
|
36
|
+
def initialize: (key_phase: 0|1, setup_cb: untyped, teardown_cb: untyped) -> void
|
37
|
+
| (setup_cb: untyped, teardown_cb: untyped) -> void
|
38
|
+
def decrypt_packet: (packet: ::String, encrypted_offset: ::Integer, expected_packet_number: ::Integer) -> [::String, ::String, ::Integer, bool]
|
39
|
+
def encrypt_packet: (plain_header: ::String, plain_payload: ::String, packet_number: ::Integer) -> ::String
|
40
|
+
def is_valid: () -> bool
|
41
|
+
def setup: (cipher_suite: untyped, secret: ::String, version: untyped) -> void
|
42
|
+
def teardown: () -> void
|
43
|
+
def apply_key_phase: (CryptoContext, ::String) -> void
|
44
|
+
def next_key_phase: () -> CryptoContext
|
45
|
+
end
|
46
|
+
|
47
|
+
class CryptoPair
|
48
|
+
attr_reader recv: CryptoContext
|
49
|
+
attr_reader send: CryptoContext
|
50
|
+
|
51
|
+
@aead_tag_size: ::Integer
|
52
|
+
@update_key_requested: bool
|
53
|
+
|
54
|
+
def initialize: (recv_setup_cb: NoCallback|untyped, recv_teardown_cb: NoCallback|untyped, send_setup_cb: NoCallback|untyped, send_teardown_cb: NoCallback|untyped) -> void
|
55
|
+
def decrypt_packet: (packet: ::String, encrypted_offset: ::Integer, expected_packet_number: ::Integer) -> [::String, ::String, ::Integer]
|
56
|
+
def encrypt_packet: (plain_header: ::String, plain_payload: ::Integer, packet_number: ::Integer) -> ::String
|
57
|
+
def setup_initial: (cid: ::String, is_client: bool, version: untyped) -> void
|
58
|
+
def teardown: () -> void
|
59
|
+
def key_phase: () -> ::Integer # TODO: 0 or 1
|
60
|
+
def update_key: () -> void
|
61
|
+
def _update_key: (::String) -> void
|
62
|
+
end
|
63
|
+
|
64
|
+
class AEAD
|
65
|
+
@cipher: OpenSSL::Cipher
|
66
|
+
@key: ::String
|
67
|
+
@iv: ::String
|
68
|
+
@cipher_name: ::String
|
69
|
+
|
70
|
+
def initialize: (cipher_name: ::String, key: ::String, iv: ::String) -> void
|
71
|
+
def decrypt: (data: ::String, associated_data: ::String, packet_number: ::Integer) -> ::String
|
72
|
+
def encrypt: (data: ::String, associated_data: ::String, packet_number: ::Integer) -> ::String
|
73
|
+
end
|
74
|
+
|
75
|
+
class HeaderProtection
|
76
|
+
@cipher: OpenSSL::Cipher
|
77
|
+
@key: ::String
|
78
|
+
@mask: ::String
|
79
|
+
@zero: ::String
|
80
|
+
|
81
|
+
def initialize: (cipher_name: ::String, key: ::String) -> void
|
82
|
+
def apply: (plain_header: ::String, protected_payload: ::String) -> ::String
|
83
|
+
def remove: (packet: ::String, encrypted_offset: ::Integer) -> [::String, ::Integer]
|
84
|
+
private def mask: (::String) -> ::String
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|