packetgen 2.8.7 → 3.0.0

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.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -1
  3. data/README.md +5 -4
  4. data/lib/packetgen.rb +6 -12
  5. data/lib/packetgen/capture.rb +43 -39
  6. data/lib/packetgen/config.rb +0 -1
  7. data/lib/packetgen/deprecation.rb +1 -1
  8. data/lib/packetgen/header.rb +9 -9
  9. data/lib/packetgen/header/asn1_base.rb +10 -10
  10. data/lib/packetgen/header/base.rb +42 -101
  11. data/lib/packetgen/header/dhcp/option.rb +5 -11
  12. data/lib/packetgen/header/dhcpv6/duid.rb +2 -0
  13. data/lib/packetgen/header/dhcpv6/option.rb +2 -19
  14. data/lib/packetgen/header/dhcpv6/options.rb +7 -0
  15. data/lib/packetgen/header/dns.rb +5 -23
  16. data/lib/packetgen/header/dns/name.rb +1 -0
  17. data/lib/packetgen/header/dns/qdsection.rb +1 -0
  18. data/lib/packetgen/header/dns/question.rb +3 -7
  19. data/lib/packetgen/header/dns/rr.rb +3 -0
  20. data/lib/packetgen/header/dns/rrsection.rb +1 -0
  21. data/lib/packetgen/header/dot11.rb +1 -17
  22. data/lib/packetgen/header/dot1x.rb +1 -0
  23. data/lib/packetgen/header/eap.rb +4 -7
  24. data/lib/packetgen/header/eth.rb +2 -0
  25. data/lib/packetgen/header/http/headers.rb +3 -0
  26. data/lib/packetgen/header/http/request.rb +5 -4
  27. data/lib/packetgen/header/http/response.rb +5 -4
  28. data/lib/packetgen/header/icmp.rb +6 -0
  29. data/lib/packetgen/header/icmpv6.rb +6 -0
  30. data/lib/packetgen/header/igmpv3/mq.rb +2 -0
  31. data/lib/packetgen/header/ip.rb +32 -30
  32. data/lib/packetgen/header/ip/addr.rb +1 -0
  33. data/lib/packetgen/header/ip/option.rb +23 -20
  34. data/lib/packetgen/header/ip/options.rb +11 -24
  35. data/lib/packetgen/header/ipv6.rb +45 -34
  36. data/lib/packetgen/header/ipv6/addr.rb +2 -0
  37. data/lib/packetgen/header/ipv6/hop_by_hop.rb +7 -31
  38. data/lib/packetgen/header/mdns.rb +1 -0
  39. data/lib/packetgen/header/mldv2/mlq.rb +2 -0
  40. data/lib/packetgen/header/ospfv2/lsa.rb +15 -25
  41. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +1 -1
  42. data/lib/packetgen/header/ospfv3/lsa.rb +8 -25
  43. data/lib/packetgen/header/snmp.rb +2 -0
  44. data/lib/packetgen/header/tcp.rb +23 -2
  45. data/lib/packetgen/header/tcp/option.rb +51 -52
  46. data/lib/packetgen/header/tcp/options.rb +17 -52
  47. data/lib/packetgen/header/tftp.rb +3 -0
  48. data/lib/packetgen/header/udp.rb +8 -0
  49. data/lib/packetgen/packet.rb +119 -102
  50. data/lib/packetgen/pcapng/block.rb +4 -10
  51. data/lib/packetgen/pcapng/epb.rb +4 -4
  52. data/lib/packetgen/pcapng/file.rb +7 -3
  53. data/lib/packetgen/pcapng/idb.rb +2 -2
  54. data/lib/packetgen/pcapng/shb.rb +3 -3
  55. data/lib/packetgen/pcapng/spb.rb +1 -8
  56. data/lib/packetgen/pcapng/unknown_block.rb +0 -7
  57. data/lib/packetgen/types.rb +1 -0
  58. data/lib/packetgen/types/array.rb +73 -71
  59. data/lib/packetgen/types/cstring.rb +1 -1
  60. data/lib/packetgen/types/enum.rb +3 -3
  61. data/lib/packetgen/types/fields.rb +66 -106
  62. data/lib/packetgen/types/int.rb +9 -5
  63. data/lib/packetgen/types/length_from.rb +45 -0
  64. data/lib/packetgen/types/oui.rb +2 -0
  65. data/lib/packetgen/types/string.rb +10 -16
  66. data/lib/packetgen/types/tlv.rb +7 -15
  67. data/lib/packetgen/utils.rb +8 -8
  68. data/lib/packetgen/utils/arp_spoofer.rb +1 -2
  69. data/lib/packetgen/version.rb +1 -1
  70. metadata +3 -21
  71. data/lib/packetgen/header/crypto.rb +0 -62
  72. data/lib/packetgen/header/esp.rb +0 -413
  73. data/lib/packetgen/header/ike.rb +0 -243
  74. data/lib/packetgen/header/ike/auth.rb +0 -165
  75. data/lib/packetgen/header/ike/cert.rb +0 -76
  76. data/lib/packetgen/header/ike/certreq.rb +0 -66
  77. data/lib/packetgen/header/ike/id.rb +0 -99
  78. data/lib/packetgen/header/ike/ke.rb +0 -79
  79. data/lib/packetgen/header/ike/nonce.rb +0 -40
  80. data/lib/packetgen/header/ike/notify.rb +0 -176
  81. data/lib/packetgen/header/ike/payload.rb +0 -315
  82. data/lib/packetgen/header/ike/sa.rb +0 -561
  83. data/lib/packetgen/header/ike/sk.rb +0 -261
  84. data/lib/packetgen/header/ike/ts.rb +0 -270
  85. data/lib/packetgen/header/ike/vendor_id.rb +0 -39
  86. data/lib/packetgen/header/netbios.rb +0 -20
  87. data/lib/packetgen/header/netbios/datagram.rb +0 -105
  88. data/lib/packetgen/header/netbios/name.rb +0 -67
  89. data/lib/packetgen/header/netbios/session.rb +0 -64
@@ -1,243 +0,0 @@
1
- # This file is part of PacketGen
2
- # See https://github.com/sdaubert/packetgen for more informations
3
- # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
4
- # This program is published under MIT license.
5
-
6
- # frozen_string_literal: true
7
-
8
- module PacketGen
9
- module Header
10
- # This class handles a pseudo-header used to differentiate ESP from IKE headers
11
- # in a UDP datagram with port 4500.
12
- # @author Sylvain Daubert
13
- # @since 2.0.0
14
- class NonESPMarker < Base
15
- # @!attribute non_esp_marker
16
- # 32-bit zero marker to differentiate IKE packet over UDP port 4500 from ESP ones
17
- # @return [Integer]
18
- define_field :non_esp_marker, Types::Int32, default: 0
19
- # @!attribute body
20
- # @return [Types::String,Header::Base]
21
- define_field :body, Types::String
22
-
23
- # Check non_esp_marker field
24
- # @see [Base#parse?]
25
- def parse?
26
- non_esp_marker.zero?
27
- end
28
- end
29
-
30
- # IKE is the Internet Key Exchange protocol (RFC 7296). Ony IKEv2 is supported.
31
- #
32
- # A IKE header consists of a header, and a set of payloads. This class
33
- # handles IKE header. For payloads, see {IKE::Payload}.
34
- #
35
- # == IKE header
36
- # The format of a IKE header is shown below:
37
- # 1 2 3
38
- # 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
39
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40
- # | IKE SA Initiator's SPI |
41
- # | |
42
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43
- # | IKE SA Responder's SPI |
44
- # | |
45
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46
- # | Next Payload | MjVer | MnVer | Exchange Type | Flags |
47
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48
- # | Message ID |
49
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50
- # | Length |
51
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52
- # A IKE header consists of:
53
- # * a IKE SA initiator SPI ({#init_spi}, {Types::Int64} type),
54
- # * a IKE SA responder SPI ({#resp_spi}, {Types::Int64} type),
55
- # * a Next Payload field ({#next}, {Types::Int8} type),
56
- # * a Version field ({#version}, {Types::Int8} type, with first 4-bit field
57
- # as major number, and last 4-bit field as minor number),
58
- # * a Exchange type ({#exchange_type}, {Types::Int8} type),
59
- # * a {#flags} field ({Types::Int8} type),
60
- # * a Message ID ({#message_id}, {Types::Int32} type),
61
- # * and a {#length} ({Types::Int32} type).
62
- #
63
- # == Create a IKE header
64
- # === Standalone
65
- # ike = PacketGen::Header::IKE.new
66
- # === Classical IKE packet
67
- # pkt = PacketGen.gen('IP').add('UDP').add('IKE')
68
- # # access to IKE header
69
- # pkt.ike # => PacketGen::Header::IKE
70
- # === NAT-T IKE packet
71
- # # NonESPMarker is used to insert a 32-bit null field between UDP header
72
- # # and IKE one to differentiate it from ESP-in-UDP (see RFC 3948)
73
- # pkt = PacketGen.gen('IP').add('UDP').add('NonESPMarker').add('IKE)
74
- # @author Sylvain Daubert
75
- # @since 2.0.0
76
- class IKE < Base
77
- # Classical well-known UDP port for IKE
78
- UDP_PORT1 = 500
79
- # Well-known UDP port for IKE when NAT is detected
80
- UDP_PORT2 = 4500
81
-
82
- PROTO_IKE = 1
83
- PROTO_AH = 2
84
- PROTO_ESP = 3
85
-
86
- EXCHANGE_TYPES = {
87
- 'IKE_SA_INIT' => 34,
88
- 'IKE_AUTH' => 35,
89
- 'CREATE_CHILD_SA' => 36,
90
- 'INFORMATIONAL' => 37
91
- }.freeze
92
-
93
- # @!attribute init_spi
94
- # 64-bit initiator SPI
95
- # @return [Integer]
96
- define_field :init_spi, Types::Int64
97
- # @!attribute resp_spi
98
- # 64-bit responder SPI
99
- # @return [Integer]
100
- define_field :resp_spi, Types::Int64
101
- # @!attribute next
102
- # 8-bit next payload type
103
- # @return [Integer]
104
- define_field :next, Types::Int8
105
- # @!attribute version
106
- # 8-bit IKE version
107
- # @return [Integer]
108
- define_field :version, Types::Int8, default: 0x20
109
- # @!attribute [r] exchange_type
110
- # 8-bit exchange type
111
- # @return [Integer]
112
- define_field :exchange_type, Types::Int8Enum, enum: EXCHANGE_TYPES
113
- # @!attribute flags
114
- # 8-bit flags
115
- # @return [Integer]
116
- define_field :flags, Types::Int8
117
- # @!attribute message_id
118
- # 32-bit message ID
119
- # @return [Integer]
120
- define_field :message_id, Types::Int32
121
- # @!attribute length
122
- # 32-bit length of total message (header + payloads)
123
- # @return [Integer]
124
- define_field :length, Types::Int32
125
-
126
- # Defining a body permits using Packet#parse to parse IKE payloads.
127
- # But this method is hidden as prefered way to access payloads is via #payloads
128
- define_field :body, Types::String
129
-
130
- # @!attribute mjver
131
- # 4-bit major version value
132
- # @return [Integer]
133
- # @!attribute mnver
134
- # 4-bit minor version value
135
- # @return [Integer]
136
- define_bit_fields_on :version, :mjver, 4, :mnver, 4
137
-
138
- # @!attribute rsv1
139
- # @return [Integer]
140
- # @!attribute rsv2
141
- # @return [Integer]
142
- # @!attribute flag_i
143
- # bit set in message sent by the original initiator
144
- # @return [Boolean]
145
- # @!attribute flag_r
146
- # indicate this message is a response to a message containing the same Message ID
147
- # @return [Boolean]
148
- # @!attribute flag_v
149
- # version flag. Ignored by IKEv2 peers, and should be set to 0
150
- # @return [Boolean]
151
- define_bit_fields_on :flags, :rsv1, 2, :flag_r, :flag_v, :flag_i, :rsv2, 3
152
-
153
- # @param [Hash] options
154
- # @see Base#initialize
155
- def initialize(options={})
156
- super
157
- calc_length unless options[:length]
158
- self.type = options[:type] if options[:type]
159
- self.type = options[:exchange_type] if options[:exchange_type]
160
- end
161
-
162
- alias type exchange_type
163
- alias type= exchange_type=
164
-
165
- # Get exchange type name
166
- # @return [String
167
- def human_exchange_type
168
- self[:exchange_type].to_human
169
- end
170
- alias human_type human_exchange_type
171
-
172
- # Calculate length field
173
- # @return [Integer]
174
- def calc_length
175
- Base.calculate_and_set_length self
176
- end
177
-
178
- # IKE payloads
179
- # @return [Array<Payload>]
180
- def payloads
181
- payloads = []
182
- body = self.body
183
- while body.is_a?(Payload)
184
- payloads << body
185
- body = body.body
186
- end
187
- payloads
188
- end
189
-
190
- # @return [String]
191
- def inspect
192
- super do |attr|
193
- case attr
194
- when :flags
195
- str_flags = ''.dup
196
- %w[r v i].each do |flag|
197
- str_flags << (send("flag_#{flag}?") ? flag.upcase : '.')
198
- end
199
- str = Inspect.shift_level
200
- str << Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''), attr,
201
- str_flags]
202
- end
203
- end
204
- end
205
-
206
- # Toggle +I+ and +R+ flags.
207
- # @return [self]
208
- def reply!
209
- self.flag_r = !self.flag_r?
210
- self.flag_i = !self.flag_i?
211
- self
212
- end
213
-
214
- # @api private
215
- # @note This method is used internally by PacketGen and should not be
216
- # directly called
217
- # @param [Packet] packet
218
- # @return [void]
219
- # @since 2.7.0 Set UDP sport according to bindings, only if sport is 0.
220
- # Needed by new bind API.
221
- def added_to_packet(packet)
222
- return unless packet.is? 'UDP'
223
- return unless packet.udp.sport.zero?
224
- packet.udp.sport = if packet.is?('NonESPMarker')
225
- UDP_PORT2
226
- else
227
- UDP_PORT1
228
- end
229
- end
230
- end
231
-
232
- self.add_class IKE
233
- self.add_class NonESPMarker
234
-
235
- UDP.bind IKE, dport: IKE::UDP_PORT1
236
- UDP.bind IKE, sport: IKE::UDP_PORT1
237
- UDP.bind NonESPMarker, dport: IKE::UDP_PORT2
238
- UDP.bind NonESPMarker, sport: IKE::UDP_PORT2
239
- NonESPMarker.bind IKE
240
- end
241
- end
242
-
243
- require_relative 'ike/payload'
@@ -1,165 +0,0 @@
1
- # coding: utf-8
2
- # This file is part of PacketGen
3
- # See https://github.com/sdaubert/packetgen for more informations
4
- # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
5
- # This program is published under MIT license.
6
-
7
- # frozen_string_literal: true
8
-
9
- module PacketGen
10
- module Header
11
- class IKE
12
- # This class handles Authentication payloads.
13
- #
14
- # A AUTH payload consists of the IKE generic payload header (see {Payload})
15
- # and some specific fields:
16
- # 1 2 3
17
- # 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
18
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19
- # | Next Payload |C| RESERVED | Payload Length |
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', method: 'SHARED_KEY')
35
- # pkt.calc_length
36
- # @author Sylvain Daubert
37
- class Auth < Payload
38
- # Payload type number
39
- PAYLOAD_TYPE = 39
40
-
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
52
-
53
- # @attribute [r] method
54
- # 8-bit Auth Method
55
- # @return [Integer]
56
- define_field_before :content, :method, Types::Int8Enum, enum: METHODS
57
- # @attribute reserved
58
- # 24-bit reserved field
59
- # @return [Integer]
60
- define_field_before :content, :reserved, Types::Int24
61
-
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?(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])
83
-
84
- case method
85
- when METHODS['SHARED_KEY']
86
- auth = prf(prf(shared_secret, 'Key Pad for IKEv2'), signed_octets)
87
- auth == content
88
- when METHODS['RSA_SIGNATURE'], METHODS['ECDSA256'], METHODS['ECDSA384'],
89
- METHODS['ECDSA512']
90
- if packet.ike_cert
91
- # FIXME: Expect a ENCODING_X509_CERT_SIG
92
- # Others types not supported for now...
93
- cert = OpenSSL::X509::Certificate.new(packet.ike_cert.content)
94
- elsif cert.nil?
95
- raise CryptoError, 'a certificate should be provided'
96
- end
97
-
98
- text = cert.to_text
99
- m = text.match(/Public Key Algorithm: ([a-zA-Z0-9-]+)/)
100
- digest = case m[1]
101
- when 'id-ecPublicKey'
102
- m2 = text.match(/Public-Key: \((\d+) bit\)/)
103
- case m2[1]
104
- when '256'
105
- OpenSSL::Digest::SHA256.new
106
- when '384'
107
- OpenSSL::Digest::SHA384.new
108
- when '521'
109
- OpenSSL::Digest::SHA512.new
110
- end
111
- when /sha([235]\d+)/
112
- OpenSSL::Digest.const_get("SHA#{$1}").new
113
- when /sha1/, 'rsaEncryption'
114
- OpenSSL::Digest::SHA1.new
115
- end
116
- signature = format_signature(cert.public_key, content.to_s)
117
- cert.public_key.verify(digest, signature, signed_octets)
118
- when METHOD_NULL
119
- true
120
- else
121
- raise NotImplementedError, "unsupported method #{human_method}"
122
- end
123
- end
124
-
125
- # Get authentication method name
126
- # @return [String]
127
- def human_method
128
- self[:method].to_human
129
- end
130
-
131
- private
132
-
133
- def prf(type, key, msg)
134
- case type
135
- when Transform::PRF_HMAC_MD5, Transform::PRF_HMAC_SHA1,
136
- Transform::PRF_HMAC_SHA2_256, Transform::PRF_HMAC_SHA2_384,
137
- Transform::PRF_HMAC_SHA2_512
138
- digestname = Transform.constants.grep(/PRF_/)
139
- .detect { |c| Transform.const_get(c) == type }
140
- .to_s.sub(/^PRF_HMAC_/, '').sub(/2_/, '')
141
- digest = OpenSSL::Digest.const_get(digestname).new
142
- else
143
- raise NotImplementedError, 'for now, only HMAC-based PRF are supported'
144
- end
145
- hmac = OpenSSL::HMAC.new(key, digest)
146
- hmac << msg
147
- hmac.digest
148
- end
149
-
150
- def format_signature(pkey, sig)
151
- if pkey.is_a?(OpenSSL::PKey::EC)
152
- # PKey::EC need a signature as a DER string representing a sequence of
153
- # 2 integers: r and s
154
- r = OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(sig[0, sig.size / 2], 2).to_i)
155
- s = OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(sig[sig.size / 2,
156
- sig.size / 2], 2).to_i)
157
- OpenSSL::ASN1::Sequence.new([r, s]).to_der
158
- else
159
- sig
160
- end
161
- end
162
- end
163
- end
164
- end
165
- end
@@ -1,76 +0,0 @@
1
- # coding: utf-8
2
- # This file is part of PacketGen
3
- # See https://github.com/sdaubert/packetgen for more informations
4
- # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
5
- # This program is published under MIT license.
6
-
7
- # frozen_string_literal: true
8
-
9
- module PacketGen
10
- module Header
11
- class IKE
12
- # This class handles Certificate payloads.
13
- #
14
- # A Cert payload consists of the IKE generic payload header (see {Payload})
15
- # and some specific fields:
16
- # 1 2 3
17
- # 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
18
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19
- # | Next Payload |C| RESERVED | Payload Length |
20
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21
- # | Cert Encoding | |
22
- # +-+-+-+-+-+-+-+-+ +
23
- # | |
24
- # ~ Certificate Data ~
25
- # | |
26
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27
- # These specific fields are:
28
- # * {#encoding},
29
- # * and {#content} (Certificate Data).
30
- #
31
- # == Create a Cert payload
32
- # # Create a IKE packet with a Cert payload
33
- # pkt = PacketGen.gen('IP').add('UDP').add('IKE').add('IKE::Cert', encoding: 'X509_CERT_SIG')
34
- # certs = cert.to_der << ca_cert.to_der
35
- # pkt.ike_cert.content.read certs
36
- # pkt.calc_length
37
- # @author Sylvain Daubert
38
- class Cert < Payload
39
- # Payload type number
40
- PAYLOAD_TYPE = 37
41
-
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
-
56
- # @attribute encoding
57
- # 8-bit certificate encoding
58
- # @return [Integer]
59
- define_field_before :content, :encoding, Types::Int8Enum, enum: ENCODINGS
60
-
61
- def initialize(options={})
62
- super
63
- self.encoding = options[:encoding] if options[:encoding]
64
- end
65
-
66
- # Get encoding name
67
- # @return [String]
68
- def human_encoding
69
- self[:encoding].to_human
70
- end
71
- end
72
- end
73
-
74
- self.add_class IKE::Cert
75
- end
76
- end