Class: PacketGen::Plugin::IKE::Auth

Inherits:
Payload
  • Object
show all
Defined in:
lib/packetgen/plugin/ike/auth.rb

Overview

This class handles Authentication payloads.

A AUTH payload consists of the IKE generic payload Plugin (see Payload) and some specific fields:

                     1                   2                   3
 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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Payload  |C|  RESERVED   |         Payload Length        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Auth Method   |                RESERVED                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
~                      Authentication Data                      ~
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

These specific fields are:

Create a KE payload

# create a IKE packet with a Auth payload
pkt = PacketGen.gen('IP').add('UDP').add('IKE').add('IKE::Auth', auth_method: 'SHARED_KEY')
pkt.calc_length

Author:

  • Sylvain Daubert

Constant Summary collapse

PAYLOAD_TYPE =

Payload type number

39
METHODS =

Authentication methods

{
  'RSA_SIGNATURE' => 1,
  'SHARED_KEY' => 2,
  'DSA_SIGNATURE' => 3,
  'ECDSA256' => 9,
  'ECDSA384' => 10,
  'ECDSA512' => 11,
  'PASSWORD' => 12,
  'NULL' => 13,
  'DIGITAL_SIGNATURE' => 14
}.freeze

Instance Attribute Summary collapse

Attributes inherited from Payload

#content, #critical, #flags, #hreserved, #length, #next

Instance Method Summary collapse

Methods inherited from Payload

#calc_length, #initialize, protocol_name

Constructor Details

This class inherits a constructor from PacketGen::Plugin::IKE::Payload

Instance Attribute Details

#auth_methodInteger (readonly)

8-bit Auth Method

Returns:

  • (Integer)


56
# File 'lib/packetgen/plugin/ike/auth.rb', line 56

define_field_before :content, :auth_method, PacketGen::Types::Int8Enum, enum: METHODS

#reservedInteger

24-bit reserved field

Returns:

  • (Integer)


60
# File 'lib/packetgen/plugin/ike/auth.rb', line 60

define_field_before :content, :reserved, PacketGen::Types::Int24

Instance Method Details

#check?(init_msg: nil, nonce: '', sk_p: '', prf: 1, shared_secret: '', cert: nil) ⇒ Boolean

Note:

For now, only NULL, SHARED_KEY and RSA, DSA and ECDSA signatures are supported.

Note:

For certificates, only check AUTH authenticity with given (or guessed from packet) certificate, but certificate chain is not verified.

Check authentication (see RFC 7296 §2.15)

Parameters:

  • init_msg (Packet) (defaults to: nil)

    first IKE message sent by peer

  • nonce (String) (defaults to: '')

    my nonce, sent in first message

  • sk_p (String) (defaults to: '')

    secret key used to compute prf(SK_px, IDx’)

  • prf (Integer) (defaults to: 1)

    PRF type to use (see Transform::PRF_* constants)

  • shared_secret (String) (defaults to: '')

    shared secret to use as PSK (shared secret method only)

  • cert (OpenSSL::X509::Certificate) (defaults to: nil)

    certificate to check AUTH signature, if not embedded in IKE message

Returns:

  • (Boolean)

Raises:

  • (TypeError)


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/packetgen/plugin/ike/auth.rb', line 76

def check?(init_msg: nil, nonce: '', sk_p: '', prf: 1, shared_secret: '',
           cert: nil)
  raise TypeError, 'init_msg should be a Packet' unless init_msg.is_a?(PacketGen::Packet)

  signed_octets = init_msg.ike.to_s
  signed_octets << nonce
  id = packet.ike.flag_i? ? packet.ike_idi : packet.ike_idr
  signed_octets << prf(prf, sk_p, id.to_s[4, id.length - 4])

  case auth_method
  when METHODS['SHARED_KEY']
    auth = prf(prf(shared_secret, 'Key Pad for IKEv2'), signed_octets)
    auth == content
  when METHODS['RSA_SIGNATURE'], METHODS['ECDSA256'], METHODS['ECDSA384'],
       METHODS['ECDSA512']
    if packet.ike_cert
      # FIXME: Expect a ENCODING_X509_CERT_SIG
      #        Others types not supported for now...
      cert = OpenSSL::X509::Certificate.new(packet.ike_cert.content)
    elsif cert.nil?
      raise CryptoError, 'a certificate should be provided'
    end

    text = cert.to_text
    m = text.match(/Public Key Algorithm: ([a-zA-Z0-9-]+)/)
    digest = case m[1]
             when 'id-ecPublicKey'
               m2 = text.match(/Public-Key: \((\d+) bit\)/)
               case m2[1]
               when '256'
                 OpenSSL::Digest::SHA256.new
               when '384'
                 OpenSSL::Digest::SHA384.new
               when '521'
                 OpenSSL::Digest::SHA512.new
               end
             when /sha([235]\d+)/
               OpenSSL::Digest.const_get("SHA#{$1}").new
             when /sha1/, 'rsaEncryption'
               OpenSSL::Digest::SHA1.new
             end
    signature = format_signature(cert.public_key, content.to_s)
    cert.public_key.verify(digest, signature, signed_octets)
  when METHOD_NULL
    true
  else
    raise NotImplementedError, "unsupported auth method #{human_auth_method}"
  end
end

#human_auth_methodString

Get authentication method name

Returns:

  • (String)


128
129
130
# File 'lib/packetgen/plugin/ike/auth.rb', line 128

def human_auth_method
  self[:auth_method].to_human
end