LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBOT1RFUwogKiAgICBXaGVuIGNoYW5naW5nIHRoaXMgZmlsZSwgcGxlYXNlIHJlLXJ1biB0aGUgcmVndGVzdCBwcm9ncmFtIHRvIGVuc3VyZQogKiAgICB0aGUgY29uZGl0aW9ucyBhcmUgaGFuZGxlZCBwcm9wZXJseS4KICoKICogVE9ETwogKiAgICBTZWN1cml0eSBhY2Nlc3MKICogICAgT3B0aW9uIGhhbmRsaW5nCiAqICAgIFRpbWUgZm9yIFJlZ0VudW1LZXkqLCBSZWdRdWVyeUluZm9LZXkqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxmY250bC5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbm50LmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9zZXJ2ZXIuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAiZmlsZS5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHJlZyk7CgovKiBGSVhNRTogZm9sbG93aW5nIGRlZmluZXMgc2hvdWxkIGJlIGNvbmZpZ3VyZWQgZ2xvYmFsICovCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCAgRVRDRElSIi93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUgRVRDRElSIi93aW5lLnN5c3RlbXJlZyIKCi8qIHJlbGF0aXZlIGluIH51c2VyLy53aW5lLyA6ICovCiNkZWZpbmUgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfQ1VSUkVOVF9VU0VSICAidXNlci5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUICAidXNlcmRlZi5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSAic3lzdGVtLnJlZyIKCi8qIF94bWFsbG9jIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgKl94bWFsbG9jKCBzaXplX3Qgc2l6ZSApCnsKICAgIHZvaWQgKnJlczsKCiAgICByZXMgPSBtYWxsb2MgKHNpemUgPyBzaXplIDogMSk7CiAgICBpZiAocmVzID09IE5VTEwpIHsKICAgICAgICBXQVJOKCJWaXJ0dWFsIG1lbW9yeSBleGhhdXN0ZWQuXG4iKTsKICAgICAgICBleGl0ICgxKTsKICAgIH0KICAgIHJldHVybiByZXM7Cn0KCi8qIF9zdHJkdXBuQSBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfc3RyZHVwbkEoTFBDU1RSIHN0cixzaXplX3QgbGVuKQp7CiAgICBMUFNUUiByZXQ7CgogICAgaWYgKCFzdHIpIHJldHVybiBOVUxMOwogICAgcmV0ID0gX3htYWxsb2MoIGxlbiArIDEgKTsKICAgIG1lbWNweSggcmV0LCBzdHIsIGxlbiApOwogICAgcmV0W2xlbl0gPSAweDAwOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCBhbnNpIHN0cmluZyB0byB1bmljb2RlIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQV1NUUiBfc3RyZHVwbkF0b1coTFBDU1RSIHN0ckEsc2l6ZV90IGxlbkEpCnsKICAgIExQV1NUUiByZXQ7CiAgICBzaXplX3QgbGVuVzsKCiAgICBpZiAoIXN0ckEpIHJldHVybiBOVUxMOwogICAgbGVuVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLDAsc3RyQSxsZW5BLE5VTEwsMCk7CiAgICByZXQgPSBfeG1hbGxvYyhsZW5XKnNpemVvZihXQ0hBUikrc2l6ZW9mKFdDSEFSKSk7CiAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwwLHN0ckEsbGVuQSxyZXQsbGVuVyk7CiAgICByZXRbbGVuV10gPSAwOwogICAgcmV0dXJuIHJldDsKfQoKLyogZHVtcCBhIFVuaWNvZGUgc3RyaW5nIHdpdGggcHJvcGVyIGVzY2FwaW5nIFtJbnRlcm5hbF0gKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci91bmljb2RlLmMgKi8Kc3RhdGljIGludCBfZHVtcF9zdHJXKGNvbnN0IFdDSEFSICpzdHIsc2l6ZV90IGxlbixGSUxFICpmLGNoYXIgZXNjYXBlWzJdKQp7CiAgICBzdGF0aWMgY29uc3QgY2hhciBlc2NhcGVzWzMyXSA9ICIuLi4uLi4uYWJ0bnZmci4uLi4uLi4uLi4uLi5lLi4uLiI7CiAgICBjaGFyIGJ1ZmZlclsyNTZdOwogICAgTFBTVFIgcG9zID0gYnVmZmVyOwogICAgaW50IGNvdW50ID0gMDsKCiAgICBmb3IgKDsgbGVuOyBzdHIrKywgbGVuLS0pCiAgICB7CiAgICAgICAgaWYgKHBvcyA+IGJ1ZmZlciArIHNpemVvZihidWZmZXIpIC0gOCkKICAgICAgICB7CiAgICAgICAgICAgIGZ3cml0ZSggYnVmZmVyLCBwb3MgLSBidWZmZXIsIDEsIGYgKTsKICAgICAgICAgICAgY291bnQgKz0gcG9zIC0gYnVmZmVyOwogICAgICAgICAgICBwb3MgPSBidWZmZXI7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyID4gMTI3KSAgLyogaGV4IGVzY2FwZSAqLwogICAgICAgIHsKICAgICAgICAgICAgaWYgKGxlbiA+IDEgJiYgc3RyWzFdIDwgMTI4ICYmIGlzeGRpZ2l0KChjaGFyKXN0clsxXSkpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFx4JTA0eCIsICpzdHIgKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxceCV4IiwgKnN0ciApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCpzdHIgPCAzMikgIC8qIG9jdGFsIG9yIEMgZXNjYXBlICovCiAgICAgICAgewogICAgICAgICAgICBpZiAoISpzdHIgJiYgbGVuID09IDEpIGNvbnRpbnVlOyAgLyogZG8gbm90IG91dHB1dCB0ZXJtaW5hdGluZyBOVUxMICovCiAgICAgICAgICAgIGlmIChlc2NhcGVzWypzdHJdICE9ICcuJykKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCVjIiwgZXNjYXBlc1sqc3RyXSApOwogICAgICAgICAgICBlbHNlIGlmIChsZW4gPiAxICYmIHN0clsxXSA+PSAnMCcgJiYgc3RyWzFdIDw9ICc3JykKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCUwM28iLCAqc3RyICk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCVvIiwgKnN0ciApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCpzdHIgPT0gJ1xcJyB8fCAqc3RyID09IGVzY2FwZVswXSB8fCAqc3RyID09IGVzY2FwZVsxXSkgKnBvcysrID0gJ1xcJzsKICAgICAgICAqcG9zKysgPSAqc3RyOwogICAgfQogICAgZndyaXRlKCBidWZmZXIsIHBvcyAtIGJ1ZmZlciwgMSwgZiApOwogICAgY291bnQgKz0gcG9zIC0gYnVmZmVyOwogICAgcmV0dXJuIGNvdW50Owp9CgovKiBjb252ZXJ0IGFuc2kgc3RyaW5nIHRvIHVuaWNvZGUgYW5kIGR1bXAgd2l0aCBwcm9wZXIgZXNjYXBpbmcgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9kdW1wX3N0ckF0b1coTFBDU1RSIHN0ckEsc2l6ZV90IGxlbixGSUxFICpmLGNoYXIgZXNjYXBlWzJdKQp7CiAgICBXQ0hBUiAqc3RyVzsKICAgIGludCByZXQ7CgogICAgaWYgKHN0ckEgPT0gTlVMTCkgcmV0dXJuIDA7CiAgICBzdHJXID0gX3N0cmR1cG5BdG9XKHN0ckEsbGVuKTsKICAgIHJldCA9IF9kdW1wX3N0clcoc3RyVyxsZW4sZixlc2NhcGUpOwogICAgZnJlZShzdHJXKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGEga2V5IHZhbHVlICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvcmVnaXN0cnkuYyAqLwpzdHJ1Y3Qga2V5X3ZhbHVlIHsKICAgIFdDSEFSICAgICAgICAgICAgKm5hbWVXOyAgIC8qIHZhbHVlIG5hbWUgKi8KICAgIGludCAgICAgICAgICAgICAgIHR5cGU7ICAgIC8qIHZhbHVlIHR5cGUgKi8KICAgIHNpemVfdCAgICAgICAgICAgIGxlbjsgICAgIC8qIHZhbHVlIGRhdGEgbGVuZ3RoIGluIGJ5dGVzICovCiAgICB2b2lkICAgICAgICAgICAgICpkYXRhOyAgICAvKiBwb2ludGVyIHRvIHZhbHVlIGRhdGEgKi8KfTsKCi8qIGR1bXAgYSB2YWx1ZSB0byBhIHRleHQgZmlsZSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3JlZ2lzdHJ5LmMgKi8Kc3RhdGljIHZvaWQgX2R1bXBfdmFsdWUoc3RydWN0IGtleV92YWx1ZSAqdmFsdWUsRklMRSAqZikKewogICAgaW50IGksIGNvdW50OwoKICAgIGlmICh2YWx1ZS0+bmFtZVdbMF0pIHsKICAgICAgICBmcHV0YyggJ1wiJywgZiApOwogICAgICAgIGNvdW50ID0gMSArIF9kdW1wX3N0clcodmFsdWUtPm5hbWVXLHN0cmxlblcodmFsdWUtPm5hbWVXKSxmLCJcIlwiIik7CiAgICAgICAgY291bnQgKz0gZnByaW50ZiggZiwgIlwiPSIgKTsKICAgIH0KICAgIGVsc2UgY291bnQgPSBmcHJpbnRmKCBmLCAiQD0iICk7CgogICAgc3dpdGNoKHZhbHVlLT50eXBlKSB7CiAgICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgY2FzZSBSRUdfRVhQQU5EX1NaOgogICAgICAgIGNhc2UgUkVHX01VTFRJX1NaOgogICAgICAgICAgICBpZiAodmFsdWUtPnR5cGUgIT0gUkVHX1NaKSBmcHJpbnRmKCBmLCAic3RyKCVkKToiLCB2YWx1ZS0+dHlwZSApOwogICAgICAgICAgICBmcHV0YyggJ1wiJywgZiApOwogICAgICAgICAgICBpZiAodmFsdWUtPmRhdGEpIF9kdW1wX3N0clcodmFsdWUtPmRhdGEsdmFsdWUtPmxlbi9zaXplb2YoV0NIQVIpLGYsIlwiXCIiKTsKICAgICAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgICAgIGlmICh2YWx1ZS0+bGVuID09IHNpemVvZihEV09SRCkpIHsKICAgICAgICAgICAgICAgIERXT1JEIGR3OwogICAgICAgICAgICAgICAgbWVtY3B5KCAmZHcsIHZhbHVlLT5kYXRhLCBzaXplb2YoRFdPUkQpICk7CiAgICAgICAgICAgICAgICBmcHJpbnRmKCBmLCAiZHdvcmQ6JTA4bHgiLCBkdyApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogZWxzZSBmYWxsIHRocm91Z2ggKi8KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBpZiAodmFsdWUtPnR5cGUgPT0gUkVHX0JJTkFSWSkgY291bnQgKz0gZnByaW50ZiggZiwgImhleDoiICk7CiAgICAgICAgICAgIGVsc2UgY291bnQgKz0gZnByaW50ZiggZiwgImhleCgleCk6IiwgdmFsdWUtPnR5cGUgKTsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLT5sZW47IGkrKykgewogICAgICAgICAgICAgICAgY291bnQgKz0gZnByaW50ZiggZiwgIiUwMngiLCAqKCh1bnNpZ25lZCBjaGFyICopdmFsdWUtPmRhdGEgKyBpKSApOwogICAgICAgICAgICAgICAgaWYgKGkgPCB2YWx1ZS0+bGVuLTEpIHsKICAgICAgICAgICAgICAgICAgICBmcHV0YyggJywnLCBmICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCsrY291bnQgPiA3NikgewogICAgICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKCBmLCAiXFxcbiAgIiApOwogICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgZnB1dGMoICdcbicsIGYgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogV0lORE9XUyAzMSBSRUdJU1RSWSBMT0FERVIsIHN1cHBsaWVkIGJ5IFRvciBTavh3YWxsLCB0b3JAc24ubm8gKi8KLyoKICAgIHJlZ2hhY2sgLSB3aW5kb3dzIDMuMTEgcmVnaXN0cnkgZGF0YSBmb3JtYXQgZGVtbyBwcm9ncmFtLgoKICAgIFRoZSByZWcuZGF0IGZpbGUgaGFzIDMgcGFydHMsIGEgaGVhZGVyLCBhIHRhYmxlIG9mIDgtYnl0ZSBlbnRyaWVzIHRoYXQgaXMKICAgIGEgY29tYmluZWQgaGFzaCB0YWJsZSBhbmQgdHJlZSBkZXNjcmlwdGlvbiwgYW5kIGZpbmFsbHkgYSB0ZXh0IHRhYmxlLgoKICAgIFRoZSBoZWFkZXIgaXMgb2J2aW91cyBmcm9tIHRoZSBzdHJ1Y3QgaGVhZGVyLiBUaGUgdGFib2ZmMSBhbmQgdGFib2ZmMgogICAgZmllbGRzIGFyZSBhbHdheXMgMHgyMCwgYW5kIHRoZWlyIHVzYWdlIGlzIHVua25vd24uCgogICAgVGhlIDgtYnl0ZSBlbnRyeSB0YWJsZSBoYXMgdmFyaW91cyBlbnRyeSB0eXBlcy4KCiAgICB0YWJlbnRbMF0gaXMgYSByb290IGluZGV4LiBUaGUgc2Vjb25kIHdvcmQgaGFzIHRoZSBpbmRleCBvZiB0aGUgcm9vdCBvZgogICAgICAgICAgICB0aGUgZGlyZWN0b3J5LgogICAgdGFiZW50WzEuLmhhc2hzaXplXSBpcyBhIGhhc2ggdGFibGUuIFRoZSBmaXJzdCB3b3JkIGluIHRoZSBoYXNoIGVudHJ5IGlzCiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUga2V5L3ZhbHVlIHRoYXQgaGFzIHRoYXQgaGFzaC4gRGF0YSB3aXRoIHRoZSBzYW1lCiAgICAgICAgICAgIGhhc2ggdmFsdWUgYXJlIG9uIGEgY2lyY3VsYXIgbGlzdC4gVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZQogICAgICAgICAgICBoYXNoIGVudHJ5IGFyZSBhbHdheXMgemVyby4KICAgIHRhYmVudFtoYXNoc2l6ZS4udGFiY250XSBpcyB0aGUgdHJlZSBzdHJ1Y3R1cmUuIFRoZXJlIGFyZSB0d28ga2luZHMgb2YKICAgICAgICAgICAgZW50cnk6IGRpcmVudCBhbmQga2V5ZW50L3ZhbGVudC4gVGhleSBhcmUgaWRlbnRpZmllZCBieSBjb250ZXh0LgogICAgdGFiZW50W2ZyZWVpZHhdIGlzIHRoZSBmaXJzdCBmcmVlIGVudHJ5LiBUaGUgZmlyc3Qgd29yZCBpbiBhIGZyZWUgZW50cnkKICAgICAgICAgICAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGZyZWUgZW50cnkuIFRoZSBsYXN0IGhhcyAwIGFzIGEgbGluay4KICAgICAgICAgICAgVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZSBmcmVlIGxpc3QgYXJlIHByb2JhYmx5IGlycmVsZXZhbnQuCgogICAgRW50cmllcyBpbiB0ZXh0IHRhYmxlIGFyZSBwcmVjZWRlZCBieSBhIHdvcmQgYXQgb2Zmc2V0LTIuIFRoaXMgd29yZAogICAgaGFzIHRoZSB2YWx1ZSAoMippbmRleCkrMSwgd2hlcmUgaW5kZXggaXMgdGhlIHJlZmVycmluZyBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBpbiB0aGUgdGFibGUuIEkgaGF2ZSBubyBzdWdnZXN0aW9uIGZvciB0aGUgMiogYW5kIHRoZSArMS4KICAgIEZvbGxvd2luZyB0aGUgd29yZCwgdGhlcmUgYXJlIE4gYnl0ZXMgb2YgZGF0YSwgYXMgcGVyIHRoZSBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBsZW5ndGguIFRoZSBvZmZzZXQgb2YgdGhlIGtleWVudC92YWxlbnQgZW50cnkgaXMgZnJvbSB0aGUgc3RhcnQKICAgIG9mIHRoZSB0ZXh0IHRhYmxlIHRvIHRoZSBmaXJzdCBkYXRhIGJ5dGUuCgogICAgVGhpcyBpbmZvcm1hdGlvbiBpcyBub3QgYXZhaWxhYmxlIGZyb20gTWljcm9zb2Z0LiBUaGUgZGF0YSBmb3JtYXQgaXMKICAgIGRlZHVjZWQgZnJvbSB0aGUgcmVnLmRhdCBmaWxlIGJ5IG1lLiBNaXN0YWtlcyBtYXkKICAgIGhhdmUgYmVlbiBtYWRlLiBJIGNsYWltIG5vIHJpZ2h0cyBhbmQgZ2l2ZSBubyBndWFyYW50ZWVzIGZvciB0aGlzIHByb2dyYW0uCgogICAgVG9yIFNq+HdhbGwsIHRvckBzbi5ubwoqLwoKLyogcmVnLmRhdCBoZWFkZXIgZm9ybWF0ICovCnN0cnVjdCBfdzMxX2hlYWRlciB7CiAgICBjaGFyCQljb29raWVbOF07CS8qICdTSENDMy4xMCcgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGFib2ZmMTsJLyogb2Zmc2V0IG9mIGhhc2ggdGFibGUgKD8/KSA9IDB4MjAgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGFib2ZmMjsJLyogb2Zmc2V0IG9mIGluZGV4IHRhYmxlICg/PykgPSAweDIwICovCiAgICB1bnNpZ25lZCBsb25nCXRhYmNudDsJCS8qIG51bWJlciBvZiBlbnRyaWVzIGluIGluZGV4IHRhYmxlICovCiAgICB1bnNpZ25lZCBsb25nCXRleHRvZmY7CS8qIG9mZnNldCBvZiB0ZXh0IHBhcnQgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGV4dHNpemU7CS8qIGJ5dGUgc2l6ZSBvZiB0ZXh0IHBhcnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWhhc2hzaXplOwkvKiBoYXNoIHNpemUgKi8KICAgIHVuc2lnbmVkIHNob3J0CWZyZWVpZHg7CS8qIGZyZWUgaW5kZXggKi8KfTsKCi8qIGdlbmVyaWMgZm9ybWF0IG9mIHRhYmxlIGVudHJpZXMgKi8Kc3RydWN0IF93MzFfdGFiZW50IHsKICAgIHVuc2lnbmVkIHNob3J0IHcwLCB3MSwgdzIsIHczOwp9OwoKLyogZGlyZWN0b3J5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfZGlyZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CXNpYmxpbmdfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBzaWJsaW5nIGRpcmVudCAqLwogICAgdW5zaWduZWQgc2hvcnQJY2hpbGRfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBjaGlsZCBkaXJlbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWtleV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGtleSBrZXllbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CXZhbHVlX2lkeDsJLyogdGFibGUgaW5kZXggb2YgdmFsdWUgdmFsZW50ICovCn07CgovKiBrZXkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9rZXllbnQgewogICAgdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHZhbHVlIHRhYmVudDogKi8Kc3RydWN0IF93MzFfdmFsZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwogICAgdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiByZWN1cnNpdmUgaGVscGVyIGZ1bmN0aW9uIHRvIGRpc3BsYXkgYSBkaXJlY3RvcnkgdHJlZSAgW0ludGVybmFsXSAqLwp2b2lkIF93MzFfZHVtcHRyZWUodW5zaWduZWQgc2hvcnQgaWR4LHVuc2lnbmVkIGNoYXIgKnR4dCxzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYixzdHJ1Y3QgX3czMV9oZWFkZXIgKmhlYWQsSEtFWSBoa2V5LHRpbWVfdCBsYXN0bW9kaWZpZWQsIGludCBsZXZlbCkKewogICAgc3RydWN0IF93MzFfZGlyZW50ICpkaXI7CiAgICBzdHJ1Y3QgX3czMV9rZXllbnQgKmtleTsKICAgIHN0cnVjdCBfdzMxX3ZhbGVudCAqdmFsOwogICAgSEtFWSBzdWJrZXkgPSAwOwogICAgc3RhdGljIGNoYXIJdGFpbFs0MDBdOwoKICAgIHdoaWxlIChpZHghPTApIHsKICAgICAgICBkaXI9KHN0cnVjdCBfdzMxX2RpcmVudCopJnRhYltpZHhdOwoKICAgICAgICBpZiAoZGlyLT5rZXlfaWR4KSB7CiAgICAgICAgICAgIGtleSA9IChzdHJ1Y3QgX3czMV9rZXllbnQqKSZ0YWJbZGlyLT5rZXlfaWR4XTsKCiAgICAgICAgICAgIG1lbWNweSh0YWlsLCZ0eHRba2V5LT5zdHJpbmdfb2ZmXSxrZXktPmxlbmd0aCk7CiAgICAgICAgICAgIHRhaWxba2V5LT5sZW5ndGhdPSdcMCc7CiAgICAgICAgICAgIC8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUKICAgICAgICAgICAgICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCFsZXZlbCAmJiAhc3RyY21wKHRhaWwsIi5jbGFzc2VzIikpIHsKICAgICAgICAgICAgICAgIF93MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLGhrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwogICAgICAgICAgICAgICAgaWR4PWRpci0+c2libGluZ19pZHg7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoc3Via2V5KSBSZWdDbG9zZUtleSggc3Via2V5ICk7CiAgICAgICAgICAgIGlmIChSZWdDcmVhdGVLZXlBKCBoa2V5LCB0YWlsLCAmc3Via2V5ICkgIT0gRVJST1JfU1VDQ0VTUykgc3Via2V5ID0gMDsKICAgICAgICAgICAgLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCiAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKICAgICAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCkgewogICAgICAgICAgICAgICAgICAgIHZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKICAgICAgICAgICAgICAgICAgICBtZW1jcHkodGFpbCwmdHh0W3ZhbC0+c3RyaW5nX29mZl0sdmFsLT5sZW5ndGgpOwogICAgICAgICAgICAgICAgICAgIHRhaWxbdmFsLT5sZW5ndGhdPSdcMCc7CiAgICAgICAgICAgICAgICAgICAgUmVnU2V0VmFsdWVBKCBzdWJrZXksIE5VTEwsIFJFR19TWiwgdGFpbCwgMCApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIFRSQUNFKCJzdHJhbmdlOiBubyBkaXJlY3Rvcnkga2V5IG5hbWUsIGlkeD0lMDR4XG4iLCBpZHgpOwogICAgICAgIF93MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHN1YmtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CiAgICAgICAgaWR4PWRpci0+c2libGluZ19pZHg7CiAgICB9CiAgICBpZiAoc3Via2V5KSBSZWdDbG9zZUtleSggc3Via2V5ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93MzFfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwp2b2lkIF93MzFfbG9hZHJlZyh2b2lkKQp7CiAgICBIRklMRSBoZjsKICAgIHN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwogICAgc3RydWN0IF93MzFfdGFiZW50CSp0YWI7CiAgICB1bnNpZ25lZCBjaGFyCQkqdHh0OwogICAgdW5zaWduZWQgaW50CQlsZW47CiAgICBPRlNUUlVDVAkJb2ZzOwogICAgQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZpbmZvOwogICAgdGltZV90CQkJbGFzdG1vZGlmaWVkOwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGhmID0gT3BlbkZpbGUoInJlZy5kYXQiLCZvZnMsT0ZfUkVBRCk7CiAgICBpZiAoaGY9PUhGSUxFX0VSUk9SKSByZXR1cm47CgogICAgLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCiAgICBpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQoaGYsJmhlYWQsc2l6ZW9mKGhlYWQpKSkgewogICAgICAgIEVSUigicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKICAgICAgICBfbGNsb3NlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSE9MCkgewogICAgICAgIEVSUigicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwogICAgLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwogICAgdGFiID0gX3htYWxsb2MobGVuKTsKICAgIGlmIChsZW4hPV9scmVhZChoZix0YWIsbGVuKSkgewogICAgICAgIEVSUigiY291bGRuJ3QgcmVhZCAlZCBieXRlcy5cbiIsbGVuKTsKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIHJlYWQgdGV4dCAqLwogICAgdHh0ID0gX3htYWxsb2MoaGVhZC50ZXh0c2l6ZSk7CiAgICBpZiAoLTE9PV9sbHNlZWsoaGYsaGVhZC50ZXh0b2ZmLFNFRUtfU0VUKSkgewogICAgICAgIEVSUigiY291bGRuJ3Qgc2VlayB0byB0ZXh0YmxvY2suXG4iKTsKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgZnJlZSh0eHQpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChoZWFkLnRleHRzaXplIT1fbHJlYWQoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CiAgICAgICAgRVJSKCJ0ZXh0YmxvY2sgdG9vIHNob3J0ICglZCBpbnN0ZWFkIG9mICVsZCkuXG4iLGxlbixoZWFkLnRleHRzaXplKTsKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgZnJlZSh0eHQpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmLCZoZmluZm8pKSB7CiAgICAgICAgRVJSKCJHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7CiAgICAgICAgZnJlZSh0YWIpOwogICAgICAgIGZyZWUodHh0KTsKICAgICAgICBfbGNsb3NlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBsYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CiAgICBfdzMxX2R1bXB0cmVlKHRhYlswXS53MSx0eHQsdGFiLCZoZWFkLEhLRVlfQ0xBU1NFU19ST09ULGxhc3Rtb2RpZmllZCwwKTsKICAgIGZyZWUodGFiKTsKICAgIGZyZWUodHh0KTsKICAgIF9sY2xvc2UoaGYpOwogICAgcmV0dXJuOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93cyA5NSByZWdpc3RyeSBsb2FkZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogU0VDVElPTiAxOiBtYWluIGhlYWRlcgogKgogKiBvbmNlIGF0IG9mZnNldCAwCiAqLwojZGVmaW5lCVc5NV9SRUdfQ1JFR19JRAkweDQ3NDU1MjQzCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qICJDUkVHIiA9IFc5NV9SRUdfQ1JFR19JRCAqLwogICAgRFdPUkQJdmVyc2lvbjsJLyogPz8/PyAweDAwMDEwMDAwICovCiAgICBEV09SRAlyZ2RiX29mZjsJLyogMHgwOCBPZmZzZXQgb2YgMXN0IFJHREItYmxvY2sgKi8KICAgIERXT1JECXVrMjsJCS8qIDB4MGMgKi8KICAgIFdPUkQJcmdkYl9udW07CS8qIDB4MTAgIyBvZiBSR0RCLWJsb2NrcyAqLwogICAgV09SRAl1azM7CiAgICBEV09SRAl1a1szXTsKICAgIC8qIHJna24gKi8KfSBfdzk1Y3JlZzsKCi8qIFNFQ1RJT04gMjogRGlyZWN0b3J5IGluZm9ybWF0aW9uICh0cmVlIHN0cnVjdHVyZSkKICoKICogb25jZSBvbiBvZmZzZXQgMHgyMAogKgogKiBzdHJ1Y3R1cmU6IFtyZ2tuXVtka2VdKgkocmVwZWF0IHRpbGwgbGFzdF9ka2UgaXMgcmVhY2hlZCkKICovCiNkZWZpbmUJVzk1X1JFR19SR0tOX0lECTB4NGU0YjQ3NTIKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyoiUkdLTiIgPSBXOTVfUkVHX1JHS05fSUQgKi8KICAgIERXT1JECXNpemU7CQkvKiBTaXplIG9mIHRoZSBSR0tOLWJsb2NrICovCiAgICBEV09SRAlyb290X29mZjsJLyogUmVsLiBPZmZzZXQgb2YgdGhlIHJvb3QtcmVjb3JkICovCiAgICBEV09SRCAgIGxhc3RfZGtlOyAgICAgICAvKiBPZmZzZXQgdG8gbGFzdCBES0UgPyAqLwogICAgRFdPUkQJdWtbNF07Cn0gX3c5NXJna247CgovKiBEaXNrIEtleSBFbnRyeSBTdHJ1Y3R1cmUKICoKICogdGhlIDFzdCBlbnRyeSBpbiBhICJ1c3VhbCIgcmVnaXN0cnkgZmlsZSBpcyBhIG51bC1lbnRyeSB3aXRoIHN1YmtleXM6IHRoZQogKiBoaXZlIGl0c2VsZi4gSXQgbG9va3MgdGhlIHNhbWUgbGlrZSBvdGhlciBrZXlzLiBFdmVuIHRoZSBJRC1udW1iZXIgY2FuCiAqIGJlIGFueSB2YWx1ZS4KICoKICogVGhlICJoYXNoIi12YWx1ZSBpcyBhIHZhbHVlIHJlcHJlc2VudGluZyB0aGUga2V5J3MgbmFtZS4gV2luZG93cyB3aWxsIG5vdAogKiBzZWFyY2ggZm9yIHRoZSBuYW1lLCBidXQgZm9yIGEgbWF0Y2hpbmcgaGFzaC12YWx1ZS4gaWYgaXQgZmluZHMgb25lLCBpdAogKiB3aWxsIGNvbXBhcmUgdGhlIGFjdHVhbCBzdHJpbmcgaW5mbywgb3RoZXJ3aXNlIGNvbnRpbnVlIHdpdGggdGhlIG5leHQga2V5LgogKiBUbyBjYWxjdWxhdGUgdGhlIGhhc2ggaW5pdGlhbGl6ZSBhIEQtV29yZCB3aXRoIDAgYW5kIGFkZCBhbGwgQVNDSUktdmFsdWVzCiAqIG9mIHRoZSBzdHJpbmcgd2hpY2ggYXJlIHNtYWxsZXIgdGhhbiAweDgwICgxMjgpIHRvIHRoaXMgRC1Xb3JkLgogKgogKiBJZiB5b3Ugd2FudCB0byBtb2RpZnkga2V5IG5hbWVzLCBhbHNvIG1vZGlmeSB0aGUgaGFzaC12YWx1ZXMsIHNpbmNlIHRoZXkKICogY2Fubm90IGJlIGZvdW5kIGFnYWluIChhbHRob3VnaCB0aGV5IHdvdWxkIGJlIGRpc3BsYXllZCBpbiBSRUdFRElUKQogKiBFbmQgb2YgbGlzdC1wb2ludGVycyBhcmUgZmlsbGVkIHdpdGggMHhGRkZGRkZGRgogKgogKiBEaXNrIGtleXMgYXJlIGxheWVkIG91dCBmbGF0IC4uLiBCdXQsIHNvbWV0aW1lcywgbnJMUyBhbmQgbnJNUyBhcmUgYm90aAogKiAweEZGRkYsIHdoaWNoIG1lYW5zIHNraXBwaW5nIG92ZXIgbmV4dGtleW9mZnNldCBieXRlcyAoaW5jbHVkaW5nIHRoaXMKICogc3RydWN0dXJlKSBhbmQgcmVhZGluZyBhbm90aGVyIFJHREJfc2VjdGlvbi4KICoKICogVGhlIGxhc3QgREtFIChzZWUgZmllbGQgbGFzdF9ka2UgaW4gX3c5NV9yZ2tuKSBoYXMgb25seSAzIERXT1JEcyB3aXRoCiAqIDB4ODAwMDAwMDAgKEVPTCBpbmRpY2F0b3IgPykgYXMgeDEsIHRoZSBoYXNoIHZhbHVlIGFuZCAweEZGRkZGRkZGIGFzIHgzLgogKiBUaGUgcmVtYWluaW5nIHNwYWNlIGJldHdlZW4gbGFzdF9ka2UgYW5kIHRoZSBvZmZzZXQgY2FsY3VsYXRlZCBmcm9tCiAqIHJna24tPnNpemUgc2VlbXMgdG8gYmUgZnJlZSBmb3IgdXNlIGZvciBtb3JlIGRrZTpzLgogKiBTbyBpdCBzZWVtcyBpZiBtb3JlIGRrZTpzIGFyZSBhZGRlZCwgdGhleSBhcmUgYWRkZWQgdG8gdGhhdCBzcGFjZSBhbmQKICogbGFzdF9ka2UgaXMgZ3Jvd24sIGFuZCBpbiBjYXNlIHRoYXQgImZyZWUiIHNwYWNlIGlzIG91dCwgdGhlIHNwYWNlCiAqIGdldHMgZ3Jvd24gYW5kIHJna24tPnNpemUgZ2V0cyBhZGp1c3RlZC4KICoKICogdGhlcmUgaXMgYSBvbmUgdG8gb25lIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGRrZSBhbmQgZGtoCiAqLwogLyoga2V5IHN0cnVjdCwgb25jZSBwZXIga2V5ICovCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECXgxOwkJLyogRnJlZSBlbnRyeSBpbmRpY2F0b3IoPykgKi8KICAgIERXT1JECWhhc2g7CQkvKiBzdW0gb2YgYnl0ZXMgb2Yga2V5bmFtZSAqLwogICAgRFdPUkQJeDM7CQkvKiBSb290IGtleSBpbmRpY2F0b3I/IHVzdWFsbHkgMHhGRkZGRkZGRiAqLwogICAgRFdPUkQJcHJldmx2bDsJLyogb2Zmc2V0IG9mIHByZXZpb3VzIGtleSAqLwogICAgRFdPUkQJbmV4dHN1YjsJLyogb2Zmc2V0IG9mIGNoaWxkIGtleSAqLwogICAgRFdPUkQJbmV4dDsJCS8qIG9mZnNldCBvZiBzaWJsaW5nIGtleSAqLwogICAgV09SRAluckxTOwkJLyogaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCiAgICBXT1JECW5yTVM7CQkvKiBudW1iZXIgb2YgdGhlIHJnZGIgYmxvY2sgKi8KfSBfdzk1ZGtlOwoKLyogU0VDVElPTiAzOiBrZXkgaW5mb3JtYXRpb24sIHZhbHVlcyBhbmQgZGF0YQogKgogKiBzdHJ1Y3R1cmU6CiAqICBzZWN0aW9uOglbYmxvY2tzXSoJCShyZXBlYXQgY3JlZy0+cmdkYl9udW0gdGltZXMpCiAqICBibG9ja3M6CVtyZ2RiXSBbc3ViYmxvY2tzXSogCShyZXBlYXQgdGlsbCBibG9jayBzaXplIHJlYWNoZWQgKQogKiAgc3ViYmxvY2tzOglbZGtoXSBbZGt2XSoJCShyZXBlYXQgZGtoLT52YWx1ZXMgdGltZXMgKQogKgogKiBBbiBpbnRlcmVzdGluZyByZWxhdGlvbnNoaXAgZXhpc3RzIGluIFJHREJfc2VjdGlvbi4gVGhlIERXT1JEIHZhbHVlCiAqIGF0IG9mZnNldCAweDEwIGVxdWFscyB0aGUgb25lIGF0IG9mZnNldCAweDA0IG1pbnVzIHRoZSBvbmUgYXQgb2Zmc2V0IDB4MDguCiAqIEkgaGF2ZSBubyBpZGVhIGF0IHRoZSBtb21lbnQgd2hhdCB0aGlzIG1lYW5zLiAgKEtldmluIENvemVucykKICovCgovKiBibG9jayBoZWFkZXIsIG9uY2UgcGVyIGJsb2NrICovCiNkZWZpbmUgVzk1X1JFR19SR0RCX0lECTB4NDI0NDQ3NTIKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkvKiAweDAwICdSR0RCJyA9IFc5NV9SRUdfUkdEQl9JRCAqLwogICAgRFdPUkQJc2l6ZTsJLyogMHgwNCAqLwogICAgRFdPUkQJdWsxOwkvKiAweDA4ICovCiAgICBEV09SRAl1azI7CS8qIDB4MGMgKi8KICAgIERXT1JECXVrMzsJLyogMHgxMCAqLwogICAgRFdPUkQJdWs0OwkvKiAweDE0ICovCiAgICBEV09SRAl1azU7CS8qIDB4MTggKi8KICAgIERXT1JECXVrNjsJLyogMHgxYyAqLwogICAgLyogZGtoICovCn0gX3c5NXJnZGI7CgovKiBEaXNrIEtleSBIZWFkZXIgc3RydWN0dXJlIChSR0RCIHBhcnQpLCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZglzdHJ1Y3QgewogICAgRFdPUkQJbmV4dGtleW9mZjsgCS8qIDB4MDAgb2Zmc2V0IHRvIG5leHQgZGtoICovCiAgICBXT1JECW5yTFM7CQkvKiAweDA0IGlkIGluc2lkZSB0aGUgcmdkYiBibG9jayAqLwogICAgV09SRAluck1TOwkJLyogMHgwNiBudW1iZXIgb2YgdGhlIHJnZGIgYmxvY2sgKi8KICAgIERXT1JECWJ5dGVzdXNlZDsJLyogMHgwOCAqLwogICAgV09SRAlrZXluYW1lbGVuOwkvKiAweDBjIGxlbiBvZiBuYW1lICovCiAgICBXT1JECXZhbHVlczsJCS8qIDB4MGUgbnVtYmVyIG9mIHZhbHVlcyAqLwogICAgRFdPUkQJeHgxOwkJLyogMHgxMCAqLwogICAgY2hhcgluYW1lWzFdOwkvKiAweDE0ICovCiAgICAvKiBka3YgKi8JCS8qIDB4MTQgKyBrZXluYW1lbGVuICovCn0gX3c5NWRraDsKCi8qIERpc2sgS2V5IFZhbHVlIHN0cnVjdHVyZSwgb25jZSBwZXIgdmFsdWUgKi8KdHlwZWRlZglzdHJ1Y3QgewogICAgRFdPUkQJdHlwZTsJCS8qIDB4MDAgKi8KICAgIERXT1JECXgxOwkJLyogMHgwNCAqLwogICAgV09SRAl2YWxuYW1lbGVuOwkvKiAweDA4IGxlbmd0aCBvZiBuYW1lLCAwIGlzIGRlZmF1bHQga2V5ICovCiAgICBXT1JECXZhbGRhdGFsZW47CS8qIDB4MEEgbGVuZ3RoIG9mIGRhdGEgKi8KICAgIGNoYXIJbmFtZVsxXTsJLyogMHgwYyAqLwogICAgLyogcmF3IGRhdGEgKi8JCS8qIDB4MGMgKyB2YWxuYW1lbGVuICovCn0gX3c5NWRrdjsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9sb29rdXBfZGtoIFtJbnRlcm5hbF0KICoKICogc2Vla3MgdGhlIGRraCBiZWxvbmdpbmcgdG8gYSBka2UKICovCnN0YXRpYyBfdzk1ZGtoICpfdzk1X2xvb2t1cF9ka2goX3c5NWNyZWcgKmNyZWcsaW50IG5yTFMsaW50IG5yTVMpCnsKICAgIF93OTVyZ2RiICogcmdkYjsKICAgIF93OTVka2ggKiBka2g7CiAgICBpbnQgaTsKCiAgICAvKiBnZXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgcmdkYiBkYXRhc3RvcmUgKi8KICAgIHJnZGIgPSAoX3c5NXJnZGIqKSgoY2hhciopY3JlZytjcmVnLT5yZ2RiX29mZik7CgogICAgLyogY2hlY2s6IHJlcXVlc3RlZCBibG9jayA8IGxhc3RfYmxvY2spICovCiAgICBpZiAoY3JlZy0+cmdkYl9udW0gPD0gbnJNUykgewogICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISByZXF1ZXN0ZWQgYmxvY2sgbm8uIGJleW9uZCBlbmQuXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIGZpbmQgdGhlIHJpZ2h0IGJsb2NrICovCiAgICBmb3IoaT0wOyBpPG5yTVMgO2krKykgewogICAgICAgIGlmKHJnZGItPmlkICE9IFc5NV9SRUdfUkdEQl9JRCkgeyAgLyogY2hlY2sgdGhlIG1hZ2ljICovCiAgICAgICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISBiYWQgbWFnaWMgMHglMDhseFxuIiwgcmdkYi0+aWQpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KICAgICAgICByZ2RiID0gKF93OTVyZ2RiKikgKChjaGFyKilyZ2RiK3JnZGItPnNpemUpOwkJLyogZmluZCBuZXh0IGJsb2NrICovCiAgICB9CgogICAgZGtoID0gKF93OTVka2gqKShyZ2RiICsgMSk7CQkJCS8qIGZpcnN0IHN1YiBibG9jayB3aXRoaW4gdGhlIHJnZGIgKi8KCiAgICBkbyB7CiAgICAgICAgaWYobnJMUz09ZGtoLT5uckxTICkgcmV0dXJuIGRraDsKICAgICAgICBka2ggPSAoX3c5NWRraCopKChjaGFyKilka2ggKyBka2gtPm5leHRrZXlvZmYpOwkvKiBmaW5kIG5leHQgc3ViYmxvY2sgKi8KICAgIH0gd2hpbGUgKChjaGFyICopZGtoIDwgKChjaGFyKilyZ2RiK3JnZGItPnNpemUpKTsKCmVycm9yOgogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9kdW1wX2RrdiBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfZHVtcF9ka3YoX3c5NWRraCAqZGtoLGludCBuckxTLGludCBuck1TLEZJTEUgKmYpCnsKICAgIF93OTVka3YgKiBka3Y7CiAgICBpbnQgaTsKCiAgICAvKiBmaXJzdCB2YWx1ZSBibG9jayAqLwogICAgZGt2ID0gKF93OTVka3YqKSgoY2hhciopZGtoK2RraC0+a2V5bmFtZWxlbisweDE0KTsKCiAgICAvKiBsb29wIHRocm91Z2ggdGhlIHZhbHVlcyAqLwogICAgZm9yIChpPTA7IGk8IGRraC0+dmFsdWVzOyBpKyspIHsKICAgICAgICBzdHJ1Y3Qga2V5X3ZhbHVlIHZhbHVlOwogICAgICAgIFdDSEFSICpwZGF0YTsKCiAgICAgICAgdmFsdWUubmFtZVcgPSBfc3RyZHVwbkF0b1coZGt2LT5uYW1lLGRrdi0+dmFsbmFtZWxlbik7CiAgICAgICAgdmFsdWUudHlwZSA9IGRrdi0+dHlwZTsKICAgICAgICB2YWx1ZS5sZW4gPSBka3YtPnZhbGRhdGFsZW47CgogICAgICAgIHZhbHVlLmRhdGEgPSAmKGRrdi0+bmFtZVtka3YtPnZhbG5hbWVsZW5dKTsKICAgICAgICBwZGF0YSA9IE5VTEw7CiAgICAgICAgaWYgKCAodmFsdWUudHlwZT09UkVHX1NaKSB8fCAodmFsdWUudHlwZT09UkVHX0VYUEFORF9TWikgfHwgKHZhbHVlLnR5cGU9PVJFR19NVUxUSV9TWikgKSB7CiAgICAgICAgICAgIHBkYXRhID0gX3N0cmR1cG5BdG9XKHZhbHVlLmRhdGEsdmFsdWUubGVuKTsKICAgICAgICAgICAgdmFsdWUubGVuICo9IDI7CiAgICAgICAgfQogICAgICAgIGlmIChwZGF0YSAhPSBOVUxMKSB2YWx1ZS5kYXRhID0gcGRhdGE7CgogICAgICAgIF9kdW1wX3ZhbHVlKCZ2YWx1ZSxmKTsKICAgICAgICBmcmVlKHZhbHVlLm5hbWVXKTsKICAgICAgICBpZiAocGRhdGEgIT0gTlVMTCkgZnJlZShwZGF0YSk7CgogICAgICAgIC8qIG5leHQgdmFsdWUgKi8KICAgICAgICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka3YrZGt2LT52YWxuYW1lbGVuK2Rrdi0+dmFsZGF0YWxlbisweDBjKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfZHVtcF9ka2UgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfdzk1X2R1bXBfZGtlKExQU1RSIGtleV9uYW1lLF93OTVjcmVnICpjcmVnLF93OTVyZ2tuICpyZ2tuLF93OTVka2UgKmRrZSxGSUxFICpmLGludCBsZXZlbCkKewogICAgX3c5NWRraCAqIGRraDsKICAgIExQU1RSIG5ld19rZXlfbmFtZSA9IE5VTEw7CgogICAgLyogc3BlY2lhbCByb290IGtleSAqLwogICAgaWYgKGRrZS0+bnJMUyA9PSAweGZmZmYgfHwgZGtlLT5uck1TPT0weGZmZmYpCQkvKiBlZy4gdGhlIHJvb3Qga2V5IGhhcyBubyBuYW1lICovCiAgICB7CiAgICAgICAgLyogcGFyc2UgdGhlIG9uZSBzdWJrZXkgKi8KICAgICAgICBpZiAoZGtlLT5uZXh0c3ViICE9IDB4ZmZmZmZmZmYpIHJldHVybiBfdzk1X2R1bXBfZGtlKGtleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dHN1YiksZixsZXZlbCk7CiAgICAgICAgLyogaGFzIG5vIHNpYmxpbmcga2V5cyAqLwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiBzZWFyY2ggc3ViYmxvY2sgKi8KICAgIGlmICghKGRraCA9IF93OTVfbG9va3VwX2RraChjcmVnLCBka2UtPm5yTFMsIGRrZS0+bnJNUykpKSB7CiAgICAgICAgRVJSKCJka2UgcG9pbnRpbmcgdG8gbWlzc2luZyBka2ggIVxuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChsZXZlbCA8PSAwKSB7CiAgICAgICAgLyogY3JlYXRlIG5ldyBzdWJrZXkgbmFtZSAqLwogICAgICAgIG5ld19rZXlfbmFtZSA9IF9zdHJkdXBuQShrZXlfbmFtZSxzdHJsZW4oa2V5X25hbWUpK2RraC0+a2V5bmFtZWxlbisxKTsKICAgICAgICBpZiAoc3RyY21wKG5ld19rZXlfbmFtZSwiIikgIT0gMCkgc3RyY2F0KG5ld19rZXlfbmFtZSwiXFwiKTsKICAgICAgICBzdHJuY2F0KG5ld19rZXlfbmFtZSxka2gtPm5hbWUsZGtoLT5rZXluYW1lbGVuKTsKCiAgICAgICAgLyogd2FsayBzaWJsaW5nIGtleXMgKi8KICAgICAgICBpZiAoZGtlLT5uZXh0ICE9IDB4ZmZmZmZmZmYgKSB7CiAgICAgICAgICAgIGlmICghX3c5NV9kdW1wX2RrZShrZXlfbmFtZSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHQpLGYsbGV2ZWwpKSB7CiAgICAgICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIHdyaXRlIHRoZSBrZXkgcGF0aCAoc29tZXRoaW5nIGxpa2UgW1NvZnR3YXJlXFxNaWNyb3NvZnRcXC4uXSkgb25seSBpZjoKICAgICAgICAgICAxKSBrZXkgaGFzIHNvbWUgdmFsdWVzCiAgICAgICAgICAgMikga2V5IGhhcyBubyB2YWx1ZXMgYW5kIG5vIHN1YmtleXMKICAgICAgICAqLwogICAgICAgIGlmIChka2gtPnZhbHVlcyA+IDApIHsKICAgICAgICAgICAgLyogdGhlcmUgYXJlIHNvbWUgdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgICAgIGlmICghX3c5NV9kdW1wX2Rrdihka2gsIGRrZS0+bnJMUywgZGtlLT5uck1TLGYpKSB7CiAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoKGRrZS0+bmV4dHN1YiA9PSAweGZmZmZmZmZmKSAmJiAoZGtoLT52YWx1ZXMgPT0gMCkpIHsKICAgICAgICAgICAgLyogbm8gc3Via2V5cyBhbmQgbm8gdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQogICAgfSBlbHNlIG5ld19rZXlfbmFtZSA9IF9zdHJkdXBuQShrZXlfbmFtZSxzdHJsZW4oa2V5X25hbWUpKTsKCiAgICAvKiBuZXh0IHN1YiBrZXkgKi8KICAgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgewogICAgICAgIGlmICghX3c5NV9kdW1wX2RrZShuZXdfa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSxmLGxldmVsLTEpKSB7CiAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgIHJldHVybiBUUlVFOwp9Ci8qIGVuZCB3aW5kb3dzIDk1IGxvYWRlciAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd3MgTlQgcmVnaXN0cnkgbG9hZGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIE5UIFJFR0lTVFJZIExPQURFUiAqLwoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKI2lmbmRlZiBNQVBfRkFJTEVECiNkZWZpbmUgTUFQX0ZBSUxFRCAoKExQVk9JRCktMSkKI2VuZGlmCgojZGVmaW5lIE5UX1JFR19CTE9DS19TSVpFICAgICAgICAgICAgMHgxMDAwCgojZGVmaW5lIE5UX1JFR19IRUFERVJfQkxPQ0tfSUQgICAgICAgMHg2NjY3NjU3MgkvKiByZWdmICovCiNkZWZpbmUgTlRfUkVHX1BPT0xfQkxPQ0tfSUQgICAgICAgICAweDZFNjk2MjY4CS8qIGhiaW4gKi8KI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX0lEICAgICAgICAgIDB4NmI2ZSAvKiBuayAqLwojZGVmaW5lIE5UX1JFR19WQUxVRV9CTE9DS19JRCAgICAgICAgMHg2Yjc2IC8qIHZrICovCgovKiBzdWJibG9ja3Mgb2YgbmsgKi8KI2RlZmluZSBOVF9SRUdfSEFTSF9CTE9DS19JRCAgICAgICAgIDB4NjY2YyAvKiBsZiAqLwojZGVmaW5lIE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQgICAgICAgMHg2OTZjIC8qIGxpICovCiNkZWZpbmUgTlRfUkVHX1JJX0JMT0NLX0lECSAgICAgMHg2OTcyIC8qIHJpICovCgojZGVmaW5lIE5UX1JFR19LRVlfQkxPQ0tfVFlQRSAgICAgICAgMHgyMAojZGVmaW5lIE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFICAgMHgyYwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiAweDY2Njc2NTcyICdyZWdmJyovCiAgICBEV09SRAl1azE7CQkvKiAweDA0ICovCiAgICBEV09SRAl1azI7CQkvKiAweDA4ICovCiAgICBGSUxFVElNRQlEYXRlTW9kaWZpZWQ7CS8qIDB4MGMgKi8KICAgIERXT1JECXVrMzsJCS8qIDB4MTQgKi8KICAgIERXT1JECXVrNDsJCS8qIDB4MTggKi8KICAgIERXT1JECXVrNTsJCS8qIDB4MWMgKi8KICAgIERXT1JECXVrNjsJCS8qIDB4MjAgKi8KICAgIERXT1JECVJvb3RLZXlCbG9jazsJLyogMHgyNCAqLwogICAgRFdPUkQJQmxvY2tTaXplOwkvKiAweDI4ICovCiAgICBEV09SRCAgIHVrN1sxMTZdOwogICAgRFdPUkQJQ2hlY2tzdW07IC8qIGF0IG9mZnNldCAweDFGQyAqLwp9IG50X3JlZ2Y7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlibG9ja3NpemU7CiAgICBCWVRFCWRhdGFbMV07Cn0gbnRfaGJpbl9zdWI7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qIDB4NkU2OTYyNjggJ2hiaW4nICovCiAgICBEV09SRAlvZmZfcHJldjsKICAgIERXT1JECW9mZl9uZXh0OwogICAgRFdPUkQJdWsxOwogICAgRFdPUkQJdWsyOwkJLyogMHgxMCAqLwogICAgRFdPUkQJdWszOwkJLyogMHgxNCAqLwogICAgRFdPUkQJdWs0OwkJLyogMHgxOCAqLwogICAgRFdPUkQJc2l6ZTsJCS8qIDB4MUMgKi8KICAgIG50X2hiaW5fc3ViCWhiaW5fc3ViOwkvKiAweDIwICovCn0gbnRfaGJpbjsKCi8qCiAqIHRoZSB2YWx1ZV9saXN0IGNvbnNpc3RzIG9mIG9mZnNldHMgdG8gdGhlIHZhbHVlcyAodmspCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECVN1YkJsb2NrSWQ7CQkvKiAweDAwIDB4NkI2RSAqLwogICAgV09SRAlUeXBlOwkJCS8qIDB4MDIgZm9yIHRoZSByb290LWtleTogMHgyQywgb3RoZXJ3aXNlIDB4MjAqLwogICAgRklMRVRJTUUJd3JpdGV0aW1lOwkvKiAweDA0ICovCiAgICBEV09SRAl1azE7CQkJLyogMHgwQyAqLwogICAgRFdPUkQJcGFyZW50X29mZjsJCS8qIDB4MTAgT2Zmc2V0IG9mIE93bmVyL1BhcmVudCBrZXkgKi8KICAgIERXT1JECW5yX3N1YmtleXM7CQkvKiAweDE0IG51bWJlciBvZiBzdWItS2V5cyAqLwogICAgRFdPUkQJdWs4OwkJCS8qIDB4MTggKi8KICAgIERXT1JECWxmX29mZjsJCQkvKiAweDFDIE9mZnNldCBvZiB0aGUgc3ViLWtleSBsZi1SZWNvcmRzICovCiAgICBEV09SRAl1azI7CQkJLyogMHgyMCAqLwogICAgRFdPUkQJbnJfdmFsdWVzOwkJLyogMHgyNCBudW1iZXIgb2YgdmFsdWVzICovCiAgICBEV09SRAl2YWx1ZWxpc3Rfb2ZmOwkJLyogMHgyOCBPZmZzZXQgb2YgdGhlIFZhbHVlLUxpc3QgKi8KICAgIERXT1JECW9mZl9zazsJCQkvKiAweDJjIE9mZnNldCBvZiB0aGUgc2stUmVjb3JkICovCiAgICBEV09SRAlvZmZfY2xhc3M7CQkvKiAweDMwIE9mZnNldCBvZiB0aGUgQ2xhc3MtTmFtZSAqLwogICAgRFdPUkQJdWszOwkJCS8qIDB4MzQgKi8KICAgIERXT1JECXVrNDsJCQkvKiAweDM4ICovCiAgICBEV09SRAl1azU7CQkJLyogMHgzYyAqLwogICAgRFdPUkQJdWs2OwkJCS8qIDB4NDAgKi8KICAgIERXT1JECXVrNzsJCQkvKiAweDQ0ICovCiAgICBXT1JECW5hbWVfbGVuOwkJLyogMHg0OCBuYW1lLWxlbmd0aCAqLwogICAgV09SRAljbGFzc19sZW47CQkvKiAweDRhIGNsYXNzLW5hbWUgbGVuZ3RoICovCiAgICBjaGFyCW5hbWVbMV07CQkvKiAweDRjIGtleS1uYW1lICovCn0gbnRfbms7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlvZmZfbms7CS8qIDB4MDAgKi8KICAgIERXT1JECW5hbWU7CS8qIDB4MDQgKi8KfSBoYXNoX3JlYzsKCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwIDB4NjY2YyAqLwogICAgV09SRAlucl9rZXlzOwkvKiAweDA2ICovCiAgICBoYXNoX3JlYwloYXNoX3JlY1sxXTsKfSBudF9sZjsKCi8qCiBsaXN0IG9mIHN1YmtleXMgd2l0aG91dCBoYXNoCgogbGkgLS0rLS0+bmsKICAgICAgfAogICAgICArLS0+bmsKICovCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwIDB4Njk2YyAqLwogICAgV09SRAlucl9rZXlzOwogICAgRFdPUkQJb2ZmX25rWzFdOwp9IG50X2xpOwoKLyoKIHRoaXMgaXMgYSBpbnRlcm1lZGlhdGUgbm9kZQoKIHJpIC0tKy0tPmxpLS0rLS0+bmsKICAgICAgfCAgICAgICArCiAgICAgIHwgICAgICAgKy0tPm5rCiAgICAgIHwKICAgICAgKy0tPmxpLS0rLS0+bmsKICAgICAgICAgICAgICArCgkgICAgICArLS0+bmsKICovCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwIDB4Njk3MiAqLwogICAgV09SRAlucl9saTsJCS8qIDB4MDIgbnVtYmVyIG9mZiBvZmZzZXRzICovCiAgICBEV09SRAlvZmZfbGlbMV07CS8qIDB4MDQgcG9pbnRzIHRvIGxpICovCn0gbnRfcmk7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAndmsnICovCiAgICBXT1JECW5hbV9sZW47CiAgICBEV09SRAlkYXRhX2xlbjsKICAgIERXT1JECWRhdGFfb2ZmOwogICAgRFdPUkQJdHlwZTsKICAgIFdPUkQJZmxhZzsKICAgIFdPUkQJdWsxOwogICAgY2hhcgluYW1lWzFdOwp9IG50X3ZrOwoKLyoKICogZ2V0cyBhIHZhbHVlCiAqCiAqIHZrLT5mbGFnOgogKiAgMCB2YWx1ZSBpcyBhIGRlZmF1bHQgdmFsdWUKICogIDEgdGhlIHZhbHVlIGhhcyBhIG5hbWUKICoKICogdmstPmRhdGFfbGVuCiAqICBsZW4gb2YgdGhlIHdob2xlIGRhdGEgYmxvY2sKICogIC0gcmVnX3N6ICh1bmljb2RlKQogKiAgICBieXRlcyBpbmNsdWRpbmcgdGhlIHRlcm1pbmF0aW5nIFwwID0gMioobnVtYmVyX29mX2NoYXJzKzEpCiAqICAtIHJlZ19kd29yZCwgcmVnX2JpbmFyeToKICogICAgaWYgaGlnaGVzdCBiaXQgb2YgZGF0YV9sZW4gaXMgc2V0IGRhdGFfb2ZmIGNvbnRhaW5zIHRoZSB2YWx1ZQogKi8Kc3RhdGljIGludCBfbnRfZHVtcF92ayhMUFNUUiBrZXlfbmFtZSwgY2hhciAqYmFzZSwgbnRfdmsgKnZrLEZJTEUgKmYpCnsKICAgIEJZVEUgKnBkYXRhID0gKEJZVEUgKikoYmFzZSt2ay0+ZGF0YV9vZmYrNCk7IC8qIHN0YXJ0IG9mIGRhdGEgKi8KICAgIHN0cnVjdCBrZXlfdmFsdWUgdmFsdWU7CgogICAgaWYgKHZrLT5pZCAhPSBOVF9SRUdfVkFMVUVfQkxPQ0tfSUQpIHsKICAgICAgICBFUlIoInVua25vd24gYmxvY2sgZm91bmQgKDB4JTA0eCksIHBsZWFzZSByZXBvcnQhXG4iLCB2ay0+aWQpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICB2YWx1ZS5uYW1lVyA9IF9zdHJkdXBuQXRvVyh2ay0+bmFtZSx2ay0+bmFtX2xlbik7CiAgICB2YWx1ZS50eXBlID0gdmstPnR5cGU7CiAgICB2YWx1ZS5sZW4gPSAodmstPmRhdGFfbGVuICYgMHg3ZmZmZmZmZik7CiAgICB2YWx1ZS5kYXRhID0gKHZrLT5kYXRhX2xlbiAmIDB4ODAwMDAwMDApID8gKExQQllURSkmKHZrLT5kYXRhX29mZik6IHBkYXRhOwoKICAgIF9kdW1wX3ZhbHVlKCZ2YWx1ZSxmKTsKICAgIGZyZWUodmFsdWUubmFtZVcpOwoKICAgIHJldHVybiBUUlVFOwp9CgovKiBpdCdzIGNhbGxlZCBmcm9tIF9udF9kdW1wX2xmKCkgKi8Kc3RhdGljIGludCBfbnRfZHVtcF9uayhMUFNUUiBrZXlfbmFtZSxjaGFyICpiYXNlLG50X25rICpuayxGSUxFICpmLGludCBsZXZlbCk7CgovKgogKiBnZXQgdGhlIHN1YmtleXMKICoKICogdGhpcyBzdHJ1Y3R1cmUgY29udGFpbnMgdGhlIGhhc2ggb2YgYSBrZXluYW1lIGFuZCBwb2ludHMgdG8gYWxsCiAqIHN1YmtleXMKICoKICogZXhjZXB0aW9uOiBpZiB0aGUgaWQgaXMgJ2lsJyB0aGVyZSBhcmUgbm8gaGFzaCB2YWx1ZXMgYW5kIGV2ZXJ5CiAqIGR3b3JkIGlzIGEgb2Zmc2V0CiAqLwpzdGF0aWMgaW50IF9udF9kdW1wX2xmKExQU1RSIGtleV9uYW1lLCBjaGFyICpiYXNlLCBpbnQgc3Via2V5cywgbnRfbGYgKmxmLCBGSUxFICpmLCBpbnQgbGV2ZWwpCnsKICAgIGludCBpOwoKICAgIGlmIChsZi0+aWQgPT0gTlRfUkVHX0hBU0hfQkxPQ0tfSUQpIHsKICAgICAgICBpZiAoc3Via2V5cyAhPSBsZi0+bnJfa2V5cykgZ290byBlcnJvcjE7CgogICAgICAgIGZvciAoaT0wOyBpPGxmLT5ucl9rZXlzOyBpKyspCiAgICAgICAgICAgIGlmICghX250X2R1bXBfbmsoa2V5X25hbWUsIGJhc2UsIChudF9uayopKGJhc2UrbGYtPmhhc2hfcmVjW2ldLm9mZl9uays0KSwgZiwgbGV2ZWwpKSBnb3RvIGVycm9yOwogICAgfSBlbHNlIGlmIChsZi0+aWQgPT0gTlRfUkVHX05PSEFTSF9CTE9DS19JRCkgewogICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKWxmOwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCiAgICAgICAgZm9yIChpPTA7IGk8bGktPm5yX2tleXM7IGkrKykKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9uayhrZXlfbmFtZSwgYmFzZSwgKG50X25rKikoYmFzZStsaS0+b2ZmX25rW2ldKzQpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfUklfQkxPQ0tfSUQpIHsgIC8qIHJpICovCiAgICAgICAgbnRfcmkgKiByaSA9IChudF9yaSopbGY7CiAgICAgICAgaW50IGxpX3N1YmtleXMgPSAwOwoKICAgICAgICAvKiBjb3VudCBhbGwgc3Via2V5cyAqLwogICAgICAgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKSB7CiAgICAgICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmKGxpLT5pZCAhPSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKSBnb3RvIGVycm9yMjsKICAgICAgICAgICAgbGlfc3Via2V5cyArPSBsaS0+bnJfa2V5czsKICAgICAgICB9CgogICAgICAgIC8qIGNoZWNrIG51bWJlciAqLwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpX3N1YmtleXMpIGdvdG8gZXJyb3IxOwoKICAgICAgICAvKiBsb29wIHRocm91Z2ggdGhlIGtleXMgKi8KICAgICAgICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykgewogICAgICAgICAgICBudF9saSAqbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmICghX250X2R1bXBfbGYoa2V5X25hbWUsIGJhc2UsIGxpLT5ucl9rZXlzLCAobnRfbGYqKWxpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgfSBlbHNlIGdvdG8gZXJyb3IyOwoKICAgIHJldHVybiBUUlVFOwoKZXJyb3IyOgogICAgaWYgKGxmLT5pZCA9PSAweDY4NmMpCiAgICAgICAgRklYTUUoInVua25vd24gV2luIFhQIG5vZGUgaWQgMHg2ODZjOiBkbyB3ZSBuZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBpdCA/XG4iKTsKICAgIGVsc2UKICAgICAgICBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBsZi0+aWQpOwogICAgcmV0dXJuIFRSVUU7CgplcnJvcjE6CiAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgKGluY29uc2lzdGVudCBudW1iZXIgb2Ygc3Via2V5cylcbiIpOwogICAgcmV0dXJuIEZBTFNFOwoKZXJyb3I6CiAgICBFUlIoImVycm9yIHJlYWRpbmcgbGYgYmxvY2tcbiIpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKiBfbnRfZHVtcF9uayBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX250X2R1bXBfbmsoTFBTVFIga2V5X25hbWUsY2hhciAqYmFzZSxudF9uayAqbmssRklMRSAqZixpbnQgbGV2ZWwpCnsKICAgIHVuc2lnbmVkIGludCBuOwogICAgRFdPUkQgKnZsOwogICAgTFBTVFIgbmV3X2tleV9uYW1lID0gTlVMTDsKCiAgICBUUkFDRSgiJXNcbiIsIGtleV9uYW1lKTsKCiAgICBpZiAobmstPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5rbm93biBub2RlIGlkIDB4JTA0eCwgcGxlYXNlIHJlcG9ydCFcbiIsIG5rLT5TdWJCbG9ja0lkKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKChuay0+VHlwZSE9TlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpICYmICgoKG50X25rKikoYmFzZStuay0+cGFyZW50X29mZis0KSktPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkpIHsKICAgICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCFcbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiBjcmVhdGUgdGhlIG5ldyBrZXkgKi8KICAgIGlmIChsZXZlbCA8PSAwKSB7CiAgICAgICAgLyogY3JlYXRlIG5ldyBzdWJrZXkgbmFtZSAqLwogICAgICAgIG5ld19rZXlfbmFtZSA9IF9zdHJkdXBuQShrZXlfbmFtZSxzdHJsZW4oa2V5X25hbWUpK25rLT5uYW1lX2xlbisxKTsKICAgICAgICBpZiAoc3RyY21wKG5ld19rZXlfbmFtZSwiIikgIT0gMCkgc3RyY2F0KG5ld19rZXlfbmFtZSwiXFwiKTsKICAgICAgICBzdHJuY2F0KG5ld19rZXlfbmFtZSxuay0+bmFtZSxuay0+bmFtZV9sZW4pOwoKICAgICAgICAvKiB3cml0ZSB0aGUga2V5IHBhdGggKHNvbWV0aGluZyBsaWtlIFtTb2Z0d2FyZVxcTWljcm9zb2Z0XFwuLl0pIG9ubHkgaWY6CiAgICAgICAgICAgMSkga2V5IGhhcyBzb21lIHZhbHVlcwogICAgICAgICAgIDIpIGtleSBoYXMgbm8gdmFsdWVzIGFuZCBubyBzdWJrZXlzCiAgICAgICAgKi8KICAgICAgICBpZiAobmstPm5yX3ZhbHVlcyA+IDApIHsKICAgICAgICAgICAgLyogdGhlcmUgYXJlIHNvbWUgdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQogICAgICAgIGlmICgobmstPm5yX3N1YmtleXMgPT0gMCkgJiYgKG5rLT5ucl92YWx1ZXMgPT0gMCkpIHsKICAgICAgICAgICAgLyogbm8gc3Via2V5cyBhbmQgbm8gdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQoKICAgICAgICAvKiBsb29wIHRyb3VnaCB0aGUgdmFsdWUgbGlzdCAqLwogICAgICAgIHZsID0gKERXT1JEICopKGJhc2UrbmstPnZhbHVlbGlzdF9vZmYrNCk7CiAgICAgICAgZm9yIChuPTA7IG48bmstPm5yX3ZhbHVlczsgbisrKSB7CiAgICAgICAgICAgIG50X3ZrICogdmsgPSAobnRfdmsqKShiYXNlK3ZsW25dKzQpOwogICAgICAgICAgICBpZiAoIV9udF9kdW1wX3ZrKG5ld19rZXlfbmFtZSwgYmFzZSwgdmssIGYpKSB7CiAgICAgICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgbmV3X2tleV9uYW1lID0gX3N0cmR1cG5BKGtleV9uYW1lLHN0cmxlbihrZXlfbmFtZSkpOwoKICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUgc3Via2V5cyAqLwogICAgaWYgKG5rLT5ucl9zdWJrZXlzKSB7CiAgICAgICAgbnRfbGYgKmxmID0gKG50X2xmKikoYmFzZStuay0+bGZfb2ZmKzQpOwogICAgICAgIGlmICghX250X2R1bXBfbGYobmV3X2tleV9uYW1lLCBiYXNlLCBuay0+bnJfc3Via2V5cywgbGYsIGYsIGxldmVsLTEpKSB7CiAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyogZW5kIG50IGxvYWRlciAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NldF9yZWdpc3RyeV9sZXZlbHMgW0ludGVybmFsXQogKgogKiBzZXQgbGV2ZWwgdG8gMCBmb3IgbG9hZGluZyBzeXN0ZW0gZmlsZXMKICogc2V0IGxldmVsIHRvIDEgZm9yIGxvYWRpbmcgdXNlciBmaWxlcwogKi8Kc3RhdGljIHZvaWQgX3NldF9yZWdpc3RyeV9sZXZlbHMoaW50IGxldmVsLGludCBzYXZpbmcsaW50IHBlcmlvZCkKewogICAgU0VSVkVSX1NUQVJUX1JFUSggc2V0X3JlZ2lzdHJ5X2xldmVscyApCiAgICB7CglyZXEtPmN1cnJlbnQgPSBsZXZlbDsKCXJlcS0+c2F2aW5nICA9IHNhdmluZzsKICAgICAgICByZXEtPnBlcmlvZCAgPSBwZXJpb2Q7CiAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICB9CiAgICBTRVJWRVJfRU5EX1JFUTsKfQoKLyogX3NhdmVfYXRfZXhpdCBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9zYXZlX2F0X2V4aXQoSEtFWSBoa2V5LExQQ1NUUiBwYXRoKQp7CiAgICBMUENTVFIgY29uZmRpciA9IGdldF9jb25maWdfZGlyKCk7CgogICAgU0VSVkVSX1NUQVJUX1JFUSggc2F2ZV9yZWdpc3RyeV9hdGV4aXQgKQogICAgewogICAgICAgIHJlcS0+aGtleSA9IGhrZXk7CiAgICAgICAgd2luZV9zZXJ2ZXJfYWRkX2RhdGEoIHJlcSwgY29uZmRpciwgc3RybGVuKGNvbmZkaXIpICk7CiAgICAgICAgd2luZV9zZXJ2ZXJfYWRkX2RhdGEoIHJlcSwgcGF0aCwgc3RybGVuKHBhdGgpKzEgKTsKICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgIH0KICAgIFNFUlZFUl9FTkRfUkVROwp9CgovKiBjb25maWd1cmUgc2F2ZSBmaWxlcyBhbmQgc3RhcnQgdGhlIHBlcmlvZGljIHNhdmluZyB0aW1lciBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9pbml0X3JlZ2lzdHJ5X3NhdmluZyggSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQgKQp7CiAgICBpbnQgYWxsOwogICAgaW50IHBlcmlvZCA9IDA7CiAgICBjaGFyIGJ1ZmZlclsyMF07CgogICAgYWxsID0gIVBST0ZJTEVfR2V0V2luZUluaUJvb2woInJlZ2lzdHJ5IiwiU2F2ZU9ubHlVcGRhdGVkS2V5cyIsMSk7CiAgICBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJyZWdpc3RyeSIsICJQZXJpb2RpY1NhdmUiLCAiIiwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSApOwogICAgaWYgKGJ1ZmZlclswXSkgcGVyaW9kID0gYXRvaShidWZmZXIpOwoKICAgIC8qIHNldCBzYXZpbmcgbGV2ZWwgKDAgZm9yIHNhdmluZyBldmVyeXRoaW5nLCAxIGZvciBzYXZpbmcgb25seSBtb2RpZmllZCBrZXlzKSAqLwogICAgX3NldF9yZWdpc3RyeV9sZXZlbHMoMSwhYWxsLHBlcmlvZCoxMDAwKTsKCiAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgicmVnaXN0cnkiLCJXcml0ZXRvSG9tZVJlZ2lzdHJ5RmlsZXMiLDEpKQogICAgewogICAgICAgIF9zYXZlX2F0X2V4aXQoSEtFWV9DVVJSRU5UX1VTRVIsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0NVUlJFTlRfVVNFUiApOwogICAgICAgIF9zYXZlX2F0X2V4aXQoSEtFWV9MT0NBTF9NQUNISU5FLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FKTsKICAgICAgICBfc2F2ZV9hdF9leGl0KGhrZXlfdXNlcnNfZGVmYXVsdCwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUKTsKICAgIH0KCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2FsbG9jYXRlX2RlZmF1bHRfa2V5cyBbSW50ZXJuYWxdCiAqIFJlZ2lzdHJ5IGluaXRpYWxpc2F0aW9uLCBhbGxvY2F0ZXMgc29tZSBkZWZhdWx0IGtleXMuCiAqLwpzdGF0aWMgdm9pZCBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzKHZvaWQpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJVFJBQ0UoIih2b2lkKVxuIik7CgoJUmVnQ3JlYXRlS2V5QShIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXhBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3dzIE5UXFxDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50QnVpbGROdW1iZXIKCSAqCQkJCQkJQ3VycmVudFR5cGUKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE93bmVyCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPcmdhbml6YXRpb24KCSAqCgkgKi8KCS8qIFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTTk1QXFxQYXJhbWV0ZXJzXFxSRkMxMTU2QWdlbnQKCSAqIAkJCQkJc3RyaW5nCVN5c0NvbnRhY3QKCSAqIAkJCQkJc3RyaW5nCVN5c0xvY2F0aW9uCgkgKiAJCQkJCQlTeXNTZXJ2aWNlcwoJICovCglpZiAoLTEhPWdldGhvc3RuYW1lKGJ1ZiwyMDApKSB7CgkJUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXENvbnRyb2xcXENvbXB1dGVyTmFtZVxcQ29tcHV0ZXJOYW1lIiwmaGtleSk7CgkJUmVnU2V0VmFsdWVFeEEoaGtleSwiQ29tcHV0ZXJOYW1lIiwwLFJFR19TWixidWYsc3RybGVuKGJ1ZikrMSk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9CgogICAgICAgIFJlZ0NyZWF0ZUtleUEoSEtFWV9VU0VSUywiLkRlZmF1bHQiLCZoa2V5KTsKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKfQoKI2RlZmluZSBSRUdfRE9OVExPQUQgLTEKI2RlZmluZSBSRUdfV0lOMzEgICAgIDAKI2RlZmluZSBSRUdfV0lOOTUgICAgIDEKI2RlZmluZSBSRUdfV0lOTlQgICAgIDIKCi8qIHJldHVybiB0aGUgdHlwZSBvZiBuYXRpdmUgcmVnaXN0cnkgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9nZXRfcmVnX3R5cGUodm9pZCkKewogICAgY2hhciB3aW5kaXJbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBjaGFyIHRtcFtNQVhfUEFUSE5BTUVfTEVOXTsKICAgIGludCByZXQgPSBSRUdfV0lOMzE7CgogICAgR2V0V2luZG93c0RpcmVjdG9yeUEod2luZGlyLE1BWF9QQVRITkFNRV9MRU4pOwoKICAgIC8qIHRlc3QgJXdpbmRpciUvc3lzdGVtMzIvY29uZmlnL3N5c3RlbSAtLT4gd2lubnQgKi8KICAgIHN0cmNweSh0bXAsIHdpbmRpcik7CiAgICBzdHJuY2F0KHRtcCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc3lzdGVtIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbih0bXApIC0gMSk7CiAgICBpZihHZXRGaWxlQXR0cmlidXRlc0EodG1wKSAhPSAoRFdPUkQpLTEpIHsKICAgICAgcmV0ID0gUkVHX1dJTk5UOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0uZGF0IC0tPiB3aW45NSAqLwogICAgICBzdHJjcHkodG1wLCB3aW5kaXIpOwogICAgICBzdHJuY2F0KHRtcCwgIlxcc3lzdGVtLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4odG1wKSAtIDEpOwogICAgICBpZihHZXRGaWxlQXR0cmlidXRlc0EodG1wKSAhPSAoRFdPUkQpLTEpIHsKICAgICAgICByZXQgPSBSRUdfV0lOOTU7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoKHJldCA9PSBSRUdfV0lOTlQpICYmICghUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiV2luZSIsICJQcm9maWxlIiwgIiIsIHRtcCwgTUFYX1BBVEhOQU1FX0xFTikpKSB7CiAgICAgICBNRVNTQUdFKCJXaGVuIHlvdSBhcmUgcnVubmluZyB3aXRoIGEgbmF0aXZlIE5UIGRpcmVjdG9yeSBzcGVjaWZ5XG4iKTsKICAgICAgIE1FU1NBR0UoIidQcm9maWxlPTxwcm9maWxlZGlyZWN0b3J5Picgb3IgZGlzYWJsZSBsb2FkaW5nIG9mIFdpbmRvd3NcbiIpOwogICAgICAgTUVTU0FHRSgicmVnaXN0cnkgKExvYWRXaW5kb3dzUmVnaXN0cnlGaWxlcz1OKVxuIik7CiAgICAgICByZXQgPSBSRUdfRE9OVExPQUQ7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKI2RlZmluZSBXSU5FX1JFR19WRVJfRVJST1IgIC0xCiNkZWZpbmUgV0lORV9SRUdfVkVSXzEgICAgICAgMAojZGVmaW5lIFdJTkVfUkVHX1ZFUl8yICAgICAgIDEKI2RlZmluZSBXSU5FX1JFR19WRVJfT0xEICAgICAyCiNkZWZpbmUgV0lORV9SRUdfVkVSX1VOS05PV04gMwoKLyogcmV0dXJuIHRoZSB2ZXJzaW9uIG9mIHdpbmUgcmVnaXN0cnkgZmlsZSBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX2dldF93aW5lX3JlZ2lzdHJ5X2ZpbGVfZm9ybWF0X3ZlcnNpb24oTFBDU1RSIGZuKQp7CiAgICBGSUxFICpmOwogICAgY2hhciB0bXBbNTBdOwogICAgaW50IHZlcjsKCiAgICBpZiAoKGY9Zm9wZW4oZm4sInJ0IikpID09IE5VTEwpIHsKICAgICAgICBXQVJOKCJDb3VsZG4ndCBvcGVuICVzIGZvciByZWFkaW5nOiAlc1xuIixmbixzdHJlcnJvcihlcnJubykpOwogICAgICAgIHJldHVybiBXSU5FX1JFR19WRVJfRVJST1I7CiAgICB9CgogICAgaWYgKGZnZXRzKHRtcCw1MCxmKSA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiRXJyb3IgcmVhZGluZyAlczogJXNcbiIsZm4sc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICBmY2xvc2UoZik7CiAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl9FUlJPUjsKICAgIH0KICAgIGZjbG9zZShmKTsKCiAgICBpZiAoc3NjYW5mKHRtcCwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIiwmdmVyKSAhPSAxKSByZXR1cm4gV0lORV9SRUdfVkVSX1VOS05PV047CiAgICBzd2l0Y2ggKHZlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl8xOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBXSU5FX1JFR19WRVJfMjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl9VTktOT1dOOwogICAgfQp9CgovKiBsb2FkIHRoZSByZWdpc3RyeSBmaWxlIGluIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgbG9hZF93aW5lX3JlZ2lzdHJ5KEhLRVkgaGtleSxMUENTVFIgZm4pCnsKICAgIGludCBmaWxlX2Zvcm1hdDsKCiAgICBmaWxlX2Zvcm1hdCA9IF9nZXRfd2luZV9yZWdpc3RyeV9maWxlX2Zvcm1hdF92ZXJzaW9uKGZuKTsKICAgIHN3aXRjaCAoZmlsZV9mb3JtYXQpIHsKCiAgICAgICAgY2FzZSBXSU5FX1JFR19WRVJfMToKICAgICAgICAgICAgV0FSTigiVW5hYmxlIHRvIGxvYWQgcmVnaXN0cnkgZmlsZSAlczogb2xkIGZvcm1hdCB3aGljaCBpcyBubyBsb25nZXIgc3VwcG9ydGVkLlxuIixmbik7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVfUkVHX1ZFUl8yOiB7CiAgICAgICAgICAgIEhBTkRMRSBmaWxlOwogICAgICAgICAgICBpZiAoKGZpbGUgPSBGSUxFX0NyZWF0ZUZpbGUoIGZuLCBHRU5FUklDX1JFQUQsIDAsIE5VTEwsIE9QRU5fRVhJU1RJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFX0FUVFJJQlVURV9OT1JNQUwsIDAsIFRSVUUsIERSSVZFX1VOS05PV04gKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNFUlZFUl9TVEFSVF9SRVEoIGxvYWRfcmVnaXN0cnkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlcS0+aGtleSAgICA9IGhrZXk7CiAgICAgICAgICAgICAgICAgICAgcmVxLT5maWxlICAgID0gZmlsZTsKICAgICAgICAgICAgICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFNFUlZFUl9FTkRfUkVROwogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGZpbGUgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgV0lORV9SRUdfVkVSX1VOS05PV046CiAgICAgICAgICAgIFdBUk4oIlVuYWJsZSB0byBsb2FkIHJlZ2lzdHJ5IGZpbGUgJXM6IHVua25vd24gZm9ybWF0LlxuIixmbik7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVfUkVHX1ZFUl9FUlJPUjoKICAgICAgICAgICAgYnJlYWs7CiAgICB9Cn0KCi8qIGdlbmVyYXRlIGFuZCByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHRtcCBmaWxlIGFuZCBhc3NvY2lhdGVkIHN0cmVhbSBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfZ2V0X3RtcF9mbihGSUxFICoqZikKewogICAgTFBTVFIgcmV0OwogICAgaW50IHRtcF9mZCxjb3VudDsKCiAgICByZXQgPSBfeG1hbGxvYyg1MCk7CiAgICBmb3IgKGNvdW50ID0gMDs7KSB7CiAgICAgICAgc3ByaW50ZihyZXQsIi90bXAvcmVnJWx4JTA0eC50bXAiLChsb25nKWdldHBpZCgpLGNvdW50KyspOwogICAgICAgIGlmICgodG1wX2ZkID0gb3BlbihyZXQsT19DUkVBVCB8IE9fRVhDTCB8IE9fV1JPTkxZLDA2NjYpKSAhPSAtMSkgYnJlYWs7CiAgICAgICAgaWYgKGVycm5vICE9IEVFWElTVCkgewogICAgICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgZXJyb3Igd2hpbGUgb3BlbigpIGNhbGw6ICVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgIGZyZWUocmV0KTsKICAgICAgICAgICAgKmYgPSBOVUxMOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCgqZiA9IGZkb3Blbih0bXBfZmQsInciKSkgPT0gTlVMTCkgewogICAgICAgIEVSUigiVW5leHBlY3RlZCBlcnJvciB3aGlsZSBmZG9wZW4oKSBjYWxsOiAlc1xuIixzdHJlcnJvcihlcnJubykpOwogICAgICAgIGNsb3NlKHRtcF9mZCk7CiAgICAgICAgZnJlZShyZXQpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgd2luOTUgbmF0aXZlIHJlZ2lzdHJ5IGZpbGUgdG8gd2luZSBmb3JtYXQgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX2NvbnZlcnRfd2luOTVfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoTFBDU1RSIGZuLGludCBsZXZlbCkKewogICAgaW50IGZkOwogICAgRklMRSAqZjsKICAgIERPU19GVUxMX05BTUUgZnVsbF9uYW1lOwogICAgdm9pZCAqYmFzZTsKICAgIExQU1RSIHJldCA9IE5VTEw7CiAgICBzdHJ1Y3Qgc3RhdCBzdDsKCiAgICBfdzk1Y3JlZyAqY3JlZzsKICAgIF93OTVyZ2tuICpyZ2tuOwogICAgX3c5NWRrZSAqZGtlLCAqcm9vdF9ka2U7CgogICAgaWYgKCFET1NGU19HZXRGdWxsTmFtZSggZm4sIDAsICZmdWxsX25hbWUgKSkgcmV0dXJuIE5VTEw7CgogICAgLyogbWFwIHRoZSByZWdpc3RyeSBpbnRvIHRoZSBtZW1vcnkgKi8KICAgIGlmICgoZmQgPSBvcGVuKGZ1bGxfbmFtZS5sb25nX25hbWUsIE9fUkRPTkxZIHwgT19OT05CTE9DSykpID09IC0xKSByZXR1cm4gTlVMTDsKICAgIGlmICgoZnN0YXQoZmQsICZzdCkgPT0gLTEpKSBnb3RvIGVycm9yMTsKICAgIGlmICghc3Quc3Rfc2l6ZSkgZ290byBlcnJvcjE7CiAgICBpZiAoKGJhc2UgPSBtbWFwKE5VTEwsIHN0LnN0X3NpemUsIFBST1RfUkVBRCwgTUFQX1BSSVZBVEUsIGZkLCAwKSkgPT0gTUFQX0ZBSUxFRCkgZ290byBlcnJvcjE7CgogICAgLyogY29udHJvbCBzaWduYXR1cmUgKi8KICAgIGlmICgqKExQRFdPUkQpYmFzZSAhPSBXOTVfUkVHX0NSRUdfSUQpIHsKICAgICAgICBFUlIoInVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW45NSByZWdpc3RyeSBmaWxlICVzOiB1bmtub3duIHNpZ25hdHVyZS5cbiIsZm4pOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgY3JlZyA9IGJhc2U7CiAgICAvKiBsb2FkIHRoZSBoZWFkZXIgKHJna24pICovCiAgICByZ2tuID0gKF93OTVyZ2tuKikoY3JlZyArIDEpOwogICAgaWYgKHJna24tPmlkICE9IFc5NV9SRUdfUkdLTl9JRCkgewogICAgICAgIEVSUigic2Vjb25kIElGRiBoZWFkZXIgbm90IFJHS04sIGJ1dCAlbHhcbiIsIHJna24tPmlkKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHJna24tPnJvb3Rfb2ZmICE9IDB4MjApIHsKICAgICAgICBFUlIoInJna24tPnJvb3Rfb2ZmIG5vdCAweDIwLCBwbGVhc2UgcmVwb3J0ICFcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+bGFzdF9ka2UgPiByZ2tuLT5zaXplKQogICAgewogICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgbGFzdF9ka2UgPiBzaXplIVxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICAvKiB2ZXJpZnkgbGFzdCBka2UgKi8KICAgIGRrZSA9IChfdzk1ZGtlKikoKGNoYXIqKXJna24gKyByZ2tuLT5sYXN0X2RrZSk7CiAgICBpZiAoZGtlLT54MSAhPSAweDgwMDAwMDAwKQogICAgeyAvKiB3cm9uZyBtYWdpYyAqLwogICAgICBFUlIoImxhc3QgZGtlIGludmFsaWQgIVxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+c2l6ZSA+IGNyZWctPnJnZGJfb2ZmKQogICAgewogICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgcmdrbiBzaXplID4gcmdkYl9vZmYgIVxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICByb290X2RrZSA9IChfdzk1ZGtlKikoKGNoYXIqKXJna24gKyByZ2tuLT5yb290X29mZik7CiAgICBpZiAoIChyb290X2RrZS0+cHJldmx2bCAhPSAweGZmZmZmZmZmKSB8fCAocm9vdF9ka2UtPm5leHQgIT0gMHhmZmZmZmZmZikgKQogICAgewogICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISBpbnZhbGlkIHJvb3QgZGtlICFcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKCAocmV0ID0gX2dldF90bXBfZm4oJmYpKSA9PSBOVUxMKSBnb3RvIGVycm9yOwogICAgZnByaW50ZihmLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gMiIpOwogICAgX3c5NV9kdW1wX2RrZSgiIixjcmVnLHJna24scm9vdF9ka2UsZixsZXZlbCk7CiAgICBmY2xvc2UoZik7CgplcnJvcjoKICAgIGlmKHJldCA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJVbmFibGUgdG8gbG9hZCBuYXRpdmUgd2luOTUgcmVnaXN0cnkgZmlsZSAlcy5cbiIsZm4pOwogICAgICAgIEVSUigiUGxlYXNlIHJlcG9ydCB0aGlzLlxuIik7CiAgICAgICAgRVJSKCJNYWtlIGEgYmFja3VwIG9mIHRoZSBmaWxlLCBydW4gYSBnb29kIHJlZyBjbGVhbmVyIHByb2dyYW0gYW5kIHRyeSBhZ2FpbiFcbiIpOwogICAgfQoKICAgIG11bm1hcChiYXNlLCBzdC5zdF9zaXplKTsKZXJyb3IxOgogICAgY2xvc2UoZmQpOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCB3aW5udCBuYXRpdmUgcmVnaXN0cnkgZmlsZSB0byB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfY29udmVydF93aW5udF9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChMUENTVFIgZm4saW50IGxldmVsKQp7CiAgICBGSUxFICpmOwogICAgdm9pZCAqYmFzZTsKICAgIExQU1RSIHJldCA9IE5VTEw7CiAgICBIQU5ETEUgaEZpbGU7CiAgICBIQU5ETEUgaE1hcHBpbmc7CgogICAgbnRfcmVnZiAqcmVnZjsKICAgIG50X2hiaW4gKmhiaW47CiAgICBudF9oYmluX3N1YiAqaGJpbl9zdWI7CiAgICBudF9uayAqbms7CgogICAgVFJBQ0UoIiVzXG4iLCBmbik7CgogICAgaEZpbGUgPSBDcmVhdGVGaWxlQSggZm4sIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELCBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwICk7CiAgICBpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CiAgICBoTWFwcGluZyA9IENyZWF0ZUZpbGVNYXBwaW5nQSggaEZpbGUsIE5VTEwsIFBBR0VfUkVBRE9OTFl8U0VDX0NPTU1JVCwgMCwgMCwgTlVMTCApOwogICAgaWYgKCFoTWFwcGluZykgZ290byBlcnJvcjE7CiAgICBiYXNlID0gTWFwVmlld09mRmlsZSggaE1hcHBpbmcsIEZJTEVfTUFQX1JFQUQsIDAsIDAsIDAgKTsKICAgIENsb3NlSGFuZGxlKCBoTWFwcGluZyApOwogICAgaWYgKCFiYXNlKSBnb3RvIGVycm9yMTsKCiAgICAvKiBjb250cm9sIHNpZ25hdHVyZSAqLwogICAgaWYgKCooTFBEV09SRCliYXNlICE9IE5UX1JFR19IRUFERVJfQkxPQ0tfSUQpIHsKICAgICAgICBFUlIoInVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW5udCByZWdpc3RyeSBmaWxlICVzOiB1bmtub3duIHNpZ25hdHVyZS5cbiIsZm4pOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogc3RhcnQgYmxvY2sgKi8KICAgIHJlZ2YgPSBiYXNlOwoKICAgIC8qIGhiaW4gYmxvY2sgKi8KICAgIGhiaW4gPSAobnRfaGJpbiopKChjaGFyKikgYmFzZSArIDB4MTAwMCk7CiAgICBpZiAoaGJpbi0+aWQgIT0gTlRfUkVHX1BPT0xfQkxPQ0tfSUQpIHsKICAgICAgRVJSKCAiaGJpbiBibG9jayBpbnZhbGlkXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBoYmluX3N1YiBibG9jayAqLwogICAgaGJpbl9zdWIgPSAobnRfaGJpbl9zdWIqKSYoaGJpbi0+aGJpbl9zdWIpOwogICAgaWYgKChoYmluX3N1Yi0+ZGF0YVswXSAhPSAnbicpIHx8IChoYmluX3N1Yi0+ZGF0YVsxXSAhPSAnaycpKSB7CiAgICAgIEVSUiggImhiaW5fc3ViIGJsb2NrIGludmFsaWRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIG5rIGJsb2NrICovCiAgICBuayA9IChudF9uayopJihoYmluX3N1Yi0+ZGF0YVswXSk7CiAgICBpZiAobmstPlR5cGUgIT0gTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpIHsKICAgICAgRVJSKCAic3BlY2lhbCBuayBibG9jayBub3QgZm91bmRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGlmICggKHJldCA9IF9nZXRfdG1wX2ZuKCZmKSkgPT0gTlVMTCkgZ290byBlcnJvcjsKICAgIGZwcmludGYoZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uIDIiKTsKICAgIF9udF9kdW1wX25rKCIiLChjaGFyKiliYXNlKzB4MTAwMCxuayxmLGxldmVsKTsKICAgIGZjbG9zZShmKTsKCmVycm9yOgogICAgVW5tYXBWaWV3T2ZGaWxlKCBiYXNlICk7CmVycm9yMToKICAgIENsb3NlSGFuZGxlKGhGaWxlKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgbmF0aXZlIHJlZ2lzdHJ5IHRvIHdpbmUgZm9ybWF0IGFuZCBsb2FkIGl0IHZpYSBzZXJ2ZXIgY2FsbCBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShMUENTVFIgZm4sSEtFWSBoa2V5LGludCByZWdfdHlwZSxpbnQgbGV2ZWwpCnsKICAgIExQU1RSIHRtcCA9IE5VTEw7CgogICAgc3dpdGNoIChyZWdfdHlwZSkgewogICAgICAgIGNhc2UgUkVHX1dJTk5UOgogICAgICAgICAgICAvKiBGSVhNRTogZm9sbG93aW5nIGZ1bmN0aW9uIGRvZXNuJ3QgcmVhbGx5IGNvbnZlcnQgeWV0ICovCiAgICAgICAgICAgIHRtcCA9IF9jb252ZXJ0X3dpbm50X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KGZuLGxldmVsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfV0lOOTU6CiAgICAgICAgICAgIHRtcCA9IF9jb252ZXJ0X3dpbjk1X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KGZuLGxldmVsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfV0lOMzE6CiAgICAgICAgICAgIEVSUigiRG9uJ3Qga25vdyBob3cgdG8gY29udmVydCBuYXRpdmUgMy4xIHJlZ2lzdHJ5IHlldC5cbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoIlVua25vd24gcmVnaXN0cnkgZm9ybWF0IHBhcmFtZXRlciAoJWQpXG4iLHJlZ190eXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHRtcCAhPSBOVUxMKSB7CiAgICAgICAgbG9hZF93aW5lX3JlZ2lzdHJ5KGhrZXksdG1wKTsKICAgICAgICBUUkFDRSgiRmlsZSAlcyBzdWNjZXNzZnVsbHkgY29udmVydGVkIHRvICVzIGFuZCBsb2FkZWQgdG8gcmVnaXN0cnkuXG4iLGZuLHRtcCk7CiAgICAgICAgdW5saW5rKHRtcCk7CiAgICB9CiAgICBlbHNlIFdBUk4oIlVuYWJsZSB0byBjb252ZXJ0ICVzIChkb2Vzbid0IGV4aXN0PylcbiIsZm4pOwogICAgZnJlZSh0bXApOwp9CgovKiBsb2FkIGFsbCBuYXRpdmUgd2luZG93cyByZWdpc3RyeSBmaWxlcyBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9sb2FkX3dpbmRvd3NfcmVnaXN0cnkoIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgaW50IHJlZ190eXBlOwogICAgY2hhciB3aW5kaXJbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBjaGFyIHBhdGhbTUFYX1BBVEhOQU1FX0xFTl07CgogICAgR2V0V2luZG93c0RpcmVjdG9yeUEod2luZGlyLE1BWF9QQVRITkFNRV9MRU4pOwoKICAgIHJlZ190eXBlID0gX2dldF9yZWdfdHlwZSgpOwogICAgc3dpdGNoIChyZWdfdHlwZSkgewogICAgICAgIGNhc2UgUkVHX1dJTk5UOiB7CiAgICAgICAgICAgIEhLRVkgaGtleTsKCiAgICAgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgbnR1c2VyLmRhdCAqLwogICAgICAgICAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiV2luZSIsICJQcm9maWxlIiwgIiIsIHBhdGgsIE1BWF9QQVRITkFNRV9MRU4pKSB7CiAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxudHVzZXIuZGF0Iik7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0NVUlJFTlRfVVNFUixSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGRlZmF1bHQgdXNlci5kYXQgKi8KICAgICAgICAgICAgaWYgKGhrZXlfdXNlcnNfZGVmYXVsdCkgewogICAgICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdChwYXRoLCJcXHN5c3RlbTMyXFxjb25maWdcXGRlZmF1bHQiKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfdXNlcnNfZGVmYXVsdCxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICogRklYTUUKICAgICAgICAgICAgKiAgbWFwIEhMTVxTeXN0ZW1cQ29udHJvbFNldDAwMSB0byBITE1cU3lzdGVtXEN1cnJlbnRDb250cm9sU2V0CiAgICAgICAgICAgICovCgogICAgICAgICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCAiU1lTVEVNIiwgJmhrZXkpKSB7CgkgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwoJICAgICAgc3RyY2F0KHBhdGgsIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc3lzdGVtIik7CiAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleSxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsICJTT0ZUV0FSRSIsICZoa2V5KSkgewogICAgICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdChwYXRoLCJcXHN5c3RlbTMyXFxjb25maWdcXHNvZnR3YXJlIik7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5LFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0zMlxcY29uZmlnXFxzYW0iKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9MT0NBTF9NQUNISU5FLFJFR19XSU5OVCwwKTsKCiAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgIHN0cmNhdChwYXRoLCJcXHN5c3RlbTMyXFxjb25maWdcXHNlY3VyaXR5Iik7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLEhLRVlfTE9DQUxfTUFDSElORSxSRUdfV0lOTlQsMCk7CgogICAgICAgICAgICAvKiB0aGlzIGtleSBpcyBnZW5lcmF0ZWQgd2hlbiB0aGUgbnQtY29yZSBib290ZWQgc3VjY2Vzc2Z1bGx5ICovCiAgICAgICAgICAgIGlmICghUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ2xvbmUiLCZoa2V5KSkgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBSRUdfV0lOOTU6CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeSgiYzpcXHN5c3RlbS4xc3QiLEhLRVlfTE9DQUxfTUFDSElORSxSRUdfV0lOOTUsMCk7CgogICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0uZGF0Iik7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLEhLRVlfTE9DQUxfTUFDSElORSxSRUdfV0lOOTUsMCk7CgogICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxjbGFzc2VzLmRhdCIpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0NMQVNTRVNfUk9PVCxSRUdfV0lOOTUsMCk7CgogICAgICAgICAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCJXaW5lIiwiUHJvZmlsZSIsIiIscGF0aCxNQVhfUEFUSE5BTUVfTEVOKSkgewoJICAgICAgICAvKiB1c2VyIHNwZWNpZmljIHVzZXIuZGF0ICovCgkgICAgICAgIHN0cm5jYXQocGF0aCwgIlxcdXNlci5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0NVUlJFTlRfVVNFUixSRUdfV0lOOTUsMSk7CgoJICAgICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCgkgICAgICAgIGlmIChoa2V5X3VzZXJzX2RlZmF1bHQpIHsKICAgICAgICAgICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICAgICAgICAgIHN0cmNhdChwYXRoLCJcXHVzZXIuZGF0Iik7CiAgICAgICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV91c2Vyc19kZWZhdWx0LFJFR19XSU45NSwxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFx1c2VyLmRhdCIpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9DVVJSRU5UX1VTRVIsUkVHX1dJTjk1LDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFJFR19XSU4zMToKICAgICAgICAgICAgLyogRklYTUU6IGhlcmUgd2Ugc2hvdWxkIGNvbnZlcnQgdG8gKi5yZWcgZmlsZSBzdXBwb3J0ZWQgYnkgc2VydmVyIGFuZCBjYWxsIFJFUV9MT0FEX1JFR0lTVFJZLCBzZWUgUkVHX1dJTjk1IGNhc2UgKi8KICAgICAgICAgICAgX3czMV9sb2FkcmVnKCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFJFR19ET05UTE9BRDoKICAgICAgICAgICAgVFJBQ0UoIlJFR19ET05UTE9BRFxuIik7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoInN3aXRjaDogbm8gbWF0Y2ggKCVkKVxuIixyZWdfdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgIH0KfQoKLyogbG9hZCBnbG9iYWwgcmVnaXN0cnkgZmlsZXMgKHN0b3JlZCBpbiAvZXRjL3dpbmUpIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2xvYWRfZ2xvYmFsX3JlZ2lzdHJ5KHZvaWQpCnsKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIC8qIExvYWQgdGhlIGdsb2JhbCBIS1UgaGl2ZSBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIgKi8KICAgIGxvYWRfd2luZV9yZWdpc3RyeSggSEtFWV9VU0VSUywgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCApOwoKICAgIC8qIExvYWQgdGhlIGdsb2JhbCBtYWNoaW5lIGRlZmF1bHRzIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpciAqLwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KCBIS0VZX0xPQ0FMX01BQ0hJTkUsIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FICk7Cn0KCi8qIGxvYWQgaG9tZSByZWdpc3RyeSBmaWxlcyAoc3RvcmVkIGluIH4vLndpbmUpIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2xvYWRfaG9tZV9yZWdpc3RyeSggSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQgKQp7CiAgICBMUENTVFIgY29uZmRpciA9IGdldF9jb25maWdfZGlyKCk7CiAgICBMUFNUUiB0bXAgPSBfeG1hbGxvYyhzdHJsZW4oY29uZmRpcikrMjApOwoKICAgIHN0cmNweSh0bXAsY29uZmRpcik7CiAgICBzdHJjYXQodG1wLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQpOwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KGhrZXlfdXNlcnNfZGVmYXVsdCx0bXApOwoKICAgIHN0cmNweSh0bXAsY29uZmRpcik7CiAgICBzdHJjYXQodG1wLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIpOwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KEhLRVlfQ1VSUkVOVF9VU0VSLHRtcCk7CgogICAgc3RyY3B5KHRtcCxjb25mZGlyKTsKICAgIHN0cmNhdCh0bXAsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUpOwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KEhLRVlfTE9DQUxfTUFDSElORSx0bXApOwoKICAgIGZyZWUodG1wKTsKfQoKLyogbG9hZCBhbGwgcmVnaXN0cnkgKG5hdGl2ZSBhbmQgZ2xvYmFsIGFuZCBob21lKSAqLwp2b2lkIFNIRUxMX0xvYWRSZWdpc3RyeSggdm9pZCApCnsKICAgIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0OwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGlmICghQ0xJRU5UX0lzQm9vdFRocmVhZCgpKSByZXR1cm47ICAvKiBhbHJlYWR5IGxvYWRlZCAqLwoKICAgIGlmIChSZWdDcmVhdGVLZXlBKEhLRVlfVVNFUlMsIi5EZWZhdWx0IiwmaGtleV91c2Vyc19kZWZhdWx0KSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBjcmVhdGUgSEtFWV9VU0VSUy8uRGVmYXVsdFxuIiApOwogICAgICAgIEV4aXRQcm9jZXNzKDEpOwogICAgfQoKICAgIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXMoKTsKICAgIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKDAsMCwwKTsKICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sKCJSZWdpc3RyeSIsIkxvYWRXaW5kb3dzUmVnaXN0cnlGaWxlcyIsMSkpCiAgICAgICAgX2xvYWRfd2luZG93c19yZWdpc3RyeSggaGtleV91c2Vyc19kZWZhdWx0ICk7CiAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgiUmVnaXN0cnkiLCJMb2FkR2xvYmFsUmVnaXN0cnlGaWxlcyIsMSkpCiAgICAgICAgX2xvYWRfZ2xvYmFsX3JlZ2lzdHJ5KCk7CiAgICBfc2V0X3JlZ2lzdHJ5X2xldmVscygxLDAsMCk7CiAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgiUmVnaXN0cnkiLCJMb2FkSG9tZVJlZ2lzdHJ5RmlsZXMiLDEpKQogICAgICAgIF9sb2FkX2hvbWVfcmVnaXN0cnkoIGhrZXlfdXNlcnNfZGVmYXVsdCApOwogICAgX2luaXRfcmVnaXN0cnlfc2F2aW5nKCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKICAgIFJlZ0Nsb3NlS2V5KGhrZXlfdXNlcnNfZGVmYXVsdCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICBBUEkgRlVOQ1RJT05TICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0ZsdXNoS2V5IFtBRFZBUEkzMi5AXQogKiBJbW1lZGlhdGVseSB3cml0ZXMga2V5IHRvIHJlZ2lzdHJ5LgogKiBPbmx5IHJldHVybnMgYWZ0ZXIgZGF0YSBoYXMgYmVlbiB3cml0dGVuIHRvIGRpc2suCiAqCiAqIEZJWE1FOiBkb2VzIGl0IHJlYWxseSB3YWl0IHVudGlsIGRhdGEgaXMgd3JpdHRlbiA/CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdyaXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkoIEhLRVkgaGtleSApCnsKICAgIEZJWE1FKCAiKCV4KTogc3R1YlxuIiwgaGtleSApOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1VuTG9hZEtleUEgW0FEVkFQSTMyLkBdCiAqLwpMT05HIFdJTkFQSSBSZWdVbkxvYWRLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSApCnsKICAgIEZJWE1FKCIoJXgsJXMpOiBzdHViXG4iLGhrZXksIGRlYnVnc3RyX2EobHBTdWJLZXkpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5QSBbQURWQVBJMzIuQF0KICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSwgTFBDU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwT2xkRmlsZSApCnsKICAgIEZJWE1FKCIoJXgsJXMsJXMsJXMpOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl9hKGxwU3ViS2V5KSwKICAgICAgICAgIGRlYnVnc3RyX2EobHBOZXdGaWxlKSxkZWJ1Z3N0cl9hKGxwT2xkRmlsZSkpOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgoKCgoKLyogMTYtYml0IGZ1bmN0aW9ucyAqLwoKLyogMCBhbmQgMSBhcmUgdmFsaWQgcm9vdGtleXMgaW4gd2luMTYgc2hlbGwuZGxsIGFuZCBhcmUgdXNlZCBieQogKiBzb21lIHByb2dyYW1zLiBEbyBub3QgcmVtb3ZlIHRob3NlIGNhc2VzLiAtTU0KICovCnN0YXRpYyBpbmxpbmUgdm9pZCBmaXhfd2luMTZfaGtleSggSEtFWSAqaGtleSApCnsKICAgIGlmICgqaGtleSA9PSAwIHx8ICpoa2V5ID09IDEpICpoa2V5ID0gSEtFWV9DTEFTU0VTX1JPT1Q7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0VudW1LZXkgICBbS0VSTkVMLjIxNl0KICogICAgICAgICAgIFJlZ0VudW1LZXkgICBbU0hFTEwuN10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MTYoIEhLRVkgaGtleSwgRFdPUkQgaW5kZXgsIExQU1RSIG5hbWUsIERXT1JEIG5hbWVfbGVuICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRW51bUtleUEoIGhrZXksIGluZGV4LCBuYW1lLCBuYW1lX2xlbiApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdPcGVuS2V5ICAgW0tFUk5FTC4yMTddCiAqICAgICAgICAgICBSZWdPcGVuS2V5ICAgW1NIRUxMLjFdCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUEhLRVkgcmV0a2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnT3BlbktleUEoIGhrZXksIG5hbWUsIHJldGtleSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdDcmVhdGVLZXkgICBbS0VSTkVMLjIxOF0KICogICAgICAgICAgIFJlZ0NyZWF0ZUtleSAgIFtTSEVMTC4yXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUEhLRVkgcmV0a2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5QSggaGtleSwgbmFtZSwgcmV0a2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0RlbGV0ZUtleSAgIFtLRVJORUwuMjE5XQogKiAgICAgICAgICAgUmVnRGVsZXRlS2V5ICAgW1NIRUxMLjRdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdEZWxldGVLZXlBKCBoa2V5LCBuYW1lICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0Nsb3NlS2V5ICAgW0tFUk5FTC4yMjBdCiAqICAgICAgICAgICBSZWdDbG9zZUtleSAgIFtTSEVMTC4zXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0Nsb3NlS2V5MTYoIEhLRVkgaGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0Nsb3NlS2V5KCBoa2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1NldFZhbHVlICAgW0tFUk5FTC4yMjFdCiAqICAgICAgICAgICBSZWdTZXRWYWx1ZSAgIFtTSEVMTC41XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIERXT1JEIHR5cGUsIExQQ1NUUiBkYXRhLCBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlQSggaGtleSwgbmFtZSwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRGVsZXRlVmFsdWUgIFtLRVJORUwuMjIyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMTYoIEhLRVkgaGtleSwgTFBTVFIgbmFtZSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0RlbGV0ZVZhbHVlQSggaGtleSwgbmFtZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdFbnVtVmFsdWUgICBbS0VSTkVMLjIyM10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUxNiggSEtFWSBoa2V5LCBEV09SRCBpbmRleCwgTFBTVFIgdmFsdWUsIExQRFdPUkQgdmFsX2NvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgcmVzZXJ2ZWQsIExQRFdPUkQgdHlwZSwgTFBCWVRFIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdFbnVtVmFsdWVBKCBoa2V5LCBpbmRleCwgdmFsdWUsIHZhbF9jb3VudCwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUgICBbS0VSTkVMLjIyNF0KICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUgICBbU0hFTEwuNl0KICoKICogTk9URVMKICogICAgSXMgdGhpcyBIQUNLIHN0aWxsIGFwcGxpY2FibGU/CiAqCiAqIEhBQ0sKICogICAgVGhlIDE2Yml0IFJlZ1F1ZXJ5VmFsdWUgZG9lc24ndCBoYW5kbGUgc2VsZWN0b3JibG9ja3MgYW55d2F5LCBzbyB3ZSBqdXN0CiAqICAgIG1hc2sgb3V0IHRoZSBoaWdoIDE2IGJpdC4gIFRoaXMgKG5vdCBzbyBtdWNoIGluY2lkZW50bHkpIGhvcGVmdWxseSBmaXhlcwogKiAgICBBbGR1cyBGSDQpCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUFNUUiBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICBpZiAoY291bnQpICpjb3VudCAmPSAweGZmZmY7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUEoIGhrZXksIG5hbWUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWVFeCAgIFtLRVJORUwuMjI1XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUERXT1JEIHJlc2VydmVkLCBMUERXT1JEIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlRXhBKCBoa2V5LCBuYW1lLCByZXNlcnZlZCwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnU2V0VmFsdWVFeCAgIFtLRVJORUwuMjI2XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXgxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgRFdPUkQgcmVzZXJ2ZWQsIERXT1JEIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlNUIEJZVEUgKmRhdGEsIERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICBpZiAoIWNvdW50ICYmICh0eXBlPT1SRUdfU1opKSBjb3VudCA9IHN0cmxlbihkYXRhKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUV4QSggaGtleSwgbmFtZSwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0ZsdXNoS2V5ICAgW0tFUk5FTC4yMjddCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkxNiggSEtFWSBoa2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRmx1c2hLZXkoIGhrZXkgKTsKfQo=