packetgen-plugin-ipsec 1.0.2 → 1.1.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.
@@ -1,163 +1,176 @@
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
- # frozen_string_literal: true
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
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
8
52
 
9
- module PacketGen
10
- module Plugin
11
- class IKE
12
- # This class handles Authentication payloads.
13
- #
14
- # A AUTH payload consists of the IKE generic payload Plugin (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', auth_method: 'SHARED_KEY')
35
- # pkt.calc_length
36
- # @author Sylvain Daubert
37
- class Auth < Payload
38
- # Payload type number
39
- PAYLOAD_TYPE = 39
53
+ # @attribute [r] auth_method
54
+ # 8-bit Auth Method
55
+ # @return [Integer]
56
+ define_attr_before :content, :auth_method, BinStruct::Int8Enum, enum: METHODS
57
+ # @attribute reserved
58
+ # 24-bit reserved field
59
+ # @return [Integer]
60
+ define_attr_before :content, :reserved, BinStruct::Int24
40
61
 
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
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: '', # rubocop:disable Metrics/ParameterLists
77
+ cert: nil)
78
+ raise TypeError, 'init_msg should be a Packet' unless init_msg.is_a?(PacketGen::Packet)
52
79
 
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
80
+ signed_octets = build_signed_octets(init_msg, nonce, sk_p, prf)
81
+ case auth_method
82
+ when METHODS['SHARED_KEY']
83
+ check_shared_key?(shared_secret, signed_octets)
84
+ when METHODS['RSA_SIGNATURE'], METHODS['ECDSA256'], METHODS['ECDSA384'],
85
+ METHODS['ECDSA512']
86
+ check_signature?(cert, signed_octets)
87
+ when METHOD_NULL
88
+ true
89
+ else
90
+ raise NotImplementedError, "unsupported auth method #{human_auth_method}"
91
+ end
92
+ end
61
93
 
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])
94
+ # Get authentication method name
95
+ # @return [String]
96
+ def human_auth_method
97
+ self[:auth_method].to_human
98
+ end
83
99
 
84
- case auth_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
100
+ private
97
101
 
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 auth method #{human_auth_method}"
122
- end
102
+ def build_signed_octets(init_msg, nonce, sk_p, prf)
103
+ signed_octets = init_msg.ike.to_s
104
+ signed_octets << nonce
105
+ id = packet.ike.flag_i? ? packet.ike_idi : packet.ike_idr
106
+ signed_octets << prf(prf, sk_p, id.to_s[4, id.length - 4])
107
+ end
108
+
109
+ def prf(type, key, msg)
110
+ case type
111
+ when Transform::PRF_HMAC_MD5, Transform::PRF_HMAC_SHA1,
112
+ Transform::PRF_HMAC_SHA2_256, Transform::PRF_HMAC_SHA2_384,
113
+ Transform::PRF_HMAC_SHA2_512
114
+ digestname = Transform.constants.grep(/PRF_/)
115
+ .detect { |c| Transform.const_get(c) == type }
116
+ .to_s.sub(/^PRF_HMAC_/, '').sub('2_', '')
117
+ digest = OpenSSL::Digest.const_get(digestname).new
118
+ else
119
+ raise NotImplementedError, 'for now, only HMAC-based PRF are supported'
123
120
  end
121
+ hmac = OpenSSL::HMAC.new(key, digest)
122
+ hmac << msg
123
+ hmac.digest
124
+ end
125
+
126
+ def check_shared_key?(shared_secret, signed_octets)
127
+ auth = prf(prf(shared_secret, 'Key Pad for IKEv2'), signed_octets)
128
+ auth == content
129
+ end
124
130
 
125
- # Get authentication method name
126
- # @return [String]
127
- def human_auth_method
128
- self[:auth_method].to_human
131
+ def check_signature?(cert, signed_octets)
132
+ if packet.ike_cert
133
+ # FIXME: Expect a ENCODING_X509_CERT_SIG
134
+ # Others types not supported for now...
135
+ cert = OpenSSL::X509::Certificate.new(packet.ike_cert.content)
136
+ elsif cert.nil?
137
+ raise CryptoError, 'a certificate should be provided'
129
138
  end
130
139
 
131
- private
140
+ text = cert.to_text
141
+ digest = build_digest_object(text)
142
+ signature = format_signature(cert.public_key, content.to_s)
143
+ cert.public_key.verify(digest, signature, signed_octets)
144
+ end
132
145
 
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'
146
+ def build_digest_object(text)
147
+ m = text.match(/Public Key Algorithm: ([a-zA-Z0-9-]+)/)
148
+ case m[1]
149
+ when 'id-ecPublicKey'
150
+ m2 = text.match(/Public-Key: \((\d+) bit\)/)
151
+ case m2[1]
152
+ when '256', '384'
153
+ OpenSSL::Digest.new("SHA#{m2[1]}")
154
+ when '521'
155
+ OpenSSL::Digest.new(SHA512)
144
156
  end
145
- hmac = OpenSSL::HMAC.new(key, digest)
146
- hmac << msg
147
- hmac.digest
157
+ when /sha([235]\d+)/
158
+ OpenSSL::Digest.new("SHA#{$1}")
159
+ when /sha1/, 'rsaEncryption'
160
+ OpenSSL::Digest.new('SHA1')
148
161
  end
162
+ end
149
163
 
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
164
+ def format_signature(pkey, sig)
165
+ if pkey.is_a?(OpenSSL::PKey::EC)
166
+ # PKey::EC need a signature as a DER string representing a sequence of
167
+ # 2 integers: r and s
168
+ r = OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(sig[0, sig.size / 2], 2).to_i)
169
+ s = OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(sig[sig.size / 2,
170
+ sig.size / 2], 2).to_i)
171
+ OpenSSL::ASN1::Sequence.new([r, s]).to_der
172
+ else
173
+ sig
161
174
  end
162
175
  end
163
176
  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
- # frozen_string_literal: true
8
-
9
- module PacketGen
10
- module Plugin
11
- class IKE
12
- # This class handles Certificate payloads.
13
- #
14
- # A Cert payload consists of the IKE generic payload Plugin (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
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
- 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
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
- # @attribute encoding
57
- # 8-bit certificate encoding
58
- # @return [Integer]
59
- define_field_before :content, :encoding, PacketGen::Types::Int8Enum, enum: ENCODINGS
56
+ # @attribute encoding
57
+ # 8-bit certificate encoding
58
+ # @return [Integer]
59
+ define_attr_before :content, :encoding, BinStruct::Int8Enum, enum: ENCODINGS
60
60
 
61
- def initialize(options={})
62
- super
63
- self.encoding = options[:encoding] if options[:encoding]
64
- end
61
+ def initialize(options={})
62
+ super
63
+ self.encoding = options[:encoding] if options[:encoding]
64
+ end
65
65
 
66
- # Get encoding name
67
- # @return [String]
68
- def human_encoding
69
- self[:encoding].to_human
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
- # frozen_string_literal: true
8
-
9
- module PacketGen
10
- module Plugin
11
- class IKE
12
- # This class handles Certificate Request payloads.
13
- #
14
- # A CertReq payload consists of the IKE generic payload Plugin (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
- # ~ Certification Authority ~
25
- # | |
26
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27
- # These specific fields are:
28
- # * {#encoding},
29
- # * and {#content} (Certification Authority).
30
- #
31
- # == Create a CertReq payload
32
- # # Create a IKE packet with a CertReq payload
33
- # pkt = PacketGen.gen('IP').add('UDP').add('IKE').add('IKE::CertReq', encoding: 'X509_CERT_SIG')
34
- # pkt.ike_certreq.content.read OpenSSL::Digest::SHA1.digest(ca_cert.to_der)
35
- # pkt.calc_length
36
- # @author Sylvain Daubert
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
- # Get list of 20-byte string (SHA-1 hashes)
42
- # @return [String]
43
- def human_content
44
- strs = []
45
- idx = 0
46
- while idx < content.size
47
- strs << content[idx, 20]
48
- idx += 20
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
- # @return [String]
54
- def inspect
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