LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBOT1RFUwogKiAgICBXaGVuIGNoYW5naW5nIHRoaXMgZmlsZSwgcGxlYXNlIHJlLXJ1biB0aGUgcmVndGVzdCBwcm9ncmFtIHRvIGVuc3VyZQogKiAgICB0aGUgY29uZGl0aW9ucyBhcmUgaGFuZGxlZCBwcm9wZXJseS4KICoKICogVE9ETwogKiAgICBTZWN1cml0eSBhY2Nlc3MKICogICAgT3B0aW9uIGhhbmRsaW5nCiAqICAgIFRpbWUgZm9yIFJlZ0VudW1LZXkqLCBSZWdRdWVyeUluZm9LZXkqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KI2RlZmluZSBOT05BTUVMRVNTU1RSVUNUCiNpbmNsdWRlICJudHN0YXR1cy5oIgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgoKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5lL2xpYnJhcnkuaCIKI2luY2x1ZGUgIndpbmUvc2VydmVyLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKI2luY2x1ZGUgImZpbGUuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChyZWcpOwoKI2RlZmluZSBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUICAiL3dpbmUudXNlcnJlZyIKI2RlZmluZSBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSAiL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIgICJ1c2VyLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQgICJ1c2VyZGVmLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FICJzeXN0ZW0ucmVnIgoKc3RhdGljIGNvbnN0IFdDSEFSIENsYXNzZXNSb290V1tdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0MnLCdsJywnYScsJ3MnLCdzJywnZScsJ3MnLDB9OwoKI2RlZmluZSBJU19PUFRJT05fRkFMU0UoY2gpIFwKICAgICgoY2gpID09ICduJyB8fCAoY2gpID09ICdOJyB8fCAoY2gpID09ICdmJyB8fCAoY2gpID09ICdGJyB8fCAoY2gpID09ICcwJykKCi8qIF94bWFsbG9jIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgKl94bWFsbG9jKCBzaXplX3Qgc2l6ZSApCnsKICAgIHZvaWQgKnJlczsKCiAgICByZXMgPSBtYWxsb2MgKHNpemUgPyBzaXplIDogMSk7CiAgICBpZiAocmVzID09IE5VTEwpIHsKICAgICAgICBXQVJOKCJWaXJ0dWFsIG1lbW9yeSBleGhhdXN0ZWQuXG4iKTsKICAgICAgICBleGl0ICgxKTsKICAgIH0KICAgIHJldHVybiByZXM7Cn0KCi8qIF94c3RyZHVwIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF94c3RyZHVwKExQQ1NUUiBzdHIpCnsKICAgIExQU1RSIHJldDsKICAgIHNpemVfdCBsZW4gPSBzdHJsZW4oc3RyKSArIDE7CgogICAgaWYgKCFzdHIpIHJldHVybiBOVUxMOwogICAgcmV0ID0gX3htYWxsb2MoIGxlbiApOwogICAgbWVtY3B5KCByZXQsIHN0ciwgbGVuICk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IGFuc2kgc3RyaW5nIHRvIHVuaWNvZGUgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBXU1RSIF9zdHJkdXBuQXRvVyhMUENTVFIgc3RyQSxzaXplX3QgbGVuQSkKewogICAgTFBXU1RSIHJldDsKICAgIERXT1JEIGxlbjsKCiAgICBpZiAoIXN0ckEpIHJldHVybiBOVUxMOwogICAgaWYgKFJ0bE11bHRpQnl0ZVRvVW5pY29kZVNpemUoICZsZW4sIHN0ckEsIGxlbkEgKSAhPSBTVEFUVVNfU1VDQ0VTUykgcmV0dXJuIE5VTEw7CgogICAgcmV0ID0gX3htYWxsb2MobGVuK3NpemVvZihXQ0hBUikpOwogICAgUnRsTXVsdGlCeXRlVG9Vbmljb2RlTihyZXQsIGxlbiwgTlVMTCwgc3RyQSwgbGVuQSk7CiAgICByZXRbbGVuIC8gc2l6ZW9mKFdDSEFSKV0gPSAwOwogICAgcmV0dXJuIHJldDsKfQoKLyogZHVtcCBhIFVuaWNvZGUgc3RyaW5nIHdpdGggcHJvcGVyIGVzY2FwaW5nIFtJbnRlcm5hbF0gKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci91bmljb2RlLmMgKi8Kc3RhdGljIGludCBfZHVtcF9zdHJXKGNvbnN0IFdDSEFSICpzdHIsc2l6ZV90IGxlbixGSUxFICpmLGNvbnN0IGNoYXIgZXNjYXBlWzJdKQp7CiAgICBzdGF0aWMgY29uc3QgY2hhciBlc2NhcGVzWzMyXSA9ICIuLi4uLi4uYWJ0bnZmci4uLi4uLi4uLi4uLi5lLi4uLiI7CiAgICBjaGFyIGJ1ZmZlclsyNTZdOwogICAgTFBTVFIgcG9zID0gYnVmZmVyOwogICAgaW50IGNvdW50ID0gMDsKCiAgICBmb3IgKDsgbGVuOyBzdHIrKywgbGVuLS0pCiAgICB7CiAgICAgICAgaWYgKHBvcyA+IGJ1ZmZlciArIHNpemVvZihidWZmZXIpIC0gOCkKICAgICAgICB7CiAgICAgICAgICAgIGZ3cml0ZSggYnVmZmVyLCBwb3MgLSBidWZmZXIsIDEsIGYgKTsKICAgICAgICAgICAgY291bnQgKz0gcG9zIC0gYnVmZmVyOwogICAgICAgICAgICBwb3MgPSBidWZmZXI7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyID4gMTI3KSAgLyogaGV4IGVzY2FwZSAqLwogICAgICAgIHsKICAgICAgICAgICAgaWYgKGxlbiA+IDEgJiYgc3RyWzFdIDwgMTI4ICYmIGlzeGRpZ2l0KChjaGFyKXN0clsxXSkpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFx4JTA0eCIsICpzdHIgKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxceCV4IiwgKnN0ciApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCpzdHIgPCAzMikgIC8qIG9jdGFsIG9yIEMgZXNjYXBlICovCiAgICAgICAgewogICAgICAgICAgICBpZiAoISpzdHIgJiYgbGVuID09IDEpIGNvbnRpbnVlOyAgLyogZG8gbm90IG91dHB1dCB0ZXJtaW5hdGluZyBOVUxMICovCiAgICAgICAgICAgIGlmIChlc2NhcGVzWypzdHJdICE9ICcuJykKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCVjIiwgZXNjYXBlc1sqc3RyXSApOwogICAgICAgICAgICBlbHNlIGlmIChsZW4gPiAxICYmIHN0clsxXSA+PSAnMCcgJiYgc3RyWzFdIDw9ICc3JykKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCUwM28iLCAqc3RyICk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCVvIiwgKnN0ciApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCpzdHIgPT0gJ1xcJyB8fCAqc3RyID09IGVzY2FwZVswXSB8fCAqc3RyID09IGVzY2FwZVsxXSkgKnBvcysrID0gJ1xcJzsKICAgICAgICAqcG9zKysgPSAqc3RyOwogICAgfQogICAgZndyaXRlKCBidWZmZXIsIHBvcyAtIGJ1ZmZlciwgMSwgZiApOwogICAgY291bnQgKz0gcG9zIC0gYnVmZmVyOwogICAgcmV0dXJuIGNvdW50Owp9CgovKiBjb252ZXJ0IGFuc2kgc3RyaW5nIHRvIHVuaWNvZGUgYW5kIGR1bXAgd2l0aCBwcm9wZXIgZXNjYXBpbmcgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9kdW1wX3N0ckF0b1coTFBDU1RSIHN0ckEsc2l6ZV90IGxlbixGSUxFICpmLGNvbnN0IGNoYXIgZXNjYXBlWzJdKQp7CiAgICBXQ0hBUiAqc3RyVzsKICAgIGludCByZXQ7CgogICAgaWYgKHN0ckEgPT0gTlVMTCkgcmV0dXJuIDA7CiAgICBzdHJXID0gX3N0cmR1cG5BdG9XKHN0ckEsbGVuKTsKICAgIHJldCA9IF9kdW1wX3N0clcoc3RyVyxsZW4sZixlc2NhcGUpOwogICAgZnJlZShzdHJXKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGEga2V5IHZhbHVlICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvcmVnaXN0cnkuYyAqLwpzdHJ1Y3Qga2V5X3ZhbHVlIHsKICAgIFdDSEFSICAgICAgICAgICAgKm5hbWVXOyAgIC8qIHZhbHVlIG5hbWUgKi8KICAgIGludCAgICAgICAgICAgICAgIHR5cGU7ICAgIC8qIHZhbHVlIHR5cGUgKi8KICAgIHNpemVfdCAgICAgICAgICAgIGxlbjsgICAgIC8qIHZhbHVlIGRhdGEgbGVuZ3RoIGluIGJ5dGVzICovCiAgICB2b2lkICAgICAgICAgICAgICpkYXRhOyAgICAvKiBwb2ludGVyIHRvIHZhbHVlIGRhdGEgKi8KfTsKCi8qIGR1bXAgYSB2YWx1ZSB0byBhIHRleHQgZmlsZSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3JlZ2lzdHJ5LmMgKi8Kc3RhdGljIHZvaWQgX2R1bXBfdmFsdWUoc3RydWN0IGtleV92YWx1ZSAqdmFsdWUsRklMRSAqZikKewogICAgaW50IGksIGNvdW50OwoKICAgIGlmICh2YWx1ZS0+bmFtZVdbMF0pIHsKICAgICAgICBmcHV0YyggJ1wiJywgZiApOwogICAgICAgIGNvdW50ID0gMSArIF9kdW1wX3N0clcodmFsdWUtPm5hbWVXLHN0cmxlblcodmFsdWUtPm5hbWVXKSxmLCJcIlwiIik7CiAgICAgICAgY291bnQgKz0gZnByaW50ZiggZiwgIlwiPSIgKTsKICAgIH0KICAgIGVsc2UgY291bnQgPSBmcHJpbnRmKCBmLCAiQD0iICk7CgogICAgc3dpdGNoKHZhbHVlLT50eXBlKSB7CiAgICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgY2FzZSBSRUdfRVhQQU5EX1NaOgogICAgICAgIGNhc2UgUkVHX01VTFRJX1NaOgogICAgICAgICAgICBpZiAodmFsdWUtPnR5cGUgIT0gUkVHX1NaKSBmcHJpbnRmKCBmLCAic3RyKCVkKToiLCB2YWx1ZS0+dHlwZSApOwogICAgICAgICAgICBmcHV0YyggJ1wiJywgZiApOwogICAgICAgICAgICBpZiAodmFsdWUtPmRhdGEpIF9kdW1wX3N0clcodmFsdWUtPmRhdGEsdmFsdWUtPmxlbi9zaXplb2YoV0NIQVIpLGYsIlwiXCIiKTsKICAgICAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgICAgIGlmICh2YWx1ZS0+bGVuID09IHNpemVvZihEV09SRCkpIHsKICAgICAgICAgICAgICAgIERXT1JEIGR3OwogICAgICAgICAgICAgICAgbWVtY3B5KCAmZHcsIHZhbHVlLT5kYXRhLCBzaXplb2YoRFdPUkQpICk7CiAgICAgICAgICAgICAgICBmcHJpbnRmKCBmLCAiZHdvcmQ6JTA4bHgiLCBkdyApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogZWxzZSBmYWxsIHRocm91Z2ggKi8KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBpZiAodmFsdWUtPnR5cGUgPT0gUkVHX0JJTkFSWSkgY291bnQgKz0gZnByaW50ZiggZiwgImhleDoiICk7CiAgICAgICAgICAgIGVsc2UgY291bnQgKz0gZnByaW50ZiggZiwgImhleCgleCk6IiwgdmFsdWUtPnR5cGUgKTsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLT5sZW47IGkrKykgewogICAgICAgICAgICAgICAgY291bnQgKz0gZnByaW50ZiggZiwgIiUwMngiLCAqKCh1bnNpZ25lZCBjaGFyICopdmFsdWUtPmRhdGEgKyBpKSApOwogICAgICAgICAgICAgICAgaWYgKGkgPCB2YWx1ZS0+bGVuLTEpIHsKICAgICAgICAgICAgICAgICAgICBmcHV0YyggJywnLCBmICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCsrY291bnQgPiA3NikgewogICAgICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKCBmLCAiXFxcbiAgIiApOwogICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgZnB1dGMoICdcbicsIGYgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogV0lORE9XUyAzMSBSRUdJU1RSWSBMT0FERVIsIHN1cHBsaWVkIGJ5IFRvciBTavh3YWxsLCB0b3JAc24ubm8gKi8KLyoKICAgIHJlZ2hhY2sgLSB3aW5kb3dzIDMuMTEgcmVnaXN0cnkgZGF0YSBmb3JtYXQgZGVtbyBwcm9ncmFtLgoKICAgIFRoZSByZWcuZGF0IGZpbGUgaGFzIDMgcGFydHMsIGEgaGVhZGVyLCBhIHRhYmxlIG9mIDgtYnl0ZSBlbnRyaWVzIHRoYXQgaXMKICAgIGEgY29tYmluZWQgaGFzaCB0YWJsZSBhbmQgdHJlZSBkZXNjcmlwdGlvbiwgYW5kIGZpbmFsbHkgYSB0ZXh0IHRhYmxlLgoKICAgIFRoZSBoZWFkZXIgaXMgb2J2aW91cyBmcm9tIHRoZSBzdHJ1Y3QgaGVhZGVyLiBUaGUgdGFib2ZmMSBhbmQgdGFib2ZmMgogICAgZmllbGRzIGFyZSBhbHdheXMgMHgyMCwgYW5kIHRoZWlyIHVzYWdlIGlzIHVua25vd24uCgogICAgVGhlIDgtYnl0ZSBlbnRyeSB0YWJsZSBoYXMgdmFyaW91cyBlbnRyeSB0eXBlcy4KCiAgICB0YWJlbnRbMF0gaXMgYSByb290IGluZGV4LiBUaGUgc2Vjb25kIHdvcmQgaGFzIHRoZSBpbmRleCBvZiB0aGUgcm9vdCBvZgogICAgICAgICAgICB0aGUgZGlyZWN0b3J5LgogICAgdGFiZW50WzEuLmhhc2hzaXplXSBpcyBhIGhhc2ggdGFibGUuIFRoZSBmaXJzdCB3b3JkIGluIHRoZSBoYXNoIGVudHJ5IGlzCiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUga2V5L3ZhbHVlIHRoYXQgaGFzIHRoYXQgaGFzaC4gRGF0YSB3aXRoIHRoZSBzYW1lCiAgICAgICAgICAgIGhhc2ggdmFsdWUgYXJlIG9uIGEgY2lyY3VsYXIgbGlzdC4gVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZQogICAgICAgICAgICBoYXNoIGVudHJ5IGFyZSBhbHdheXMgemVyby4KICAgIHRhYmVudFtoYXNoc2l6ZS4udGFiY250XSBpcyB0aGUgdHJlZSBzdHJ1Y3R1cmUuIFRoZXJlIGFyZSB0d28ga2luZHMgb2YKICAgICAgICAgICAgZW50cnk6IGRpcmVudCBhbmQga2V5ZW50L3ZhbGVudC4gVGhleSBhcmUgaWRlbnRpZmllZCBieSBjb250ZXh0LgogICAgdGFiZW50W2ZyZWVpZHhdIGlzIHRoZSBmaXJzdCBmcmVlIGVudHJ5LiBUaGUgZmlyc3Qgd29yZCBpbiBhIGZyZWUgZW50cnkKICAgICAgICAgICAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGZyZWUgZW50cnkuIFRoZSBsYXN0IGhhcyAwIGFzIGEgbGluay4KICAgICAgICAgICAgVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZSBmcmVlIGxpc3QgYXJlIHByb2JhYmx5IGlycmVsZXZhbnQuCgogICAgRW50cmllcyBpbiB0ZXh0IHRhYmxlIGFyZSBwcmVjZWRlZCBieSBhIHdvcmQgYXQgb2Zmc2V0LTIuIFRoaXMgd29yZAogICAgaGFzIHRoZSB2YWx1ZSAoMippbmRleCkrMSwgd2hlcmUgaW5kZXggaXMgdGhlIHJlZmVycmluZyBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBpbiB0aGUgdGFibGUuIEkgaGF2ZSBubyBzdWdnZXN0aW9uIGZvciB0aGUgMiogYW5kIHRoZSArMS4KICAgIEZvbGxvd2luZyB0aGUgd29yZCwgdGhlcmUgYXJlIE4gYnl0ZXMgb2YgZGF0YSwgYXMgcGVyIHRoZSBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBsZW5ndGguIFRoZSBvZmZzZXQgb2YgdGhlIGtleWVudC92YWxlbnQgZW50cnkgaXMgZnJvbSB0aGUgc3RhcnQKICAgIG9mIHRoZSB0ZXh0IHRhYmxlIHRvIHRoZSBmaXJzdCBkYXRhIGJ5dGUuCgogICAgVGhpcyBpbmZvcm1hdGlvbiBpcyBub3QgYXZhaWxhYmxlIGZyb20gTWljcm9zb2Z0LiBUaGUgZGF0YSBmb3JtYXQgaXMKICAgIGRlZHVjZWQgZnJvbSB0aGUgcmVnLmRhdCBmaWxlIGJ5IG1lLiBNaXN0YWtlcyBtYXkKICAgIGhhdmUgYmVlbiBtYWRlLiBJIGNsYWltIG5vIHJpZ2h0cyBhbmQgZ2l2ZSBubyBndWFyYW50ZWVzIGZvciB0aGlzIHByb2dyYW0uCgogICAgVG9yIFNq+HdhbGwsIHRvckBzbi5ubwoqLwoKLyogcmVnLmRhdCBoZWFkZXIgZm9ybWF0ICovCnN0cnVjdCBfdzMxX2hlYWRlciB7CiAgICBjaGFyCQljb29raWVbOF07CS8qICdTSENDMy4xMCcgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGFib2ZmMTsJLyogb2Zmc2V0IG9mIGhhc2ggdGFibGUgKD8/KSA9IDB4MjAgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGFib2ZmMjsJLyogb2Zmc2V0IG9mIGluZGV4IHRhYmxlICg/PykgPSAweDIwICovCiAgICB1bnNpZ25lZCBsb25nCXRhYmNudDsJCS8qIG51bWJlciBvZiBlbnRyaWVzIGluIGluZGV4IHRhYmxlICovCiAgICB1bnNpZ25lZCBsb25nCXRleHRvZmY7CS8qIG9mZnNldCBvZiB0ZXh0IHBhcnQgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGV4dHNpemU7CS8qIGJ5dGUgc2l6ZSBvZiB0ZXh0IHBhcnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWhhc2hzaXplOwkvKiBoYXNoIHNpemUgKi8KICAgIHVuc2lnbmVkIHNob3J0CWZyZWVpZHg7CS8qIGZyZWUgaW5kZXggKi8KfTsKCi8qIGdlbmVyaWMgZm9ybWF0IG9mIHRhYmxlIGVudHJpZXMgKi8Kc3RydWN0IF93MzFfdGFiZW50IHsKICAgIHVuc2lnbmVkIHNob3J0IHcwLCB3MSwgdzIsIHczOwp9OwoKLyogZGlyZWN0b3J5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfZGlyZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CXNpYmxpbmdfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBzaWJsaW5nIGRpcmVudCAqLwogICAgdW5zaWduZWQgc2hvcnQJY2hpbGRfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBjaGlsZCBkaXJlbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWtleV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGtleSBrZXllbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CXZhbHVlX2lkeDsJLyogdGFibGUgaW5kZXggb2YgdmFsdWUgdmFsZW50ICovCn07CgovKiBrZXkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9rZXllbnQgewogICAgdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHZhbHVlIHRhYmVudDogKi8Kc3RydWN0IF93MzFfdmFsZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwogICAgdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiByZWN1cnNpdmUgaGVscGVyIGZ1bmN0aW9uIHRvIGRpc3BsYXkgYSBkaXJlY3RvcnkgdHJlZSAgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfdzMxX2R1bXB0cmVlKHVuc2lnbmVkIHNob3J0IGlkeCwgdW5zaWduZWQgY2hhciAqdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBfdzMxX3RhYmVudCAqdGFiLCBzdHJ1Y3QgX3czMV9oZWFkZXIgKmhlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgSEtFWSBoa2V5LCBVTE9ORyBsYXN0bW9kaWZpZWQsIGludCBsZXZlbCkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIGNsYXNzZXNXW10gPSB7Jy4nLCdjJywnbCcsJ2EnLCdzJywncycsJ2UnLCdzJywwfTsKICAgIHN0cnVjdCBfdzMxX2RpcmVudCAqZGlyOwogICAgc3RydWN0IF93MzFfa2V5ZW50ICprZXk7CiAgICBzdHJ1Y3QgX3czMV92YWxlbnQgKnZhbDsKICAgIEhLRVkgc3Via2V5ID0gMDsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVywgdmFsdWVXOwogICAgc3RhdGljIFdDSEFSIHRhaWxbNDAwXTsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IGhrZXk7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZ2YWx1ZVcsIE5VTEwgKTsKCiAgICB3aGlsZSAoaWR4IT0wKSB7CiAgICAgICAgZGlyPShzdHJ1Y3QgX3czMV9kaXJlbnQqKSZ0YWJbaWR4XTsKCiAgICAgICAgaWYgKGRpci0+a2V5X2lkeCkgewogICAgICAgICAgICBEV09SRCBsZW47CiAgICAgICAgICAgIGtleSA9IChzdHJ1Y3QgX3czMV9rZXllbnQqKSZ0YWJbZGlyLT5rZXlfaWR4XTsKCiAgICAgICAgICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4oIHRhaWwsIHNpemVvZih0YWlsKS1zaXplb2YoV0NIQVIpLCAmbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdHh0W2tleS0+c3RyaW5nX29mZl0sIGtleS0+bGVuZ3RoKTsKICAgICAgICAgICAgdGFpbFtsZW4vc2l6ZW9mKFdDSEFSKV0gPSAwOwoKICAgICAgICAgICAgLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZQogICAgICAgICAgICAgKiB0b3BsZXZlbCBzdWJkaXJlY3RvcnkgYmVsb25nIHRvIFxTT0ZUV0FSRVxDbGFzc2VzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoIWxldmVsICYmICFzdHJjbXBXKHRhaWwsY2xhc3Nlc1cpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxoa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKICAgICAgICAgICAgICAgIGlkeD1kaXItPnNpYmxpbmdfaWR4OwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChzdWJrZXkpIE50Q2xvc2UoIHN1YmtleSApOwogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCB0YWlsICk7CiAgICAgICAgICAgIGlmIChOdENyZWF0ZUtleSggJnN1YmtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpIHN1YmtleSA9IDA7CgogICAgICAgICAgICAvKiBvbmx5IGFkZCBpZiBsZWFmIG5vZGUgb3IgdmFsdWVkIG5vZGUgKi8KICAgICAgICAgICAgaWYgKGRpci0+dmFsdWVfaWR4IT0wfHxkaXItPmNoaWxkX2lkeD09MCkgewogICAgICAgICAgICAgICAgaWYgKGRpci0+dmFsdWVfaWR4KSB7CiAgICAgICAgICAgICAgICAgICAgRFdPUkQgbGVuOwogICAgICAgICAgICAgICAgICAgIHZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKICAgICAgICAgICAgICAgICAgICBSdGxNdWx0aUJ5dGVUb1VuaWNvZGVOKCB0YWlsLCBzaXplb2YodGFpbCkgLSBzaXplb2YoV0NIQVIpLCAmbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0eHRbdmFsLT5zdHJpbmdfb2ZmXSwgdmFsLT5sZW5ndGgpOwogICAgICAgICAgICAgICAgICAgIHRhaWxbbGVuL3NpemVvZihXQ0hBUildID0gMDsKICAgICAgICAgICAgICAgICAgICBOdFNldFZhbHVlS2V5KCBzdWJrZXksICZ2YWx1ZVcsIDAsIFJFR19TWiwgdGFpbCwgbGVuICsgc2l6ZW9mKFdDSEFSKSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIFRSQUNFKCJzdHJhbmdlOiBubyBkaXJlY3Rvcnkga2V5IG5hbWUsIGlkeD0lMDR4XG4iLCBpZHgpOwogICAgICAgIF93MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHN1YmtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CiAgICAgICAgaWR4PWRpci0+c2libGluZ19pZHg7CiAgICB9CiAgICBpZiAoc3Via2V5KSBOdENsb3NlKCBzdWJrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3czMV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93MzFfbG9hZHJlZyh2b2lkKQp7CiAgICBIQU5ETEUgICAgICAgICAgICAgICAgICAgICAgaGY7CiAgICBIS0VZICAgICAgICAgICAgICAgICAgICAgICAgcm9vdDsKICAgIE9CSkVDVF9BVFRSSUJVVEVTICAgICAgICAgICBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgICAgICAgICAgICAgIG5hbWVXOwogICAgc3RydWN0IF93MzFfaGVhZGVyICAgICAgICAgIGhlYWQ7CiAgICBzdHJ1Y3QgX3czMV90YWJlbnQqICAgICAgICAgdGFiID0gTlVMTDsKICAgIHVuc2lnbmVkIGNoYXIqICAgICAgICAgICAgICB0eHQgPSBOVUxMOwogICAgdW5zaWduZWQgaW50CQlsZW47CiAgICBPRlNUUlVDVAkJICAgICAgICBvZnM7CiAgICBVTE9ORwkJCWxhc3Rtb2RpZmllZDsKICAgIE5UU1RBVFVTICAgICAgICAgICAgICAgICAgICBzdGF0dXM7CiAgICBJT19TVEFUVVNfQkxPQ0sgICAgICAgICAgICAgaW9zYjsKICAgIEZJTEVfUE9TSVRJT05fSU5GT1JNQVRJT04gICBmcGk7CiAgICBGSUxFX0JBU0lDX0lORk9STUFUSU9OICAgICAgZmJpOwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGhmID0gKEhBTkRMRSlPcGVuRmlsZSgicmVnLmRhdCIsJm9mcyxPRl9SRUFEKTsKICAgIGlmIChoZj09KEhBTkRMRSlIRklMRV9FUlJPUikgcmV0dXJuOwoKICAgIC8qIHJlYWQgJiBkdW1wIGhlYWRlciAqLwogICAgaWYgKE50UmVhZEZpbGUoaGYsIDAsIE5VTEwsIE5VTEwsICZpb3NiLCAKICAgICAgICAgICAgICAgICAgICZoZWFkLCBzaXplb2YoaGVhZCksIE5VTEwsIE5VTEwpICE9IFNUQVRVU19TVUNDRVNTIHx8CiAgICAgICAgaW9zYi5JbmZvcm1hdGlvbiAhPSBzaXplb2YoaGVhZCkpCiAgICB7CiAgICAgICAgRVJSKCJyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwogICAgICAgIGdvdG8gZG9uZTsKICAgIH0KICAgIGlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpICE9IDApCiAgICB7CiAgICAgICAgRVJSKCJyZWcuZGF0IGhhcyBiYWQgc2lnbmF0dXJlLlxuIik7CiAgICAgICAgZ290byBkb25lOwogICAgfQoKICAgIGxlbiA9IGhlYWQudGFiY250ICogc2l6ZW9mKHN0cnVjdCBfdzMxX3RhYmVudCk7CiAgICAvKiByZWFkIGFuZCBkdW1wIGluZGV4IHRhYmxlICovCiAgICB0YWIgPSBfeG1hbGxvYyhsZW4pOwogICAgaWYgKE50UmVhZEZpbGUoaGYsIDAsIE5VTEwsIE5VTEwsICZpb3NiLAogICAgICAgICAgICAgICAgICAgdGFiLCBsZW4sIE5VTEwsIE5VTEwpICE9IFNUQVRVU19TVUNDRVNTIHx8CiAgICAgICAgaW9zYi5JbmZvcm1hdGlvbiAhPSBsZW4pIAogICAgewogICAgICAgIEVSUigiY291bGRuJ3QgcmVhZCBpbmRleCB0YWJsZSAoJWQgYnl0ZXMpLlxuIixsZW4pOwogICAgICAgIGdvdG8gZG9uZTsKICAgIH0KCiAgICAvKiByZWFkIHRleHQgKi8KICAgIHR4dCA9IF94bWFsbG9jKGhlYWQudGV4dHNpemUpOwogICAgZnBpLkN1cnJlbnRCeXRlT2Zmc2V0LnMuTG93UGFydCA9IGhlYWQudGV4dG9mZjsKICAgIGZwaS5DdXJyZW50Qnl0ZU9mZnNldC5zLkhpZ2hQYXJ0ID0gMDsKICAgIGlmIChOdFNldEluZm9ybWF0aW9uRmlsZShoZiwgJmlvc2IsICZmcGksIHNpemVvZihmcGkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlUG9zaXRpb25JbmZvcm1hdGlvbikgIT0gU1RBVFVTX1NVQ0NFU1MpCiAgICB7CiAgICAgICAgRVJSKCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOwogICAgICAgIGdvdG8gZG9uZTsKICAgIH0KICAgIHN0YXR1cyA9IE50UmVhZEZpbGUoaGYsIDAsIE5VTEwsIE5VTEwsICZpb3NiLCB0eHQsIGhlYWQudGV4dHNpemUsIE5VTEwsIE5VTEwpOwogICAgaWYgKCEoc3RhdHVzID09IFNUQVRVU19TVUNDRVNTIHx8IHN0YXR1cyA9PSBTVEFUVVNfRU5EX09GX0ZJTEUpIHx8CiAgICAgICAgaW9zYi5JbmZvcm1hdGlvbiAhPSBoZWFkLnRleHRzaXplKQogICAgewogICAgICAgIEVSUigidGV4dGJsb2NrIHRvbyBzaG9ydCAoJWQgaW5zdGVhZCBvZiAlbGQpLlxuIiwgbGVuLCBoZWFkLnRleHRzaXplKTsKICAgICAgICBnb3RvIGRvbmU7CiAgICB9CiAgICBpZiAoTnRRdWVyeUluZm9ybWF0aW9uRmlsZShoZiwgJmlvc2IsICZmYmksIHNpemVvZihmYmkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZUJhc2ljSW5mb3JtYXRpb24pICE9IFNUQVRVU19TVUNDRVNTKQogICAgewogICAgICAgIEVSUigiQ291bGRuJ3QgZ2V0IGJhc2ljIGluZm9ybWF0aW9uLlxuIik7CiAgICAgICAgZ290byBkb25lOwogICAgfQogICAgUnRsVGltZVRvU2Vjb25kc1NpbmNlMTk3MCgmZmJpLkxhc3RXcml0ZVRpbWUsICZsYXN0bW9kaWZpZWQpOwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBDbGFzc2VzUm9vdFcgKTsKCiAgICBpZiAoIU50Q3JlYXRlS2V5KCAmcm9vdCwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICB7CiAgICAgICAgX3czMV9kdW1wdHJlZSh0YWJbMF0udzEsdHh0LHRhYiwmaGVhZCxyb290LGxhc3Rtb2RpZmllZCwwKTsKICAgICAgICBOdENsb3NlKCByb290ICk7CiAgICB9CiBkb25lOgogICAgaWYgKHRhYikgZnJlZSh0YWIpOwogICAgaWYgKHR4dCkgZnJlZSh0eHQpOwogICAgTnRDbG9zZShoZik7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dzIDk1IHJlZ2lzdHJ5IGxvYWRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBTRUNUSU9OIDE6IG1haW4gaGVhZGVyCiAqCiAqIG9uY2UgYXQgb2Zmc2V0IDAKICovCiNkZWZpbmUJVzk1X1JFR19DUkVHX0lECTB4NDc0NTUyNDMKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogIkNSRUciID0gVzk1X1JFR19DUkVHX0lEICovCiAgICBEV09SRAl2ZXJzaW9uOwkvKiA/Pz8/IDB4MDAwMTAwMDAgKi8KICAgIERXT1JECXJnZGJfb2ZmOwkvKiAweDA4IE9mZnNldCBvZiAxc3QgUkdEQi1ibG9jayAqLwogICAgRFdPUkQJdWsyOwkJLyogMHgwYyAqLwogICAgV09SRAlyZ2RiX251bTsJLyogMHgxMCAjIG9mIFJHREItYmxvY2tzICovCiAgICBXT1JECXVrMzsKICAgIERXT1JECXVrWzNdOwogICAgLyogcmdrbiAqLwp9IF93OTVjcmVnOwoKLyogU0VDVElPTiAyOiBEaXJlY3RvcnkgaW5mb3JtYXRpb24gKHRyZWUgc3RydWN0dXJlKQogKgogKiBvbmNlIG9uIG9mZnNldCAweDIwCiAqCiAqIHN0cnVjdHVyZTogW3Jna25dW2RrZV0qCShyZXBlYXQgdGlsbCBsYXN0X2RrZSBpcyByZWFjaGVkKQogKi8KI2RlZmluZQlXOTVfUkVHX1JHS05fSUQJMHg0ZTRiNDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiJSR0tOIiA9IFc5NV9SRUdfUkdLTl9JRCAqLwogICAgRFdPUkQJc2l6ZTsJCS8qIFNpemUgb2YgdGhlIFJHS04tYmxvY2sgKi8KICAgIERXT1JECXJvb3Rfb2ZmOwkvKiBSZWwuIE9mZnNldCBvZiB0aGUgcm9vdC1yZWNvcmQgKi8KICAgIERXT1JEICAgbGFzdF9ka2U7ICAgICAgIC8qIE9mZnNldCB0byBsYXN0IERLRSA/ICovCiAgICBEV09SRAl1a1s0XTsKfSBfdzk1cmdrbjsKCi8qIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZQogKgogKiB0aGUgMXN0IGVudHJ5IGluIGEgInVzdWFsIiByZWdpc3RyeSBmaWxlIGlzIGEgbnVsLWVudHJ5IHdpdGggc3Via2V5czogdGhlCiAqIGhpdmUgaXRzZWxmLiBJdCBsb29rcyB0aGUgc2FtZSBsaWtlIG90aGVyIGtleXMuIEV2ZW4gdGhlIElELW51bWJlciBjYW4KICogYmUgYW55IHZhbHVlLgogKgogKiBUaGUgImhhc2giLXZhbHVlIGlzIGEgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBrZXkncyBuYW1lLiBXaW5kb3dzIHdpbGwgbm90CiAqIHNlYXJjaCBmb3IgdGhlIG5hbWUsIGJ1dCBmb3IgYSBtYXRjaGluZyBoYXNoLXZhbHVlLiBpZiBpdCBmaW5kcyBvbmUsIGl0CiAqIHdpbGwgY29tcGFyZSB0aGUgYWN0dWFsIHN0cmluZyBpbmZvLCBvdGhlcndpc2UgY29udGludWUgd2l0aCB0aGUgbmV4dCBrZXkuCiAqIFRvIGNhbGN1bGF0ZSB0aGUgaGFzaCBpbml0aWFsaXplIGEgRC1Xb3JkIHdpdGggMCBhbmQgYWRkIGFsbCBBU0NJSS12YWx1ZXMKICogb2YgdGhlIHN0cmluZyB3aGljaCBhcmUgc21hbGxlciB0aGFuIDB4ODAgKDEyOCkgdG8gdGhpcyBELVdvcmQuCiAqCiAqIElmIHlvdSB3YW50IHRvIG1vZGlmeSBrZXkgbmFtZXMsIGFsc28gbW9kaWZ5IHRoZSBoYXNoLXZhbHVlcywgc2luY2UgdGhleQogKiBjYW5ub3QgYmUgZm91bmQgYWdhaW4gKGFsdGhvdWdoIHRoZXkgd291bGQgYmUgZGlzcGxheWVkIGluIFJFR0VESVQpCiAqIEVuZCBvZiBsaXN0LXBvaW50ZXJzIGFyZSBmaWxsZWQgd2l0aCAweEZGRkZGRkZGCiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuck1TIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKgogKiBUaGUgbGFzdCBES0UgKHNlZSBmaWVsZCBsYXN0X2RrZSBpbiBfdzk1X3Jna24pIGhhcyBvbmx5IDMgRFdPUkRzIHdpdGgKICogMHg4MDAwMDAwMCAoRU9MIGluZGljYXRvciA/KSBhcyB4MSwgdGhlIGhhc2ggdmFsdWUgYW5kIDB4RkZGRkZGRkYgYXMgeDMuCiAqIFRoZSByZW1haW5pbmcgc3BhY2UgYmV0d2VlbiBsYXN0X2RrZSBhbmQgdGhlIG9mZnNldCBjYWxjdWxhdGVkIGZyb20KICogcmdrbi0+c2l6ZSBzZWVtcyB0byBiZSBmcmVlIGZvciB1c2UgZm9yIG1vcmUgZGtlOnMuCiAqIFNvIGl0IHNlZW1zIGlmIG1vcmUgZGtlOnMgYXJlIGFkZGVkLCB0aGV5IGFyZSBhZGRlZCB0byB0aGF0IHNwYWNlIGFuZAogKiBsYXN0X2RrZSBpcyBncm93biwgYW5kIGluIGNhc2UgdGhhdCAiZnJlZSIgc3BhY2UgaXMgb3V0LCB0aGUgc3BhY2UKICogZ2V0cyBncm93biBhbmQgcmdrbi0+c2l6ZSBnZXRzIGFkanVzdGVkLgogKgogKiB0aGVyZSBpcyBhIG9uZSB0byBvbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gZGtlIGFuZCBka2gKICovCiAvKiBrZXkgc3RydWN0LCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJeDE7CQkvKiBGcmVlIGVudHJ5IGluZGljYXRvcig/KSAqLwogICAgRFdPUkQJaGFzaDsJCS8qIHN1bSBvZiBieXRlcyBvZiBrZXluYW1lICovCiAgICBEV09SRAl4MzsJCS8qIFJvb3Qga2V5IGluZGljYXRvcj8gdXN1YWxseSAweEZGRkZGRkZGICovCiAgICBEV09SRAlwcmV2bHZsOwkvKiBvZmZzZXQgb2YgcHJldmlvdXMga2V5ICovCiAgICBEV09SRAluZXh0c3ViOwkvKiBvZmZzZXQgb2YgY2hpbGQga2V5ICovCiAgICBEV09SRAluZXh0OwkJLyogb2Zmc2V0IG9mIHNpYmxpbmcga2V5ICovCiAgICBXT1JECW5yTFM7CQkvKiBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KICAgIFdPUkQJbnJNUzsJCS8qIG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwp9IF93OTVka2U7CgovKiBTRUNUSU9OIDM6IGtleSBpbmZvcm1hdGlvbiwgdmFsdWVzIGFuZCBkYXRhCiAqCiAqIHN0cnVjdHVyZToKICogIHNlY3Rpb246CVtibG9ja3NdKgkJKHJlcGVhdCBjcmVnLT5yZ2RiX251bSB0aW1lcykKICogIGJsb2NrczoJW3JnZGJdIFtzdWJibG9ja3NdKiAJKHJlcGVhdCB0aWxsIGJsb2NrIHNpemUgcmVhY2hlZCApCiAqICBzdWJibG9ja3M6CVtka2hdIFtka3ZdKgkJKHJlcGVhdCBka2gtPnZhbHVlcyB0aW1lcyApCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgRFdPUkQgdmFsdWUKICogYXQgb2Zmc2V0IDB4MTAgZXF1YWxzIHRoZSBvbmUgYXQgb2Zmc2V0IDB4MDQgbWludXMgdGhlIG9uZSBhdCBvZmZzZXQgMHgwOC4KICogSSBoYXZlIG5vIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKi8KCi8qIGJsb2NrIGhlYWRlciwgb25jZSBwZXIgYmxvY2sgKi8KI2RlZmluZSBXOTVfUkVHX1JHREJfSUQJMHg0MjQ0NDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CS8qIDB4MDAgJ1JHREInID0gVzk1X1JFR19SR0RCX0lEICovCiAgICBEV09SRAlzaXplOwkvKiAweDA0ICovCiAgICBEV09SRAl1azE7CS8qIDB4MDggKi8KICAgIERXT1JECXVrMjsJLyogMHgwYyAqLwogICAgRFdPUkQJdWszOwkvKiAweDEwICovCiAgICBEV09SRAl1azQ7CS8qIDB4MTQgKi8KICAgIERXT1JECXVrNTsJLyogMHgxOCAqLwogICAgRFdPUkQJdWs2OwkvKiAweDFjICovCiAgICAvKiBka2ggKi8KfSBfdzk1cmdkYjsKCi8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCksIG9uY2UgcGVyIGtleSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAluZXh0a2V5b2ZmOyAJLyogMHgwMCBvZmZzZXQgdG8gbmV4dCBka2ggKi8KICAgIFdPUkQJbnJMUzsJCS8qIDB4MDQgaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCiAgICBXT1JECW5yTVM7CQkvKiAweDA2IG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwogICAgRFdPUkQJYnl0ZXN1c2VkOwkvKiAweDA4ICovCiAgICBXT1JECWtleW5hbWVsZW47CS8qIDB4MGMgbGVuIG9mIG5hbWUgKi8KICAgIFdPUkQJdmFsdWVzOwkJLyogMHgwZSBudW1iZXIgb2YgdmFsdWVzICovCiAgICBEV09SRAl4eDE7CQkvKiAweDEwICovCiAgICBjaGFyCW5hbWVbMV07CS8qIDB4MTQgKi8KICAgIC8qIGRrdiAqLwkJLyogMHgxNCArIGtleW5hbWVsZW4gKi8KfSBfdzk1ZGtoOwoKLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlLCBvbmNlIHBlciB2YWx1ZSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAl0eXBlOwkJLyogMHgwMCAqLwogICAgRFdPUkQJeDE7CQkvKiAweDA0ICovCiAgICBXT1JECXZhbG5hbWVsZW47CS8qIDB4MDggbGVuZ3RoIG9mIG5hbWUsIDAgaXMgZGVmYXVsdCBrZXkgKi8KICAgIFdPUkQJdmFsZGF0YWxlbjsJLyogMHgwQSBsZW5ndGggb2YgZGF0YSAqLwogICAgY2hhcgluYW1lWzFdOwkvKiAweDBjICovCiAgICAvKiByYXcgZGF0YSAqLwkJLyogMHgwYyArIHZhbG5hbWVsZW4gKi8KfSBfdzk1ZGt2OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvb2t1cF9ka2ggW0ludGVybmFsXQogKgogKiBzZWVrcyB0aGUgZGtoIGJlbG9uZ2luZyB0byBhIGRrZQogKi8Kc3RhdGljIF93OTVka2ggKl93OTVfbG9va3VwX2RraChfdzk1Y3JlZyAqY3JlZyxpbnQgbnJMUyxpbnQgbnJNUykKewogICAgX3c5NXJnZGIgKiByZ2RiOwogICAgX3c5NWRraCAqIGRraDsKICAgIGludCBpOwoKICAgIC8qIGdldCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZ2RiIGRhdGFzdG9yZSAqLwogICAgcmdkYiA9IChfdzk1cmdkYiopKChjaGFyKiljcmVnK2NyZWctPnJnZGJfb2ZmKTsKCiAgICAvKiBjaGVjazogcmVxdWVzdGVkIGJsb2NrIDwgbGFzdF9ibG9jaykgKi8KICAgIGlmIChjcmVnLT5yZ2RiX251bSA8PSBuck1TKSB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJlcXVlc3RlZCBibG9jayBuby4gYmV5b25kIGVuZC5cbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogZmluZCB0aGUgcmlnaHQgYmxvY2sgKi8KICAgIGZvcihpPTA7IGk8bnJNUyA7aSsrKSB7CiAgICAgICAgaWYocmdkYi0+aWQgIT0gVzk1X1JFR19SR0RCX0lEKSB7ICAvKiBjaGVjayB0aGUgbWFnaWMgKi8KICAgICAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGJhZCBtYWdpYyAweCUwOGx4XG4iLCByZ2RiLT5pZCk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIHJnZGIgPSAoX3c5NXJnZGIqKSAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSk7CQkvKiBmaW5kIG5leHQgYmxvY2sgKi8KICAgIH0KCiAgICBka2ggPSAoX3c5NWRraCopKHJnZGIgKyAxKTsJCQkJLyogZmlyc3Qgc3ViIGJsb2NrIHdpdGhpbiB0aGUgcmdkYiAqLwoKICAgIGRvIHsKICAgICAgICBpZihuckxTPT1ka2gtPm5yTFMgKSByZXR1cm4gZGtoOwogICAgICAgIGRraCA9IChfdzk1ZGtoKikoKGNoYXIqKWRraCArIGRraC0+bmV4dGtleW9mZik7CS8qIGZpbmQgbmV4dCBzdWJibG9jayAqLwogICAgfSB3aGlsZSAoKGNoYXIgKilka2ggPCAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSkpOwoKZXJyb3I6CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2R1bXBfZGt2IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9kdW1wX2Rrdihfdzk1ZGtoICpka2gsaW50IG5yTFMsaW50IG5yTVMsRklMRSAqZikKewogICAgX3c5NWRrdiAqIGRrdjsKICAgIGludCBpOwoKICAgIC8qIGZpcnN0IHZhbHVlIGJsb2NrICovCiAgICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka2grZGtoLT5rZXluYW1lbGVuKzB4MTQpOwoKICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUgdmFsdWVzICovCiAgICBmb3IgKGk9MDsgaTwgZGtoLT52YWx1ZXM7IGkrKykgewogICAgICAgIHN0cnVjdCBrZXlfdmFsdWUgdmFsdWU7CiAgICAgICAgV0NIQVIgKnBkYXRhOwoKICAgICAgICB2YWx1ZS5uYW1lVyA9IF9zdHJkdXBuQXRvVyhka3YtPm5hbWUsZGt2LT52YWxuYW1lbGVuKTsKICAgICAgICB2YWx1ZS50eXBlID0gZGt2LT50eXBlOwogICAgICAgIHZhbHVlLmxlbiA9IGRrdi0+dmFsZGF0YWxlbjsKCiAgICAgICAgdmFsdWUuZGF0YSA9ICYoZGt2LT5uYW1lW2Rrdi0+dmFsbmFtZWxlbl0pOwogICAgICAgIHBkYXRhID0gTlVMTDsKICAgICAgICBpZiAoICh2YWx1ZS50eXBlPT1SRUdfU1opIHx8ICh2YWx1ZS50eXBlPT1SRUdfRVhQQU5EX1NaKSB8fCAodmFsdWUudHlwZT09UkVHX01VTFRJX1NaKSApIHsKICAgICAgICAgICAgcGRhdGEgPSBfc3RyZHVwbkF0b1codmFsdWUuZGF0YSx2YWx1ZS5sZW4pOwogICAgICAgICAgICB2YWx1ZS5sZW4gKj0gMjsKICAgICAgICB9CiAgICAgICAgaWYgKHBkYXRhICE9IE5VTEwpIHZhbHVlLmRhdGEgPSBwZGF0YTsKCiAgICAgICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgICAgIGZyZWUodmFsdWUubmFtZVcpOwogICAgICAgIGlmIChwZGF0YSAhPSBOVUxMKSBmcmVlKHBkYXRhKTsKCiAgICAgICAgLyogbmV4dCB2YWx1ZSAqLwogICAgICAgIGRrdiA9IChfdzk1ZGt2KikoKGNoYXIqKWRrditka3YtPnZhbG5hbWVsZW4rZGt2LT52YWxkYXRhbGVuKzB4MGMpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9kdW1wX2RrZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfZHVtcF9ka2UoTFBDU1RSIGtleV9uYW1lLF93OTVjcmVnICpjcmVnLF93OTVyZ2tuICpyZ2tuLF93OTVka2UgKmRrZSxGSUxFICpmLGludCBsZXZlbCkKewogICAgX3c5NWRraCAqIGRraDsKICAgIExQU1RSIG5ld19rZXlfbmFtZSA9IE5VTEw7CgogICAgLyogc3BlY2lhbCByb290IGtleSAqLwogICAgaWYgKGRrZS0+bnJMUyA9PSAweGZmZmYgfHwgZGtlLT5uck1TPT0weGZmZmYpCQkvKiBlZy4gdGhlIHJvb3Qga2V5IGhhcyBubyBuYW1lICovCiAgICB7CiAgICAgICAgLyogcGFyc2UgdGhlIG9uZSBzdWJrZXkgKi8KICAgICAgICBpZiAoZGtlLT5uZXh0c3ViICE9IDB4ZmZmZmZmZmYpIHJldHVybiBfdzk1X2R1bXBfZGtlKGtleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dHN1YiksZixsZXZlbCk7CiAgICAgICAgLyogaGFzIG5vIHNpYmxpbmcga2V5cyAqLwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiBzZWFyY2ggc3ViYmxvY2sgKi8KICAgIGlmICghKGRraCA9IF93OTVfbG9va3VwX2RraChjcmVnLCBka2UtPm5yTFMsIGRrZS0+bnJNUykpKSB7CiAgICAgICAgRVJSKCJka2UgcG9pbnRpbmcgdG8gbWlzc2luZyBka2ggIVxuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChsZXZlbCA8PSAwKSB7CiAgICAgICAgLyogY3JlYXRlIG5ldyBzdWJrZXkgbmFtZSAqLwogICAgICAgIHNpemVfdCBsZW4gPSBzdHJsZW4oa2V5X25hbWUpOwogICAgICAgIG5ld19rZXlfbmFtZSA9IF94bWFsbG9jKGxlbitka2gtPmtleW5hbWVsZW4rMik7CiAgICAgICAgbWVtY3B5KCBuZXdfa2V5X25hbWUsIGtleV9uYW1lLCBsZW4gKTsKICAgICAgICBpZiAobGVuKSBuZXdfa2V5X25hbWVbbGVuKytdID0gJ1xcJzsKICAgICAgICBtZW1jcHkoIG5ld19rZXlfbmFtZSArIGxlbiwgZGtoLT5uYW1lLCBka2gtPmtleW5hbWVsZW4gKTsKICAgICAgICBuZXdfa2V5X25hbWVbbGVuICsgZGtoLT5rZXluYW1lbGVuXSA9IDA7CgogICAgICAgIC8qIHdhbGsgc2libGluZyBrZXlzICovCiAgICAgICAgaWYgKGRrZS0+bmV4dCAhPSAweGZmZmZmZmZmICkgewogICAgICAgICAgICBpZiAoIV93OTVfZHVtcF9ka2Uoa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0KSxmLGxldmVsKSkgewogICAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiB3cml0ZSB0aGUga2V5IHBhdGggKHNvbWV0aGluZyBsaWtlIFtTb2Z0d2FyZVxcTWljcm9zb2Z0XFwuLl0pIG9ubHkgaWY6CiAgICAgICAgICAgMSkga2V5IGhhcyBzb21lIHZhbHVlcwogICAgICAgICAgIDIpIGtleSBoYXMgbm8gdmFsdWVzIGFuZCBubyBzdWJrZXlzCiAgICAgICAgKi8KICAgICAgICBpZiAoZGtoLT52YWx1ZXMgPiAwKSB7CiAgICAgICAgICAgIC8qIHRoZXJlIGFyZSBzb21lIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgICAgICBpZiAoIV93OTVfZHVtcF9ka3YoZGtoLCBka2UtPm5yTFMsIGRrZS0+bnJNUyxmKSkgewogICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKChka2UtPm5leHRzdWIgPT0gMHhmZmZmZmZmZikgJiYgKGRraC0+dmFsdWVzID09IDApKSB7CiAgICAgICAgICAgIC8qIG5vIHN1YmtleXMgYW5kIG5vIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KICAgIH0gZWxzZSBuZXdfa2V5X25hbWUgPSBfeHN0cmR1cChrZXlfbmFtZSk7CgogICAgLyogbmV4dCBzdWIga2V5ICovCiAgICBpZiAoZGtlLT5uZXh0c3ViICE9IDB4ZmZmZmZmZmYpIHsKICAgICAgICBpZiAoIV93OTVfZHVtcF9ka2UobmV3X2tleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dHN1YiksZixsZXZlbC0xKSkgewogICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICByZXR1cm4gVFJVRTsKfQovKiBlbmQgd2luZG93cyA5NSBsb2FkZXIgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dzIE5UIHJlZ2lzdHJ5IGxvYWRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBOVCBSRUdJU1RSWSBMT0FERVIgKi8KCiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKCiNpZm5kZWYgTUFQX0ZBSUxFRAojZGVmaW5lIE1BUF9GQUlMRUQgKChMUFZPSUQpLTEpCiNlbmRpZgoKI2RlZmluZSBOVF9SRUdfQkxPQ0tfU0laRSAgICAgICAgICAgIDB4MTAwMAoKI2RlZmluZSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEICAgICAgIDB4NjY2NzY1NzIJLyogcmVnZiAqLwojZGVmaW5lIE5UX1JFR19QT09MX0JMT0NLX0lEICAgICAgICAgMHg2RTY5NjI2OAkvKiBoYmluICovCiNkZWZpbmUgTlRfUkVHX0tFWV9CTE9DS19JRCAgICAgICAgICAweDZiNmUgLyogbmsgKi8KI2RlZmluZSBOVF9SRUdfVkFMVUVfQkxPQ0tfSUQgICAgICAgIDB4NmI3NiAvKiB2ayAqLwoKLyogc3ViYmxvY2tzIG9mIG5rICovCiNkZWZpbmUgTlRfUkVHX0hBU0hfQkxPQ0tfSUQgICAgICAgICAweDY2NmMgLyogbGYgKi8KI2RlZmluZSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEICAgICAgIDB4Njk2YyAvKiBsaSAqLwojZGVmaW5lIE5UX1JFR19SSV9CTE9DS19JRAkgICAgIDB4Njk3MiAvKiByaSAqLwoKI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX1RZUEUgICAgICAgIDB4MjAKI2RlZmluZSBOVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSAgIDB4MmMKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogMHg2NjY3NjU3MiAncmVnZicqLwogICAgRFdPUkQJdWsxOwkJLyogMHgwNCAqLwogICAgRFdPUkQJdWsyOwkJLyogMHgwOCAqLwogICAgRklMRVRJTUUJRGF0ZU1vZGlmaWVkOwkvKiAweDBjICovCiAgICBEV09SRAl1azM7CQkvKiAweDE0ICovCiAgICBEV09SRAl1azQ7CQkvKiAweDE4ICovCiAgICBEV09SRAl1azU7CQkvKiAweDFjICovCiAgICBEV09SRAl1azY7CQkvKiAweDIwICovCiAgICBEV09SRAlSb290S2V5QmxvY2s7CS8qIDB4MjQgKi8KICAgIERXT1JECUJsb2NrU2l6ZTsJLyogMHgyOCAqLwogICAgRFdPUkQgICB1azdbMTE2XTsKICAgIERXT1JECUNoZWNrc3VtOyAvKiBhdCBvZmZzZXQgMHgxRkMgKi8KfSBudF9yZWdmOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJYmxvY2tzaXplOwogICAgQllURQlkYXRhWzFdOwp9IG50X2hiaW5fc3ViOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiAweDZFNjk2MjY4ICdoYmluJyAqLwogICAgRFdPUkQJb2ZmX3ByZXY7CiAgICBEV09SRAlvZmZfbmV4dDsKICAgIERXT1JECXVrMTsKICAgIERXT1JECXVrMjsJCS8qIDB4MTAgKi8KICAgIERXT1JECXVrMzsJCS8qIDB4MTQgKi8KICAgIERXT1JECXVrNDsJCS8qIDB4MTggKi8KICAgIERXT1JECXNpemU7CQkvKiAweDFDICovCiAgICBudF9oYmluX3N1YgloYmluX3N1YjsJLyogMHgyMCAqLwp9IG50X2hiaW47CgovKgogKiB0aGUgdmFsdWVfbGlzdCBjb25zaXN0cyBvZiBvZmZzZXRzIHRvIHRoZSB2YWx1ZXMgKHZrKQogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlTdWJCbG9ja0lkOwkJLyogMHgwMCAweDZCNkUgKi8KICAgIFdPUkQJVHlwZTsJCQkvKiAweDAyIGZvciB0aGUgcm9vdC1rZXk6IDB4MkMsIG90aGVyd2lzZSAweDIwKi8KICAgIEZJTEVUSU1FCXdyaXRldGltZTsJLyogMHgwNCAqLwogICAgRFdPUkQJdWsxOwkJCS8qIDB4MEMgKi8KICAgIERXT1JECXBhcmVudF9vZmY7CQkvKiAweDEwIE9mZnNldCBvZiBPd25lci9QYXJlbnQga2V5ICovCiAgICBEV09SRAlucl9zdWJrZXlzOwkJLyogMHgxNCBudW1iZXIgb2Ygc3ViLUtleXMgKi8KICAgIERXT1JECXVrODsJCQkvKiAweDE4ICovCiAgICBEV09SRAlsZl9vZmY7CQkJLyogMHgxQyBPZmZzZXQgb2YgdGhlIHN1Yi1rZXkgbGYtUmVjb3JkcyAqLwogICAgRFdPUkQJdWsyOwkJCS8qIDB4MjAgKi8KICAgIERXT1JECW5yX3ZhbHVlczsJCS8qIDB4MjQgbnVtYmVyIG9mIHZhbHVlcyAqLwogICAgRFdPUkQJdmFsdWVsaXN0X29mZjsJCS8qIDB4MjggT2Zmc2V0IG9mIHRoZSBWYWx1ZS1MaXN0ICovCiAgICBEV09SRAlvZmZfc2s7CQkJLyogMHgyYyBPZmZzZXQgb2YgdGhlIHNrLVJlY29yZCAqLwogICAgRFdPUkQJb2ZmX2NsYXNzOwkJLyogMHgzMCBPZmZzZXQgb2YgdGhlIENsYXNzLU5hbWUgKi8KICAgIERXT1JECXVrMzsJCQkvKiAweDM0ICovCiAgICBEV09SRAl1azQ7CQkJLyogMHgzOCAqLwogICAgRFdPUkQJdWs1OwkJCS8qIDB4M2MgKi8KICAgIERXT1JECXVrNjsJCQkvKiAweDQwICovCiAgICBEV09SRAl1azc7CQkJLyogMHg0NCAqLwogICAgV09SRAluYW1lX2xlbjsJCS8qIDB4NDggbmFtZS1sZW5ndGggKi8KICAgIFdPUkQJY2xhc3NfbGVuOwkJLyogMHg0YSBjbGFzcy1uYW1lIGxlbmd0aCAqLwogICAgY2hhcgluYW1lWzFdOwkJLyogMHg0YyBrZXktbmFtZSAqLwp9IG50X25rOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJb2ZmX25rOwkvKiAweDAwICovCiAgICBEV09SRAluYW1lOwkvKiAweDA0ICovCn0gaGFzaF9yZWM7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY2NmMgKi8KICAgIFdPUkQJbnJfa2V5czsJLyogMHgwNiAqLwogICAgaGFzaF9yZWMJaGFzaF9yZWNbMV07Cn0gbnRfbGY7CgovKgogbGlzdCBvZiBzdWJrZXlzIHdpdGhvdXQgaGFzaAoKIGxpIC0tKy0tPm5rCiAgICAgIHwKICAgICAgKy0tPm5rCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY5NmMgKi8KICAgIFdPUkQJbnJfa2V5czsKICAgIERXT1JECW9mZl9ua1sxXTsKfSBudF9saTsKCi8qCiB0aGlzIGlzIGEgaW50ZXJtZWRpYXRlIG5vZGUKCiByaSAtLSstLT5saS0tKy0tPm5rCiAgICAgIHwgICAgICAgKwogICAgICB8ICAgICAgICstLT5uawogICAgICB8CiAgICAgICstLT5saS0tKy0tPm5rCiAgICAgICAgICAgICAgKwoJICAgICAgKy0tPm5rCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY5NzIgKi8KICAgIFdPUkQJbnJfbGk7CQkvKiAweDAyIG51bWJlciBvZmYgb2Zmc2V0cyAqLwogICAgRFdPUkQJb2ZmX2xpWzFdOwkvKiAweDA0IHBvaW50cyB0byBsaSAqLwp9IG50X3JpOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgJ3ZrJyAqLwogICAgV09SRAluYW1fbGVuOwogICAgRFdPUkQJZGF0YV9sZW47CiAgICBEV09SRAlkYXRhX29mZjsKICAgIERXT1JECXR5cGU7CiAgICBXT1JECWZsYWc7CiAgICBXT1JECXVrMTsKICAgIGNoYXIJbmFtZVsxXTsKfSBudF92azsKCi8qCiAqIGdldHMgYSB2YWx1ZQogKgogKiB2ay0+ZmxhZzoKICogIDAgdmFsdWUgaXMgYSBkZWZhdWx0IHZhbHVlCiAqICAxIHRoZSB2YWx1ZSBoYXMgYSBuYW1lCiAqCiAqIHZrLT5kYXRhX2xlbgogKiAgbGVuIG9mIHRoZSB3aG9sZSBkYXRhIGJsb2NrCiAqICAtIHJlZ19zeiAodW5pY29kZSkKICogICAgYnl0ZXMgaW5jbHVkaW5nIHRoZSB0ZXJtaW5hdGluZyBcMCA9IDIqKG51bWJlcl9vZl9jaGFycysxKQogKiAgLSByZWdfZHdvcmQsIHJlZ19iaW5hcnk6CiAqICAgIGlmIGhpZ2hlc3QgYml0IG9mIGRhdGFfbGVuIGlzIHNldCBkYXRhX29mZiBjb250YWlucyB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQgX250X2R1bXBfdmsoTFBTVFIga2V5X25hbWUsIGNoYXIgKmJhc2UsIG50X3ZrICp2ayxGSUxFICpmKQp7CiAgICBCWVRFICpwZGF0YSA9IChCWVRFICopKGJhc2UrdmstPmRhdGFfb2ZmKzQpOyAvKiBzdGFydCBvZiBkYXRhICovCiAgICBzdHJ1Y3Qga2V5X3ZhbHVlIHZhbHVlOwoKICAgIGlmICh2ay0+aWQgIT0gTlRfUkVHX1ZBTFVFX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmtub3duIGJsb2NrIGZvdW5kICgweCUwNHgpLCBwbGVhc2UgcmVwb3J0IVxuIiwgdmstPmlkKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgdmFsdWUubmFtZVcgPSBfc3RyZHVwbkF0b1codmstPm5hbWUsdmstPm5hbV9sZW4pOwogICAgdmFsdWUudHlwZSA9IHZrLT50eXBlOwogICAgdmFsdWUubGVuID0gKHZrLT5kYXRhX2xlbiAmIDB4N2ZmZmZmZmYpOwogICAgdmFsdWUuZGF0YSA9ICh2ay0+ZGF0YV9sZW4gJiAweDgwMDAwMDAwKSA/IChMUEJZVEUpJih2ay0+ZGF0YV9vZmYpOiBwZGF0YTsKCiAgICBfZHVtcF92YWx1ZSgmdmFsdWUsZik7CiAgICBmcmVlKHZhbHVlLm5hbWVXKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyogaXQncyBjYWxsZWQgZnJvbSBfbnRfZHVtcF9sZigpICovCnN0YXRpYyBpbnQgX250X2R1bXBfbmsoTFBDU1RSIGtleV9uYW1lLGNoYXIgKmJhc2UsbnRfbmsgKm5rLEZJTEUgKmYsaW50IGxldmVsKTsKCi8qCiAqIGdldCB0aGUgc3Via2V5cwogKgogKiB0aGlzIHN0cnVjdHVyZSBjb250YWlucyB0aGUgaGFzaCBvZiBhIGtleW5hbWUgYW5kIHBvaW50cyB0byBhbGwKICogc3Via2V5cwogKgogKiBleGNlcHRpb246IGlmIHRoZSBpZCBpcyAnaWwnIHRoZXJlIGFyZSBubyBoYXNoIHZhbHVlcyBhbmQgZXZlcnkKICogZHdvcmQgaXMgYSBvZmZzZXQKICovCnN0YXRpYyBpbnQgX250X2R1bXBfbGYoTFBDU1RSIGtleV9uYW1lLCBjaGFyICpiYXNlLCBpbnQgc3Via2V5cywgbnRfbGYgKmxmLCBGSUxFICpmLCBpbnQgbGV2ZWwpCnsKICAgIGludCBpOwoKICAgIGlmIChsZi0+aWQgPT0gTlRfUkVHX0hBU0hfQkxPQ0tfSUQpIHsKICAgICAgICBpZiAoc3Via2V5cyAhPSBsZi0+bnJfa2V5cykgZ290byBlcnJvcjE7CgogICAgICAgIGZvciAoaT0wOyBpPGxmLT5ucl9rZXlzOyBpKyspCiAgICAgICAgICAgIGlmICghX250X2R1bXBfbmsoa2V5X25hbWUsIGJhc2UsIChudF9uayopKGJhc2UrbGYtPmhhc2hfcmVjW2ldLm9mZl9uays0KSwgZiwgbGV2ZWwpKSBnb3RvIGVycm9yOwogICAgfSBlbHNlIGlmIChsZi0+aWQgPT0gTlRfUkVHX05PSEFTSF9CTE9DS19JRCkgewogICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKWxmOwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCiAgICAgICAgZm9yIChpPTA7IGk8bGktPm5yX2tleXM7IGkrKykKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9uayhrZXlfbmFtZSwgYmFzZSwgKG50X25rKikoYmFzZStsaS0+b2ZmX25rW2ldKzQpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfUklfQkxPQ0tfSUQpIHsgIC8qIHJpICovCiAgICAgICAgbnRfcmkgKiByaSA9IChudF9yaSopbGY7CiAgICAgICAgaW50IGxpX3N1YmtleXMgPSAwOwoKICAgICAgICAvKiBjb3VudCBhbGwgc3Via2V5cyAqLwogICAgICAgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKSB7CiAgICAgICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmKGxpLT5pZCAhPSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKSBnb3RvIGVycm9yMjsKICAgICAgICAgICAgbGlfc3Via2V5cyArPSBsaS0+bnJfa2V5czsKICAgICAgICB9CgogICAgICAgIC8qIGNoZWNrIG51bWJlciAqLwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpX3N1YmtleXMpIGdvdG8gZXJyb3IxOwoKICAgICAgICAvKiBsb29wIHRocm91Z2ggdGhlIGtleXMgKi8KICAgICAgICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykgewogICAgICAgICAgICBudF9saSAqbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmICghX250X2R1bXBfbGYoa2V5X25hbWUsIGJhc2UsIGxpLT5ucl9rZXlzLCAobnRfbGYqKWxpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgfSBlbHNlIGdvdG8gZXJyb3IyOwoKICAgIHJldHVybiBUUlVFOwoKZXJyb3IyOgogICAgaWYgKGxmLT5pZCA9PSAweDY4NmMpCiAgICAgICAgRklYTUUoInVua25vd24gV2luIFhQIG5vZGUgaWQgMHg2ODZjOiBkbyB3ZSBuZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBpdCA/XG4iKTsKICAgIGVsc2UKICAgICAgICBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBsZi0+aWQpOwogICAgcmV0dXJuIFRSVUU7CgplcnJvcjE6CiAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgKGluY29uc2lzdGVudCBudW1iZXIgb2Ygc3Via2V5cylcbiIpOwogICAgcmV0dXJuIEZBTFNFOwoKZXJyb3I6CiAgICBFUlIoImVycm9yIHJlYWRpbmcgbGYgYmxvY2tcbiIpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKiBfbnRfZHVtcF9uayBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX250X2R1bXBfbmsoTFBDU1RSIGtleV9uYW1lLGNoYXIgKmJhc2UsbnRfbmsgKm5rLEZJTEUgKmYsaW50IGxldmVsKQp7CiAgICB1bnNpZ25lZCBpbnQgbjsKICAgIERXT1JEICp2bDsKICAgIExQU1RSIG5ld19rZXlfbmFtZSA9IE5VTEw7CgogICAgVFJBQ0UoIiVzXG4iLCBrZXlfbmFtZSk7CgogICAgaWYgKG5rLT5TdWJCbG9ja0lkICE9IE5UX1JFR19LRVlfQkxPQ0tfSUQpIHsKICAgICAgICBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBuay0+U3ViQmxvY2tJZCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICgobmstPlR5cGUhPU5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKSAmJiAoKChudF9uayopKGJhc2UrbmstPnBhcmVudF9vZmYrNCkpLT5TdWJCbG9ja0lkICE9IE5UX1JFR19LRVlfQkxPQ0tfSUQpKSB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhXG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgLyogY3JlYXRlIHRoZSBuZXcga2V5ICovCiAgICBpZiAobGV2ZWwgPD0gMCkgewogICAgICAgIC8qIGNyZWF0ZSBuZXcgc3Via2V5IG5hbWUgKi8KICAgICAgICBzaXplX3QgbGVuID0gc3RybGVuKGtleV9uYW1lKTsKICAgICAgICBuZXdfa2V5X25hbWUgPSBfeG1hbGxvYyggbGVuK25rLT5uYW1lX2xlbisyICk7CiAgICAgICAgbWVtY3B5KCBuZXdfa2V5X25hbWUsIGtleV9uYW1lLCBsZW4gKTsKICAgICAgICBpZiAobGVuKSBuZXdfa2V5X25hbWVbbGVuKytdID0gJ1xcJzsKICAgICAgICBtZW1jcHkoIG5ld19rZXlfbmFtZSArIGxlbiwgbmstPm5hbWUsIG5rLT5uYW1lX2xlbiApOwogICAgICAgIG5ld19rZXlfbmFtZVtsZW4gKyBuay0+bmFtZV9sZW5dID0gMDsKCiAgICAgICAgLyogd3JpdGUgdGhlIGtleSBwYXRoIChzb21ldGhpbmcgbGlrZSBbU29mdHdhcmVcXE1pY3Jvc29mdFxcLi5dKSBvbmx5IGlmOgogICAgICAgICAgIDEpIGtleSBoYXMgc29tZSB2YWx1ZXMKICAgICAgICAgICAyKSBrZXkgaGFzIG5vIHZhbHVlcyBhbmQgbm8gc3Via2V5cwogICAgICAgICovCiAgICAgICAgaWYgKG5rLT5ucl92YWx1ZXMgPiAwKSB7CiAgICAgICAgICAgIC8qIHRoZXJlIGFyZSBzb21lIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KICAgICAgICBpZiAoKG5rLT5ucl9zdWJrZXlzID09IDApICYmIChuay0+bnJfdmFsdWVzID09IDApKSB7CiAgICAgICAgICAgIC8qIG5vIHN1YmtleXMgYW5kIG5vIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KCiAgICAgICAgLyogbG9vcCB0cm91Z2ggdGhlIHZhbHVlIGxpc3QgKi8KICAgICAgICB2bCA9IChEV09SRCAqKShiYXNlK25rLT52YWx1ZWxpc3Rfb2ZmKzQpOwogICAgICAgIGZvciAobj0wOyBuPG5rLT5ucl92YWx1ZXM7IG4rKykgewogICAgICAgICAgICBudF92ayAqIHZrID0gKG50X3ZrKikoYmFzZSt2bFtuXSs0KTsKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF92ayhuZXdfa2V5X25hbWUsIGJhc2UsIHZrLCBmKSkgewogICAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSBlbHNlIG5ld19rZXlfbmFtZSA9IF94c3RyZHVwKGtleV9uYW1lKTsKCiAgICAvKiBsb29wIHRocm91Z2ggdGhlIHN1YmtleXMgKi8KICAgIGlmIChuay0+bnJfc3Via2V5cykgewogICAgICAgIG50X2xmICpsZiA9IChudF9sZiopKGJhc2UrbmstPmxmX29mZis0KTsKICAgICAgICBpZiAoIV9udF9kdW1wX2xmKG5ld19rZXlfbmFtZSwgYmFzZSwgbmstPm5yX3N1YmtleXMsIGxmLCBmLCBsZXZlbC0xKSkgewogICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qIGVuZCBudCBsb2FkZXIgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zZXRfcmVnaXN0cnlfbGV2ZWxzIFtJbnRlcm5hbF0KICoKICogc2V0IGxldmVsIHRvIDAgZm9yIGxvYWRpbmcgc3lzdGVtIGZpbGVzCiAqIHNldCBsZXZlbCB0byAxIGZvciBsb2FkaW5nIHVzZXIgZmlsZXMKICovCnN0YXRpYyB2b2lkIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKGludCBsZXZlbCxpbnQgc2F2aW5nLGludCBwZXJpb2QpCnsKICAgIFNFUlZFUl9TVEFSVF9SRVEoIHNldF9yZWdpc3RyeV9sZXZlbHMgKQogICAgewoJcmVxLT5jdXJyZW50ID0gbGV2ZWw7CglyZXEtPnNhdmluZyAgPSBzYXZpbmc7CiAgICAgICAgcmVxLT5wZXJpb2QgID0gcGVyaW9kOwogICAgICAgIHdpbmVfc2VydmVyX2NhbGwoIHJlcSApOwogICAgfQogICAgU0VSVkVSX0VORF9SRVE7Cn0KCi8qIF9zYXZlX2F0X2V4aXQgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfc2F2ZV9hdF9leGl0KEhLRVkgaGtleSxMUENTVFIgcGF0aCkKewogICAgTFBDU1RSIGNvbmZkaXIgPSB3aW5lX2dldF9jb25maWdfZGlyKCk7CgogICAgU0VSVkVSX1NUQVJUX1JFUSggc2F2ZV9yZWdpc3RyeV9hdGV4aXQgKQogICAgewogICAgICAgIHJlcS0+aGtleSA9IGhrZXk7CiAgICAgICAgd2luZV9zZXJ2ZXJfYWRkX2RhdGEoIHJlcSwgY29uZmRpciwgc3RybGVuKGNvbmZkaXIpICk7CiAgICAgICAgd2luZV9zZXJ2ZXJfYWRkX2RhdGEoIHJlcSwgcGF0aCwgc3RybGVuKHBhdGgpKzEgKTsKICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgIH0KICAgIFNFUlZFUl9FTkRfUkVROwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXMgW0ludGVybmFsXQogKiBSZWdpc3RyeSBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIHNvbWUgZGVmYXVsdCBrZXlzLgogKi8Kc3RhdGljIHZvaWQgX2FsbG9jYXRlX2RlZmF1bHRfa2V5cyh2b2lkKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgU3RhdERhdGFXW10gPSB7J0QnLCd5JywnbicsJ0QnLCdhJywndCcsJ2EnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1AnLCdlJywncicsJ2YnLCdTJywndCcsJ2EnLCd0JywncycsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUycsJ3QnLCdhJywndCcsJ0QnLCdhJywndCcsJ2EnLDB9OwogICAgSEtFWSBoa2V5OwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgU3RhdERhdGFXICk7CiAgICBpZiAoIU50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpIE50Q2xvc2UoIGhrZXkgKTsKfQoKc3RhdGljIHZvaWQgZ2V0X3dpbmRvd3NfZGlyKFdDSEFSKiBidWZmZXIsIHVuc2lnbmVkIGxlbikKewogICAgT0JKRUNUX0FUVFJJQlVURVMgICBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgICAgICBuYW1lVywga2V5VzsKICAgIEhLRVkgICAgICAgICAgICAgICAgaGtleTsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwoKICAgIGlmIChSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCAiTWFjaGluZVxcU29mdHdhcmVcXFdpbmVcXFdpbmVcXENvbmZpZ1xcd2luZSIgKSkKICAgIHsKICAgICAgICBpZiAoIU50T3BlbktleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciApKQogICAgICAgIHsKICAgICAgICAgICAgY2hhciB0bXBbTUFYX1BBVEhOQU1FX0xFTipzaXplb2YoV0NIQVIpICsgc2l6ZW9mKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OKV07CiAgICAgICAgICAgIERXT1JEIGNvdW50OwoKICAgICAgICAgICAgUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZrZXlXLCAiV2luZG93cyIpOwogICAgICAgICAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleSwgJmtleVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICAgICAgICAgIG1lbWNweShidWZmZXIsIHN0ciwgbWluKCgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhTGVuZ3RoLCBsZW4pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJmtleVcgKTsKICAgICAgICB9CiAgICAgICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwogICAgfQp9CgoKI2RlZmluZSBSRUdfRE9OVExPQUQgLTEKI2RlZmluZSBSRUdfV0lOMzEgICAgIDAKI2RlZmluZSBSRUdfV0lOOTUgICAgIDEKI2RlZmluZSBSRUdfV0lOTlQgICAgIDIKCi8qIHJldHVybiB0aGUgdHlwZSBvZiBuYXRpdmUgcmVnaXN0cnkgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9nZXRfcmVnX3R5cGUoY29uc3QgV0NIQVIqIHdpbmRpcikKewogICAgV0NIQVIgdG1wW01BWF9QQVRITkFNRV9MRU5dOwogICAgaW50IHJldCA9IFJFR19XSU4zMTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBudF9yZWdfcGF0aFdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHdpbjl4X3JlZ19wYXRoV1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJy4nLCdkJywnYScsJ3QnLDB9OwoKICAgIC8qIHRlc3QgJXdpbmRpciUvc3lzdGVtMzIvY29uZmlnL3N5c3RlbSAtLT4gd2lubnQgKi8KICAgIHN0cmNweVcodG1wLCB3aW5kaXIpOwogICAgc3RyY2F0Vyh0bXAsIG50X3JlZ19wYXRoVyk7CiAgICBpZihHZXRGaWxlQXR0cmlidXRlc1codG1wKSAhPSBJTlZBTElEX0ZJTEVfQVRUUklCVVRFUykKICAgICAgcmV0ID0gUkVHX1dJTk5UOwogICAgZWxzZQogICAgewogICAgICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0uZGF0IC0tPiB3aW45NSAqLwogICAgICBzdHJjcHlXKHRtcCwgd2luZGlyKTsKICAgICAgc3RyY2F0Vyh0bXAsIHdpbjl4X3JlZ19wYXRoVyk7CiAgICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzVyh0bXApICE9IElOVkFMSURfRklMRV9BVFRSSUJVVEVTKQogICAgICAgIHJldCA9IFJFR19XSU45NTsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgovKiBsb2FkIHRoZSByZWdpc3RyeSBmaWxlIGluIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgbG9hZF93aW5lX3JlZ2lzdHJ5KEhLRVkgaGtleSxMUENTVFIgZm4pCnsKICAgIEhBTkRMRSBmaWxlOwogICAgaWYgKChmaWxlID0gRklMRV9DcmVhdGVGaWxlKCBmbiwgR0VORVJJQ19SRUFELCAwLCBOVUxMLCBPUEVOX0VYSVNUSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFX0FUVFJJQlVURV9OT1JNQUwsIDAsIFRSVUUsIERSSVZFX1VOS05PV04gKSkpCiAgICB7CiAgICAgICAgU0VSVkVSX1NUQVJUX1JFUSggbG9hZF9yZWdpc3RyeSApCiAgICAgICAgewogICAgICAgICAgICByZXEtPmhrZXkgICAgPSBoa2V5OwogICAgICAgICAgICByZXEtPmZpbGUgICAgPSBmaWxlOwogICAgICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgICAgICB9CiAgICAgICAgU0VSVkVSX0VORF9SRVE7CiAgICAgICAgQ2xvc2VIYW5kbGUoIGZpbGUgKTsKICAgIH0KfQoKLyogZ2VuZXJhdGUgYW5kIHJldHVybiB0aGUgbmFtZSBvZiB0aGUgdG1wIGZpbGUgYW5kIGFzc29jaWF0ZWQgc3RyZWFtIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9nZXRfdG1wX2ZuKEZJTEUgKipmKQp7CiAgICBMUFNUUiByZXQ7CiAgICBpbnQgdG1wX2ZkLGNvdW50OwoKICAgIHJldCA9IF94bWFsbG9jKDUwKTsKICAgIGZvciAoY291bnQgPSAwOzspIHsKICAgICAgICBzcHJpbnRmKHJldCwiL3RtcC9yZWclbHglMDR4LnRtcCIsKGxvbmcpZ2V0cGlkKCksY291bnQrKyk7CiAgICAgICAgaWYgKCh0bXBfZmQgPSBvcGVuKHJldCxPX0NSRUFUIHwgT19FWENMIHwgT19XUk9OTFksMDY2NikpICE9IC0xKSBicmVhazsKICAgICAgICBpZiAoZXJybm8gIT0gRUVYSVNUKSB7CiAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBlcnJvciB3aGlsZSBvcGVuKCkgY2FsbDogJXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICAgICAgZnJlZShyZXQpOwogICAgICAgICAgICAqZiA9IE5VTEw7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoKCpmID0gZmRvcGVuKHRtcF9mZCwidyIpKSA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJVbmV4cGVjdGVkIGVycm9yIHdoaWxlIGZkb3BlbigpIGNhbGw6ICVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgY2xvc2UodG1wX2ZkKTsKICAgICAgICBmcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCB3aW45NSBuYXRpdmUgcmVnaXN0cnkgZmlsZSB0byB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfY29udmVydF93aW45NV9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChMUENXU1RSIGZuLCBpbnQgbGV2ZWwpCnsKICAgIEhBTkRMRSBoRmlsZSwgaE1hcHBpbmc7CiAgICBGSUxFICpmOwogICAgdm9pZCAqYmFzZTsKICAgIExQU1RSIHJldCA9IE5VTEw7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgTEFSR0VfSU5URUdFUiBsZ19pbnQ7CiAgICBOVFNUQVRVUyBudHM7CiAgICBTSVpFX1QgbGVuOwoKICAgIF93OTVjcmVnICpjcmVnOwogICAgX3c5NXJna24gKnJna247CiAgICBfdzk1ZGtlICpka2UsICpyb290X2RrZTsKCiAgICBoRmlsZSA9IENyZWF0ZUZpbGVXKCBmbiwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIDAgKTsKICAgIGlmICggaEZpbGUgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUgKSByZXR1cm4gTlVMTDsKCiAgICBhdHRyLkxlbmd0aCAgICAgICAgICAgICAgICAgICA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSAgICAgICAgICAgID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSAgICAgICAgICAgICAgID0gTlVMTDsKICAgIGF0dHIuQXR0cmlidXRlcyAgICAgICAgICAgICAgID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yICAgICAgID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBsZ19pbnQuUXVhZFBhcnQgPSAwOwogICAgbnRzID0gTnRDcmVhdGVTZWN0aW9uKCAmaE1hcHBpbmcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBTVEFOREFSRF9SSUdIVFNfUkVRVUlSRUR8U0VDVElPTl9RVUVSWXxTRUNUSU9OX01BUF9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgICAmYXR0ciwgJmxnX2ludCwgUEFHRV9SRUFET05MWSwgU0VDX0NPTU1JVCwgaEZpbGUgKTsKICAgIGlmIChudHMgIT0gU1RBVFVTX1NVQ0NFU1MpIGdvdG8gZXJyb3IxOwoKICAgIGJhc2UgPSBOVUxMOyBsZW4gPSAwOwogICAgbnRzID0gTnRNYXBWaWV3T2ZTZWN0aW9uKCBoTWFwcGluZywgR2V0Q3VycmVudFByb2Nlc3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmJhc2UsIDAsIDAsICZsZ19pbnQsICZsZW4sIFZpZXdTaGFyZSwgMCwgCgkJCSAgICAgIFBBR0VfUkVBRE9OTFkpOwogICAgTnRDbG9zZSggaE1hcHBpbmcgKTsKICAgIGlmIChudHMgIT0gU1RBVFVTX1NVQ0NFU1MpIGdvdG8gZXJyb3IxOwoKICAgIC8qIGNvbnRyb2wgc2lnbmF0dXJlICovCiAgICBpZiAoKihMUERXT1JEKWJhc2UgIT0gVzk1X1JFR19DUkVHX0lEKSB7CiAgICAgICAgRVJSKCJ1bmFibGUgdG8gbG9hZCBuYXRpdmUgd2luOTUgcmVnaXN0cnkgZmlsZSAlczogdW5rbm93biBzaWduYXR1cmUuXG4iLAogICAgICAgICAgICBkZWJ1Z3N0cl93KGZuKSk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBjcmVnID0gYmFzZTsKICAgIC8qIGxvYWQgdGhlIGhlYWRlciAocmdrbikgKi8KICAgIHJna24gPSAoX3c5NXJna24qKShjcmVnICsgMSk7CiAgICBpZiAocmdrbi0+aWQgIT0gVzk1X1JFR19SR0tOX0lEKSB7CiAgICAgICAgRVJSKCJzZWNvbmQgSUZGIGhlYWRlciBub3QgUkdLTiwgYnV0ICVseFxuIiwgcmdrbi0+aWQpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+cm9vdF9vZmYgIT0gMHgyMCkgewogICAgICAgIEVSUigicmdrbi0+cm9vdF9vZmYgbm90IDB4MjAsIHBsZWFzZSByZXBvcnQgIVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5sYXN0X2RrZSA+IHJna24tPnNpemUpCiAgICB7CiAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISBsYXN0X2RrZSA+IHNpemUhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIC8qIHZlcmlmeSBsYXN0IGRrZSAqLwogICAgZGtlID0gKF93OTVka2UqKSgoY2hhciopcmdrbiArIHJna24tPmxhc3RfZGtlKTsKICAgIGlmIChka2UtPngxICE9IDB4ODAwMDAwMDApCiAgICB7IC8qIHdyb25nIG1hZ2ljICovCiAgICAgIEVSUigibGFzdCBka2UgaW52YWxpZCAhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5zaXplID4gY3JlZy0+cmdkYl9vZmYpCiAgICB7CiAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISByZ2tuIHNpemUgPiByZ2RiX29mZiAhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIHJvb3RfZGtlID0gKF93OTVka2UqKSgoY2hhciopcmdrbiArIHJna24tPnJvb3Rfb2ZmKTsKICAgIGlmICggKHJvb3RfZGtlLT5wcmV2bHZsICE9IDB4ZmZmZmZmZmYpIHx8IChyb290X2RrZS0+bmV4dCAhPSAweGZmZmZmZmZmKSApCiAgICB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGludmFsaWQgcm9vdCBka2UgIVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAoIChyZXQgPSBfZ2V0X3RtcF9mbigmZikpID09IE5VTEwpIGdvdG8gZXJyb3I7CiAgICBmcHJpbnRmKGYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAyIik7CiAgICBfdzk1X2R1bXBfZGtlKCIiLGNyZWcscmdrbixyb290X2RrZSxmLGxldmVsKTsKICAgIGZjbG9zZShmKTsKCmVycm9yOgogICAgaWYocmV0ID09IE5VTEwpIHsKICAgICAgICBFUlIoIlVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW45NSByZWdpc3RyeSBmaWxlICVzLlxuIiwgZGVidWdzdHJfdyhmbikpOwogICAgICAgIEVSUigiUGxlYXNlIHJlcG9ydCB0aGlzLlxuIik7CiAgICAgICAgRVJSKCJNYWtlIGEgYmFja3VwIG9mIHRoZSBmaWxlLCBydW4gYSBnb29kIHJlZyBjbGVhbmVyIHByb2dyYW0gYW5kIHRyeSBhZ2FpbiFcbiIpOwogICAgfQoKICAgIE50VW5tYXBWaWV3T2ZTZWN0aW9uKCBHZXRDdXJyZW50UHJvY2VzcygpLCBiYXNlICk7CmVycm9yMToKICAgIE50Q2xvc2UoaEZpbGUpOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCB3aW5udCBuYXRpdmUgcmVnaXN0cnkgZmlsZSB0byB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfY29udmVydF93aW5udF9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChMUENXU1RSIGZuLCBpbnQgbGV2ZWwpCnsKICAgIEZJTEUgKmY7CiAgICB2b2lkICpiYXNlOwogICAgTFBTVFIgcmV0ID0gTlVMTDsKICAgIEhBTkRMRSBoRmlsZTsKICAgIEhBTkRMRSBoTWFwcGluZzsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBMQVJHRV9JTlRFR0VSIGxnX2ludDsKICAgIE5UU1RBVFVTIG50czsKICAgIFNJWkVfVCBsZW47CgogICAgbnRfcmVnZiAqcmVnZjsKICAgIG50X2hiaW4gKmhiaW47CiAgICBudF9oYmluX3N1YiAqaGJpbl9zdWI7CiAgICBudF9uayAqbms7CgogICAgVFJBQ0UoIiVzXG4iLCBkZWJ1Z3N0cl93KGZuKSk7CgogICAgaEZpbGUgPSBDcmVhdGVGaWxlVyggZm4sIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELCBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwICk7CiAgICBpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CiAgICBhdHRyLkxlbmd0aCAgICAgICAgICAgICAgICAgICA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSAgICAgICAgICAgID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSAgICAgICAgICAgICAgID0gTlVMTDsKICAgIGF0dHIuQXR0cmlidXRlcyAgICAgICAgICAgICAgID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yICAgICAgID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBsZ19pbnQuUXVhZFBhcnQgPSAwOwogICAgbnRzID0gTnRDcmVhdGVTZWN0aW9uKCAmaE1hcHBpbmcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBTVEFOREFSRF9SSUdIVFNfUkVRVUlSRUR8U0VDVElPTl9RVUVSWXxTRUNUSU9OX01BUF9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgICAmYXR0ciwgJmxnX2ludCwgUEFHRV9SRUFET05MWSwgU0VDX0NPTU1JVCwgaEZpbGUgKTsKICAgIGlmIChudHMgIT0gU1RBVFVTX1NVQ0NFU1MpIGdvdG8gZXJyb3IxOwoKICAgIGJhc2UgPSBOVUxMOyBsZW4gPSAwOwogICAgbnRzID0gTnRNYXBWaWV3T2ZTZWN0aW9uKCBoTWFwcGluZywgR2V0Q3VycmVudFByb2Nlc3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmJhc2UsIDAsIDAsICZsZ19pbnQsICZsZW4sIFZpZXdTaGFyZSwgMCwgCgkJCSAgICAgIFBBR0VfUkVBRE9OTFkpOwogICAgTnRDbG9zZSggaE1hcHBpbmcgKTsKICAgIGlmIChudHMgIT0gU1RBVFVTX1NVQ0NFU1MpIGdvdG8gZXJyb3IxOwoKICAgIC8qIGNvbnRyb2wgc2lnbmF0dXJlICovCiAgICBpZiAoKihMUERXT1JEKWJhc2UgIT0gTlRfUkVHX0hFQURFUl9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5hYmxlIHRvIGxvYWQgbmF0aXZlIHdpbm50IHJlZ2lzdHJ5IGZpbGUgJXM6IHVua25vd24gc2lnbmF0dXJlLlxuIiwKICAgICAgICAgICAgZGVidWdzdHJfdyhmbikpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogc3RhcnQgYmxvY2sgKi8KICAgIHJlZ2YgPSBiYXNlOwoKICAgIC8qIGhiaW4gYmxvY2sgKi8KICAgIGhiaW4gPSAobnRfaGJpbiopKChjaGFyKikgYmFzZSArIDB4MTAwMCk7CiAgICBpZiAoaGJpbi0+aWQgIT0gTlRfUkVHX1BPT0xfQkxPQ0tfSUQpIHsKICAgICAgRVJSKCAiaGJpbiBibG9jayBpbnZhbGlkXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBoYmluX3N1YiBibG9jayAqLwogICAgaGJpbl9zdWIgPSAobnRfaGJpbl9zdWIqKSYoaGJpbi0+aGJpbl9zdWIpOwogICAgaWYgKChoYmluX3N1Yi0+ZGF0YVswXSAhPSAnbicpIHx8IChoYmluX3N1Yi0+ZGF0YVsxXSAhPSAnaycpKSB7CiAgICAgIEVSUiggImhiaW5fc3ViIGJsb2NrIGludmFsaWRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIG5rIGJsb2NrICovCiAgICBuayA9IChudF9uayopJihoYmluX3N1Yi0+ZGF0YVswXSk7CiAgICBpZiAobmstPlR5cGUgIT0gTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpIHsKICAgICAgRVJSKCAic3BlY2lhbCBuayBibG9jayBub3QgZm91bmRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGlmICggKHJldCA9IF9nZXRfdG1wX2ZuKCZmKSkgPT0gTlVMTCkgZ290byBlcnJvcjsKICAgIGZwcmludGYoZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uIDIiKTsKICAgIF9udF9kdW1wX25rKCIiLChjaGFyKiliYXNlKzB4MTAwMCxuayxmLGxldmVsKTsKICAgIGZjbG9zZShmKTsKCmVycm9yOgogICAgTnRVbm1hcFZpZXdPZlNlY3Rpb24oIEdldEN1cnJlbnRQcm9jZXNzKCksIGJhc2UgKTsKZXJyb3IxOgogICAgTnRDbG9zZShoRmlsZSk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IG5hdGl2ZSByZWdpc3RyeSB0byB3aW5lIGZvcm1hdCBhbmQgbG9hZCBpdCB2aWEgc2VydmVyIGNhbGwgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkoTFBDV1NUUiBmbiwgSEtFWSBoa2V5LCBpbnQgcmVnX3R5cGUsIGludCBsZXZlbCkKewogICAgTFBTVFIgdG1wID0gTlVMTDsKCiAgICBzd2l0Y2ggKHJlZ190eXBlKSB7CiAgICAgICAgY2FzZSBSRUdfV0lOTlQ6CiAgICAgICAgICAgIC8qIEZJWE1FOiBmb2xsb3dpbmcgZnVuY3Rpb24gZG9lc24ndCByZWFsbHkgY29udmVydCB5ZXQgKi8KICAgICAgICAgICAgdG1wID0gX2NvbnZlcnRfd2lubnRfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoZm4sbGV2ZWwpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19XSU45NToKICAgICAgICAgICAgdG1wID0gX2NvbnZlcnRfd2luOTVfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoZm4sbGV2ZWwpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19XSU4zMToKICAgICAgICAgICAgRVJSKCJEb24ndCBrbm93IGhvdyB0byBjb252ZXJ0IG5hdGl2ZSAzLjEgcmVnaXN0cnkgeWV0LlxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiVW5rbm93biByZWdpc3RyeSBmb3JtYXQgcGFyYW1ldGVyICglZClcbiIscmVnX3R5cGUpOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAodG1wICE9IE5VTEwpIHsKICAgICAgICBsb2FkX3dpbmVfcmVnaXN0cnkoaGtleSx0bXApOwogICAgICAgIFRSQUNFKCJGaWxlICVzIHN1Y2Nlc3NmdWxseSBjb252ZXJ0ZWQgdG8gJXMgYW5kIGxvYWRlZCB0byByZWdpc3RyeS5cbiIsCiAgICAgICAgICAgICAgZGVidWdzdHJfdyhmbiksIHRtcCk7CiAgICAgICAgdW5saW5rKHRtcCk7CiAgICB9CiAgICBlbHNlIFdBUk4oIlVuYWJsZSB0byBjb252ZXJ0ICVzIChkb2Vzbid0IGV4aXN0PylcbiIsIGRlYnVnc3RyX3coZm4pKTsKICAgIGZyZWUodG1wKTsKfQoKLyogbG9hZCBhbGwgbmF0aXZlIHdpbmRvd3MgcmVnaXN0cnkgZmlsZXMgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfbG9hZF93aW5kb3dzX3JlZ2lzdHJ5KCBIS0VZIGhrZXlfbG9jYWxfbWFjaGluZSwgSEtFWSBoa2V5X2N1cnJlbnRfdXNlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQgKQp7CiAgICBpbnQgcmVnX3R5cGU7CiAgICBXQ0hBUiB3aW5kaXJbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBXQ0hBUiBwYXRoW01BWF9QQVRITkFNRV9MRU5dOwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgSEtFWSBoa2V5LCBwcm9maWxlX2tleTsKICAgIGNoYXIgdG1wWzEwMjRdOwogICAgRFdPUkQgZHVtbXk7CgogICAgc3RhdGljIGNvbnN0IFdDSEFSIFdpbmVXW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVycsJ2knLCduJywnZScsJ1xcJywnVycsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ1cnLCdpJywnbicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFByb2ZpbGVXW10gPSB7J1AnLCdyJywnbycsJ2YnLCdpJywnbCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFN5c3RlbVtdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLCdTJywneScsJ3MnLCd0JywnZScsJ20nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFNvZnR3YXJlW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBDbG9uZVtdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1MnLCd5JywncycsJ3QnLCdlJywnbScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbCcsJ28nLCduJywnZScsMH07CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBXaW5lVyApOwogICAgaWYgKE50Q3JlYXRlS2V5KCAmcHJvZmlsZV9rZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKSBwcm9maWxlX2tleSA9IDA7CgogICAgZ2V0X3dpbmRvd3NfZGlyKHdpbmRpciwgc2l6ZW9mKHdpbmRpcikpOwoKICAgIHJlZ190eXBlID0gX2dldF9yZWdfdHlwZSh3aW5kaXIpOwogICAgc3dpdGNoIChyZWdfdHlwZSkgewogICAgICAgIGNhc2UgUkVHX1dJTk5UOiB7CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBudHVzZXJfZGF0V1tdID0geydcXCcsJ24nLCd0JywndScsJ3MnLCdlJywncicsJy4nLCdkJywnYScsJ3QnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgZGVmYXVsdFdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdkJywnZScsJ2YnLCdhJywndScsJ2wnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHN5c3RlbVdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc29mdHdhcmVXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywncycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc2FtV1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJzMnLCcyJywnXFwnLCdjJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ3MnLCdhJywnbScsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzZWN1cml0eVdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdzJywnZScsJ2MnLCd1JywncicsJ2knLCd0JywneScsMH07CgogICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIG50dXNlci5kYXQgKi8KICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgUHJvZmlsZVcgKTsKICAgICAgICAgICAgaWYgKHByb2ZpbGVfa2V5ICYmICFOdFF1ZXJ5VmFsdWVLZXkoIHByb2ZpbGVfa2V5LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wLCBzaXplb2YodG1wKSwgJmR1bW15ICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGEpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBudHVzZXJfZGF0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2N1cnJlbnRfdXNlcixSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBNRVNTQUdFKCJXaGVuIHlvdSBhcmUgcnVubmluZyB3aXRoIGEgbmF0aXZlIE5UIGRpcmVjdG9yeSBzcGVjaWZ5XG4iKTsKICAgICAgICAgICAgICAgIE1FU1NBR0UoIidQcm9maWxlPTxwcm9maWxlZGlyZWN0b3J5Picgb3IgZGlzYWJsZSBsb2FkaW5nIG9mIFdpbmRvd3NcbiIpOwogICAgICAgICAgICAgICAgTUVTU0FHRSgicmVnaXN0cnkgKExvYWRXaW5kb3dzUmVnaXN0cnlGaWxlcz1OKVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogZGVmYXVsdCB1c2VyLmRhdCAqLwogICAgICAgICAgICBpZiAoaGtleV91c2Vyc19kZWZhdWx0KSB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIGRlZmF1bHRXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfdXNlcnNfZGVmYXVsdCxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICogRklYTUUKICAgICAgICAgICAgKiAgbWFwIEhMTVxTeXN0ZW1cQ29udHJvbFNldDAwMSB0byBITE1cU3lzdGVtXEN1cnJlbnRDb250cm9sU2V0CiAgICAgICAgICAgICovCiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFN5c3RlbSApOwogICAgICAgICAgICBpZiAoIU50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgc3lzdGVtVyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5LFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBTb2Z0d2FyZSApOwogICAgICAgICAgICBpZiAoIU50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgc29mdHdhcmVXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXksUkVHX1dJTk5ULDEpOwogICAgICAgICAgICAgICAgTnRDbG9zZSggaGtleSApOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgc2FtVyk7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfbG9jYWxfbWFjaGluZSxSRUdfV0lOTlQsMCk7CgogICAgICAgICAgICBzdHJjcHlXKHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBzZWN1cml0eVcpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2xvY2FsX21hY2hpbmUsUkVHX1dJTk5ULDApOwoKICAgICAgICAgICAgLyogdGhpcyBrZXkgaXMgZ2VuZXJhdGVkIHdoZW4gdGhlIG50LWNvcmUgYm9vdGVkIHN1Y2Nlc3NmdWxseSAqLwogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBDbG9uZSApOwogICAgICAgICAgICBpZiAoIU50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIFJFR19XSU45NToKICAgICAgICB7CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzeXN0ZW1fMXN0V1tdID0geydjJywnOicsJ1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnLicsJzEnLCdzJywndCcsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzeXN0ZW1fZGF0V1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJy4nLCdkJywnYScsJ3QnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgY2xhc3Nlc19kYXRXW10gPSB7J1xcJywnYycsJ2wnLCdhJywncycsJ3MnLCdlJywncycsJy4nLCdkJywnYScsJ3QnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgdXNlcl9kYXRXW10gPSB7J1xcJywndScsJ3MnLCdlJywncicsJy4nLCdkJywnYScsJ3QnLDB9OwoKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHN5c3RlbV8xc3RXLGhrZXlfbG9jYWxfbWFjaGluZSxSRUdfV0lOOTUsMCk7CgogICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgc3lzdGVtX2RhdFcpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2xvY2FsX21hY2hpbmUsUkVHX1dJTjk1LDApOwoKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgQ2xhc3Nlc1Jvb3RXICk7CiAgICAgICAgICAgIGlmICghTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBjbGFzc2VzX2RhdFcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleSxSRUdfV0lOOTUsMCk7CiAgICAgICAgICAgICAgICBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFByb2ZpbGVXICk7CiAgICAgICAgICAgIGlmIChwcm9maWxlX2tleSAmJiAhTnRRdWVyeVZhbHVlS2V5KCBwcm9maWxlX2tleSwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcCwgc2l6ZW9mKHRtcCksICZkdW1teSApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIHVzZXIuZGF0ICovCiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgdXNlcl9kYXRXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfY3VycmVudF91c2VyLFJFR19XSU45NSwxKTsKCgkgICAgICAgIC8qIGRlZmF1bHQgdXNlci5kYXQgKi8KCSAgICAgICAgaWYgKGhrZXlfdXNlcnNfZGVmYXVsdCkgewogICAgICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHVzZXJfZGF0Vyk7CiAgICAgICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV91c2Vyc19kZWZhdWx0LFJFR19XSU45NSwxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgdXNlcl9kYXRXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfY3VycmVudF91c2VyLFJFR19XSU45NSwxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgUkVHX1dJTjMxOgogICAgICAgICAgICAvKiBGSVhNRTogaGVyZSB3ZSBzaG91bGQgY29udmVydCB0byAqLnJlZyBmaWxlIHN1cHBvcnRlZCBieSBzZXJ2ZXIgYW5kIGNhbGwgUkVRX0xPQURfUkVHSVNUUlksIHNlZSBSRUdfV0lOOTUgY2FzZSAqLwogICAgICAgICAgICBfdzMxX2xvYWRyZWcoKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgUkVHX0RPTlRMT0FEOgogICAgICAgICAgICBUUkFDRSgiUkVHX0RPTlRMT0FEXG4iKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigic3dpdGNoOiBubyBtYXRjaCAoJWQpXG4iLHJlZ190eXBlKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgfQogICAgaWYgKHByb2ZpbGVfa2V5KSBOdENsb3NlKCBwcm9maWxlX2tleSApOwp9CgovKiBsb2FkIGhvbWUgcmVnaXN0cnkgZmlsZXMgKHN0b3JlZCBpbiB+Ly53aW5lKSBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9sb2FkX2hvbWVfcmVnaXN0cnkoIEhLRVkgaGtleV9sb2NhbF9tYWNoaW5lLCBIS0VZIGhrZXlfY3VycmVudF91c2VyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIS0VZIGhrZXlfdXNlcnNfZGVmYXVsdCApCnsKICAgIExQQ1NUUiBjb25mZGlyID0gd2luZV9nZXRfY29uZmlnX2RpcigpOwogICAgTFBTVFIgdG1wID0gX3htYWxsb2Moc3RybGVuKGNvbmZkaXIpKzIwKTsKCiAgICBzdHJjcHkodG1wLGNvbmZkaXIpOwogICAgc3RyY2F0KHRtcCwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUKTsKICAgIGxvYWRfd2luZV9yZWdpc3RyeShoa2V5X3VzZXJzX2RlZmF1bHQsdG1wKTsKCiAgICBzdHJjcHkodG1wLGNvbmZkaXIpOwogICAgc3RyY2F0KHRtcCwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfQ1VSUkVOVF9VU0VSKTsKICAgIGxvYWRfd2luZV9yZWdpc3RyeShoa2V5X2N1cnJlbnRfdXNlcix0bXApOwoKICAgIHN0cmNweSh0bXAsY29uZmRpcik7CiAgICBzdHJjYXQodG1wLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FKTsKICAgIGxvYWRfd2luZV9yZWdpc3RyeShoa2V5X2xvY2FsX21hY2hpbmUsdG1wKTsKCiAgICBmcmVlKHRtcCk7Cn0KCgovKiBsb2FkIGFsbCByZWdpc3RyeSAobmF0aXZlIGFuZCBnbG9iYWwgYW5kIGhvbWUpICovCnZvaWQgU0hFTExfTG9hZFJlZ2lzdHJ5KCB2b2lkICkKewogICAgSEtFWSBoa2V5X2xvY2FsX21hY2hpbmUsIGhrZXlfdXNlcnMsIGhrZXlfdXNlcnNfZGVmYXVsdCwgaGtleV9jdXJyZW50X3VzZXIsIGhrZXlfY29uZmlnOwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgRFdPUkQgY291bnQ7CiAgICBVTE9ORyBkaXNwb3M7CiAgICBCT09MIHJlczsKICAgIGludCBhbGwsIHBlcmlvZDsKICAgIGNoYXIgdG1wWzEwMjRdOwoKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBNYWNoaW5lV1tdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBVc2VyV1tdID0geydVJywncycsJ2UnLCdyJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBEZWZhdWx0V1tdID0geycuJywnRCcsJ2UnLCdmJywnYScsJ3UnLCdsJywndCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgUmVnaXN0cnlXW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCd5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsb2FkX3dpbl9yZWdfZmlsZXNXW10gPSB7J0wnLCdvJywnYScsJ2QnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLCdGJywnaScsJ2wnLCdlJywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgbG9hZF9nbG9iYWxfcmVnX2ZpbGVzV1tdID0geydMJywnbycsJ2EnLCdkJywnRycsJ2wnLCdvJywnYicsJ2EnLCdsJywnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLCdGJywnaScsJ2wnLCdlJywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgbG9hZF9ob21lX3JlZ19maWxlc1dbXSA9IHsnTCcsJ28nLCdhJywnZCcsJ0gnLCdvJywnbScsJ2UnLCdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywneScsJ0YnLCdpJywnbCcsJ2UnLCdzJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBTYXZlT25seVVwZGF0ZWRLZXlzV1tdID0geydTJywnYScsJ3YnLCdlJywnTycsJ24nLCdsJywneScsJ1UnLCdwJywnZCcsJ2EnLCd0JywnZScsJ2QnLCdLJywnZScsJ3knLCdzJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBQZXJpb2RpY1NhdmVXW10gPSB7J1AnLCdlJywncicsJ2knLCdvJywnZCcsJ2knLCdjJywnUycsJ2EnLCd2JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgV3JpdGV0b0hvbWVSZWdpc3RyeUZpbGVzV1tdID0geydXJywncicsJ2knLCd0JywnZScsJ3QnLCdvJywnSCcsJ28nLCdtJywnZScsJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCd5JywnRicsJ2knLCdsJywnZScsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIEdsb2JhbFJlZ2lzdHJ5RGlyV1tdID0geydHJywnbCcsJ28nLCdiJywnYScsJ2wnLCdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywneScsJ0QnLCdpJywncicsMH07CgogICAgVFJBQ0UoIih2b2lkKVxuIik7CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBVc2VyVyApOwogICAgTnRDcmVhdGVLZXkoICZoa2V5X3VzZXJzLCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsICZkaXNwb3MgKTsKICAgIGlmIChkaXNwb3MgPT0gUkVHX09QRU5FRF9FWElTVElOR19LRVkpCiAgICB7CiAgICAgICAgLyogc29tZW9uZSBlbHNlIGFscmVhZHkgbG9hZGVkIHRoZSByZWdpc3RyeSAqLwogICAgICAgIE50Q2xvc2UoIGhrZXlfdXNlcnMgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgTWFjaGluZVcgKTsKICAgIE50Q3JlYXRlS2V5KCAmaGtleV9sb2NhbF9tYWNoaW5lLCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKTsKCiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5X3VzZXJzOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgRGVmYXVsdFcgKTsKICAgIGlmIChOdENyZWF0ZUtleSggJmhrZXlfdXNlcnNfZGVmYXVsdCwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICB7CiAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIEhLRVlfVVNFUlMvLkRlZmF1bHRcbiIgKTsKICAgICAgICBFeGl0UHJvY2VzcygxKTsKICAgIH0KICAgIFJ0bE9wZW5DdXJyZW50VXNlciggS0VZX0FMTF9BQ0NFU1MsICZoa2V5X2N1cnJlbnRfdXNlciApOwoKICAgIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKDAsMCwwKTsKICAgIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXMoKTsKCiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgUmVnaXN0cnlXICk7CiAgICBpZiAoTnRPcGVuS2V5KCAmaGtleV9jb25maWcsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciApKSBoa2V5X2NvbmZpZyA9IDA7CgogICAgLyogbG9hZCB3aW5kb3dzIHJlZ2lzdHJ5IGlmIHJlcXVpcmVkICovCgogICAgcmVzID0gVFJVRTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IGhrZXlfY29uZmlnOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgbG9hZF93aW5fcmVnX2ZpbGVzVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgcmVzID0gIUlTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQogICAgaWYgKHJlcykgX2xvYWRfd2luZG93c19yZWdpc3RyeSggaGtleV9sb2NhbF9tYWNoaW5lLCBoa2V5X2N1cnJlbnRfdXNlciwgaGtleV91c2Vyc19kZWZhdWx0ICk7CgogICAgLyogbG9hZCBnbG9iYWwgcmVnaXN0cnkgaWYgcmVxdWlyZWQgKi8KCiAgICByZXMgPSBUUlVFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgbG9hZF9nbG9iYWxfcmVnX2ZpbGVzVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgcmVzID0gIUlTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQogICAgaWYgKHJlcykKICAgIHsKICAgICAgICAvKiBsb2FkIGdsb2JhbCByZWdpc3RyeSBmaWxlcyAoc3RvcmVkIGluIC9ldGMvd2luZSkgKi8KICAgICAgICBjaGFyICpwLCBjb25maWdmaWxlW01BWF9QQVRITkFNRV9MRU5dOwoKICAgICAgICAvKiBPdmVycmlkZSBFVENESVI/ICovCiAgICAgICAgY29uZmlnZmlsZVswXSA9IDA7CiAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgR2xvYmFsUmVnaXN0cnlEaXJXICk7CiAgICAgICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICAgICAgUnRsVW5pY29kZVRvTXVsdGlCeXRlTiggY29uZmlnZmlsZSwgc2l6ZW9mKGNvbmZpZ2ZpbGUpLCBOVUxMLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyLCAoc3RybGVuVyhzdHIpICsgMSkgKiBzaXplb2YoV0NIQVIpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGNvbmZpZ2ZpbGVbMF0gIT0gJy8nKSBzdHJjcHkoY29uZmlnZmlsZSwgRVRDRElSKTsKCiAgICAgICAgVFJBQ0UoIkdsb2JhbFJlZ2lzdHJ5RGlyIGlzICclcycuXG4iLCBjb25maWdmaWxlKTsKCiAgICAgICAgLyogTG9hZCB0aGUgZ2xvYmFsIEhLVSBoaXZlIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpciAqLwogICAgICAgIHAgPSBjb25maWdmaWxlICsgc3RybGVuKGNvbmZpZ2ZpbGUpOwogICAgICAgIHN0cmNweShwLCBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUKTsKICAgICAgICBsb2FkX3dpbmVfcmVnaXN0cnkoIGhrZXlfdXNlcnMsIGNvbmZpZ2ZpbGUgKTsKCiAgICAgICAgLyogTG9hZCB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyICovCiAgICAgICAgc3RyY3B5KHAsIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FKTsKICAgICAgICBsb2FkX3dpbmVfcmVnaXN0cnkoIGhrZXlfbG9jYWxfbWFjaGluZSwgY29uZmlnZmlsZSApOwogICAgfQoKICAgIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKDEsMCwwKTsKCiAgICAvKiBsb2FkIGhvbWUgcmVnaXN0cnkgaWYgcmVxdWlyZWQgKi8KCiAgICByZXMgPSBUUlVFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgbG9hZF9ob21lX3JlZ19maWxlc1cgKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X2NvbmZpZywgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICB7CiAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgIHJlcyA9ICFJU19PUFRJT05fRkFMU0Uoc3RyWzBdKTsKICAgIH0KICAgIGlmIChyZXMpIF9sb2FkX2hvbWVfcmVnaXN0cnkoIGhrZXlfbG9jYWxfbWFjaGluZSwgaGtleV9jdXJyZW50X3VzZXIsIGhrZXlfdXNlcnNfZGVmYXVsdCApOwoKICAgIC8qIHNldHVwIHJlZ2lzdHJ5IHNhdmluZyAqLwoKICAgIGFsbCA9IEZBTFNFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgU2F2ZU9ubHlVcGRhdGVkS2V5c1cgKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X2NvbmZpZywgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICB7CiAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgIGFsbCA9IElTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQoKICAgIHBlcmlvZCA9IDA7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBQZXJpb2RpY1NhdmVXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICBwZXJpb2QgPSAoaW50KXN0cnRvbFcoc3RyLCBOVUxMLCAxMCk7CiAgICB9CgogICAgLyogc2V0IHNhdmluZyBsZXZlbCAoMCBmb3Igc2F2aW5nIGV2ZXJ5dGhpbmcsIDEgZm9yIHNhdmluZyBvbmx5IG1vZGlmaWVkIGtleXMpICovCiAgICBfc2V0X3JlZ2lzdHJ5X2xldmVscygxLCFhbGwscGVyaW9kKjEwMDApOwoKICAgIC8qIHNldHVwIGtleXMgdG8gc2F2ZSAqLwoKICAgIHJlcyA9IFRSVUU7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBXcml0ZXRvSG9tZVJlZ2lzdHJ5RmlsZXNXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICByZXMgPSAhSVNfT1BUSU9OX0ZBTFNFKHN0clswXSk7CiAgICB9CiAgICBpZiAocmVzKQogICAgewogICAgICAgIF9zYXZlX2F0X2V4aXQoaGtleV9jdXJyZW50X3VzZXIsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0NVUlJFTlRfVVNFUiApOwogICAgICAgIF9zYXZlX2F0X2V4aXQoaGtleV9sb2NhbF9tYWNoaW5lLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FKTsKICAgICAgICBfc2F2ZV9hdF9leGl0KGhrZXlfdXNlcnNfZGVmYXVsdCwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUKTsKICAgIH0KCiAgICBOdENsb3NlKGhrZXlfdXNlcnNfZGVmYXVsdCk7CiAgICBOdENsb3NlKGhrZXlfY3VycmVudF91c2VyKTsKICAgIE50Q2xvc2UoaGtleV91c2Vycyk7CiAgICBOdENsb3NlKGhrZXlfbG9jYWxfbWFjaGluZSk7CiAgICBOdENsb3NlKGhrZXlfY29uZmlnKTsKfQo=