packetgen-plugin-ipsec 1.0.2 → 1.0.3
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 +4 -4
- data/.github/workflows/specs.yml +28 -0
- data/.rubocop.yml +8 -1
- data/.travis.yml +1 -1
- data/Gemfile +11 -0
- data/Rakefile +10 -4
- data/lib/packetgen/plugin/crypto.rb +6 -4
- data/lib/packetgen/plugin/esp.rb +373 -370
- data/lib/packetgen/plugin/ike.rb +218 -217
- data/lib/packetgen/plugin/ike/auth.rb +141 -141
- data/lib/packetgen/plugin/ike/cert.rb +61 -62
- data/lib/packetgen/plugin/ike/certreq.rb +51 -52
- data/lib/packetgen/plugin/ike/id.rb +80 -80
- data/lib/packetgen/plugin/ike/ke.rb +64 -66
- data/lib/packetgen/plugin/ike/nonce.rb +29 -31
- data/lib/packetgen/plugin/ike/notify.rb +135 -139
- data/lib/packetgen/plugin/ike/payload.rb +58 -57
- data/lib/packetgen/plugin/ike/sa.rb +515 -452
- data/lib/packetgen/plugin/ike/sk.rb +219 -221
- data/lib/packetgen/plugin/ike/ts.rb +223 -223
- data/lib/packetgen/plugin/ike/vendor_id.rb +28 -30
- data/lib/packetgen/plugin/ipsec_version.rb +8 -1
- data/packetgen-plugin-ipsec.gemspec +3 -9
- metadata +8 -77
@@ -1,163 +1,163 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
# This file is part of IPsec packetgen plugin.
|
3
5
|
# See https://github.com/sdaubert/packetgen-plugin-ipsec for more informations
|
4
6
|
# Copyright (c) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
5
7
|
# This program is published under MIT license.
|
6
8
|
|
7
|
-
|
9
|
+
module PacketGen::Plugin
|
10
|
+
class IKE
|
11
|
+
# This class handles Authentication payloads.
|
12
|
+
#
|
13
|
+
# A AUTH payload consists of the IKE generic payload Plugin (see {Payload})
|
14
|
+
# and some specific fields:
|
15
|
+
# 1 2 3
|
16
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
17
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
18
|
+
# | Next Payload |C| RESERVED | Payload Length |
|
19
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
20
|
+
# | Auth Method | RESERVED |
|
21
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
22
|
+
# | |
|
23
|
+
# ~ Authentication Data ~
|
24
|
+
# | |
|
25
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
26
|
+
# These specific fields are:
|
27
|
+
# * {#type} (ID type),
|
28
|
+
# * {#reserved},
|
29
|
+
# * and {#content} (Identification Data).
|
30
|
+
#
|
31
|
+
# == Create a KE payload
|
32
|
+
# # create a IKE packet with a Auth payload
|
33
|
+
# pkt = PacketGen.gen('IP').add('UDP').add('IKE').add('IKE::Auth', auth_method: 'SHARED_KEY')
|
34
|
+
# pkt.calc_length
|
35
|
+
# @author Sylvain Daubert
|
36
|
+
class Auth < Payload
|
37
|
+
# Payload type number
|
38
|
+
PAYLOAD_TYPE = 39
|
8
39
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
# | Auth Method | RESERVED |
|
22
|
-
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
23
|
-
# | |
|
24
|
-
# ~ Authentication Data ~
|
25
|
-
# | |
|
26
|
-
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
27
|
-
# These specific fields are:
|
28
|
-
# * {#type} (ID type),
|
29
|
-
# * {#reserved},
|
30
|
-
# * and {#content} (Identification Data).
|
31
|
-
#
|
32
|
-
# == Create a KE payload
|
33
|
-
# # create a IKE packet with a Auth payload
|
34
|
-
# pkt = PacketGen.gen('IP').add('UDP').add('IKE').add('IKE::Auth', auth_method: 'SHARED_KEY')
|
35
|
-
# pkt.calc_length
|
36
|
-
# @author Sylvain Daubert
|
37
|
-
class Auth < Payload
|
38
|
-
# Payload type number
|
39
|
-
PAYLOAD_TYPE = 39
|
40
|
+
# Authentication methods
|
41
|
+
METHODS = {
|
42
|
+
'RSA_SIGNATURE' => 1,
|
43
|
+
'SHARED_KEY' => 2,
|
44
|
+
'DSA_SIGNATURE' => 3,
|
45
|
+
'ECDSA256' => 9,
|
46
|
+
'ECDSA384' => 10,
|
47
|
+
'ECDSA512' => 11,
|
48
|
+
'PASSWORD' => 12,
|
49
|
+
'NULL' => 13,
|
50
|
+
'DIGITAL_SIGNATURE' => 14
|
51
|
+
}.freeze
|
40
52
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
'NULL' => 13,
|
50
|
-
'DIGITAL_SIGNATURE' => 14
|
51
|
-
}.freeze
|
53
|
+
# @attribute [r] auth_method
|
54
|
+
# 8-bit Auth Method
|
55
|
+
# @return [Integer]
|
56
|
+
define_field_before :content, :auth_method, PacketGen::Types::Int8Enum, enum: METHODS
|
57
|
+
# @attribute reserved
|
58
|
+
# 24-bit reserved field
|
59
|
+
# @return [Integer]
|
60
|
+
define_field_before :content, :reserved, PacketGen::Types::Int24
|
52
61
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
62
|
+
# Check authentication (see RFC 7296 §2.15)
|
63
|
+
# @param [Packet] init_msg first IKE message sent by peer
|
64
|
+
# @param [String] nonce my nonce, sent in first message
|
65
|
+
# @param [String] sk_p secret key used to compute prf(SK_px, IDx')
|
66
|
+
# @param [Integer] prf PRF type to use (see {Transform}+::PRF_*+ constants)
|
67
|
+
# @param [String] shared_secret shared secret to use as PSK (shared secret
|
68
|
+
# method only)
|
69
|
+
# @param [OpenSSL::X509::Certificate] cert certificate to check AUTH signature,
|
70
|
+
# if not embedded in IKE message
|
71
|
+
# @return [Boolean]
|
72
|
+
# @note For now, only NULL, SHARED_KEY and RSA, DSA and ECDSA signatures are
|
73
|
+
# supported.
|
74
|
+
# @note For certificates, only check AUTH authenticity with given (or guessed
|
75
|
+
# from packet) certificate, but certificate chain is not verified.
|
76
|
+
def check?(init_msg: nil, nonce: '', sk_p: '', prf: 1, shared_secret: '',
|
77
|
+
cert: nil)
|
78
|
+
raise TypeError, 'init_msg should be a Packet' unless init_msg.is_a?(PacketGen::Packet)
|
61
79
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
# @param [Integer] prf PRF type to use (see {Transform}+::PRF_*+ constants)
|
67
|
-
# @param [String] shared_secret shared secret to use as PSK (shared secret
|
68
|
-
# method only)
|
69
|
-
# @param [OpenSSL::X509::Certificate] cert certificate to check AUTH signature,
|
70
|
-
# if not embedded in IKE message
|
71
|
-
# @return [Boolean]
|
72
|
-
# @note For now, only NULL, SHARED_KEY and RSA, DSA and ECDSA signatures are
|
73
|
-
# supported.
|
74
|
-
# @note For certificates, only check AUTH authenticity with given (or guessed
|
75
|
-
# from packet) certificate, but certificate chain is not verified.
|
76
|
-
def check?(init_msg: nil, nonce: '', sk_p: '', prf: 1, shared_secret: '',
|
77
|
-
cert: nil)
|
78
|
-
raise TypeError, 'init_msg should be a Packet' unless init_msg.is_a?(Packet)
|
79
|
-
signed_octets = init_msg.ike.to_s
|
80
|
-
signed_octets << nonce
|
81
|
-
id = packet.ike.flag_i? ? packet.ike_idi : packet.ike_idr
|
82
|
-
signed_octets << prf(prf, sk_p, id.to_s[4, id.length - 4])
|
80
|
+
signed_octets = init_msg.ike.to_s
|
81
|
+
signed_octets << nonce
|
82
|
+
id = packet.ike.flag_i? ? packet.ike_idi : packet.ike_idr
|
83
|
+
signed_octets << prf(prf, sk_p, id.to_s[4, id.length - 4])
|
83
84
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
85
|
+
case auth_method
|
86
|
+
when METHODS['SHARED_KEY']
|
87
|
+
auth = prf(prf(shared_secret, 'Key Pad for IKEv2'), signed_octets)
|
88
|
+
auth == content
|
89
|
+
when METHODS['RSA_SIGNATURE'], METHODS['ECDSA256'], METHODS['ECDSA384'],
|
90
|
+
METHODS['ECDSA512']
|
91
|
+
if packet.ike_cert
|
92
|
+
# FIXME: Expect a ENCODING_X509_CERT_SIG
|
93
|
+
# Others types not supported for now...
|
94
|
+
cert = OpenSSL::X509::Certificate.new(packet.ike_cert.content)
|
95
|
+
elsif cert.nil?
|
96
|
+
raise CryptoError, 'a certificate should be provided'
|
97
|
+
end
|
97
98
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
end
|
111
|
-
when /sha([235]\d+)/
|
112
|
-
OpenSSL::Digest.const_get("SHA#{$1}").new
|
113
|
-
when /sha1/, 'rsaEncryption'
|
114
|
-
OpenSSL::Digest::SHA1.new
|
99
|
+
text = cert.to_text
|
100
|
+
m = text.match(/Public Key Algorithm: ([a-zA-Z0-9-]+)/)
|
101
|
+
digest = case m[1]
|
102
|
+
when 'id-ecPublicKey'
|
103
|
+
m2 = text.match(/Public-Key: \((\d+) bit\)/)
|
104
|
+
case m2[1]
|
105
|
+
when '256'
|
106
|
+
OpenSSL::Digest::SHA256.new
|
107
|
+
when '384'
|
108
|
+
OpenSSL::Digest::SHA384.new
|
109
|
+
when '521'
|
110
|
+
OpenSSL::Digest::SHA512.new
|
115
111
|
end
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
112
|
+
when /sha([235]\d+)/
|
113
|
+
OpenSSL::Digest.const_get("SHA#{$1}").new
|
114
|
+
when /sha1/, 'rsaEncryption'
|
115
|
+
OpenSSL::Digest::SHA1.new
|
116
|
+
end
|
117
|
+
signature = format_signature(cert.public_key, content.to_s)
|
118
|
+
cert.public_key.verify(digest, signature, signed_octets)
|
119
|
+
when METHOD_NULL
|
120
|
+
true
|
121
|
+
else
|
122
|
+
raise NotImplementedError, "unsupported auth method #{human_auth_method}"
|
123
123
|
end
|
124
|
+
end
|
124
125
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
126
|
+
# Get authentication method name
|
127
|
+
# @return [String]
|
128
|
+
def human_auth_method
|
129
|
+
self[:auth_method].to_human
|
130
|
+
end
|
130
131
|
|
131
|
-
|
132
|
+
private
|
132
133
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
end
|
145
|
-
hmac = OpenSSL::HMAC.new(key, digest)
|
146
|
-
hmac << msg
|
147
|
-
hmac.digest
|
134
|
+
def prf(type, key, msg)
|
135
|
+
case type
|
136
|
+
when Transform::PRF_HMAC_MD5, Transform::PRF_HMAC_SHA1,
|
137
|
+
Transform::PRF_HMAC_SHA2_256, Transform::PRF_HMAC_SHA2_384,
|
138
|
+
Transform::PRF_HMAC_SHA2_512
|
139
|
+
digestname = Transform.constants.grep(/PRF_/)
|
140
|
+
.detect { |c| Transform.const_get(c) == type }
|
141
|
+
.to_s.sub(/^PRF_HMAC_/, '').sub(/2_/, '')
|
142
|
+
digest = OpenSSL::Digest.const_get(digestname).new
|
143
|
+
else
|
144
|
+
raise NotImplementedError, 'for now, only HMAC-based PRF are supported'
|
148
145
|
end
|
146
|
+
hmac = OpenSSL::HMAC.new(key, digest)
|
147
|
+
hmac << msg
|
148
|
+
hmac.digest
|
149
|
+
end
|
149
150
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
end
|
151
|
+
def format_signature(pkey, sig)
|
152
|
+
if pkey.is_a?(OpenSSL::PKey::EC)
|
153
|
+
# PKey::EC need a signature as a DER string representing a sequence of
|
154
|
+
# 2 integers: r and s
|
155
|
+
r = OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(sig[0, sig.size / 2], 2).to_i)
|
156
|
+
s = OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(sig[sig.size / 2,
|
157
|
+
sig.size / 2], 2).to_i)
|
158
|
+
OpenSSL::ASN1::Sequence.new([r, s]).to_der
|
159
|
+
else
|
160
|
+
sig
|
161
161
|
end
|
162
162
|
end
|
163
163
|
end
|
@@ -1,76 +1,75 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
# This file is part of IPsec packetgen plugin.
|
3
5
|
# See https://github.com/sdaubert/packetgen-plugin-ipsec for more informations
|
4
6
|
# Copyright (c) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
5
7
|
# This program is published under MIT license.
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
#
|
37
|
-
|
38
|
-
class Cert < Payload
|
39
|
-
# Payload type number
|
40
|
-
PAYLOAD_TYPE = 37
|
9
|
+
module PacketGen::Plugin
|
10
|
+
class IKE
|
11
|
+
# This class handles Certificate payloads.
|
12
|
+
#
|
13
|
+
# A Cert payload consists of the IKE generic payload Plugin (see {Payload})
|
14
|
+
# and some specific fields:
|
15
|
+
# 1 2 3
|
16
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
17
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
18
|
+
# | Next Payload |C| RESERVED | Payload Length |
|
19
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
20
|
+
# | Cert Encoding | |
|
21
|
+
# +-+-+-+-+-+-+-+-+ +
|
22
|
+
# | |
|
23
|
+
# ~ Certificate Data ~
|
24
|
+
# | |
|
25
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
26
|
+
# These specific fields are:
|
27
|
+
# * {#encoding},
|
28
|
+
# * and {#content} (Certificate Data).
|
29
|
+
#
|
30
|
+
# == Create a Cert payload
|
31
|
+
# # Create a IKE packet with a Cert payload
|
32
|
+
# pkt = PacketGen.gen('IP').add('UDP').add('IKE').add('IKE::Cert', encoding: 'X509_CERT_SIG')
|
33
|
+
# certs = cert.to_der << ca_cert.to_der
|
34
|
+
# pkt.ike_cert.content.read certs
|
35
|
+
# pkt.calc_length
|
36
|
+
# @author Sylvain Daubert
|
37
|
+
class Cert < Payload
|
38
|
+
# Payload type number
|
39
|
+
PAYLOAD_TYPE = 37
|
41
40
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
41
|
+
# Certificate encoding
|
42
|
+
ENCODINGS = {
|
43
|
+
'PKCS7_WRAPPED_X509' => 1,
|
44
|
+
'PGP' => 2,
|
45
|
+
'DNS_SIGNED_KEY' => 3,
|
46
|
+
'X509_CERT_SIG' => 4,
|
47
|
+
'KERBEROS_TOKEN' => 6,
|
48
|
+
'X509_CRL' => 7,
|
49
|
+
'X509_ARL' => 8,
|
50
|
+
'SPKI_CERT' => 9,
|
51
|
+
'X509_CERT_ATTR' => 10,
|
52
|
+
'HASH_URL_X509_CERT' => 12,
|
53
|
+
'HASH_URL_X509_BUNDLE' => 13
|
54
|
+
}.freeze
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
# @attribute encoding
|
57
|
+
# 8-bit certificate encoding
|
58
|
+
# @return [Integer]
|
59
|
+
define_field_before :content, :encoding, PacketGen::Types::Int8Enum, enum: ENCODINGS
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
def initialize(options={})
|
62
|
+
super
|
63
|
+
self.encoding = options[:encoding] if options[:encoding]
|
64
|
+
end
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
66
|
+
# Get encoding name
|
67
|
+
# @return [String]
|
68
|
+
def human_encoding
|
69
|
+
self[:encoding].to_human
|
71
70
|
end
|
72
71
|
end
|
73
|
-
|
74
|
-
Header.add_class IKE::Cert
|
75
72
|
end
|
73
|
+
|
74
|
+
PacketGen::Header.add_class IKE::Cert
|
76
75
|
end
|
@@ -1,66 +1,65 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
# This file is part of IPsec packetgen plugin.
|
3
5
|
# See https://github.com/sdaubert/packetgen-plugin-ipsec for more informations
|
4
6
|
# Copyright (c) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
5
7
|
# This program is published under MIT license.
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
#
|
36
|
-
|
37
|
-
class CertReq < Cert
|
38
|
-
# Payload type number
|
39
|
-
PAYLOAD_TYPE = 38
|
9
|
+
module PacketGen::Plugin
|
10
|
+
class IKE
|
11
|
+
# This class handles Certificate Request payloads.
|
12
|
+
#
|
13
|
+
# A CertReq payload consists of the IKE generic payload Plugin (see {Payload})
|
14
|
+
# and some specific fields:
|
15
|
+
# 1 2 3
|
16
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
17
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
18
|
+
# | Next Payload |C| RESERVED | Payload Length |
|
19
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
20
|
+
# | Cert Encoding | |
|
21
|
+
# +-+-+-+-+-+-+-+-+ +
|
22
|
+
# | |
|
23
|
+
# ~ Certification Authority ~
|
24
|
+
# | |
|
25
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
26
|
+
# These specific fields are:
|
27
|
+
# * {#encoding},
|
28
|
+
# * and {#content} (Certification Authority).
|
29
|
+
#
|
30
|
+
# == Create a CertReq payload
|
31
|
+
# # Create a IKE packet with a CertReq payload
|
32
|
+
# pkt = PacketGen.gen('IP').add('UDP').add('IKE').add('IKE::CertReq', encoding: 'X509_CERT_SIG')
|
33
|
+
# pkt.ike_certreq.content.read OpenSSL::Digest::SHA1.digest(ca_cert.to_der)
|
34
|
+
# pkt.calc_length
|
35
|
+
# @author Sylvain Daubert
|
36
|
+
class CertReq < Cert
|
37
|
+
# Payload type number
|
38
|
+
PAYLOAD_TYPE = 38
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
50
|
-
strs.map(&:inspect).join(',')
|
40
|
+
# Get list of 20-byte string (SHA-1 hashes)
|
41
|
+
# @return [String]
|
42
|
+
def human_content
|
43
|
+
strs = []
|
44
|
+
idx = 0
|
45
|
+
while idx < content.size
|
46
|
+
strs << content[idx, 20]
|
47
|
+
idx += 20
|
51
48
|
end
|
49
|
+
strs.map(&:inspect).join(',')
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [String]
|
53
|
+
def inspect
|
54
|
+
super do |attr|
|
55
|
+
next unless attr == :content
|
52
56
|
|
53
|
-
|
54
|
-
|
55
|
-
super do |attr|
|
56
|
-
next unless attr == :content
|
57
|
-
str = Inspect.shift_level
|
58
|
-
str << Inspect::FMT_ATTR % ['hashes', :content, human_content]
|
59
|
-
end
|
57
|
+
str = PacketGen::Inspect.shift_level
|
58
|
+
str << PacketGen::Inspect::FMT_ATTR % ['hashes', :content, human_content]
|
60
59
|
end
|
61
60
|
end
|
62
61
|
end
|
63
|
-
|
64
|
-
Header.add_class IKE::CertReq
|
65
62
|
end
|
63
|
+
|
64
|
+
PacketGen::Header.add_class IKE::CertReq
|
66
65
|
end
|