LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBOT1RFUwogKiAgICBXaGVuIGNoYW5naW5nIHRoaXMgZmlsZSwgcGxlYXNlIHJlLXJ1biB0aGUgcmVndGVzdCBwcm9ncmFtIHRvIGVuc3VyZQogKiAgICB0aGUgY29uZGl0aW9ucyBhcmUgaGFuZGxlZCBwcm9wZXJseS4KICoKICogVE9ETwogKiAgICBTZWN1cml0eSBhY2Nlc3MKICogICAgT3B0aW9uIGhhbmRsaW5nCiAqICAgIFRpbWUgZm9yIFJlZ0VudW1LZXkqLCBSZWdRdWVyeUluZm9LZXkqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KI2RlZmluZSBOT05BTUVMRVNTU1RSVUNUCiNpbmNsdWRlICJudHN0YXR1cy5oIgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgoKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5lL2xpYnJhcnkuaCIKI2luY2x1ZGUgIndpbmUvc2VydmVyLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKI2luY2x1ZGUgImZpbGUuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChyZWcpOwoKI2RlZmluZSBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUICAiL3dpbmUudXNlcnJlZyIKI2RlZmluZSBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSAiL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIgICJ1c2VyLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQgICJ1c2VyZGVmLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FICJzeXN0ZW0ucmVnIgoKc3RhdGljIGNvbnN0IFdDSEFSIENsYXNzZXNSb290V1tdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0MnLCdsJywnYScsJ3MnLCdzJywnZScsJ3MnLDB9OwoKI2RlZmluZSBJU19PUFRJT05fRkFMU0UoY2gpIFwKICAgICgoY2gpID09ICduJyB8fCAoY2gpID09ICdOJyB8fCAoY2gpID09ICdmJyB8fCAoY2gpID09ICdGJyB8fCAoY2gpID09ICcwJykKCi8qIF94bWFsbG9jIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgKl94bWFsbG9jKCBzaXplX3Qgc2l6ZSApCnsKICAgIHZvaWQgKnJlczsKCiAgICByZXMgPSBtYWxsb2MgKHNpemUgPyBzaXplIDogMSk7CiAgICBpZiAocmVzID09IE5VTEwpIHsKICAgICAgICBXQVJOKCJWaXJ0dWFsIG1lbW9yeSBleGhhdXN0ZWQuXG4iKTsKICAgICAgICBleGl0ICgxKTsKICAgIH0KICAgIHJldHVybiByZXM7Cn0KCi8qIF94c3RyZHVwIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF94c3RyZHVwKExQQ1NUUiBzdHIpCnsKICAgIExQU1RSIHJldDsKICAgIHNpemVfdCBsZW4gPSBzdHJsZW4oc3RyKSArIDE7CgogICAgaWYgKCFzdHIpIHJldHVybiBOVUxMOwogICAgcmV0ID0gX3htYWxsb2MoIGxlbiApOwogICAgbWVtY3B5KCByZXQsIHN0ciwgbGVuICk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IGFuc2kgc3RyaW5nIHRvIHVuaWNvZGUgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBXU1RSIF9zdHJkdXBuQXRvVyhMUENTVFIgc3RyQSxzaXplX3QgbGVuQSkKewogICAgTFBXU1RSIHJldDsKICAgIERXT1JEIGxlbjsKCiAgICBpZiAoIXN0ckEpIHJldHVybiBOVUxMOwogICAgaWYgKFJ0bE11bHRpQnl0ZVRvVW5pY29kZVNpemUoICZsZW4sIHN0ckEsIGxlbkEgKSAhPSBTVEFUVVNfU1VDQ0VTUykgcmV0dXJuIE5VTEw7CgogICAgcmV0ID0gX3htYWxsb2MobGVuK3NpemVvZihXQ0hBUikpOwogICAgUnRsTXVsdGlCeXRlVG9Vbmljb2RlTihyZXQsIGxlbiwgTlVMTCwgc3RyQSwgbGVuQSk7CiAgICByZXRbbGVuIC8gc2l6ZW9mKFdDSEFSKV0gPSAwOwogICAgcmV0dXJuIHJldDsKfQoKLyogZHVtcCBhIFVuaWNvZGUgc3RyaW5nIHdpdGggcHJvcGVyIGVzY2FwaW5nIFtJbnRlcm5hbF0gKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci91bmljb2RlLmMgKi8Kc3RhdGljIGludCBfZHVtcF9zdHJXKGNvbnN0IFdDSEFSICpzdHIsc2l6ZV90IGxlbixGSUxFICpmLGNoYXIgZXNjYXBlWzJdKQp7CiAgICBzdGF0aWMgY29uc3QgY2hhciBlc2NhcGVzWzMyXSA9ICIuLi4uLi4uYWJ0bnZmci4uLi4uLi4uLi4uLi5lLi4uLiI7CiAgICBjaGFyIGJ1ZmZlclsyNTZdOwogICAgTFBTVFIgcG9zID0gYnVmZmVyOwogICAgaW50IGNvdW50ID0gMDsKCiAgICBmb3IgKDsgbGVuOyBzdHIrKywgbGVuLS0pCiAgICB7CiAgICAgICAgaWYgKHBvcyA+IGJ1ZmZlciArIHNpemVvZihidWZmZXIpIC0gOCkKICAgICAgICB7CiAgICAgICAgICAgIGZ3cml0ZSggYnVmZmVyLCBwb3MgLSBidWZmZXIsIDEsIGYgKTsKICAgICAgICAgICAgY291bnQgKz0gcG9zIC0gYnVmZmVyOwogICAgICAgICAgICBwb3MgPSBidWZmZXI7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyID4gMTI3KSAgLyogaGV4IGVzY2FwZSAqLwogICAgICAgIHsKICAgICAgICAgICAgaWYgKGxlbiA+IDEgJiYgc3RyWzFdIDwgMTI4ICYmIGlzeGRpZ2l0KChjaGFyKXN0clsxXSkpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFx4JTA0eCIsICpzdHIgKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxceCV4IiwgKnN0ciApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCpzdHIgPCAzMikgIC8qIG9jdGFsIG9yIEMgZXNjYXBlICovCiAgICAgICAgewogICAgICAgICAgICBpZiAoISpzdHIgJiYgbGVuID09IDEpIGNvbnRpbnVlOyAgLyogZG8gbm90IG91dHB1dCB0ZXJtaW5hdGluZyBOVUxMICovCiAgICAgICAgICAgIGlmIChlc2NhcGVzWypzdHJdICE9ICcuJykKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCVjIiwgZXNjYXBlc1sqc3RyXSApOwogICAgICAgICAgICBlbHNlIGlmIChsZW4gPiAxICYmIHN0clsxXSA+PSAnMCcgJiYgc3RyWzFdIDw9ICc3JykKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCUwM28iLCAqc3RyICk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCVvIiwgKnN0ciApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCpzdHIgPT0gJ1xcJyB8fCAqc3RyID09IGVzY2FwZVswXSB8fCAqc3RyID09IGVzY2FwZVsxXSkgKnBvcysrID0gJ1xcJzsKICAgICAgICAqcG9zKysgPSAqc3RyOwogICAgfQogICAgZndyaXRlKCBidWZmZXIsIHBvcyAtIGJ1ZmZlciwgMSwgZiApOwogICAgY291bnQgKz0gcG9zIC0gYnVmZmVyOwogICAgcmV0dXJuIGNvdW50Owp9CgovKiBjb252ZXJ0IGFuc2kgc3RyaW5nIHRvIHVuaWNvZGUgYW5kIGR1bXAgd2l0aCBwcm9wZXIgZXNjYXBpbmcgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9kdW1wX3N0ckF0b1coTFBDU1RSIHN0ckEsc2l6ZV90IGxlbixGSUxFICpmLGNoYXIgZXNjYXBlWzJdKQp7CiAgICBXQ0hBUiAqc3RyVzsKICAgIGludCByZXQ7CgogICAgaWYgKHN0ckEgPT0gTlVMTCkgcmV0dXJuIDA7CiAgICBzdHJXID0gX3N0cmR1cG5BdG9XKHN0ckEsbGVuKTsKICAgIHJldCA9IF9kdW1wX3N0clcoc3RyVyxsZW4sZixlc2NhcGUpOwogICAgZnJlZShzdHJXKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGEga2V5IHZhbHVlICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvcmVnaXN0cnkuYyAqLwpzdHJ1Y3Qga2V5X3ZhbHVlIHsKICAgIFdDSEFSICAgICAgICAgICAgKm5hbWVXOyAgIC8qIHZhbHVlIG5hbWUgKi8KICAgIGludCAgICAgICAgICAgICAgIHR5cGU7ICAgIC8qIHZhbHVlIHR5cGUgKi8KICAgIHNpemVfdCAgICAgICAgICAgIGxlbjsgICAgIC8qIHZhbHVlIGRhdGEgbGVuZ3RoIGluIGJ5dGVzICovCiAgICB2b2lkICAgICAgICAgICAgICpkYXRhOyAgICAvKiBwb2ludGVyIHRvIHZhbHVlIGRhdGEgKi8KfTsKCi8qIGR1bXAgYSB2YWx1ZSB0byBhIHRleHQgZmlsZSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3JlZ2lzdHJ5LmMgKi8Kc3RhdGljIHZvaWQgX2R1bXBfdmFsdWUoc3RydWN0IGtleV92YWx1ZSAqdmFsdWUsRklMRSAqZikKewogICAgaW50IGksIGNvdW50OwoKICAgIGlmICh2YWx1ZS0+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+dmFsbmFtZWxlbl0pOwogICAgICAgIHBkYXRhID0gTlVMTDsKICAgICAgICBpZiAoICh2YWx1ZS50eXBlPT1SRUdfU1opIHx8ICh2YWx1ZS50eXBlPT1SRUdfRVhQQU5EX1NaKSB8fCAodmFsdWUudHlwZT09UkVHX01VTFRJX1NaKSApIHsKICAgICAgICAgICAgcGRhdGEgPSBfc3RyZHVwbkF0b1codmFsdWUuZGF0YSx2YWx1ZS5sZW4pOwogICAgICAgICAgICB2YWx1ZS5sZW4gKj0gMjsKICAgICAgICB9CiAgICAgICAgaWYgKHBkYXRhICE9IE5VTEwpIHZhbHVlLmRhdGEgPSBwZGF0YTsKCiAgICAgICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgICAgIGZyZWUodmFsdWUubmFtZVcpOwogICAgICAgIGlmIChwZGF0YSAhPSBOVUxMKSBmcmVlKHBkYXRhKTsKCiAgICAgICAgLyogbmV4dCB2YWx1ZSAqLwogICAgICAgIGRrdiA9IChfdzk1ZGt2KikoKGNoYXIqKWRrditka3YtPnZhbG5hbWVsZW4rZGt2LT52YWxkYXRhbGVuKzB4MGMpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9kdW1wX2RrZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfZHVtcF9ka2UoTFBTVFIga2V5X25hbWUsX3c5NWNyZWcgKmNyZWcsX3c5NXJna24gKnJna24sX3c5NWRrZSAqZGtlLEZJTEUgKmYsaW50IGxldmVsKQp7CiAgICBfdzk1ZGtoICogZGtoOwogICAgTFBTVFIgbmV3X2tleV9uYW1lID0gTlVMTDsKCiAgICAvKiBzcGVjaWFsIHJvb3Qga2V5ICovCiAgICBpZiAoZGtlLT5uckxTID09IDB4ZmZmZiB8fCBka2UtPm5yTVM9PTB4ZmZmZikJCS8qIGVnLiB0aGUgcm9vdCBrZXkgaGFzIG5vIG5hbWUgKi8KICAgIHsKICAgICAgICAvKiBwYXJzZSB0aGUgb25lIHN1YmtleSAqLwogICAgICAgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgcmV0dXJuIF93OTVfZHVtcF9ka2Uoa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSxmLGxldmVsKTsKICAgICAgICAvKiBoYXMgbm8gc2libGluZyBrZXlzICovCiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIHNlYXJjaCBzdWJibG9jayAqLwogICAgaWYgKCEoZGtoID0gX3c5NV9sb29rdXBfZGtoKGNyZWcsIGRrZS0+bnJMUywgZGtlLT5uck1TKSkpIHsKICAgICAgICBFUlIoImRrZSBwb2ludGluZyB0byBtaXNzaW5nIGRraCAhXG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGxldmVsIDw9IDApIHsKICAgICAgICAvKiBjcmVhdGUgbmV3IHN1YmtleSBuYW1lICovCiAgICAgICAgc2l6ZV90IGxlbiA9IHN0cmxlbihrZXlfbmFtZSk7CiAgICAgICAgbmV3X2tleV9uYW1lID0gX3htYWxsb2MobGVuK2RraC0+a2V5bmFtZWxlbisyKTsKICAgICAgICBtZW1jcHkoIG5ld19rZXlfbmFtZSwga2V5X25hbWUsIGxlbiApOwogICAgICAgIGlmIChsZW4pIG5ld19rZXlfbmFtZVtsZW4rK10gPSAnXFwnOwogICAgICAgIG1lbWNweSggbmV3X2tleV9uYW1lICsgbGVuLCBka2gtPm5hbWUsIGRraC0+a2V5bmFtZWxlbiApOwogICAgICAgIG5ld19rZXlfbmFtZVtsZW4gKyBka2gtPmtleW5hbWVsZW5dID0gMDsKCiAgICAgICAgLyogd2FsayBzaWJsaW5nIGtleXMgKi8KICAgICAgICBpZiAoZGtlLT5uZXh0ICE9IDB4ZmZmZmZmZmYgKSB7CiAgICAgICAgICAgIGlmICghX3c5NV9kdW1wX2RrZShrZXlfbmFtZSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHQpLGYsbGV2ZWwpKSB7CiAgICAgICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIHdyaXRlIHRoZSBrZXkgcGF0aCAoc29tZXRoaW5nIGxpa2UgW1NvZnR3YXJlXFxNaWNyb3NvZnRcXC4uXSkgb25seSBpZjoKICAgICAgICAgICAxKSBrZXkgaGFzIHNvbWUgdmFsdWVzCiAgICAgICAgICAgMikga2V5IGhhcyBubyB2YWx1ZXMgYW5kIG5vIHN1YmtleXMKICAgICAgICAqLwogICAgICAgIGlmIChka2gtPnZhbHVlcyA+IDApIHsKICAgICAgICAgICAgLyogdGhlcmUgYXJlIHNvbWUgdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgICAgIGlmICghX3c5NV9kdW1wX2Rrdihka2gsIGRrZS0+bnJMUywgZGtlLT5uck1TLGYpKSB7CiAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoKGRrZS0+bmV4dHN1YiA9PSAweGZmZmZmZmZmKSAmJiAoZGtoLT52YWx1ZXMgPT0gMCkpIHsKICAgICAgICAgICAgLyogbm8gc3Via2V5cyBhbmQgbm8gdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQogICAgfSBlbHNlIG5ld19rZXlfbmFtZSA9IF94c3RyZHVwKGtleV9uYW1lKTsKCiAgICAvKiBuZXh0IHN1YiBrZXkgKi8KICAgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgewogICAgICAgIGlmICghX3c5NV9kdW1wX2RrZShuZXdfa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSxmLGxldmVsLTEpKSB7CiAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgIHJldHVybiBUUlVFOwp9Ci8qIGVuZCB3aW5kb3dzIDk1IGxvYWRlciAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd3MgTlQgcmVnaXN0cnkgbG9hZGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIE5UIFJFR0lTVFJZIExPQURFUiAqLwoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKI2lmbmRlZiBNQVBfRkFJTEVECiNkZWZpbmUgTUFQX0ZBSUxFRCAoKExQVk9JRCktMSkKI2VuZGlmCgojZGVmaW5lIE5UX1JFR19CTE9DS19TSVpFICAgICAgICAgICAgMHgxMDAwCgojZGVmaW5lIE5UX1JFR19IRUFERVJfQkxPQ0tfSUQgICAgICAgMHg2NjY3NjU3MgkvKiByZWdmICovCiNkZWZpbmUgTlRfUkVHX1BPT0xfQkxPQ0tfSUQgICAgICAgICAweDZFNjk2MjY4CS8qIGhiaW4gKi8KI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX0lEICAgICAgICAgIDB4NmI2ZSAvKiBuayAqLwojZGVmaW5lIE5UX1JFR19WQUxVRV9CTE9DS19JRCAgICAgICAgMHg2Yjc2IC8qIHZrICovCgovKiBzdWJibG9ja3Mgb2YgbmsgKi8KI2RlZmluZSBOVF9SRUdfSEFTSF9CTE9DS19JRCAgICAgICAgIDB4NjY2YyAvKiBsZiAqLwojZGVmaW5lIE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQgICAgICAgMHg2OTZjIC8qIGxpICovCiNkZWZpbmUgTlRfUkVHX1JJX0JMT0NLX0lECSAgICAgMHg2OTcyIC8qIHJpICovCgojZGVmaW5lIE5UX1JFR19LRVlfQkxPQ0tfVFlQRSAgICAgICAgMHgyMAojZGVmaW5lIE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFICAgMHgyYwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiAweDY2Njc2NTcyICdyZWdmJyovCiAgICBEV09SRAl1azE7CQkvKiAweDA0ICovCiAgICBEV09SRAl1azI7CQkvKiAweDA4ICovCiAgICBGSUxFVElNRQlEYXRlTW9kaWZpZWQ7CS8qIDB4MGMgKi8KICAgIERXT1JECXVrMzsJCS8qIDB4MTQgKi8KICAgIERXT1JECXVrNDsJCS8qIDB4MTggKi8KICAgIERXT1JECXVrNTsJCS8qIDB4MWMgKi8KICAgIERXT1JECXVrNjsJCS8qIDB4MjAgKi8KICAgIERXT1JECVJvb3RLZXlCbG9jazsJLyogMHgyNCAqLwogICAgRFdPUkQJQmxvY2tTaXplOwkvKiAweDI4ICovCiAgICBEV09SRCAgIHVrN1sxMTZdOwogICAgRFdPUkQJQ2hlY2tzdW07IC8qIGF0IG9mZnNldCAweDFGQyAqLwp9IG50X3JlZ2Y7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlibG9ja3NpemU7CiAgICBCWVRFCWRhdGFbMV07Cn0gbnRfaGJpbl9zdWI7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qIDB4NkU2OTYyNjggJ2hiaW4nICovCiAgICBEV09SRAlvZmZfcHJldjsKICAgIERXT1JECW9mZl9uZXh0OwogICAgRFdPUkQJdWsxOwogICAgRFdPUkQJdWsyOwkJLyogMHgxMCAqLwogICAgRFdPUkQJdWszOwkJLyogMHgxNCAqLwogICAgRFdPUkQJdWs0OwkJLyogMHgxOCAqLwogICAgRFdPUkQJc2l6ZTsJCS8qIDB4MUMgKi8KICAgIG50X2hiaW5fc3ViCWhiaW5fc3ViOwkvKiAweDIwICovCn0gbnRfaGJpbjsKCi8qCiAqIHRoZSB2YWx1ZV9saXN0IGNvbnNpc3RzIG9mIG9mZnNldHMgdG8gdGhlIHZhbHVlcyAodmspCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECVN1YkJsb2NrSWQ7CQkvKiAweDAwIDB4NkI2RSAqLwogICAgV09SRAlUeXBlOwkJCS8qIDB4MDIgZm9yIHRoZSByb290LWtleTogMHgyQywgb3RoZXJ3aXNlIDB4MjAqLwogICAgRklMRVRJTUUJd3JpdGV0aW1lOwkvKiAweDA0ICovCiAgICBEV09SRAl1azE7CQkJLyogMHgwQyAqLwogICAgRFdPUkQJcGFyZW50X29mZjsJCS8qIDB4MTAgT2Zmc2V0IG9mIE93bmVyL1BhcmVudCBrZXkgKi8KICAgIERXT1JECW5yX3N1YmtleXM7CQkvKiAweDE0IG51bWJlciBvZiBzdWItS2V5cyAqLwogICAgRFdPUkQJdWs4OwkJCS8qIDB4MTggKi8KICAgIERXT1JECWxmX29mZjsJCQkvKiAweDFDIE9mZnNldCBvZiB0aGUgc3ViLWtleSBsZi1SZWNvcmRzICovCiAgICBEV09SRAl1azI7CQkJLyogMHgyMCAqLwogICAgRFdPUkQJbnJfdmFsdWVzOwkJLyogMHgyNCBudW1iZXIgb2YgdmFsdWVzICovCiAgICBEV09SRAl2YWx1ZWxpc3Rfb2ZmOwkJLyogMHgyOCBPZmZzZXQgb2YgdGhlIFZhbHVlLUxpc3QgKi8KICAgIERXT1JECW9mZl9zazsJCQkvKiAweDJjIE9mZnNldCBvZiB0aGUgc2stUmVjb3JkICovCiAgICBEV09SRAlvZmZfY2xhc3M7CQkvKiAweDMwIE9mZnNldCBvZiB0aGUgQ2xhc3MtTmFtZSAqLwogICAgRFdPUkQJdWszOwkJCS8qIDB4MzQgKi8KICAgIERXT1JECXVrNDsJCQkvKiAweDM4ICovCiAgICBEV09SRAl1azU7CQkJLyogMHgzYyAqLwogICAgRFdPUkQJdWs2OwkJCS8qIDB4NDAgKi8KICAgIERXT1JECXVrNzsJCQkvKiAweDQ0ICovCiAgICBXT1JECW5hbWVfbGVuOwkJLyogMHg0OCBuYW1lLWxlbmd0aCAqLwogICAgV09SRAljbGFzc19sZW47CQkvKiAweDRhIGNsYXNzLW5hbWUgbGVuZ3RoICovCiAgICBjaGFyCW5hbWVbMV07CQkvKiAweDRjIGtleS1uYW1lICovCn0gbnRfbms7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlvZmZfbms7CS8qIDB4MDAgKi8KICAgIERXT1JECW5hbWU7CS8qIDB4MDQgKi8KfSBoYXNoX3JlYzsKCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwIDB4NjY2YyAqLwogICAgV09SRAlucl9rZXlzOwkvKiAweDA2ICovCiAgICBoYXNoX3JlYwloYXNoX3JlY1sxXTsKfSBudF9sZjsKCi8qCiBsaXN0IG9mIHN1YmtleXMgd2l0aG91dCBoYXNoCgogbGkgLS0rLS0+bmsKICAgICAgfAogICAgICArLS0+bmsKICovCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwIDB4Njk2YyAqLwogICAgV09SRAlucl9rZXlzOwogICAgRFdPUkQJb2ZmX25rWzFdOwp9IG50X2xpOwoKLyoKIHRoaXMgaXMgYSBpbnRlcm1lZGlhdGUgbm9kZQoKIHJpIC0tKy0tPmxpLS0rLS0+bmsKICAgICAgfCAgICAgICArCiAgICAgIHwgICAgICAgKy0tPm5rCiAgICAgIHwKICAgICAgKy0tPmxpLS0rLS0+bmsKICAgICAgICAgICAgICArCgkgICAgICArLS0+bmsKICovCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwIDB4Njk3MiAqLwogICAgV09SRAlucl9saTsJCS8qIDB4MDIgbnVtYmVyIG9mZiBvZmZzZXRzICovCiAgICBEV09SRAlvZmZfbGlbMV07CS8qIDB4MDQgcG9pbnRzIHRvIGxpICovCn0gbnRfcmk7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAndmsnICovCiAgICBXT1JECW5hbV9sZW47CiAgICBEV09SRAlkYXRhX2xlbjsKICAgIERXT1JECWRhdGFfb2ZmOwogICAgRFdPUkQJdHlwZTsKICAgIFdPUkQJZmxhZzsKICAgIFdPUkQJdWsxOwogICAgY2hhcgluYW1lWzFdOwp9IG50X3ZrOwoKLyoKICogZ2V0cyBhIHZhbHVlCiAqCiAqIHZrLT5mbGFnOgogKiAgMCB2YWx1ZSBpcyBhIGRlZmF1bHQgdmFsdWUKICogIDEgdGhlIHZhbHVlIGhhcyBhIG5hbWUKICoKICogdmstPmRhdGFfbGVuCiAqICBsZW4gb2YgdGhlIHdob2xlIGRhdGEgYmxvY2sKICogIC0gcmVnX3N6ICh1bmljb2RlKQogKiAgICBieXRlcyBpbmNsdWRpbmcgdGhlIHRlcm1pbmF0aW5nIFwwID0gMioobnVtYmVyX29mX2NoYXJzKzEpCiAqICAtIHJlZ19kd29yZCwgcmVnX2JpbmFyeToKICogICAgaWYgaGlnaGVzdCBiaXQgb2YgZGF0YV9sZW4gaXMgc2V0IGRhdGFfb2ZmIGNvbnRhaW5zIHRoZSB2YWx1ZQogKi8Kc3RhdGljIGludCBfbnRfZHVtcF92ayhMUFNUUiBrZXlfbmFtZSwgY2hhciAqYmFzZSwgbnRfdmsgKnZrLEZJTEUgKmYpCnsKICAgIEJZVEUgKnBkYXRhID0gKEJZVEUgKikoYmFzZSt2ay0+ZGF0YV9vZmYrNCk7IC8qIHN0YXJ0IG9mIGRhdGEgKi8KICAgIHN0cnVjdCBrZXlfdmFsdWUgdmFsdWU7CgogICAgaWYgKHZrLT5pZCAhPSBOVF9SRUdfVkFMVUVfQkxPQ0tfSUQpIHsKICAgICAgICBFUlIoInVua25vd24gYmxvY2sgZm91bmQgKDB4JTA0eCksIHBsZWFzZSByZXBvcnQhXG4iLCB2ay0+aWQpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICB2YWx1ZS5uYW1lVyA9IF9zdHJkdXBuQXRvVyh2ay0+bmFtZSx2ay0+bmFtX2xlbik7CiAgICB2YWx1ZS50eXBlID0gdmstPnR5cGU7CiAgICB2YWx1ZS5sZW4gPSAodmstPmRhdGFfbGVuICYgMHg3ZmZmZmZmZik7CiAgICB2YWx1ZS5kYXRhID0gKHZrLT5kYXRhX2xlbiAmIDB4ODAwMDAwMDApID8gKExQQllURSkmKHZrLT5kYXRhX29mZik6IHBkYXRhOwoKICAgIF9kdW1wX3ZhbHVlKCZ2YWx1ZSxmKTsKICAgIGZyZWUodmFsdWUubmFtZVcpOwoKICAgIHJldHVybiBUUlVFOwp9CgovKiBpdCdzIGNhbGxlZCBmcm9tIF9udF9kdW1wX2xmKCkgKi8Kc3RhdGljIGludCBfbnRfZHVtcF9uayhMUFNUUiBrZXlfbmFtZSxjaGFyICpiYXNlLG50X25rICpuayxGSUxFICpmLGludCBsZXZlbCk7CgovKgogKiBnZXQgdGhlIHN1YmtleXMKICoKICogdGhpcyBzdHJ1Y3R1cmUgY29udGFpbnMgdGhlIGhhc2ggb2YgYSBrZXluYW1lIGFuZCBwb2ludHMgdG8gYWxsCiAqIHN1YmtleXMKICoKICogZXhjZXB0aW9uOiBpZiB0aGUgaWQgaXMgJ2lsJyB0aGVyZSBhcmUgbm8gaGFzaCB2YWx1ZXMgYW5kIGV2ZXJ5CiAqIGR3b3JkIGlzIGEgb2Zmc2V0CiAqLwpzdGF0aWMgaW50IF9udF9kdW1wX2xmKExQU1RSIGtleV9uYW1lLCBjaGFyICpiYXNlLCBpbnQgc3Via2V5cywgbnRfbGYgKmxmLCBGSUxFICpmLCBpbnQgbGV2ZWwpCnsKICAgIGludCBpOwoKICAgIGlmIChsZi0+aWQgPT0gTlRfUkVHX0hBU0hfQkxPQ0tfSUQpIHsKICAgICAgICBpZiAoc3Via2V5cyAhPSBsZi0+bnJfa2V5cykgZ290byBlcnJvcjE7CgogICAgICAgIGZvciAoaT0wOyBpPGxmLT5ucl9rZXlzOyBpKyspCiAgICAgICAgICAgIGlmICghX250X2R1bXBfbmsoa2V5X25hbWUsIGJhc2UsIChudF9uayopKGJhc2UrbGYtPmhhc2hfcmVjW2ldLm9mZl9uays0KSwgZiwgbGV2ZWwpKSBnb3RvIGVycm9yOwogICAgfSBlbHNlIGlmIChsZi0+aWQgPT0gTlRfUkVHX05PSEFTSF9CTE9DS19JRCkgewogICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKWxmOwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCiAgICAgICAgZm9yIChpPTA7IGk8bGktPm5yX2tleXM7IGkrKykKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9uayhrZXlfbmFtZSwgYmFzZSwgKG50X25rKikoYmFzZStsaS0+b2ZmX25rW2ldKzQpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfUklfQkxPQ0tfSUQpIHsgIC8qIHJpICovCiAgICAgICAgbnRfcmkgKiByaSA9IChudF9yaSopbGY7CiAgICAgICAgaW50IGxpX3N1YmtleXMgPSAwOwoKICAgICAgICAvKiBjb3VudCBhbGwgc3Via2V5cyAqLwogICAgICAgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKSB7CiAgICAgICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmKGxpLT5pZCAhPSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKSBnb3RvIGVycm9yMjsKICAgICAgICAgICAgbGlfc3Via2V5cyArPSBsaS0+bnJfa2V5czsKICAgICAgICB9CgogICAgICAgIC8qIGNoZWNrIG51bWJlciAqLwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpX3N1YmtleXMpIGdvdG8gZXJyb3IxOwoKICAgICAgICAvKiBsb29wIHRocm91Z2ggdGhlIGtleXMgKi8KICAgICAgICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykgewogICAgICAgICAgICBudF9saSAqbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmICghX250X2R1bXBfbGYoa2V5X25hbWUsIGJhc2UsIGxpLT5ucl9rZXlzLCAobnRfbGYqKWxpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgfSBlbHNlIGdvdG8gZXJyb3IyOwoKICAgIHJldHVybiBUUlVFOwoKZXJyb3IyOgogICAgaWYgKGxmLT5pZCA9PSAweDY4NmMpCiAgICAgICAgRklYTUUoInVua25vd24gV2luIFhQIG5vZGUgaWQgMHg2ODZjOiBkbyB3ZSBuZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBpdCA/XG4iKTsKICAgIGVsc2UKICAgICAgICBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBsZi0+aWQpOwogICAgcmV0dXJuIFRSVUU7CgplcnJvcjE6CiAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgKGluY29uc2lzdGVudCBudW1iZXIgb2Ygc3Via2V5cylcbiIpOwogICAgcmV0dXJuIEZBTFNFOwoKZXJyb3I6CiAgICBFUlIoImVycm9yIHJlYWRpbmcgbGYgYmxvY2tcbiIpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKiBfbnRfZHVtcF9uayBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX250X2R1bXBfbmsoTFBTVFIga2V5X25hbWUsY2hhciAqYmFzZSxudF9uayAqbmssRklMRSAqZixpbnQgbGV2ZWwpCnsKICAgIHVuc2lnbmVkIGludCBuOwogICAgRFdPUkQgKnZsOwogICAgTFBTVFIgbmV3X2tleV9uYW1lID0gTlVMTDsKCiAgICBUUkFDRSgiJXNcbiIsIGtleV9uYW1lKTsKCiAgICBpZiAobmstPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5rbm93biBub2RlIGlkIDB4JTA0eCwgcGxlYXNlIHJlcG9ydCFcbiIsIG5rLT5TdWJCbG9ja0lkKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKChuay0+VHlwZSE9TlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpICYmICgoKG50X25rKikoYmFzZStuay0+cGFyZW50X29mZis0KSktPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkpIHsKICAgICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCFcbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiBjcmVhdGUgdGhlIG5ldyBrZXkgKi8KICAgIGlmIChsZXZlbCA8PSAwKSB7CiAgICAgICAgLyogY3JlYXRlIG5ldyBzdWJrZXkgbmFtZSAqLwogICAgICAgIHNpemVfdCBsZW4gPSBzdHJsZW4oa2V5X25hbWUpOwogICAgICAgIG5ld19rZXlfbmFtZSA9IF94bWFsbG9jKCBsZW4rbmstPm5hbWVfbGVuKzIgKTsKICAgICAgICBtZW1jcHkoIG5ld19rZXlfbmFtZSwga2V5X25hbWUsIGxlbiApOwogICAgICAgIGlmIChsZW4pIG5ld19rZXlfbmFtZVtsZW4rK10gPSAnXFwnOwogICAgICAgIG1lbWNweSggbmV3X2tleV9uYW1lICsgbGVuLCBuay0+bmFtZSwgbmstPm5hbWVfbGVuICk7CiAgICAgICAgbmV3X2tleV9uYW1lW2xlbiArIG5rLT5uYW1lX2xlbl0gPSAwOwoKICAgICAgICAvKiB3cml0ZSB0aGUga2V5IHBhdGggKHNvbWV0aGluZyBsaWtlIFtTb2Z0d2FyZVxcTWljcm9zb2Z0XFwuLl0pIG9ubHkgaWY6CiAgICAgICAgICAgMSkga2V5IGhhcyBzb21lIHZhbHVlcwogICAgICAgICAgIDIpIGtleSBoYXMgbm8gdmFsdWVzIGFuZCBubyBzdWJrZXlzCiAgICAgICAgKi8KICAgICAgICBpZiAobmstPm5yX3ZhbHVlcyA+IDApIHsKICAgICAgICAgICAgLyogdGhlcmUgYXJlIHNvbWUgdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQogICAgICAgIGlmICgobmstPm5yX3N1YmtleXMgPT0gMCkgJiYgKG5rLT5ucl92YWx1ZXMgPT0gMCkpIHsKICAgICAgICAgICAgLyogbm8gc3Via2V5cyBhbmQgbm8gdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQoKICAgICAgICAvKiBsb29wIHRyb3VnaCB0aGUgdmFsdWUgbGlzdCAqLwogICAgICAgIHZsID0gKERXT1JEICopKGJhc2UrbmstPnZhbHVlbGlzdF9vZmYrNCk7CiAgICAgICAgZm9yIChuPTA7IG48bmstPm5yX3ZhbHVlczsgbisrKSB7CiAgICAgICAgICAgIG50X3ZrICogdmsgPSAobnRfdmsqKShiYXNlK3ZsW25dKzQpOwogICAgICAgICAgICBpZiAoIV9udF9kdW1wX3ZrKG5ld19rZXlfbmFtZSwgYmFzZSwgdmssIGYpKSB7CiAgICAgICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgbmV3X2tleV9uYW1lID0gX3hzdHJkdXAoa2V5X25hbWUpOwoKICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUgc3Via2V5cyAqLwogICAgaWYgKG5rLT5ucl9zdWJrZXlzKSB7CiAgICAgICAgbnRfbGYgKmxmID0gKG50X2xmKikoYmFzZStuay0+bGZfb2ZmKzQpOwogICAgICAgIGlmICghX250X2R1bXBfbGYobmV3X2tleV9uYW1lLCBiYXNlLCBuay0+bnJfc3Via2V5cywgbGYsIGYsIGxldmVsLTEpKSB7CiAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyogZW5kIG50IGxvYWRlciAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NldF9yZWdpc3RyeV9sZXZlbHMgW0ludGVybmFsXQogKgogKiBzZXQgbGV2ZWwgdG8gMCBmb3IgbG9hZGluZyBzeXN0ZW0gZmlsZXMKICogc2V0IGxldmVsIHRvIDEgZm9yIGxvYWRpbmcgdXNlciBmaWxlcwogKi8Kc3RhdGljIHZvaWQgX3NldF9yZWdpc3RyeV9sZXZlbHMoaW50IGxldmVsLGludCBzYXZpbmcsaW50IHBlcmlvZCkKewogICAgU0VSVkVSX1NUQVJUX1JFUSggc2V0X3JlZ2lzdHJ5X2xldmVscyApCiAgICB7CglyZXEtPmN1cnJlbnQgPSBsZXZlbDsKCXJlcS0+c2F2aW5nICA9IHNhdmluZzsKICAgICAgICByZXEtPnBlcmlvZCAgPSBwZXJpb2Q7CiAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICB9CiAgICBTRVJWRVJfRU5EX1JFUTsKfQoKLyogX3NhdmVfYXRfZXhpdCBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9zYXZlX2F0X2V4aXQoSEtFWSBoa2V5LExQQ1NUUiBwYXRoKQp7CiAgICBMUENTVFIgY29uZmRpciA9IHdpbmVfZ2V0X2NvbmZpZ19kaXIoKTsKCiAgICBTRVJWRVJfU1RBUlRfUkVRKCBzYXZlX3JlZ2lzdHJ5X2F0ZXhpdCApCiAgICB7CiAgICAgICAgcmVxLT5oa2V5ID0gaGtleTsKICAgICAgICB3aW5lX3NlcnZlcl9hZGRfZGF0YSggcmVxLCBjb25mZGlyLCBzdHJsZW4oY29uZmRpcikgKTsKICAgICAgICB3aW5lX3NlcnZlcl9hZGRfZGF0YSggcmVxLCBwYXRoLCBzdHJsZW4ocGF0aCkrMSApOwogICAgICAgIHdpbmVfc2VydmVyX2NhbGwoIHJlcSApOwogICAgfQogICAgU0VSVkVSX0VORF9SRVE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2FsbG9jYXRlX2RlZmF1bHRfa2V5cyBbSW50ZXJuYWxdCiAqIFJlZ2lzdHJ5IGluaXRpYWxpc2F0aW9uLCBhbGxvY2F0ZXMgc29tZSBkZWZhdWx0IGtleXMuCiAqLwpzdGF0aWMgdm9pZCBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzKHZvaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBTdGF0RGF0YVdbXSA9IHsnRCcsJ3knLCduJywnRCcsJ2EnLCd0JywnYScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUCcsJ2UnLCdyJywnZicsJ1MnLCd0JywnYScsJ3QnLCdzJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywndCcsJ2EnLCd0JywnRCcsJ2EnLCd0JywnYScsMH07CiAgICBIS0VZIGhrZXk7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CgogICAgVFJBQ0UoIih2b2lkKVxuIik7CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBTdGF0RGF0YVcgKTsKICAgIGlmICghTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkgTnRDbG9zZSggaGtleSApOwp9CgpzdGF0aWMgdm9pZCBnZXRfd2luZG93c19kaXIoV0NIQVIqIGJ1ZmZlciwgdW5zaWduZWQgbGVuKQp7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyAgIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyAgICAgIG5hbWVXLCBrZXlXOwogICAgSEtFWSAgICAgICAgICAgICAgICBoa2V5OwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgaWYgKFJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsICJNYWNoaW5lXFxTb2Z0d2FyZVxcV2luZVxcV2luZVxcQ29uZmlnXFx3aW5lIiApKQogICAgewogICAgICAgIGlmICghTnRPcGVuS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyICkpCiAgICAgICAgewogICAgICAgICAgICBjaGFyIHRtcFtNQVhfUEFUSE5BTUVfTEVOKnNpemVvZihXQ0hBUikgKyBzaXplb2YoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04pXTsKICAgICAgICAgICAgRFdPUkQgY291bnQ7CgogICAgICAgICAgICBSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJmtleVcsICJXaW5kb3dzIik7CiAgICAgICAgICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5LCAma2V5VywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgICAgICAgICAgbWVtY3B5KGJ1ZmZlciwgc3RyLCBtaW4oKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGFMZW5ndGgsIGxlbikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAma2V5VyApOwogICAgICAgIH0KICAgICAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CiAgICB9Cn0KCgojZGVmaW5lIFJFR19ET05UTE9BRCAtMQojZGVmaW5lIFJFR19XSU4zMSAgICAgMAojZGVmaW5lIFJFR19XSU45NSAgICAgMQojZGVmaW5lIFJFR19XSU5OVCAgICAgMgoKLyogcmV0dXJuIHRoZSB0eXBlIG9mIG5hdGl2ZSByZWdpc3RyeSBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX2dldF9yZWdfdHlwZShjb25zdCBXQ0hBUiogd2luZGlyKQp7CiAgICBXQ0hBUiB0bXBbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBpbnQgcmV0ID0gUkVHX1dJTjMxOwogICAgc3RhdGljIGNvbnN0IFdDSEFSIG50X3JlZ19wYXRoV1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJzMnLCcyJywnXFwnLCdjJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgd2luOXhfcmVnX3BhdGhXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnLicsJ2QnLCdhJywndCcsMH07CgogICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0zMi9jb25maWcvc3lzdGVtIC0tPiB3aW5udCAqLwogICAgc3RyY3B5Vyh0bXAsIHdpbmRpcik7CiAgICBzdHJjYXRXKHRtcCwgbnRfcmVnX3BhdGhXKTsKICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzVyh0bXApICE9IChEV09SRCktMSkKICAgICAgcmV0ID0gUkVHX1dJTk5UOwogICAgZWxzZQogICAgewogICAgICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0uZGF0IC0tPiB3aW45NSAqLwogICAgICBzdHJjcHlXKHRtcCwgd2luZGlyKTsKICAgICAgc3RyY2F0Vyh0bXAsIHdpbjl4X3JlZ19wYXRoVyk7CiAgICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzVyh0bXApICE9IChEV09SRCktMSkKICAgICAgICByZXQgPSBSRUdfV0lOOTU7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKLyogbG9hZCB0aGUgcmVnaXN0cnkgZmlsZSBpbiB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIGxvYWRfd2luZV9yZWdpc3RyeShIS0VZIGhrZXksTFBDU1RSIGZuKQp7CiAgICBIQU5ETEUgZmlsZTsKICAgIGlmICgoZmlsZSA9IEZJTEVfQ3JlYXRlRmlsZSggZm4sIEdFTkVSSUNfUkVBRCwgMCwgTlVMTCwgT1BFTl9FWElTVElORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRV9BVFRSSUJVVEVfTk9STUFMLCAwLCBUUlVFLCBEUklWRV9VTktOT1dOICkpKQogICAgewogICAgICAgIFNFUlZFUl9TVEFSVF9SRVEoIGxvYWRfcmVnaXN0cnkgKQogICAgICAgIHsKICAgICAgICAgICAgcmVxLT5oa2V5ICAgID0gaGtleTsKICAgICAgICAgICAgcmVxLT5maWxlICAgID0gZmlsZTsKICAgICAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICAgICAgfQogICAgICAgIFNFUlZFUl9FTkRfUkVROwogICAgICAgIENsb3NlSGFuZGxlKCBmaWxlICk7CiAgICB9Cn0KCi8qIGdlbmVyYXRlIGFuZCByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHRtcCBmaWxlIGFuZCBhc3NvY2lhdGVkIHN0cmVhbSBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfZ2V0X3RtcF9mbihGSUxFICoqZikKewogICAgTFBTVFIgcmV0OwogICAgaW50IHRtcF9mZCxjb3VudDsKCiAgICByZXQgPSBfeG1hbGxvYyg1MCk7CiAgICBmb3IgKGNvdW50ID0gMDs7KSB7CiAgICAgICAgc3ByaW50ZihyZXQsIi90bXAvcmVnJWx4JTA0eC50bXAiLChsb25nKWdldHBpZCgpLGNvdW50KyspOwogICAgICAgIGlmICgodG1wX2ZkID0gb3BlbihyZXQsT19DUkVBVCB8IE9fRVhDTCB8IE9fV1JPTkxZLDA2NjYpKSAhPSAtMSkgYnJlYWs7CiAgICAgICAgaWYgKGVycm5vICE9IEVFWElTVCkgewogICAgICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgZXJyb3Igd2hpbGUgb3BlbigpIGNhbGw6ICVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgIGZyZWUocmV0KTsKICAgICAgICAgICAgKmYgPSBOVUxMOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCgqZiA9IGZkb3Blbih0bXBfZmQsInciKSkgPT0gTlVMTCkgewogICAgICAgIEVSUigiVW5leHBlY3RlZCBlcnJvciB3aGlsZSBmZG9wZW4oKSBjYWxsOiAlc1xuIixzdHJlcnJvcihlcnJubykpOwogICAgICAgIGNsb3NlKHRtcF9mZCk7CiAgICAgICAgZnJlZShyZXQpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgd2luOTUgbmF0aXZlIHJlZ2lzdHJ5IGZpbGUgdG8gd2luZSBmb3JtYXQgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX2NvbnZlcnRfd2luOTVfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoTFBDV1NUUiBmbiwgaW50IGxldmVsKQp7CiAgICBIQU5ETEUgaEZpbGUsIGhNYXBwaW5nOwogICAgRklMRSAqZjsKICAgIHZvaWQgKmJhc2U7CiAgICBMUFNUUiByZXQgPSBOVUxMOwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIExBUkdFX0lOVEVHRVIgbGdfaW50OwogICAgTlRTVEFUVVMgbnRzOwogICAgU0laRV9UIGxlbjsKCiAgICBfdzk1Y3JlZyAqY3JlZzsKICAgIF93OTVyZ2tuICpyZ2tuOwogICAgX3c5NWRrZSAqZGtlLCAqcm9vdF9ka2U7CgogICAgaEZpbGUgPSBDcmVhdGVGaWxlVyggZm4sIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELCBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwICk7CiAgICBpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CgogICAgYXR0ci5MZW5ndGggICAgICAgICAgICAgICAgICAgPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgICAgICAgICAgICA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgICAgICAgICAgICAgICA9IE5VTEw7CiAgICBhdHRyLkF0dHJpYnV0ZXMgICAgICAgICAgICAgICA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciAgICAgICA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgbGdfaW50LlF1YWRQYXJ0ID0gMDsKICAgIG50cyA9IE50Q3JlYXRlU2VjdGlvbiggJmhNYXBwaW5nLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RBTkRBUkRfUklHSFRTX1JFUVVJUkVEfFNFQ1RJT05fUVVFUll8U0VDVElPTl9NQVBfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF0dHIsICZsZ19pbnQsIFBBR0VfUkVBRE9OTFksIFNFQ19DT01NSVQsIGhGaWxlICk7CiAgICBpZiAobnRzICE9IFNUQVRVU19TVUNDRVNTKSBnb3RvIGVycm9yMTsKCiAgICBiYXNlID0gTlVMTDsgbGVuID0gMDsKICAgIG50cyA9IE50TWFwVmlld09mU2VjdGlvbiggaE1hcHBpbmcsIEdldEN1cnJlbnRQcm9jZXNzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZiYXNlLCAwLCAwLCAmbGdfaW50LCAmbGVuLCBWaWV3U2hhcmUsIDAsIAoJCQkgICAgICBQQUdFX1JFQURPTkxZKTsKICAgIE50Q2xvc2UoIGhNYXBwaW5nICk7CiAgICBpZiAobnRzICE9IFNUQVRVU19TVUNDRVNTKSBnb3RvIGVycm9yMTsKCiAgICAvKiBjb250cm9sIHNpZ25hdHVyZSAqLwogICAgaWYgKCooTFBEV09SRCliYXNlICE9IFc5NV9SRUdfQ1JFR19JRCkgewogICAgICAgIEVSUigidW5hYmxlIHRvIGxvYWQgbmF0aXZlIHdpbjk1IHJlZ2lzdHJ5IGZpbGUgJXM6IHVua25vd24gc2lnbmF0dXJlLlxuIiwKICAgICAgICAgICAgZGVidWdzdHJfdyhmbikpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgY3JlZyA9IGJhc2U7CiAgICAvKiBsb2FkIHRoZSBoZWFkZXIgKHJna24pICovCiAgICByZ2tuID0gKF93OTVyZ2tuKikoY3JlZyArIDEpOwogICAgaWYgKHJna24tPmlkICE9IFc5NV9SRUdfUkdLTl9JRCkgewogICAgICAgIEVSUigic2Vjb25kIElGRiBoZWFkZXIgbm90IFJHS04sIGJ1dCAlbHhcbiIsIHJna24tPmlkKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHJna24tPnJvb3Rfb2ZmICE9IDB4MjApIHsKICAgICAgICBFUlIoInJna24tPnJvb3Rfb2ZmIG5vdCAweDIwLCBwbGVhc2UgcmVwb3J0ICFcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+bGFzdF9ka2UgPiByZ2tuLT5zaXplKQogICAgewogICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgbGFzdF9ka2UgPiBzaXplIVxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICAvKiB2ZXJpZnkgbGFzdCBka2UgKi8KICAgIGRrZSA9IChfdzk1ZGtlKikoKGNoYXIqKXJna24gKyByZ2tuLT5sYXN0X2RrZSk7CiAgICBpZiAoZGtlLT54MSAhPSAweDgwMDAwMDAwKQogICAgeyAvKiB3cm9uZyBtYWdpYyAqLwogICAgICBFUlIoImxhc3QgZGtlIGludmFsaWQgIVxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+c2l6ZSA+IGNyZWctPnJnZGJfb2ZmKQogICAgewogICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgcmdrbiBzaXplID4gcmdkYl9vZmYgIVxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICByb290X2RrZSA9IChfdzk1ZGtlKikoKGNoYXIqKXJna24gKyByZ2tuLT5yb290X29mZik7CiAgICBpZiAoIChyb290X2RrZS0+cHJldmx2bCAhPSAweGZmZmZmZmZmKSB8fCAocm9vdF9ka2UtPm5leHQgIT0gMHhmZmZmZmZmZikgKQogICAgewogICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISBpbnZhbGlkIHJvb3QgZGtlICFcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKCAocmV0ID0gX2dldF90bXBfZm4oJmYpKSA9PSBOVUxMKSBnb3RvIGVycm9yOwogICAgZnByaW50ZihmLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gMiIpOwogICAgX3c5NV9kdW1wX2RrZSgiIixjcmVnLHJna24scm9vdF9ka2UsZixsZXZlbCk7CiAgICBmY2xvc2UoZik7CgplcnJvcjoKICAgIGlmKHJldCA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJVbmFibGUgdG8gbG9hZCBuYXRpdmUgd2luOTUgcmVnaXN0cnkgZmlsZSAlcy5cbiIsIGRlYnVnc3RyX3coZm4pKTsKICAgICAgICBFUlIoIlBsZWFzZSByZXBvcnQgdGhpcy5cbiIpOwogICAgICAgIEVSUigiTWFrZSBhIGJhY2t1cCBvZiB0aGUgZmlsZSwgcnVuIGEgZ29vZCByZWcgY2xlYW5lciBwcm9ncmFtIGFuZCB0cnkgYWdhaW4hXG4iKTsKICAgIH0KCiAgICBOdFVubWFwVmlld09mU2VjdGlvbiggR2V0Q3VycmVudFByb2Nlc3MoKSwgYmFzZSApOwplcnJvcjE6CiAgICBOdENsb3NlKGhGaWxlKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgd2lubnQgbmF0aXZlIHJlZ2lzdHJ5IGZpbGUgdG8gd2luZSBmb3JtYXQgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX2NvbnZlcnRfd2lubnRfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoTFBDV1NUUiBmbiwgaW50IGxldmVsKQp7CiAgICBGSUxFICpmOwogICAgdm9pZCAqYmFzZTsKICAgIExQU1RSIHJldCA9IE5VTEw7CiAgICBIQU5ETEUgaEZpbGU7CiAgICBIQU5ETEUgaE1hcHBpbmc7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgTEFSR0VfSU5URUdFUiBsZ19pbnQ7CiAgICBOVFNUQVRVUyBudHM7CiAgICBTSVpFX1QgbGVuOwoKICAgIG50X3JlZ2YgKnJlZ2Y7CiAgICBudF9oYmluICpoYmluOwogICAgbnRfaGJpbl9zdWIgKmhiaW5fc3ViOwogICAgbnRfbmsgKm5rOwoKICAgIFRSQUNFKCIlc1xuIiwgZGVidWdzdHJfdyhmbikpOwoKICAgIGhGaWxlID0gQ3JlYXRlRmlsZVcoIGZuLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwogICAgaWYgKCBoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSApIHJldHVybiBOVUxMOwogICAgYXR0ci5MZW5ndGggICAgICAgICAgICAgICAgICAgPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgICAgICAgICAgICA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgICAgICAgICAgICAgICA9IE5VTEw7CiAgICBhdHRyLkF0dHJpYnV0ZXMgICAgICAgICAgICAgICA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciAgICAgICA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgbGdfaW50LlF1YWRQYXJ0ID0gMDsKICAgIG50cyA9IE50Q3JlYXRlU2VjdGlvbiggJmhNYXBwaW5nLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RBTkRBUkRfUklHSFRTX1JFUVVJUkVEfFNFQ1RJT05fUVVFUll8U0VDVElPTl9NQVBfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF0dHIsICZsZ19pbnQsIFBBR0VfUkVBRE9OTFksIFNFQ19DT01NSVQsIGhGaWxlICk7CiAgICBpZiAobnRzICE9IFNUQVRVU19TVUNDRVNTKSBnb3RvIGVycm9yMTsKCiAgICBiYXNlID0gTlVMTDsgbGVuID0gMDsKICAgIG50cyA9IE50TWFwVmlld09mU2VjdGlvbiggaE1hcHBpbmcsIEdldEN1cnJlbnRQcm9jZXNzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZiYXNlLCAwLCAwLCAmbGdfaW50LCAmbGVuLCBWaWV3U2hhcmUsIDAsIAoJCQkgICAgICBQQUdFX1JFQURPTkxZKTsKICAgIE50Q2xvc2UoIGhNYXBwaW5nICk7CiAgICBpZiAobnRzICE9IFNUQVRVU19TVUNDRVNTKSBnb3RvIGVycm9yMTsKCiAgICAvKiBjb250cm9sIHNpZ25hdHVyZSAqLwogICAgaWYgKCooTFBEV09SRCliYXNlICE9IE5UX1JFR19IRUFERVJfQkxPQ0tfSUQpIHsKICAgICAgICBFUlIoInVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW5udCByZWdpc3RyeSBmaWxlICVzOiB1bmtub3duIHNpZ25hdHVyZS5cbiIsCiAgICAgICAgICAgIGRlYnVnc3RyX3coZm4pKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIHN0YXJ0IGJsb2NrICovCiAgICByZWdmID0gYmFzZTsKCiAgICAvKiBoYmluIGJsb2NrICovCiAgICBoYmluID0gKG50X2hiaW4qKSgoY2hhciopIGJhc2UgKyAweDEwMDApOwogICAgaWYgKGhiaW4tPmlkICE9IE5UX1JFR19QT09MX0JMT0NLX0lEKSB7CiAgICAgIEVSUiggImhiaW4gYmxvY2sgaW52YWxpZFxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogaGJpbl9zdWIgYmxvY2sgKi8KICAgIGhiaW5fc3ViID0gKG50X2hiaW5fc3ViKikmKGhiaW4tPmhiaW5fc3ViKTsKICAgIGlmICgoaGJpbl9zdWItPmRhdGFbMF0gIT0gJ24nKSB8fCAoaGJpbl9zdWItPmRhdGFbMV0gIT0gJ2snKSkgewogICAgICBFUlIoICJoYmluX3N1YiBibG9jayBpbnZhbGlkXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBuayBibG9jayAqLwogICAgbmsgPSAobnRfbmsqKSYoaGJpbl9zdWItPmRhdGFbMF0pOwogICAgaWYgKG5rLT5UeXBlICE9IE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKSB7CiAgICAgIEVSUiggInNwZWNpYWwgbmsgYmxvY2sgbm90IGZvdW5kXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAoIChyZXQgPSBfZ2V0X3RtcF9mbigmZikpID09IE5VTEwpIGdvdG8gZXJyb3I7CiAgICBmcHJpbnRmKGYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAyIik7CiAgICBfbnRfZHVtcF9uaygiIiwoY2hhciopYmFzZSsweDEwMDAsbmssZixsZXZlbCk7CiAgICBmY2xvc2UoZik7CgplcnJvcjoKICAgIE50VW5tYXBWaWV3T2ZTZWN0aW9uKCBHZXRDdXJyZW50UHJvY2VzcygpLCBiYXNlICk7CmVycm9yMToKICAgIE50Q2xvc2UoaEZpbGUpOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCBuYXRpdmUgcmVnaXN0cnkgdG8gd2luZSBmb3JtYXQgYW5kIGxvYWQgaXQgdmlhIHNlcnZlciBjYWxsIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KExQQ1dTVFIgZm4sIEhLRVkgaGtleSwgaW50IHJlZ190eXBlLCBpbnQgbGV2ZWwpCnsKICAgIExQU1RSIHRtcCA9IE5VTEw7CgogICAgc3dpdGNoIChyZWdfdHlwZSkgewogICAgICAgIGNhc2UgUkVHX1dJTk5UOgogICAgICAgICAgICAvKiBGSVhNRTogZm9sbG93aW5nIGZ1bmN0aW9uIGRvZXNuJ3QgcmVhbGx5IGNvbnZlcnQgeWV0ICovCiAgICAgICAgICAgIHRtcCA9IF9jb252ZXJ0X3dpbm50X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KGZuLGxldmVsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfV0lOOTU6CiAgICAgICAgICAgIHRtcCA9IF9jb252ZXJ0X3dpbjk1X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KGZuLGxldmVsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfV0lOMzE6CiAgICAgICAgICAgIEVSUigiRG9uJ3Qga25vdyBob3cgdG8gY29udmVydCBuYXRpdmUgMy4xIHJlZ2lzdHJ5IHlldC5cbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoIlVua25vd24gcmVnaXN0cnkgZm9ybWF0IHBhcmFtZXRlciAoJWQpXG4iLHJlZ190eXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHRtcCAhPSBOVUxMKSB7CiAgICAgICAgbG9hZF93aW5lX3JlZ2lzdHJ5KGhrZXksdG1wKTsKICAgICAgICBUUkFDRSgiRmlsZSAlcyBzdWNjZXNzZnVsbHkgY29udmVydGVkIHRvICVzIGFuZCBsb2FkZWQgdG8gcmVnaXN0cnkuXG4iLAogICAgICAgICAgICAgIGRlYnVnc3RyX3coZm4pLCB0bXApOwogICAgICAgIHVubGluayh0bXApOwogICAgfQogICAgZWxzZSBXQVJOKCJVbmFibGUgdG8gY29udmVydCAlcyAoZG9lc24ndCBleGlzdD8pXG4iLCBkZWJ1Z3N0cl93KGZuKSk7CiAgICBmcmVlKHRtcCk7Cn0KCi8qIGxvYWQgYWxsIG5hdGl2ZSB3aW5kb3dzIHJlZ2lzdHJ5IGZpbGVzIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2xvYWRfd2luZG93c19yZWdpc3RyeSggSEtFWSBoa2V5X2xvY2FsX21hY2hpbmUsIEhLRVkgaGtleV9jdXJyZW50X3VzZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgaW50IHJlZ190eXBlOwogICAgV0NIQVIgd2luZGlyW01BWF9QQVRITkFNRV9MRU5dOwogICAgV0NIQVIgcGF0aFtNQVhfUEFUSE5BTUVfTEVOXTsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIEhLRVkgaGtleSwgcHJvZmlsZV9rZXk7CiAgICBjaGFyIHRtcFsxMDI0XTsKICAgIERXT1JEIGR1bW15OwoKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBXaW5lV1tdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1cnLCdpJywnbicsJ2UnLCdcXCcsJ1cnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdXJywnaScsJ24nLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBQcm9maWxlV1tdID0geydQJywncicsJ28nLCdmJywnaScsJ2wnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBTeXN0ZW1bXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywnUycsJ3knLCdzJywndCcsJ2UnLCdtJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBTb2Z0d2FyZVtdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLCdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgQ2xvbmVbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywneScsJ3MnLCd0JywnZScsJ20nLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQycsJ2wnLCdvJywnbicsJ2UnLDB9OwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgV2luZVcgKTsKICAgIGlmIChOdENyZWF0ZUtleSggJnByb2ZpbGVfa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkgcHJvZmlsZV9rZXkgPSAwOwoKICAgIGdldF93aW5kb3dzX2Rpcih3aW5kaXIsIHNpemVvZih3aW5kaXIpKTsKCiAgICByZWdfdHlwZSA9IF9nZXRfcmVnX3R5cGUod2luZGlyKTsKICAgIHN3aXRjaCAocmVnX3R5cGUpIHsKICAgICAgICBjYXNlIFJFR19XSU5OVDogewogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgbnR1c2VyX2RhdFdbXSA9IHsnXFwnLCduJywndCcsJ3UnLCdzJywnZScsJ3InLCcuJywnZCcsJ2EnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIGRlZmF1bHRXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywnZCcsJ2UnLCdmJywnYScsJ3UnLCdsJywndCcsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzeXN0ZW1XW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHNvZnR3YXJlV1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJzMnLCcyJywnXFwnLCdjJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ3MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHNhbVdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdzJywnYScsJ20nLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc2VjdXJpdHlXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywncycsJ2UnLCdjJywndScsJ3InLCdpJywndCcsJ3knLDB9OwoKICAgICAgICAgICAgLyogdXNlciBzcGVjaWZpYyBudHVzZXIuZGF0ICovCiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFByb2ZpbGVXICk7CiAgICAgICAgICAgIGlmIChwcm9maWxlX2tleSAmJiAhTnRRdWVyeVZhbHVlS2V5KCBwcm9maWxlX2tleSwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcCwgc2l6ZW9mKHRtcCksICZkdW1teSApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgbnR1c2VyX2RhdFcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9jdXJyZW50X3VzZXIsUkVHX1dJTk5ULDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTUVTU0FHRSgiV2hlbiB5b3UgYXJlIHJ1bm5pbmcgd2l0aCBhIG5hdGl2ZSBOVCBkaXJlY3Rvcnkgc3BlY2lmeVxuIik7CiAgICAgICAgICAgICAgICBNRVNTQUdFKCInUHJvZmlsZT08cHJvZmlsZWRpcmVjdG9yeT4nIG9yIGRpc2FibGUgbG9hZGluZyBvZiBXaW5kb3dzXG4iKTsKICAgICAgICAgICAgICAgIE1FU1NBR0UoInJlZ2lzdHJ5IChMb2FkV2luZG93c1JlZ2lzdHJ5RmlsZXM9TilcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGRlZmF1bHQgdXNlci5kYXQgKi8KICAgICAgICAgICAgaWYgKGhrZXlfdXNlcnNfZGVmYXVsdCkgewogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBkZWZhdWx0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X3VzZXJzX2RlZmF1bHQsUkVHX1dJTk5ULDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAqIEZJWE1FCiAgICAgICAgICAgICogIG1hcCBITE1cU3lzdGVtXENvbnRyb2xTZXQwMDEgdG8gSExNXFN5c3RlbVxDdXJyZW50Q29udHJvbFNldAogICAgICAgICAgICAqLwogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBTeXN0ZW0gKTsKICAgICAgICAgICAgaWYgKCFOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHN5c3RlbVcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleSxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgICAgICBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgU29mdHdhcmUgKTsKICAgICAgICAgICAgaWYgKCFOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHNvZnR3YXJlVyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5LFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHNhbVcpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2xvY2FsX21hY2hpbmUsUkVHX1dJTk5ULDApOwoKICAgICAgICAgICAgc3RyY3B5VyhwYXRoLHdpbmRpcik7CiAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgc2VjdXJpdHlXKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9sb2NhbF9tYWNoaW5lLFJFR19XSU5OVCwwKTsKCiAgICAgICAgICAgIC8qIHRoaXMga2V5IGlzIGdlbmVyYXRlZCB3aGVuIHRoZSBudC1jb3JlIGJvb3RlZCBzdWNjZXNzZnVsbHkgKi8KICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgQ2xvbmUgKTsKICAgICAgICAgICAgaWYgKCFOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKSBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBSRUdfV0lOOTU6CiAgICAgICAgewogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3lzdGVtXzFzdFdbXSA9IHsnYycsJzonLCdcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJy4nLCcxJywncycsJ3QnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3lzdGVtX2RhdFdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCcuJywnZCcsJ2EnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIGNsYXNzZXNfZGF0V1tdID0geydcXCcsJ2MnLCdsJywnYScsJ3MnLCdzJywnZScsJ3MnLCcuJywnZCcsJ2EnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHVzZXJfZGF0V1tdID0geydcXCcsJ3UnLCdzJywnZScsJ3InLCcuJywnZCcsJ2EnLCd0JywwfTsKCiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShzeXN0ZW1fMXN0Vyxoa2V5X2xvY2FsX21hY2hpbmUsUkVHX1dJTjk1LDApOwoKICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHN5c3RlbV9kYXRXKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9sb2NhbF9tYWNoaW5lLFJFR19XSU45NSwwKTsKCiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIENsYXNzZXNSb290VyApOwogICAgICAgICAgICBpZiAoIU50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgY2xhc3Nlc19kYXRXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXksUkVHX1dJTjk1LDApOwogICAgICAgICAgICAgICAgTnRDbG9zZSggaGtleSApOwogICAgICAgICAgICB9CgogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBQcm9maWxlVyApOwogICAgICAgICAgICBpZiAocHJvZmlsZV9rZXkgJiYgIU50UXVlcnlWYWx1ZUtleSggcHJvZmlsZV9rZXksICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAsIHNpemVvZih0bXApLCAmZHVtbXkgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogdXNlciBzcGVjaWZpYyB1c2VyLmRhdCAqLwogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YSk7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHVzZXJfZGF0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2N1cnJlbnRfdXNlcixSRUdfV0lOOTUsMSk7CgoJICAgICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCgkgICAgICAgIGlmIChoa2V5X3VzZXJzX2RlZmF1bHQpIHsKICAgICAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCB1c2VyX2RhdFcpOwogICAgICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfdXNlcnNfZGVmYXVsdCxSRUdfV0lOOTUsMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHVzZXJfZGF0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2N1cnJlbnRfdXNlcixSRUdfV0lOOTUsMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIFJFR19XSU4zMToKICAgICAgICAgICAgLyogRklYTUU6IGhlcmUgd2Ugc2hvdWxkIGNvbnZlcnQgdG8gKi5yZWcgZmlsZSBzdXBwb3J0ZWQgYnkgc2VydmVyIGFuZCBjYWxsIFJFUV9MT0FEX1JFR0lTVFJZLCBzZWUgUkVHX1dJTjk1IGNhc2UgKi8KICAgICAgICAgICAgX3czMV9sb2FkcmVnKCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFJFR19ET05UTE9BRDoKICAgICAgICAgICAgVFJBQ0UoIlJFR19ET05UTE9BRFxuIik7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoInN3aXRjaDogbm8gbWF0Y2ggKCVkKVxuIixyZWdfdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgIH0KICAgIGlmIChwcm9maWxlX2tleSkgTnRDbG9zZSggcHJvZmlsZV9rZXkgKTsKfQoKLyogbG9hZCBob21lIHJlZ2lzdHJ5IGZpbGVzIChzdG9yZWQgaW4gfi8ud2luZSkgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfbG9hZF9ob21lX3JlZ2lzdHJ5KCBIS0VZIGhrZXlfbG9jYWxfbWFjaGluZSwgSEtFWSBoa2V5X2N1cnJlbnRfdXNlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQgKQp7CiAgICBMUENTVFIgY29uZmRpciA9IHdpbmVfZ2V0X2NvbmZpZ19kaXIoKTsKICAgIExQU1RSIHRtcCA9IF94bWFsbG9jKHN0cmxlbihjb25mZGlyKSsyMCk7CgogICAgc3RyY3B5KHRtcCxjb25mZGlyKTsKICAgIHN0cmNhdCh0bXAsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCk7CiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoaGtleV91c2Vyc19kZWZhdWx0LHRtcCk7CgogICAgc3RyY3B5KHRtcCxjb25mZGlyKTsKICAgIHN0cmNhdCh0bXAsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0NVUlJFTlRfVVNFUik7CiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoaGtleV9jdXJyZW50X3VzZXIsdG1wKTsKCiAgICBzdHJjcHkodG1wLGNvbmZkaXIpOwogICAgc3RyY2F0KHRtcCwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSk7CiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoaGtleV9sb2NhbF9tYWNoaW5lLHRtcCk7CgogICAgZnJlZSh0bXApOwp9CgoKLyogbG9hZCBhbGwgcmVnaXN0cnkgKG5hdGl2ZSBhbmQgZ2xvYmFsIGFuZCBob21lKSAqLwp2b2lkIFNIRUxMX0xvYWRSZWdpc3RyeSggdm9pZCApCnsKICAgIEhLRVkgaGtleV9sb2NhbF9tYWNoaW5lLCBoa2V5X3VzZXJzLCBoa2V5X3VzZXJzX2RlZmF1bHQsIGhrZXlfY3VycmVudF91c2VyLCBoa2V5X2NvbmZpZzsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIERXT1JEIGNvdW50OwogICAgVUxPTkcgZGlzcG9zOwogICAgQk9PTCByZXM7CiAgICBpbnQgYWxsLCBwZXJpb2Q7CiAgICBjaGFyIHRtcFsxMDI0XTsKCiAgICBzdGF0aWMgY29uc3QgV0NIQVIgTWFjaGluZVdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgVXNlcldbXSA9IHsnVScsJ3MnLCdlJywncicsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgRGVmYXVsdFdbXSA9IHsnLicsJ0QnLCdlJywnZicsJ2EnLCd1JywnbCcsJ3QnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFJlZ2lzdHJ5V1tdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVycsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVycsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywneScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgbG9hZF93aW5fcmVnX2ZpbGVzV1tdID0geydMJywnbycsJ2EnLCdkJywnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCd5JywnRicsJ2knLCdsJywnZScsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGxvYWRfZ2xvYmFsX3JlZ19maWxlc1dbXSA9IHsnTCcsJ28nLCdhJywnZCcsJ0cnLCdsJywnbycsJ2InLCdhJywnbCcsJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCd5JywnRicsJ2knLCdsJywnZScsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGxvYWRfaG9tZV9yZWdfZmlsZXNXW10gPSB7J0wnLCdvJywnYScsJ2QnLCdIJywnbycsJ20nLCdlJywnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLCdGJywnaScsJ2wnLCdlJywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgU2F2ZU9ubHlVcGRhdGVkS2V5c1dbXSA9IHsnUycsJ2EnLCd2JywnZScsJ08nLCduJywnbCcsJ3knLCdVJywncCcsJ2QnLCdhJywndCcsJ2UnLCdkJywnSycsJ2UnLCd5JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgUGVyaW9kaWNTYXZlV1tdID0geydQJywnZScsJ3InLCdpJywnbycsJ2QnLCdpJywnYycsJ1MnLCdhJywndicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFdyaXRldG9Ib21lUmVnaXN0cnlGaWxlc1dbXSA9IHsnVycsJ3InLCdpJywndCcsJ2UnLCd0JywnbycsJ0gnLCdvJywnbScsJ2UnLCdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywneScsJ0YnLCdpJywnbCcsJ2UnLCdzJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBHbG9iYWxSZWdpc3RyeURpcldbXSA9IHsnRycsJ2wnLCdvJywnYicsJ2EnLCdsJywnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLCdEJywnaScsJ3InLDB9OwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgVXNlclcgKTsKICAgIE50Q3JlYXRlS2V5KCAmaGtleV91c2VycywgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCAmZGlzcG9zICk7CiAgICBpZiAoZGlzcG9zID09IFJFR19PUEVORURfRVhJU1RJTkdfS0VZKQogICAgewogICAgICAgIC8qIHNvbWVvbmUgZWxzZSBhbHJlYWR5IGxvYWRlZCB0aGUgcmVnaXN0cnkgKi8KICAgICAgICBOdENsb3NlKCBoa2V5X3VzZXJzICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIE1hY2hpbmVXICk7CiAgICBOdENyZWF0ZUtleSggJmhrZXlfbG9jYWxfbWFjaGluZSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICk7CgogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gaGtleV91c2VyczsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIERlZmF1bHRXICk7CiAgICBpZiAoTnRDcmVhdGVLZXkoICZoa2V5X3VzZXJzX2RlZmF1bHQsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKQogICAgewogICAgICAgIEVSUigiQ2Fubm90IGNyZWF0ZSBIS0VZX1VTRVJTLy5EZWZhdWx0XG4iICk7CiAgICAgICAgRXhpdFByb2Nlc3MoMSk7CiAgICB9CiAgICBSdGxPcGVuQ3VycmVudFVzZXIoIEtFWV9BTExfQUNDRVNTLCAmaGtleV9jdXJyZW50X3VzZXIgKTsKCiAgICBfc2V0X3JlZ2lzdHJ5X2xldmVscygwLDAsMCk7CiAgICBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzKCk7CgogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFJlZ2lzdHJ5VyApOwogICAgaWYgKE50T3BlbktleSggJmhrZXlfY29uZmlnLCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIgKSkgaGtleV9jb25maWcgPSAwOwoKICAgIC8qIGxvYWQgd2luZG93cyByZWdpc3RyeSBpZiByZXF1aXJlZCAqLwoKICAgIHJlcyA9IFRSVUU7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5X2NvbmZpZzsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIGxvYWRfd2luX3JlZ19maWxlc1cgKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X2NvbmZpZywgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICB7CiAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgIHJlcyA9ICFJU19PUFRJT05fRkFMU0Uoc3RyWzBdKTsKICAgIH0KICAgIGlmIChyZXMpIF9sb2FkX3dpbmRvd3NfcmVnaXN0cnkoIGhrZXlfbG9jYWxfbWFjaGluZSwgaGtleV9jdXJyZW50X3VzZXIsIGhrZXlfdXNlcnNfZGVmYXVsdCApOwoKICAgIC8qIGxvYWQgZ2xvYmFsIHJlZ2lzdHJ5IGlmIHJlcXVpcmVkICovCgogICAgcmVzID0gVFJVRTsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIGxvYWRfZ2xvYmFsX3JlZ19maWxlc1cgKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X2NvbmZpZywgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICB7CiAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgIHJlcyA9ICFJU19PUFRJT05fRkFMU0Uoc3RyWzBdKTsKICAgIH0KICAgIGlmIChyZXMpCiAgICB7CiAgICAgICAgLyogbG9hZCBnbG9iYWwgcmVnaXN0cnkgZmlsZXMgKHN0b3JlZCBpbiAvZXRjL3dpbmUpICovCiAgICAgICAgY2hhciAqcCwgY29uZmlnZmlsZVtNQVhfUEFUSE5BTUVfTEVOXTsKCiAgICAgICAgLyogT3ZlcnJpZGUgRVRDRElSPyAqLwogICAgICAgIGNvbmZpZ2ZpbGVbMF0gPSAwOwogICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIEdsb2JhbFJlZ2lzdHJ5RGlyVyApOwogICAgICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X2NvbmZpZywgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgICAgIFJ0bFVuaWNvZGVUb011bHRpQnl0ZU4oIGNvbmZpZ2ZpbGUsIHNpemVvZihjb25maWdmaWxlKSwgTlVMTCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ciwgKHN0cmxlblcoc3RyKSArIDEpICogc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgfQogICAgICAgIGlmIChjb25maWdmaWxlWzBdICE9ICcvJykgc3RyY3B5KGNvbmZpZ2ZpbGUsIEVUQ0RJUik7CgogICAgICAgIFRSQUNFKCJHbG9iYWxSZWdpc3RyeURpciBpcyAnJXMnLlxuIiwgY29uZmlnZmlsZSk7CgogICAgICAgIC8qIExvYWQgdGhlIGdsb2JhbCBIS1UgaGl2ZSBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIgKi8KICAgICAgICBwID0gY29uZmlnZmlsZSArIHN0cmxlbihjb25maWdmaWxlKTsKICAgICAgICBzdHJjcHkocCwgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCk7CiAgICAgICAgbG9hZF93aW5lX3JlZ2lzdHJ5KCBoa2V5X3VzZXJzLCBjb25maWdmaWxlICk7CgogICAgICAgIC8qIExvYWQgdGhlIGdsb2JhbCBtYWNoaW5lIGRlZmF1bHRzIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpciAqLwogICAgICAgIHN0cmNweShwLCBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSk7CiAgICAgICAgbG9hZF93aW5lX3JlZ2lzdHJ5KCBoa2V5X2xvY2FsX21hY2hpbmUsIGNvbmZpZ2ZpbGUgKTsKICAgIH0KCiAgICBfc2V0X3JlZ2lzdHJ5X2xldmVscygxLDAsMCk7CgogICAgLyogbG9hZCBob21lIHJlZ2lzdHJ5IGlmIHJlcXVpcmVkICovCgogICAgcmVzID0gVFJVRTsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIGxvYWRfaG9tZV9yZWdfZmlsZXNXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICByZXMgPSAhSVNfT1BUSU9OX0ZBTFNFKHN0clswXSk7CiAgICB9CiAgICBpZiAocmVzKSBfbG9hZF9ob21lX3JlZ2lzdHJ5KCBoa2V5X2xvY2FsX21hY2hpbmUsIGhrZXlfY3VycmVudF91c2VyLCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKCiAgICAvKiBzZXR1cCByZWdpc3RyeSBzYXZpbmcgKi8KCiAgICBhbGwgPSBGQUxTRTsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFNhdmVPbmx5VXBkYXRlZEtleXNXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICBhbGwgPSBJU19PUFRJT05fRkFMU0Uoc3RyWzBdKTsKICAgIH0KCiAgICBwZXJpb2QgPSAwOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgUGVyaW9kaWNTYXZlVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgcGVyaW9kID0gKGludClzdHJ0b2xXKHN0ciwgTlVMTCwgMTApOwogICAgfQoKICAgIC8qIHNldCBzYXZpbmcgbGV2ZWwgKDAgZm9yIHNhdmluZyBldmVyeXRoaW5nLCAxIGZvciBzYXZpbmcgb25seSBtb2RpZmllZCBrZXlzKSAqLwogICAgX3NldF9yZWdpc3RyeV9sZXZlbHMoMSwhYWxsLHBlcmlvZCoxMDAwKTsKCiAgICAvKiBzZXR1cCBrZXlzIHRvIHNhdmUgKi8KCiAgICByZXMgPSBUUlVFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgV3JpdGV0b0hvbWVSZWdpc3RyeUZpbGVzVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgcmVzID0gIUlTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQogICAgaWYgKHJlcykKICAgIHsKICAgICAgICBfc2F2ZV9hdF9leGl0KGhrZXlfY3VycmVudF91c2VyLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIgKTsKICAgICAgICBfc2F2ZV9hdF9leGl0KGhrZXlfbG9jYWxfbWFjaGluZSwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSk7CiAgICAgICAgX3NhdmVfYXRfZXhpdChoa2V5X3VzZXJzX2RlZmF1bHQsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCk7CiAgICB9CgogICAgTnRDbG9zZShoa2V5X3VzZXJzX2RlZmF1bHQpOwogICAgTnRDbG9zZShoa2V5X2N1cnJlbnRfdXNlcik7CiAgICBOdENsb3NlKGhrZXlfdXNlcnMpOwogICAgTnRDbG9zZShoa2V5X2xvY2FsX21hY2hpbmUpOwogICAgTnRDbG9zZShoa2V5X2NvbmZpZyk7Cn0K