# -*- coding:binary -*-
require 'spec_helper'
require 'rasn1'

RSpec.describe Msf::Exploit::Remote::Kerberos::Client::Pkinit do
  subject do
    mod = ::Msf::Exploit.new
    mod.extend ::Msf::Exploit::Remote::Kerberos::Client
    mod.send(:initialize)
    mod
  end

  let(:pfx) do
    cert_b64 = 'MIIMJgIBAzCCC/AGCSqGSIb3DQEHAaCCC+EEggvdMIIL2TCCBn8GCSqGSIb3DQEHB' \
               'qCCBnAwggZsAgEAMIIGZQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIomQRWZ' \
               'mX88MCAggAgIIGOOYzyqGw3qFOPVHeWUPU+Hl3uCXrrpCxtut6rQairJnh7ytbryO' \
               '7FLIiu/nXbV/uKRKOxc/a0kcZWA37KX179hFCtiuOcU0QDJGgGzYWmRX8tRrTTLr0' \
               'xwMMBck3S2Bo2SPmUkDXKiOtkcLFKqpeBkiMA1ZfvzW2CKkyivhIw9XtQy398JGW3' \
               'Ke6ru8zLpx3nfKiSUdQQb30mIedWo4SOHWuVQS15XifnFoxemrveiUVCNomvpBsY9' \
               'jFyK9VDksj31q9Dn0Mw572/1zOMERV/JM9Y7ZXpo34xBBT8nWeMmNJhG332w/VXx/' \
               'wuTtc9KcDKREC+PGPdV04UQPXoD8HptLArWkQtyJVFADJMkgehpyo857zLv+riMZj' \
               'k5I06759Ap0LdPROa2E4+mH5Gfs7Msmo/4G/vmGY1FCcGViKfJtFBjNyQFYJunpFP' \
               'FiIShCM6UswfQfmtjiDFRa+iCjQWD2gtVSC4SktC3UIMttGYN5UxeLIbuORFetyCI' \
               'aWk4MpeqhRZhSWodmNzvqEBjpWe4pctVRnT4g3KSvFx+ziWCcXueapAG14pc9d5NX' \
               'RhMkell48sEhG5M/ID1nLLvZogLA0Hut/0x4/BbRl+9QjtIPhWWLUpkdTiryBILOE' \
               'Z+ke5dav47PShkLc68kPP/bnn/VYBNlJvkwMILkz5Pn3BXGc+CPQAq4sy4wbgdIvJ' \
               'pENfdvY+GjA9XRwHm461U68NV254ze+IvvPi50YNOFxhHe4FRvPM369ZnpCGR+M68' \
               'IaVFsChhLvZ/sXhs61UU1w9t8Ir7R7GE2EVASveS+SMh9E+6/fUsD+luprYNhhUf9' \
               'A3dO6+CzOUUD4tx27LJqCKRjbqqCnexozQQEQU9PxytnY8+0YwlmBYiBxGV9dfJW3' \
               'umIOxe5DIOlrcxqwwoVID4L0INAtUGVQFoXXGoBUD8OAh2mRGn7GQm9NJJPr2vPtE' \
               'fw3L9iR9LQmVCSr9G5T5B1ua0lF859GT0EUzlp5j1oKPtsn4MDJ1k0IiMLuVVkmvE' \
               'C9KrUiyMpVmbAs+TzdeUu83eRLtsZdwa18UxJNm3exoefqK28JkDsQ7lmVcHvuuaT' \
               'Zb2XhiF1ISzoS/CA9jcbhSE3PUEUwMx9YQmMebbWQ5AiJnlkMew9Eu91jhpAswNgv' \
               'JyYW/yNk4xSSOFzVhVvLw/EWIwaaJPSIzdnqORHBktVIsC5oCbanm669aiT14GzY0' \
               'zR6qGPmadMBk/GCD6mCfFKvmNMvWEtVyROKyE1eS30Vyz8MtTJZ4duzgDSjETZCTL' \
               'qp0ZUe/ey7GUu2i0+5R7msbJevWlwemnfBi4LaHVnRvg7ffrKna1OjGdDU0E7f7kR' \
               'S/JkvoXCToGxIDV2BjnOaUXblwv2/B2sjTS4l2mF0ii4hw9zRtKhBpavdSDz1mRVc' \
               'qQfUX2HbTJPz4KD6HAYP9akayEWIQyFwa7/YsOj9DwzRZzWAHLVt/nXnxj5zno7eB' \
               'H44NiUriwonAlLnNX/2QzAZCXoREM8zRnb4onwaqHj/FC4tFhn3IGR7GZqDQBVRRg' \
               'wtKPfndedp1GNVpnKp7AKz9eOZaQ9i3YzniYpv+phgSfe+xpbrsAULqujpicDtL9o' \
               '+ESAiXMNkNWcgFUrOSO3vco2gKVDN1SGG5y2v68W8WlA5y+Y1HgCLv0jwH1jAsAfY' \
               'JE0N5ev45oUfujwxchsJ0GkoiPt1nnRfmuzW7ABqmwwylXlyN+tyV4hNJrQsz2qOV' \
               'Uhmqz41u/wHt2QfrWf4IrXXbzN8NtTsjNtD/hW5AA6g5aDu4X7a4rijHyRXKaLk7v' \
               '6/g4gL2vBQ+R9aZSZDEItkrECYG6jagLMAYL++JAvCSRp3khffiZD38w7cRdyS/Uc' \
               'VjgLHtB+aSD+hax9K/2MYeukIrWnn2wEHoDK2qZXMhSjPJ1SyX9RNJp1HhjwZ7vt5' \
               'dLybzraop5CLOmyzZbz2ZLKMX1E/+myQDH7CGDnIoSv6fUJK9isepxF7nQQJ+kIrw' \
               '9+ZP3/mMHiMmi7lcLCTHfeURZwxJlLfvqeazd9ABzaMZTPNOMBCC1W1FtVeOJaQMd' \
               'jByrGvE47ITUkT8JM1TPwycPcWTtrgMbJ5kqE8wZzndTIGhyn759EqB1WfMIIFUgY' \
               'JKoZIhvcNAQcBoIIFQwSCBT8wggU7MIIFNwYLKoZIhvcNAQwKAQKgggTuMIIE6jAc' \
               'BgoqhkiG9w0BDAEDMA4ECJfKqiIB4sT2AgIIAASCBMi7rLXoZavwxcXEbX930Xf4H' \
               'bcy8eg2ZQPkwRFG+nB2FAnJLfzkzTlPz/IKTxXVCsxmTZb3BBdxXhOntT3zSHYuIc' \
               'I7ngyrcZJ0Tw16s4Cez7EQuCz5cVIfdG+xS39dhXZFwlkXPfVFrb2CBgfUWhUhldp' \
               'OeBji/dlFeGS3JeaDzx3isjBB2ubZ6Ygf1likEzuIcMECP5EXwMj3jVa+DJnBTcqb' \
               '3xeMhr8b9IQuEF1EzhVKn5LknmkY+1lOTAyZu6xRMpESA7ZNZKt2eHa9QCOQb6lWH' \
               'W3HGNu2AbG64H79UWsW9qR6tB/3WN0bn6nG2IRCV47wCBQ+AkGWnQ/K+d0UlvI7hS' \
               'Gw9IG7S3UNTj65ZadOvpZZFIxgJyod8ZCuc2cU7SuY4HlKcUdDf6BVUQeOz8zEWm2' \
               'KPZSEpSNth++wDstgmEBnGRvbVUpNQavvcq5QSM6jdXRckyKRHgGEIPx9K1FWqKiM' \
               's3B8zhwSQnISt0hjHPs61jHo608UrzcIc8jvFMJGljmj8vtv9dveAVlQI8Ydk5Pw5' \
               '9+F7gbpMuT3+sQM5NzM/PH50yq1iB44C0Dq0w2Fz/azXYQSEHsFNjZHMVNOqZ7bVQ' \
               'GBGM7lUh63HVvDViKqLIhOOmv/ndLWfp17mcxapS25UOcX6XBjWOCzKVNZ5fv/7ZV' \
               'sR8tlDVc2AlhTm9q4+oX29lCqsJpBwRWH74ZU7xUWNSt+dxUia5Ahip9PwwKSqvLE' \
               'ba5nQQuQYWeeE4nPNDvcz/4UbD/MOd3FfTypTTSEBBgZc18Swx6y/rXjbn13quyzI' \
               'afhJgoiIIBrIWNTn7PACWFwfPSPT0SPRBKglZWxewVS6BiR380wAmNvhcT1WojGEu' \
               'f2JNCDaSV4xRp7+Gb/slaKQ7e39YXPZKZyvn92vWuQ60Dh17en2smI5kFljRsDlqd' \
               'PZzzPuX9hFaYLK3EniE8vHDi3S+vCu+NL6DVF9+iMVlOLau45k8oZaKuq2qMotfGU' \
               'L0+xDxgmgpi7bsA4SwtnWTjyfunzdwT8lp2s8tzGHJ99WZIZCUTWXKeOqv7f0di4q' \
               'Znzdn9lm6Fqo2lCUL43BN/cmCGMPRPX3UuTH2X63OBS+WCCuO3UYhrk0rm+u1pNQL' \
               'YARy4g9CDB9ZLpRqFtvnge0p5fm58rCErWzU7io5YgAsfW5GrZXYF900/e9lt9hEn' \
               'akx8VWbIYYiELInB1l4QgoSPHhkI1MMVT7SUnB4vJt7k4ErrFblIZ7E8hgdo4BRQ/' \
               '80T/N8drVZGljTIazgRMoZZrGV8qMVGm/nHZ5QacHajox1BnfJwBwNY492u9rEBZY' \
               'Kjq6XDtxZVRwVDrXRVSE3ml0QZcSUHyGj/Q+g5D163ns/P9kecEcqg5YSvhQUtK1t' \
               'ieL6Os3LDsq138dMiXLF2EhNqZ42cmvYR0XR257PLayg6wL42fb5q78uTzr4+Wegr' \
               'sRaQW64csDXlE68me/Uc74LC8GsKHAcMtO8gf5RVnUt57ufJKFetr6vKEgR7ASoNS' \
               'G/N4+rCYlCYrEs2uu8X0jlKXprTqotXjzhZ3S1kccCl6ChA5VuqgWU+2u0VmnaoN9' \
               'dwT56VMx9zC+htdRsvzd1aogaH2sbkEbX6t6CJmBo2ct4KdC40xNjAPBgkqhkiG9w' \
               '0BCRQxAh4AMCMGCSqGSIb3DQEJFTEWBBStfFN5yrqYxinn0ziM+vhFxqMISTAtMCE' \
               'wCQYFKw4DAhoFAAQUd1dleYzvwe5YdZTWA8aE1GZlGbEECO5masyI99hB'
    cert = OpenSSL::PKCS12.new(Base64.decode64(cert_b64), '')
    cert
  end

  context "when building a pa_pk_as_req" do
    it "Reads the correct values" do
      dh, dh_nonce = subject.build_dh
      result = subject.build_pa_pk_as_req(pfx, dh, dh_nonce, 'somedata', {})
      sd = result.decoded_value.signed_auth_pack.signed_data
      expect(sd[:version].value).to eq(3)
      expect(sd[:digest_algorithms].value.length).to eq(1)
      expect(sd[:digest_algorithms].value[0][:algorithm].value).to eq('1.3.14.3.2.26')
      expect(sd[:encap_content_info].econtent[:client_dh_nonce].value).to eq(RASN1::Types::OctetString.new(value: dh_nonce).to_der)
      expect(RASN1::Types::Integer.parse(sd[:encap_content_info].econtent[:client_public_value][:subject_public_key].value).value).to eq(dh.pub_key)
    end
  end

  context "when truncating key" do
    it "Gives expected output of RFC4556 Test case 1" do
      input = "\x00" * 256
      etype = Rex::Proto::Kerberos::Crypto::Encryption::AES256
      result = subject.k_truncate(input, etype)
      expect(result).to eq("\x5e\xe5\x0d\x67\x5c\x80\x9f\xe5\x9e\x4a\x77\x62\xc5\x4b\x65\x83\x75\x47\xea\xfb\x15\x9b\xd8\xcd\xc7\x5f\xfc\xa5\x91\x1e\x4c\x41")
    end

    it "Gives expected output of RFC4556 Test case 2" do
      input = "\x00" * 128
      etype = Rex::Proto::Kerberos::Crypto::Encryption::AES256
      result = subject.k_truncate(input, etype)
      expect(result).to eq("\xac\xf7\x70\x7c\x08\x97\x3d\xdf\xdb\x27\xcd\x36\x14\x42\xcc\xfb\xa3\x55\xc8\x88\x4c\xb4\x72\xf3\x7d\xa6\x36\xd0\x7d\x56\x78\x7e")
    end

    it "Gives expected output of RFC4556 Test case 3" do
      input = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08"
      etype = Rex::Proto::Kerberos::Crypto::Encryption::AES256
      result = subject.k_truncate(input, etype)
      expect(result).to eq("\xc4\x42\xda\x58\x5f\xcb\x80\xe4\x3b\x47\x94\x6f\x25\x40\x93\xe3\x73\x29\xd9\x90\x01\x38\x0d\xb7\x83\x71\xdb\x3a\xcf\x5c\x79\x7e")
    end

    it "Gives expected output of RFC4556 Test case 4" do
      input = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08"
      etype = Rex::Proto::Kerberos::Crypto::Encryption::AES256
      result = subject.k_truncate(input, etype)
      expect(result).to eq("\x00\x53\x95\x3b\x84\xc8\x96\xf4\xeb\x38\x5c\x3f\x2e\x75\x1c\x4a\x59\x0e\xd6\xff\xad\xca\x6f\xf6\x4f\x47\xeb\xeb\x8d\x78\x0f\xfc")
    end
  end
end
