LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxmY250bC5oPgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgImRlYnVndG9vbHMuaCIKI2luY2x1ZGUgIm9wdGlvbnMuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAic2VydmVyLmgiCiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKI2luY2x1ZGUgIndpbm50LmgiCgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKHJlZyk7CgovKiBGSVhNRTogZm9sbG93aW5nIGRlZmluZXMgc2hvdWxkIGJlIGNvbmZpZ3VyZWQgZ2xvYmFsICovCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCAgRVRDRElSIi93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUgRVRDRElSIi93aW5lLnN5c3RlbXJlZyIKCi8qIHJlbGF0aXZlIGluIH51c2VyLy53aW5lLyA6ICovCiNkZWZpbmUgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfQ1VSUkVOVF9VU0VSICAidXNlci5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUICAidXNlcmRlZi5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSAic3lzdGVtLnJlZyIKCi8qIF94bWFsbG9jIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgKl94bWFsbG9jKCBzaXplX3Qgc2l6ZSApCnsKICAgIHZvaWQgKnJlczsKCiAgICByZXMgPSBtYWxsb2MgKHNpemUgPyBzaXplIDogMSk7CiAgICBpZiAocmVzID09IE5VTEwpIHsKICAgICAgICBXQVJOKCJWaXJ0dWFsIG1lbW9yeSBleGhhdXN0ZWQuXG4iKTsKICAgICAgICBleGl0ICgxKTsKICAgIH0KICAgIHJldHVybiByZXM7Cn0KCi8qIF9zdHJkdXBuQSBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfc3RyZHVwbkEoTFBDU1RSIHN0cixzaXplX3QgbGVuKQp7CiAgICBMUFNUUiByZXQ7CgogICAgaWYgKCFzdHIpIHJldHVybiBOVUxMOwogICAgcmV0ID0gX3htYWxsb2MoIGxlbiArIDEgKTsKICAgIG1lbWNweSggcmV0LCBzdHIsIGxlbiApOwogICAgcmV0W2xlbl0gPSAweDAwOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCBhbnNpIHN0cmluZyB0byB1bmljb2RlIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQV1NUUiBfc3RyZHVwbkF0b1coTFBDU1RSIHN0ckEsc2l6ZV90IGxlbkEpCnsKICAgIExQV1NUUiByZXQ7CiAgICBzaXplX3QgbGVuVzsKCiAgICBpZiAoIXN0ckEpIHJldHVybiBOVUxMOwogICAgbGVuVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLDAsc3RyQSxsZW5BLE5VTEwsMCk7CiAgICByZXQgPSBfeG1hbGxvYyhsZW5XKnNpemVvZihXQ0hBUikrc2l6ZW9mKFdDSEFSKSk7CiAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwwLHN0ckEsbGVuQSxyZXQsbGVuVyk7CiAgICByZXRbbGVuV10gPSAwOwogICAgcmV0dXJuIHJldDsKfQoKLyogZHVtcCBhIFVuaWNvZGUgc3RyaW5nIHdpdGggcHJvcGVyIGVzY2FwaW5nIFtJbnRlcm5hbF0gKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci91bmljb2RlLmMgKi8Kc3RhdGljIGludCBfZHVtcF9zdHJXKGNvbnN0IFdDSEFSICpzdHIsc2l6ZV90IGxlbixGSUxFICpmLGNoYXIgZXNjYXBlWzJdKQp7CiAgICBzdGF0aWMgY29uc3QgY2hhciBlc2NhcGVzWzMyXSA9ICIuLi4uLi4uYWJ0bnZmci4uLi4uLi4uLi4uLi5lLi4uLiI7CiAgICBjaGFyIGJ1ZmZlclsyNTZdOwogICAgTFBTVFIgcG9zID0gYnVmZmVyOwogICAgaW50IGNvdW50ID0gMDsKCiAgICBmb3IgKDsgbGVuOyBzdHIrKywgbGVuLS0pCiAgICB7CiAgICAgICAgaWYgKHBvcyA+IGJ1ZmZlciArIHNpemVvZihidWZmZXIpIC0gOCkKICAgICAgICB7CiAgICAgICAgICAgIGZ3cml0ZSggYnVmZmVyLCBwb3MgLSBidWZmZXIsIDEsIGYgKTsKICAgICAgICAgICAgY291bnQgKz0gcG9zIC0gYnVmZmVyOwogICAgICAgICAgICBwb3MgPSBidWZmZXI7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyID4gMTI3KSAgLyogaGV4IGVzY2FwZSAqLwogICAgICAgIHsKICAgICAgICAgICAgaWYgKGxlbiA+IDEgJiYgc3RyWzFdIDwgMTI4ICYmIGlzeGRpZ2l0KChjaGFyKXN0clsxXSkpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFx4JTA0eCIsICpzdHIgKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxceCV4IiwgKnN0ciApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCpzdHIgPCAzMikgIC8qIG9jdGFsIG9yIEMgZXNjYXBlICovCiAgICAgICAgewogICAgICAgICAgICBpZiAoISpzdHIgJiYgbGVuID09IDEpIGNvbnRpbnVlOyAgLyogZG8gbm90IG91dHB1dCB0ZXJtaW5hdGluZyBOVUxMICovCiAgICAgICAgICAgIGlmIChlc2NhcGVzWypzdHJdICE9ICcuJykKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCVjIiwgZXNjYXBlc1sqc3RyXSApOwogICAgICAgICAgICBlbHNlIGlmIChsZW4gPiAxICYmIHN0clsxXSA+PSAnMCcgJiYgc3RyWzFdIDw9ICc3JykKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCUwM28iLCAqc3RyICk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXCVvIiwgKnN0ciApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCpzdHIgPT0gJ1xcJyB8fCAqc3RyID09IGVzY2FwZVswXSB8fCAqc3RyID09IGVzY2FwZVsxXSkgKnBvcysrID0gJ1xcJzsKICAgICAgICAqcG9zKysgPSAqc3RyOwogICAgfQogICAgZndyaXRlKCBidWZmZXIsIHBvcyAtIGJ1ZmZlciwgMSwgZiApOwogICAgY291bnQgKz0gcG9zIC0gYnVmZmVyOwogICAgcmV0dXJuIGNvdW50Owp9CgovKiBjb252ZXJ0IGFuc2kgc3RyaW5nIHRvIHVuaWNvZGUgYW5kIGR1bXAgd2l0aCBwcm9wZXIgZXNjYXBpbmcgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9kdW1wX3N0ckF0b1coTFBDU1RSIHN0ckEsc2l6ZV90IGxlbixGSUxFICpmLGNoYXIgZXNjYXBlWzJdKQp7CiAgICBXQ0hBUiAqc3RyVzsKICAgIGludCByZXQ7CgogICAgaWYgKHN0ckEgPT0gTlVMTCkgcmV0dXJuIDA7CiAgICBzdHJXID0gX3N0cmR1cG5BdG9XKHN0ckEsbGVuKTsKICAgIHJldCA9IF9kdW1wX3N0clcoc3RyVyxsZW4sZixlc2NhcGUpOwogICAgZnJlZShzdHJXKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGEga2V5IHZhbHVlICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvcmVnaXN0cnkuYyAqLwpzdHJ1Y3Qga2V5X3ZhbHVlIHsKICAgIFdDSEFSICAgICAgICAgICAgKm5hbWVXOyAgIC8qIHZhbHVlIG5hbWUgKi8KICAgIGludCAgICAgICAgICAgICAgIHR5cGU7ICAgIC8qIHZhbHVlIHR5cGUgKi8KICAgIHNpemVfdCAgICAgICAgICAgIGxlbjsgICAgIC8qIHZhbHVlIGRhdGEgbGVuZ3RoIGluIGJ5dGVzICovCiAgICB2b2lkICAgICAgICAgICAgICpkYXRhOyAgICAvKiBwb2ludGVyIHRvIHZhbHVlIGRhdGEgKi8KfTsKCi8qIGR1bXAgYSB2YWx1ZSB0byBhIHRleHQgZmlsZSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3JlZ2lzdHJ5LmMgKi8Kc3RhdGljIHZvaWQgX2R1bXBfdmFsdWUoc3RydWN0IGtleV92YWx1ZSAqdmFsdWUsRklMRSAqZikKewogICAgaW50IGksIGNvdW50OwoKICAgIGlmICh2YWx1ZS0+bmFtZVdbMF0pIHsKICAgICAgICBmcHV0YyggJ1wiJywgZiApOwogICAgICAgIGNvdW50ID0gMSArIF9kdW1wX3N0clcodmFsdWUtPm5hbWVXLHN0cmxlblcodmFsdWUtPm5hbWVXKSxmLCJcIlwiIik7CiAgICAgICAgY291bnQgKz0gZnByaW50ZiggZiwgIlwiPSIgKTsKICAgIH0KICAgIGVsc2UgY291bnQgPSBmcHJpbnRmKCBmLCAiQD0iICk7CgogICAgc3dpdGNoKHZhbHVlLT50eXBlKSB7CiAgICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgY2FzZSBSRUdfRVhQQU5EX1NaOgogICAgICAgIGNhc2UgUkVHX01VTFRJX1NaOgogICAgICAgICAgICBpZiAodmFsdWUtPnR5cGUgIT0gUkVHX1NaKSBmcHJpbnRmKCBmLCAic3RyKCVkKToiLCB2YWx1ZS0+dHlwZSApOwogICAgICAgICAgICBmcHV0YyggJ1wiJywgZiApOwogICAgICAgICAgICBpZiAodmFsdWUtPmRhdGEpIF9kdW1wX3N0clcodmFsdWUtPmRhdGEsdmFsdWUtPmxlbi9zaXplb2YoV0NIQVIpLGYsIlwiXCIiKTsKICAgICAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgICAgIGlmICh2YWx1ZS0+bGVuID09IHNpemVvZihEV09SRCkpIHsKICAgICAgICAgICAgICAgIERXT1JEIGR3OwogICAgICAgICAgICAgICAgbWVtY3B5KCAmZHcsIHZhbHVlLT5kYXRhLCBzaXplb2YoRFdPUkQpICk7CiAgICAgICAgICAgICAgICBmcHJpbnRmKCBmLCAiZHdvcmQ6JTA4bHgiLCBkdyApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogZWxzZSBmYWxsIHRocm91Z2ggKi8KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBpZiAodmFsdWUtPnR5cGUgPT0gUkVHX0JJTkFSWSkgY291bnQgKz0gZnByaW50ZiggZiwgImhleDoiICk7CiAgICAgICAgICAgIGVsc2UgY291bnQgKz0gZnByaW50ZiggZiwgImhleCgleCk6IiwgdmFsdWUtPnR5cGUgKTsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLT5sZW47IGkrKykgewogICAgICAgICAgICAgICAgY291bnQgKz0gZnByaW50ZiggZiwgIiUwMngiLCAqKCh1bnNpZ25lZCBjaGFyICopdmFsdWUtPmRhdGEgKyBpKSApOwogICAgICAgICAgICAgICAgaWYgKGkgPCB2YWx1ZS0+bGVuLTEpIHsKICAgICAgICAgICAgICAgICAgICBmcHV0YyggJywnLCBmICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCsrY291bnQgPiA3NikgewogICAgICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKCBmLCAiXFxcbiAgIiApOwogICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgZnB1dGMoICdcbicsIGYgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogV0lORE9XUyAzMSBSRUdJU1RSWSBMT0FERVIsIHN1cHBsaWVkIGJ5IFRvciBTavh3YWxsLCB0b3JAc24ubm8gKi8KLyoKICAgIHJlZ2hhY2sgLSB3aW5kb3dzIDMuMTEgcmVnaXN0cnkgZGF0YSBmb3JtYXQgZGVtbyBwcm9ncmFtLgoKICAgIFRoZSByZWcuZGF0IGZpbGUgaGFzIDMgcGFydHMsIGEgaGVhZGVyLCBhIHRhYmxlIG9mIDgtYnl0ZSBlbnRyaWVzIHRoYXQgaXMKICAgIGEgY29tYmluZWQgaGFzaCB0YWJsZSBhbmQgdHJlZSBkZXNjcmlwdGlvbiwgYW5kIGZpbmFsbHkgYSB0ZXh0IHRhYmxlLgoKICAgIFRoZSBoZWFkZXIgaXMgb2J2aW91cyBmcm9tIHRoZSBzdHJ1Y3QgaGVhZGVyLiBUaGUgdGFib2ZmMSBhbmQgdGFib2ZmMgogICAgZmllbGRzIGFyZSBhbHdheXMgMHgyMCwgYW5kIHRoZWlyIHVzYWdlIGlzIHVua25vd24uCgogICAgVGhlIDgtYnl0ZSBlbnRyeSB0YWJsZSBoYXMgdmFyaW91cyBlbnRyeSB0eXBlcy4KCiAgICB0YWJlbnRbMF0gaXMgYSByb290IGluZGV4LiBUaGUgc2Vjb25kIHdvcmQgaGFzIHRoZSBpbmRleCBvZiB0aGUgcm9vdCBvZgogICAgICAgICAgICB0aGUgZGlyZWN0b3J5LgogICAgdGFiZW50WzEuLmhhc2hzaXplXSBpcyBhIGhhc2ggdGFibGUuIFRoZSBmaXJzdCB3b3JkIGluIHRoZSBoYXNoIGVudHJ5IGlzCiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUga2V5L3ZhbHVlIHRoYXQgaGFzIHRoYXQgaGFzaC4gRGF0YSB3aXRoIHRoZSBzYW1lCiAgICAgICAgICAgIGhhc2ggdmFsdWUgYXJlIG9uIGEgY2lyY3VsYXIgbGlzdC4gVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZQogICAgICAgICAgICBoYXNoIGVudHJ5IGFyZSBhbHdheXMgemVyby4KICAgIHRhYmVudFtoYXNoc2l6ZS4udGFiY250XSBpcyB0aGUgdHJlZSBzdHJ1Y3R1cmUuIFRoZXJlIGFyZSB0d28ga2luZHMgb2YKICAgICAgICAgICAgZW50cnk6IGRpcmVudCBhbmQga2V5ZW50L3ZhbGVudC4gVGhleSBhcmUgaWRlbnRpZmllZCBieSBjb250ZXh0LgogICAgdGFiZW50W2ZyZWVpZHhdIGlzIHRoZSBmaXJzdCBmcmVlIGVudHJ5LiBUaGUgZmlyc3Qgd29yZCBpbiBhIGZyZWUgZW50cnkKICAgICAgICAgICAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGZyZWUgZW50cnkuIFRoZSBsYXN0IGhhcyAwIGFzIGEgbGluay4KICAgICAgICAgICAgVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZSBmcmVlIGxpc3QgYXJlIHByb2JhYmx5IGlycmVsZXZhbnQuCgogICAgRW50cmllcyBpbiB0ZXh0IHRhYmxlIGFyZSBwcmVjZWRlZCBieSBhIHdvcmQgYXQgb2Zmc2V0LTIuIFRoaXMgd29yZAogICAgaGFzIHRoZSB2YWx1ZSAoMippbmRleCkrMSwgd2hlcmUgaW5kZXggaXMgdGhlIHJlZmVycmluZyBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBpbiB0aGUgdGFibGUuIEkgaGF2ZSBubyBzdWdnZXN0aW9uIGZvciB0aGUgMiogYW5kIHRoZSArMS4KICAgIEZvbGxvd2luZyB0aGUgd29yZCwgdGhlcmUgYXJlIE4gYnl0ZXMgb2YgZGF0YSwgYXMgcGVyIHRoZSBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBsZW5ndGguIFRoZSBvZmZzZXQgb2YgdGhlIGtleWVudC92YWxlbnQgZW50cnkgaXMgZnJvbSB0aGUgc3RhcnQKICAgIG9mIHRoZSB0ZXh0IHRhYmxlIHRvIHRoZSBmaXJzdCBkYXRhIGJ5dGUuCgogICAgVGhpcyBpbmZvcm1hdGlvbiBpcyBub3QgYXZhaWxhYmxlIGZyb20gTWljcm9zb2Z0LiBUaGUgZGF0YSBmb3JtYXQgaXMKICAgIGRlZHVjZWQgZnJvbSB0aGUgcmVnLmRhdCBmaWxlIGJ5IG1lLiBNaXN0YWtlcyBtYXkKICAgIGhhdmUgYmVlbiBtYWRlLiBJIGNsYWltIG5vIHJpZ2h0cyBhbmQgZ2l2ZSBubyBndWFyYW50ZWVzIGZvciB0aGlzIHByb2dyYW0uCgogICAgVG9yIFNq+HdhbGwsIHRvckBzbi5ubwoqLwoKLyogcmVnLmRhdCBoZWFkZXIgZm9ybWF0ICovCnN0cnVjdCBfdzMxX2hlYWRlciB7CiAgICBjaGFyCQljb29raWVbOF07CS8qICdTSENDMy4xMCcgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGFib2ZmMTsJLyogb2Zmc2V0IG9mIGhhc2ggdGFibGUgKD8/KSA9IDB4MjAgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGFib2ZmMjsJLyogb2Zmc2V0IG9mIGluZGV4IHRhYmxlICg/PykgPSAweDIwICovCiAgICB1bnNpZ25lZCBsb25nCXRhYmNudDsJCS8qIG51bWJlciBvZiBlbnRyaWVzIGluIGluZGV4IHRhYmxlICovCiAgICB1bnNpZ25lZCBsb25nCXRleHRvZmY7CS8qIG9mZnNldCBvZiB0ZXh0IHBhcnQgKi8KICAgIHVuc2lnbmVkIGxvbmcJdGV4dHNpemU7CS8qIGJ5dGUgc2l6ZSBvZiB0ZXh0IHBhcnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWhhc2hzaXplOwkvKiBoYXNoIHNpemUgKi8KICAgIHVuc2lnbmVkIHNob3J0CWZyZWVpZHg7CS8qIGZyZWUgaW5kZXggKi8KfTsKCi8qIGdlbmVyaWMgZm9ybWF0IG9mIHRhYmxlIGVudHJpZXMgKi8Kc3RydWN0IF93MzFfdGFiZW50IHsKICAgIHVuc2lnbmVkIHNob3J0IHcwLCB3MSwgdzIsIHczOwp9OwoKLyogZGlyZWN0b3J5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfZGlyZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CXNpYmxpbmdfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBzaWJsaW5nIGRpcmVudCAqLwogICAgdW5zaWduZWQgc2hvcnQJY2hpbGRfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBjaGlsZCBkaXJlbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWtleV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGtleSBrZXllbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CXZhbHVlX2lkeDsJLyogdGFibGUgaW5kZXggb2YgdmFsdWUgdmFsZW50ICovCn07CgovKiBrZXkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9rZXllbnQgewogICAgdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHZhbHVlIHRhYmVudDogKi8Kc3RydWN0IF93MzFfdmFsZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwogICAgdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiByZWN1cnNpdmUgaGVscGVyIGZ1bmN0aW9uIHRvIGRpc3BsYXkgYSBkaXJlY3RvcnkgdHJlZSAgW0ludGVybmFsXSAqLwp2b2lkIF93MzFfZHVtcHRyZWUodW5zaWduZWQgc2hvcnQgaWR4LHVuc2lnbmVkIGNoYXIgKnR4dCxzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYixzdHJ1Y3QgX3czMV9oZWFkZXIgKmhlYWQsSEtFWSBoa2V5LHRpbWVfdCBsYXN0bW9kaWZpZWQsIGludCBsZXZlbCkKewogICAgc3RydWN0IF93MzFfZGlyZW50ICpkaXI7CiAgICBzdHJ1Y3QgX3czMV9rZXllbnQgKmtleTsKICAgIHN0cnVjdCBfdzMxX3ZhbGVudCAqdmFsOwogICAgSEtFWSBzdWJrZXkgPSAwOwogICAgc3RhdGljIGNoYXIJdGFpbFs0MDBdOwoKICAgIHdoaWxlIChpZHghPTApIHsKICAgICAgICBkaXI9KHN0cnVjdCBfdzMxX2RpcmVudCopJnRhYltpZHhdOwoKICAgICAgICBpZiAoZGlyLT5rZXlfaWR4KSB7CiAgICAgICAgICAgIGtleSA9IChzdHJ1Y3QgX3czMV9rZXllbnQqKSZ0YWJbZGlyLT5rZXlfaWR4XTsKCiAgICAgICAgICAgIG1lbWNweSh0YWlsLCZ0eHRba2V5LT5zdHJpbmdfb2ZmXSxrZXktPmxlbmd0aCk7CiAgICAgICAgICAgIHRhaWxba2V5LT5sZW5ndGhdPSdcMCc7CiAgICAgICAgICAgIC8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUgCiAgICAgICAgICAgICAqIHRvcGxldmVsIHN1YmRpcmVjdG9yeSBiZWxvbmcgdG8gXFNPRlRXQVJFXENsYXNzZXMKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICghbGV2ZWwgJiYgIXN0cmNtcCh0YWlsLCIuY2xhc3NlcyIpKSB7CiAgICAgICAgICAgICAgICBfdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxoa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKICAgICAgICAgICAgICAgIGlkeD1kaXItPnNpYmxpbmdfaWR4OwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwogICAgICAgICAgICBpZiAoUmVnQ3JlYXRlS2V5QSggaGtleSwgdGFpbCwgJnN1YmtleSApICE9IEVSUk9SX1NVQ0NFU1MpIHN1YmtleSA9IDA7CiAgICAgICAgICAgIC8qIG9ubHkgYWRkIGlmIGxlYWYgbm9kZSBvciB2YWx1ZWQgbm9kZSAqLwogICAgICAgICAgICBpZiAoZGlyLT52YWx1ZV9pZHghPTB8fGRpci0+Y2hpbGRfaWR4PT0wKSB7CiAgICAgICAgICAgICAgICBpZiAoZGlyLT52YWx1ZV9pZHgpIHsKICAgICAgICAgICAgICAgICAgICB2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KHRhaWwsJnR4dFt2YWwtPnN0cmluZ19vZmZdLHZhbC0+bGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICB0YWlsW3ZhbC0+bGVuZ3RoXT0nXDAnOwogICAgICAgICAgICAgICAgICAgIFJlZ1NldFZhbHVlQSggc3Via2V5LCBOVUxMLCBSRUdfU1osIHRhaWwsIDAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBUUkFDRSgic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKICAgICAgICBfdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxzdWJrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwogICAgICAgIGlkeD1kaXItPnNpYmxpbmdfaWR4OwogICAgfQogICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzMxX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kdm9pZCBfdzMxX2xvYWRyZWcodm9pZCkgCnsKICAgIEhGSUxFIGhmOwogICAgc3RydWN0IF93MzFfaGVhZGVyCWhlYWQ7CiAgICBzdHJ1Y3QgX3czMV90YWJlbnQJKnRhYjsKICAgIHVuc2lnbmVkIGNoYXIJCSp0eHQ7CiAgICB1bnNpZ25lZCBpbnQJCWxlbjsKICAgIE9GU1RSVUNUCQlvZnM7CiAgICBCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmluZm87CiAgICB0aW1lX3QJCQlsYXN0bW9kaWZpZWQ7CgogICAgVFJBQ0UoIih2b2lkKVxuIik7CgogICAgaGYgPSBPcGVuRmlsZSgicmVnLmRhdCIsJm9mcyxPRl9SRUFEKTsKICAgIGlmIChoZj09SEZJTEVfRVJST1IpIHJldHVybjsKCiAgICAvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KICAgIGlmIChzaXplb2YoaGVhZCkhPV9scmVhZChoZiwmaGVhZCxzaXplb2YoaGVhZCkpKSB7CiAgICAgICAgRVJSKCJyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpIT0wKSB7CiAgICAgICAgRVJSKCJyZWcuZGF0IGhhcyBiYWQgc2lnbmF0dXJlLlxuIik7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGxlbiA9IGhlYWQudGFiY250ICogc2l6ZW9mKHN0cnVjdCBfdzMxX3RhYmVudCk7CiAgICAvKiByZWFkIGFuZCBkdW1wIGluZGV4IHRhYmxlICovCiAgICB0YWIgPSBfeG1hbGxvYyhsZW4pOwogICAgaWYgKGxlbiE9X2xyZWFkKGhmLHRhYixsZW4pKSB7CiAgICAgICAgRVJSKCJjb3VsZG4ndCByZWFkICVkIGJ5dGVzLlxuIixsZW4pOyAKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIHJlYWQgdGV4dCAqLwogICAgdHh0ID0gX3htYWxsb2MoaGVhZC50ZXh0c2l6ZSk7CiAgICBpZiAoLTE9PV9sbHNlZWsoaGYsaGVhZC50ZXh0b2ZmLFNFRUtfU0VUKSkgewogICAgICAgIEVSUigiY291bGRuJ3Qgc2VlayB0byB0ZXh0YmxvY2suXG4iKTsgCiAgICAgICAgZnJlZSh0YWIpOwogICAgICAgIGZyZWUodHh0KTsKICAgICAgICBfbGNsb3NlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoaGVhZC50ZXh0c2l6ZSE9X2xyZWFkKGhmLHR4dCxoZWFkLnRleHRzaXplKSkgewogICAgICAgIEVSUigidGV4dGJsb2NrIHRvbyBzaG9ydCAoJWQgaW5zdGVhZCBvZiAlbGQpLlxuIixsZW4saGVhZC50ZXh0c2l6ZSk7IAogICAgICAgIGZyZWUodGFiKTsKICAgICAgICBmcmVlKHR4dCk7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGYsJmhmaW5mbykpIHsKICAgICAgICBFUlIoIkdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlIGZhaWxlZD8uXG4iKTsgCiAgICAgICAgZnJlZSh0YWIpOwogICAgICAgIGZyZWUodHh0KTsKICAgICAgICBfbGNsb3NlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBsYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CiAgICBfdzMxX2R1bXB0cmVlKHRhYlswXS53MSx0eHQsdGFiLCZoZWFkLEhLRVlfQ0xBU1NFU19ST09ULGxhc3Rtb2RpZmllZCwwKTsKICAgIGZyZWUodGFiKTsKICAgIGZyZWUodHh0KTsKICAgIF9sY2xvc2UoaGYpOwogICAgcmV0dXJuOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93cyA5NSByZWdpc3RyeSBsb2FkZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogU0VDVElPTiAxOiBtYWluIGhlYWRlcgogKgogKiBvbmNlIGF0IG9mZnNldCAwCiAqLwojZGVmaW5lCVc5NV9SRUdfQ1JFR19JRAkweDQ3NDU1MjQzCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qICJDUkVHIiA9IFc5NV9SRUdfQ1JFR19JRCAqLwogICAgRFdPUkQJdmVyc2lvbjsJLyogPz8/PyAweDAwMDEwMDAwICovCiAgICBEV09SRAlyZ2RiX29mZjsJLyogMHgwOCBPZmZzZXQgb2YgMXN0IFJHREItYmxvY2sgKi8KICAgIERXT1JECXVrMjsJCS8qIDB4MGMgKi8KICAgIFdPUkQJcmdkYl9udW07CS8qIDB4MTAgIyBvZiBSR0RCLWJsb2NrcyAqLwogICAgV09SRAl1azM7CiAgICBEV09SRAl1a1szXTsKICAgIC8qIHJna24gKi8KfSBfdzk1Y3JlZzsKCi8qIFNFQ1RJT04gMjogRGlyZWN0b3J5IGluZm9ybWF0aW9uICh0cmVlIHN0cnVjdHVyZSkKICoKICogb25jZSBvbiBvZmZzZXQgMHgyMAogKgogKiBzdHJ1Y3R1cmU6IFtyZ2tuXVtka2VdKgkocmVwZWF0IHRpbGwgbGFzdF9ka2UgaXMgcmVhY2hlZCkKICovCiNkZWZpbmUJVzk1X1JFR19SR0tOX0lECTB4NGU0YjQ3NTIKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyoiUkdLTiIgPSBXOTVfUkVHX1JHS05fSUQgKi8KICAgIERXT1JECXNpemU7CQkvKiBTaXplIG9mIHRoZSBSR0tOLWJsb2NrICovCiAgICBEV09SRAlyb290X29mZjsJLyogUmVsLiBPZmZzZXQgb2YgdGhlIHJvb3QtcmVjb3JkICovCiAgICBEV09SRCAgIGxhc3RfZGtlOyAgICAgICAvKiBPZmZzZXQgdG8gbGFzdCBES0UgPyAqLwogICAgRFdPUkQJdWtbNF07Cn0gX3c5NXJna247CgovKiBEaXNrIEtleSBFbnRyeSBTdHJ1Y3R1cmUKICoKICogdGhlIDFzdCBlbnRyeSBpbiBhICJ1c3VhbCIgcmVnaXN0cnkgZmlsZSBpcyBhIG51bC1lbnRyeSB3aXRoIHN1YmtleXM6IHRoZQogKiBoaXZlIGl0c2VsZi4gSXQgbG9va3MgdGhlIHNhbWUgbGlrZSBvdGhlciBrZXlzLiBFdmVuIHRoZSBJRC1udW1iZXIgY2FuCiAqIGJlIGFueSB2YWx1ZS4KICoKICogVGhlICJoYXNoIi12YWx1ZSBpcyBhIHZhbHVlIHJlcHJlc2VudGluZyB0aGUga2V5J3MgbmFtZS4gV2luZG93cyB3aWxsIG5vdAogKiBzZWFyY2ggZm9yIHRoZSBuYW1lLCBidXQgZm9yIGEgbWF0Y2hpbmcgaGFzaC12YWx1ZS4gaWYgaXQgZmluZHMgb25lLCBpdAogKiB3aWxsIGNvbXBhcmUgdGhlIGFjdHVhbCBzdHJpbmcgaW5mbywgb3RoZXJ3aXNlIGNvbnRpbnVlIHdpdGggdGhlIG5leHQga2V5LgogKiBUbyBjYWxjdWxhdGUgdGhlIGhhc2ggaW5pdGlhbGl6ZSBhIEQtV29yZCB3aXRoIDAgYW5kIGFkZCBhbGwgQVNDSUktdmFsdWVzIAogKiBvZiB0aGUgc3RyaW5nIHdoaWNoIGFyZSBzbWFsbGVyIHRoYW4gMHg4MCAoMTI4KSB0byB0aGlzIEQtV29yZC4gICAKICoKICogSWYgeW91IHdhbnQgdG8gbW9kaWZ5IGtleSBuYW1lcywgYWxzbyBtb2RpZnkgdGhlIGhhc2gtdmFsdWVzLCBzaW5jZSB0aGV5CiAqIGNhbm5vdCBiZSBmb3VuZCBhZ2FpbiAoYWx0aG91Z2ggdGhleSB3b3VsZCBiZSBkaXNwbGF5ZWQgaW4gUkVHRURJVCkKICogRW5kIG9mIGxpc3QtcG9pbnRlcnMgYXJlIGZpbGxlZCB3aXRoIDB4RkZGRkZGRkYKICoKICogRGlzayBrZXlzIGFyZSBsYXllZCBvdXQgZmxhdCAuLi4gQnV0LCBzb21ldGltZXMsIG5yTFMgYW5kIG5yTVMgYXJlIGJvdGgKICogMHhGRkZGLCB3aGljaCBtZWFucyBza2lwcGluZyBvdmVyIG5leHRrZXlvZmZzZXQgYnl0ZXMgKGluY2x1ZGluZyB0aGlzCiAqIHN0cnVjdHVyZSkgYW5kIHJlYWRpbmcgYW5vdGhlciBSR0RCX3NlY3Rpb24uCiAqCiAqIFRoZSBsYXN0IERLRSAoc2VlIGZpZWxkIGxhc3RfZGtlIGluIF93OTVfcmdrbikgaGFzIG9ubHkgMyBEV09SRHMgd2l0aAogKiAweDgwMDAwMDAwIChFT0wgaW5kaWNhdG9yID8pIGFzIHgxLCB0aGUgaGFzaCB2YWx1ZSBhbmQgMHhGRkZGRkZGRiBhcyB4My4KICogVGhlIHJlbWFpbmluZyBzcGFjZSBiZXR3ZWVuIGxhc3RfZGtlIGFuZCB0aGUgb2Zmc2V0IGNhbGN1bGF0ZWQgZnJvbQogKiByZ2tuLT5zaXplIHNlZW1zIHRvIGJlIGZyZWUgZm9yIHVzZSBmb3IgbW9yZSBka2U6cy4KICogU28gaXQgc2VlbXMgaWYgbW9yZSBka2U6cyBhcmUgYWRkZWQsIHRoZXkgYXJlIGFkZGVkIHRvIHRoYXQgc3BhY2UgYW5kCiAqIGxhc3RfZGtlIGlzIGdyb3duLCBhbmQgaW4gY2FzZSB0aGF0ICJmcmVlIiBzcGFjZSBpcyBvdXQsIHRoZSBzcGFjZQogKiBnZXRzIGdyb3duIGFuZCByZ2tuLT5zaXplIGdldHMgYWRqdXN0ZWQuCiAqCiAqIHRoZXJlIGlzIGEgb25lIHRvIG9uZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBka2UgYW5kIGRraAogKi8KIC8qIGtleSBzdHJ1Y3QsIG9uY2UgcGVyIGtleSAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAl4MTsJCS8qIEZyZWUgZW50cnkgaW5kaWNhdG9yKD8pICovCiAgICBEV09SRAloYXNoOwkJLyogc3VtIG9mIGJ5dGVzIG9mIGtleW5hbWUgKi8KICAgIERXT1JECXgzOwkJLyogUm9vdCBrZXkgaW5kaWNhdG9yPyB1c3VhbGx5IDB4RkZGRkZGRkYgKi8KICAgIERXT1JECXByZXZsdmw7CS8qIG9mZnNldCBvZiBwcmV2aW91cyBrZXkgKi8KICAgIERXT1JECW5leHRzdWI7CS8qIG9mZnNldCBvZiBjaGlsZCBrZXkgKi8KICAgIERXT1JECW5leHQ7CQkvKiBvZmZzZXQgb2Ygc2libGluZyBrZXkgKi8KICAgIFdPUkQJbnJMUzsJCS8qIGlkIGluc2lkZSB0aGUgcmdkYiBibG9jayAqLwogICAgV09SRAluck1TOwkJLyogbnVtYmVyIG9mIHRoZSByZ2RiIGJsb2NrICovCn0gX3c5NWRrZTsKCi8qIFNFQ1RJT04gMzoga2V5IGluZm9ybWF0aW9uLCB2YWx1ZXMgYW5kIGRhdGEKICoKICogc3RydWN0dXJlOgogKiAgc2VjdGlvbjoJW2Jsb2Nrc10qCQkocmVwZWF0IGNyZWctPnJnZGJfbnVtIHRpbWVzKQogKiAgYmxvY2tzOglbcmdkYl0gW3N1YmJsb2Nrc10qIAkocmVwZWF0IHRpbGwgYmxvY2sgc2l6ZSByZWFjaGVkICkKICogIHN1YmJsb2NrczoJW2RraF0gW2Rrdl0qCQkocmVwZWF0IGRraC0+dmFsdWVzIHRpbWVzICkKICoKICogQW4gaW50ZXJlc3RpbmcgcmVsYXRpb25zaGlwIGV4aXN0cyBpbiBSR0RCX3NlY3Rpb24uIFRoZSBEV09SRCB2YWx1ZQogKiBhdCBvZmZzZXQgMHgxMCBlcXVhbHMgdGhlIG9uZSBhdCBvZmZzZXQgMHgwNCBtaW51cyB0aGUgb25lIGF0IG9mZnNldCAweDA4LgogKiBJIGhhdmUgbm8gaWRlYSBhdCB0aGUgbW9tZW50IHdoYXQgdGhpcyBtZWFucy4gIChLZXZpbiBDb3plbnMpCiAqLwoKLyogYmxvY2sgaGVhZGVyLCBvbmNlIHBlciBibG9jayAqLwojZGVmaW5lIFc5NV9SRUdfUkdEQl9JRAkweDQyNDQ0NzUyCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJLyogMHgwMCAnUkdEQicgPSBXOTVfUkVHX1JHREJfSUQgKi8KICAgIERXT1JECXNpemU7CS8qIDB4MDQgKi8KICAgIERXT1JECXVrMTsJLyogMHgwOCAqLwogICAgRFdPUkQJdWsyOwkvKiAweDBjICovCiAgICBEV09SRAl1azM7CS8qIDB4MTAgKi8KICAgIERXT1JECXVrNDsJLyogMHgxNCAqLwogICAgRFdPUkQJdWs1OwkvKiAweDE4ICovCiAgICBEV09SRAl1azY7CS8qIDB4MWMgKi8KICAgIC8qIGRraCAqLwp9IF93OTVyZ2RiOwoKLyogRGlzayBLZXkgSGVhZGVyIHN0cnVjdHVyZSAoUkdEQiBwYXJ0KSwgb25jZSBwZXIga2V5ICovCnR5cGVkZWYJc3RydWN0IHsKICAgIERXT1JECW5leHRrZXlvZmY7IAkvKiAweDAwIG9mZnNldCB0byBuZXh0IGRraCAqLwogICAgV09SRAluckxTOwkJLyogMHgwNCBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KICAgIFdPUkQJbnJNUzsJCS8qIDB4MDYgbnVtYmVyIG9mIHRoZSByZ2RiIGJsb2NrICovCiAgICBEV09SRAlieXRlc3VzZWQ7CS8qIDB4MDggKi8KICAgIFdPUkQJa2V5bmFtZWxlbjsJLyogMHgwYyBsZW4gb2YgbmFtZSAqLwogICAgV09SRAl2YWx1ZXM7CQkvKiAweDBlIG51bWJlciBvZiB2YWx1ZXMgKi8KICAgIERXT1JECXh4MTsJCS8qIDB4MTAgKi8KICAgIGNoYXIJbmFtZVsxXTsJLyogMHgxNCAqLwogICAgLyogZGt2ICovCQkvKiAweDE0ICsga2V5bmFtZWxlbiAqLwp9IF93OTVka2g7CgovKiBEaXNrIEtleSBWYWx1ZSBzdHJ1Y3R1cmUsIG9uY2UgcGVyIHZhbHVlICovCnR5cGVkZWYJc3RydWN0IHsKICAgIERXT1JECXR5cGU7CQkvKiAweDAwICovCiAgICBEV09SRAl4MTsJCS8qIDB4MDQgKi8KICAgIFdPUkQJdmFsbmFtZWxlbjsJLyogMHgwOCBsZW5ndGggb2YgbmFtZSwgMCBpcyBkZWZhdWx0IGtleSAqLwogICAgV09SRAl2YWxkYXRhbGVuOwkvKiAweDBBIGxlbmd0aCBvZiBkYXRhICovCiAgICBjaGFyCW5hbWVbMV07CS8qIDB4MGMgKi8KICAgIC8qIHJhdyBkYXRhICovCQkvKiAweDBjICsgdmFsbmFtZWxlbiAqLwp9IF93OTVka3Y7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfbG9va3VwX2RraCBbSW50ZXJuYWxdCiAqCiAqIHNlZWtzIHRoZSBka2ggYmVsb25naW5nIHRvIGEgZGtlCiAqLwpzdGF0aWMgX3c5NWRraCAqX3c5NV9sb29rdXBfZGtoKF93OTVjcmVnICpjcmVnLGludCBuckxTLGludCBuck1TKQp7CiAgICBfdzk1cmdkYiAqIHJnZGI7CiAgICBfdzk1ZGtoICogZGtoOwogICAgaW50IGk7CgogICAgLyogZ2V0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHJnZGIgZGF0YXN0b3JlICovCiAgICByZ2RiID0gKF93OTVyZ2RiKikoKGNoYXIqKWNyZWcrY3JlZy0+cmdkYl9vZmYpOwoKICAgIC8qIGNoZWNrOiByZXF1ZXN0ZWQgYmxvY2sgPCBsYXN0X2Jsb2NrKSAqLwogICAgaWYgKGNyZWctPnJnZGJfbnVtIDw9IG5yTVMpIHsKICAgICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgcmVxdWVzdGVkIGJsb2NrIG5vLiBiZXlvbmQgZW5kLlxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBmaW5kIHRoZSByaWdodCBibG9jayAqLwogICAgZm9yKGk9MDsgaTxuck1TIDtpKyspIHsKICAgICAgICBpZihyZ2RiLT5pZCAhPSBXOTVfUkVHX1JHREJfSUQpIHsgIC8qIGNoZWNrIHRoZSBtYWdpYyAqLwogICAgICAgICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgYmFkIG1hZ2ljIDB4JTA4bHhcbiIsIHJnZGItPmlkKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiAgICAgICAgcmdkYiA9IChfdzk1cmdkYiopICgoY2hhciopcmdkYityZ2RiLT5zaXplKTsJCS8qIGZpbmQgbmV4dCBibG9jayAqLwogICAgfQoKICAgIGRraCA9IChfdzk1ZGtoKikocmdkYiArIDEpOwkJCQkvKiBmaXJzdCBzdWIgYmxvY2sgd2l0aGluIHRoZSByZ2RiICovCgogICAgZG8gewogICAgICAgIGlmKG5yTFM9PWRraC0+bnJMUyApIHJldHVybiBka2g7CiAgICAgICAgZGtoID0gKF93OTVka2gqKSgoY2hhciopZGtoICsgZGtoLT5uZXh0a2V5b2ZmKTsJLyogZmluZCBuZXh0IHN1YmJsb2NrICovCiAgICB9IHdoaWxlICgoY2hhciAqKWRraCA8ICgoY2hhciopcmdkYityZ2RiLT5zaXplKSk7CgplcnJvcjoKICAgIHJldHVybiBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfZHVtcF9ka3YgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfdzk1X2R1bXBfZGt2KF93OTVka2ggKmRraCxpbnQgbnJMUyxpbnQgbnJNUyxGSUxFICpmKQp7CiAgICBfdzk1ZGt2ICogZGt2OwogICAgaW50IGk7CgogICAgLyogZmlyc3QgdmFsdWUgYmxvY2sgKi8KICAgIGRrdiA9IChfdzk1ZGt2KikoKGNoYXIqKWRraCtka2gtPmtleW5hbWVsZW4rMHgxNCk7CgogICAgLyogbG9vcCB0aHJvdWdoIHRoZSB2YWx1ZXMgKi8KICAgIGZvciAoaT0wOyBpPCBka2gtPnZhbHVlczsgaSsrKSB7CiAgICAgICAgc3RydWN0IGtleV92YWx1ZSB2YWx1ZTsKICAgICAgICBXQ0hBUiAqcGRhdGE7CgogICAgICAgIHZhbHVlLm5hbWVXID0gX3N0cmR1cG5BdG9XKGRrdi0+bmFtZSxka3YtPnZhbG5hbWVsZW4pOwogICAgICAgIHZhbHVlLnR5cGUgPSBka3YtPnR5cGU7CiAgICAgICAgdmFsdWUubGVuID0gZGt2LT52YWxkYXRhbGVuOwoKICAgICAgICB2YWx1ZS5kYXRhID0gJihka3YtPm5hbWVbZGt2LT52YWxuYW1lbGVuXSk7CiAgICAgICAgcGRhdGEgPSBOVUxMOwogICAgICAgIGlmICggKHZhbHVlLnR5cGU9PVJFR19TWikgfHwgKHZhbHVlLnR5cGU9PVJFR19FWFBBTkRfU1opIHx8ICh2YWx1ZS50eXBlPT1SRUdfTVVMVElfU1opICkgewogICAgICAgICAgICBwZGF0YSA9IF9zdHJkdXBuQXRvVyh2YWx1ZS5kYXRhLHZhbHVlLmxlbik7CiAgICAgICAgICAgIHZhbHVlLmxlbiAqPSAyOwogICAgICAgIH0KICAgICAgICBpZiAocGRhdGEgIT0gTlVMTCkgdmFsdWUuZGF0YSA9IHBkYXRhOwoKICAgICAgICBfZHVtcF92YWx1ZSgmdmFsdWUsZik7CiAgICAgICAgZnJlZSh2YWx1ZS5uYW1lVyk7CiAgICAgICAgaWYgKHBkYXRhICE9IE5VTEwpIGZyZWUocGRhdGEpOwoKICAgICAgICAvKiBuZXh0IHZhbHVlICovCiAgICAgICAgZGt2ID0gKF93OTVka3YqKSgoY2hhciopZGt2K2Rrdi0+dmFsbmFtZWxlbitka3YtPnZhbGRhdGFsZW4rMHgwYyk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2R1bXBfZGtlIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9kdW1wX2RrZShMUFNUUiBrZXlfbmFtZSxfdzk1Y3JlZyAqY3JlZyxfdzk1cmdrbiAqcmdrbixfdzk1ZGtlICpka2UsRklMRSAqZixpbnQgbGV2ZWwpCnsKICAgIF93OTVka2ggKiBka2g7CiAgICBMUFNUUiBuZXdfa2V5X25hbWUgPSBOVUxMOwoKICAgIC8qIHNwZWNpYWwgcm9vdCBrZXkgKi8KICAgIGlmIChka2UtPm5yTFMgPT0gMHhmZmZmIHx8IGRrZS0+bnJNUz09MHhmZmZmKQkJLyogZWcuIHRoZSByb290IGtleSBoYXMgbm8gbmFtZSAqLwogICAgewogICAgICAgIC8qIHBhcnNlIHRoZSBvbmUgc3Via2V5ICovCiAgICAgICAgaWYgKGRrZS0+bmV4dHN1YiAhPSAweGZmZmZmZmZmKSByZXR1cm4gX3c5NV9kdW1wX2RrZShrZXlfbmFtZSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHRzdWIpLGYsbGV2ZWwpOwogICAgICAgIC8qIGhhcyBubyBzaWJsaW5nIGtleXMgKi8KICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgLyogc2VhcmNoIHN1YmJsb2NrICovCiAgICBpZiAoIShka2ggPSBfdzk1X2xvb2t1cF9ka2goY3JlZywgZGtlLT5uckxTLCBka2UtPm5yTVMpKSkgewogICAgICAgIEVSUigiZGtlIHBvaW50aW5nIHRvIG1pc3NpbmcgZGtoICFcbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAobGV2ZWwgPD0gMCkgewogICAgICAgIC8qIGNyZWF0ZSBuZXcgc3Via2V5IG5hbWUgKi8KICAgICAgICBuZXdfa2V5X25hbWUgPSBfc3RyZHVwbkEoa2V5X25hbWUsc3RybGVuKGtleV9uYW1lKStka2gtPmtleW5hbWVsZW4rMSk7CiAgICAgICAgaWYgKHN0cmNtcChuZXdfa2V5X25hbWUsIiIpICE9IDApIHN0cmNhdChuZXdfa2V5X25hbWUsIlxcIik7CiAgICAgICAgc3RybmNhdChuZXdfa2V5X25hbWUsZGtoLT5uYW1lLGRraC0+a2V5bmFtZWxlbik7CgogICAgICAgIC8qIHdhbGsgc2libGluZyBrZXlzICovCiAgICAgICAgaWYgKGRrZS0+bmV4dCAhPSAweGZmZmZmZmZmICkgewogICAgICAgICAgICBpZiAoIV93OTVfZHVtcF9ka2Uoa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0KSxmLGxldmVsKSkgewogICAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiB3cml0ZSB0aGUga2V5IHBhdGggKHNvbWV0aGluZyBsaWtlIFtTb2Z0d2FyZVxcTWljcm9zb2Z0XFwuLl0pIG9ubHkgaWY6IAogICAgICAgICAgIDEpIGtleSBoYXMgc29tZSB2YWx1ZXMKICAgICAgICAgICAyKSBrZXkgaGFzIG5vIHZhbHVlcyBhbmQgbm8gc3Via2V5cwogICAgICAgICovCiAgICAgICAgaWYgKGRraC0+dmFsdWVzID4gMCkgewogICAgICAgICAgICAvKiB0aGVyZSBhcmUgc29tZSB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGt2KGRraCwgZGtlLT5uckxTLCBka2UtPm5yTVMsZikpIHsKICAgICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgoZGtlLT5uZXh0c3ViID09IDB4ZmZmZmZmZmYpICYmIChka2gtPnZhbHVlcyA9PSAwKSkgewogICAgICAgICAgICAvKiBubyBzdWJrZXlzIGFuZCBubyB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICB9CiAgICB9IGVsc2UgbmV3X2tleV9uYW1lID0gX3N0cmR1cG5BKGtleV9uYW1lLHN0cmxlbihrZXlfbmFtZSkpOwoKICAgIC8qIG5leHQgc3ViIGtleSAqLwogICAgaWYgKGRrZS0+bmV4dHN1YiAhPSAweGZmZmZmZmZmKSB7CiAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGtlKG5ld19rZXlfbmFtZSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHRzdWIpLGYsbGV2ZWwtMSkpIHsKICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgcmV0dXJuIFRSVUU7Cn0KLyogZW5kIHdpbmRvd3MgOTUgbG9hZGVyICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93cyBOVCByZWdpc3RyeSBsb2FkZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogTlQgUkVHSVNUUlkgTE9BREVSICovCgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgojaWZuZGVmIE1BUF9GQUlMRUQKI2RlZmluZSBNQVBfRkFJTEVEICgoTFBWT0lEKS0xKQojZW5kaWYKCiNkZWZpbmUgTlRfUkVHX0JMT0NLX1NJWkUgICAgICAgICAgICAweDEwMDAKCiNkZWZpbmUgTlRfUkVHX0hFQURFUl9CTE9DS19JRCAgICAgICAweDY2Njc2NTcyCS8qIHJlZ2YgKi8KI2RlZmluZSBOVF9SRUdfUE9PTF9CTE9DS19JRCAgICAgICAgIDB4NkU2OTYyNjgJLyogaGJpbiAqLwojZGVmaW5lIE5UX1JFR19LRVlfQkxPQ0tfSUQgICAgICAgICAgMHg2YjZlIC8qIG5rICovCiNkZWZpbmUgTlRfUkVHX1ZBTFVFX0JMT0NLX0lEICAgICAgICAweDZiNzYgLyogdmsgKi8KCi8qIHN1YmJsb2NrcyBvZiBuayAqLwojZGVmaW5lIE5UX1JFR19IQVNIX0JMT0NLX0lEICAgICAgICAgMHg2NjZjIC8qIGxmICovCiNkZWZpbmUgTlRfUkVHX05PSEFTSF9CTE9DS19JRCAgICAgICAweDY5NmMgLyogbGkgKi8KI2RlZmluZSBOVF9SRUdfUklfQkxPQ0tfSUQJICAgICAweDY5NzIgLyogcmkgKi8KCiNkZWZpbmUgTlRfUkVHX0tFWV9CTE9DS19UWVBFICAgICAgICAweDIwCiNkZWZpbmUgTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUgICAweDJjCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qIDB4NjY2NzY1NzIgJ3JlZ2YnKi8KICAgIERXT1JECXVrMTsJCS8qIDB4MDQgKi8KICAgIERXT1JECXVrMjsJCS8qIDB4MDggKi8KICAgIEZJTEVUSU1FCURhdGVNb2RpZmllZDsJLyogMHgwYyAqLwogICAgRFdPUkQJdWszOwkJLyogMHgxNCAqLwogICAgRFdPUkQJdWs0OwkJLyogMHgxOCAqLwogICAgRFdPUkQJdWs1OwkJLyogMHgxYyAqLwogICAgRFdPUkQJdWs2OwkJLyogMHgyMCAqLwogICAgRFdPUkQJUm9vdEtleUJsb2NrOwkvKiAweDI0ICovCiAgICBEV09SRAlCbG9ja1NpemU7CS8qIDB4MjggKi8KICAgIERXT1JEICAgdWs3WzExNl07CQogICAgRFdPUkQJQ2hlY2tzdW07IC8qIGF0IG9mZnNldCAweDFGQyAqLwp9IG50X3JlZ2Y7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlibG9ja3NpemU7CiAgICBCWVRFCWRhdGFbMV07Cn0gbnRfaGJpbl9zdWI7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qIDB4NkU2OTYyNjggJ2hiaW4nICovCiAgICBEV09SRAlvZmZfcHJldjsKICAgIERXT1JECW9mZl9uZXh0OwogICAgRFdPUkQJdWsxOwogICAgRFdPUkQJdWsyOwkJLyogMHgxMCAqLwogICAgRFdPUkQJdWszOwkJLyogMHgxNCAqLwogICAgRFdPUkQJdWs0OwkJLyogMHgxOCAqLwogICAgRFdPUkQJc2l6ZTsJCS8qIDB4MUMgKi8KICAgIG50X2hiaW5fc3ViCWhiaW5fc3ViOwkvKiAweDIwICovCn0gbnRfaGJpbjsKCi8qCiAqIHRoZSB2YWx1ZV9saXN0IGNvbnNpc3RzIG9mIG9mZnNldHMgdG8gdGhlIHZhbHVlcyAodmspCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECVN1YkJsb2NrSWQ7CQkvKiAweDAwIDB4NkI2RSAqLwogICAgV09SRAlUeXBlOwkJCS8qIDB4MDIgZm9yIHRoZSByb290LWtleTogMHgyQywgb3RoZXJ3aXNlIDB4MjAqLwogICAgRklMRVRJTUUJd3JpdGV0aW1lOwkvKiAweDA0ICovCiAgICBEV09SRAl1azE7CQkJLyogMHgwQyAqLwogICAgRFdPUkQJcGFyZW50X29mZjsJCS8qIDB4MTAgT2Zmc2V0IG9mIE93bmVyL1BhcmVudCBrZXkgKi8KICAgIERXT1JECW5yX3N1YmtleXM7CQkvKiAweDE0IG51bWJlciBvZiBzdWItS2V5cyAqLwogICAgRFdPUkQJdWs4OwkJCS8qIDB4MTggKi8KICAgIERXT1JECWxmX29mZjsJCQkvKiAweDFDIE9mZnNldCBvZiB0aGUgc3ViLWtleSBsZi1SZWNvcmRzICovCiAgICBEV09SRAl1azI7CQkJLyogMHgyMCAqLwogICAgRFdPUkQJbnJfdmFsdWVzOwkJLyogMHgyNCBudW1iZXIgb2YgdmFsdWVzICovCiAgICBEV09SRAl2YWx1ZWxpc3Rfb2ZmOwkJLyogMHgyOCBPZmZzZXQgb2YgdGhlIFZhbHVlLUxpc3QgKi8KICAgIERXT1JECW9mZl9zazsJCQkvKiAweDJjIE9mZnNldCBvZiB0aGUgc2stUmVjb3JkICovCiAgICBEV09SRAlvZmZfY2xhc3M7CQkvKiAweDMwIE9mZnNldCBvZiB0aGUgQ2xhc3MtTmFtZSAqLwogICAgRFdPUkQJdWszOwkJCS8qIDB4MzQgKi8KICAgIERXT1JECXVrNDsJCQkvKiAweDM4ICovCiAgICBEV09SRAl1azU7CQkJLyogMHgzYyAqLwogICAgRFdPUkQJdWs2OwkJCS8qIDB4NDAgKi8KICAgIERXT1JECXVrNzsJCQkvKiAweDQ0ICovCiAgICBXT1JECW5hbWVfbGVuOwkJLyogMHg0OCBuYW1lLWxlbmd0aCAqLwogICAgV09SRAljbGFzc19sZW47CQkvKiAweDRhIGNsYXNzLW5hbWUgbGVuZ3RoICovCiAgICBjaGFyCW5hbWVbMV07CQkvKiAweDRjIGtleS1uYW1lICovCn0gbnRfbms7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlvZmZfbms7CS8qIDB4MDAgKi8KICAgIERXT1JECW5hbWU7CS8qIDB4MDQgKi8KfSBoYXNoX3JlYzsKCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwIDB4NjY2YyAqLwogICAgV09SRAlucl9rZXlzOwkvKiAweDA2ICovCiAgICBoYXNoX3JlYwloYXNoX3JlY1sxXTsKfSBudF9sZjsKCi8qCiBsaXN0IG9mIHN1YmtleXMgd2l0aG91dCBoYXNoCgogbGkgLS0rLS0+bmsKICAgICAgfAogICAgICArLS0+bmsKICovCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwIDB4Njk2YyAqLwogICAgV09SRAlucl9rZXlzOwogICAgRFdPUkQJb2ZmX25rWzFdOwp9IG50X2xpOwoKLyoKIHRoaXMgaXMgYSBpbnRlcm1lZGlhdGUgbm9kZQoKIHJpIC0tKy0tPmxpLS0rLS0+bmsKICAgICAgfCAgICAgICArCiAgICAgIHwgICAgICAgKy0tPm5rCiAgICAgIHwKICAgICAgKy0tPmxpLS0rLS0+bmsKICAgICAgICAgICAgICArCgkgICAgICArLS0+bmsKICovCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwIDB4Njk3MiAqLwogICAgV09SRAlucl9saTsJCS8qIDB4MDIgbnVtYmVyIG9mZiBvZmZzZXRzICovCiAgICBEV09SRAlvZmZfbGlbMV07CS8qIDB4MDQgcG9pbnRzIHRvIGxpICovCn0gbnRfcmk7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAndmsnICovCiAgICBXT1JECW5hbV9sZW47CiAgICBEV09SRAlkYXRhX2xlbjsKICAgIERXT1JECWRhdGFfb2ZmOwogICAgRFdPUkQJdHlwZTsKICAgIFdPUkQJZmxhZzsKICAgIFdPUkQJdWsxOwogICAgY2hhcgluYW1lWzFdOwp9IG50X3ZrOwoKLyoKICogZ2V0cyBhIHZhbHVlCiAqCiAqIHZrLT5mbGFnOgogKiAgMCB2YWx1ZSBpcyBhIGRlZmF1bHQgdmFsdWUKICogIDEgdGhlIHZhbHVlIGhhcyBhIG5hbWUKICoKICogdmstPmRhdGFfbGVuCiAqICBsZW4gb2YgdGhlIHdob2xlIGRhdGEgYmxvY2sKICogIC0gcmVnX3N6ICh1bmljb2RlKQogKiAgICBieXRlcyBpbmNsdWRpbmcgdGhlIHRlcm1pbmF0aW5nIFwwID0gMioobnVtYmVyX29mX2NoYXJzKzEpCiAqICAtIHJlZ19kd29yZCwgcmVnX2JpbmFyeToKICogICAgaWYgaGlnaGVzdCBiaXQgb2YgZGF0YV9sZW4gaXMgc2V0IGRhdGFfb2ZmIGNvbnRhaW5zIHRoZSB2YWx1ZQogKi8Kc3RhdGljIGludCBfbnRfZHVtcF92ayhMUFNUUiBrZXlfbmFtZSwgY2hhciAqYmFzZSwgbnRfdmsgKnZrLEZJTEUgKmYpCnsKICAgIEJZVEUgKnBkYXRhID0gKEJZVEUgKikoYmFzZSt2ay0+ZGF0YV9vZmYrNCk7IC8qIHN0YXJ0IG9mIGRhdGEgKi8KICAgIHN0cnVjdCBrZXlfdmFsdWUgdmFsdWU7CgogICAgaWYgKHZrLT5pZCAhPSBOVF9SRUdfVkFMVUVfQkxPQ0tfSUQpIHsKICAgICAgICBFUlIoInVua25vd24gYmxvY2sgZm91bmQgKDB4JTA0eCksIHBsZWFzZSByZXBvcnQhXG4iLCB2ay0+aWQpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICB2YWx1ZS5uYW1lVyA9IF9zdHJkdXBuQXRvVyh2ay0+bmFtZSx2ay0+bmFtX2xlbik7CiAgICB2YWx1ZS50eXBlID0gdmstPnR5cGU7CiAgICB2YWx1ZS5sZW4gPSAodmstPmRhdGFfbGVuICYgMHg3ZmZmZmZmZik7CiAgICB2YWx1ZS5kYXRhID0gKHZrLT5kYXRhX2xlbiAmIDB4ODAwMDAwMDApID8gKExQQllURSkmKHZrLT5kYXRhX29mZik6IHBkYXRhOwoKICAgIF9kdW1wX3ZhbHVlKCZ2YWx1ZSxmKTsKICAgIGZyZWUodmFsdWUubmFtZVcpOwoKICAgIHJldHVybiBUUlVFOwp9CgovKiBpdCdzIGNhbGxlZCBmcm9tIF9udF9kdW1wX2xmKCkgKi8Kc3RhdGljIGludCBfbnRfZHVtcF9uayhMUFNUUiBrZXlfbmFtZSxjaGFyICpiYXNlLG50X25rICpuayxGSUxFICpmLGludCBsZXZlbCk7CgovKgogKiBnZXQgdGhlIHN1YmtleXMKICoKICogdGhpcyBzdHJ1Y3R1cmUgY29udGFpbnMgdGhlIGhhc2ggb2YgYSBrZXluYW1lIGFuZCBwb2ludHMgdG8gYWxsCiAqIHN1YmtleXMKICoKICogZXhjZXB0aW9uOiBpZiB0aGUgaWQgaXMgJ2lsJyB0aGVyZSBhcmUgbm8gaGFzaCB2YWx1ZXMgYW5kIGV2ZXJ5IAogKiBkd29yZCBpcyBhIG9mZnNldAogKi8Kc3RhdGljIGludCBfbnRfZHVtcF9sZihMUFNUUiBrZXlfbmFtZSwgY2hhciAqYmFzZSwgaW50IHN1YmtleXMsIG50X2xmICpsZiwgRklMRSAqZiwgaW50IGxldmVsKQp7CiAgICBpbnQgaTsKICAgIAogICAgaWYgKGxmLT5pZCA9PSBOVF9SRUdfSEFTSF9CTE9DS19JRCkgewogICAgICAgIGlmIChzdWJrZXlzICE9IGxmLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKICAgIAogICAgICAgIGZvciAoaT0wOyBpPGxmLT5ucl9rZXlzOyBpKyspIAogICAgICAgICAgICBpZiAoIV9udF9kdW1wX25rKGtleV9uYW1lLCBiYXNlLCAobnRfbmsqKShiYXNlK2xmLT5oYXNoX3JlY1tpXS5vZmZfbmsrNCksIGYsIGxldmVsKSkgZ290byBlcnJvcjsKICAgIH0gZWxzZSBpZiAobGYtPmlkID09IE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQpIHsKICAgICAgICBudF9saSAqIGxpID0gKG50X2xpKilsZjsKICAgICAgICBpZiAoc3Via2V5cyAhPSBsaS0+bnJfa2V5cykgZ290byBlcnJvcjE7CgogICAgICAgIGZvciAoaT0wOyBpPGxpLT5ucl9rZXlzOyBpKyspCiAgICAgICAgICAgIGlmICghX250X2R1bXBfbmsoa2V5X25hbWUsIGJhc2UsIChudF9uayopKGJhc2UrbGktPm9mZl9ua1tpXSs0KSwgZiwgbGV2ZWwpKSBnb3RvIGVycm9yOwogICAgfSBlbHNlIGlmIChsZi0+aWQgPT0gTlRfUkVHX1JJX0JMT0NLX0lEKSB7ICAvKiByaSAqLwogICAgICAgIG50X3JpICogcmkgPSAobnRfcmkqKWxmOwogICAgICAgIGludCBsaV9zdWJrZXlzID0gMDsKCiAgICAgICAgLyogY291bnQgYWxsIHN1YmtleXMgKi8KICAgICAgICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykgewogICAgICAgICAgICBudF9saSAqIGxpID0gKG50X2xpKikoYmFzZStyaS0+b2ZmX2xpW2ldKzQpOwogICAgICAgICAgICBpZihsaS0+aWQgIT0gTlRfUkVHX05PSEFTSF9CTE9DS19JRCkgZ290byBlcnJvcjI7CiAgICAgICAgICAgIGxpX3N1YmtleXMgKz0gbGktPm5yX2tleXM7CiAgICAgICAgfQoKICAgICAgICAvKiBjaGVjayBudW1iZXIgKi8KICAgICAgICBpZiAoc3Via2V5cyAhPSBsaV9zdWJrZXlzKSBnb3RvIGVycm9yMTsKCiAgICAgICAgLyogbG9vcCB0aHJvdWdoIHRoZSBrZXlzICovCiAgICAgICAgZm9yIChpPTA7IGk8cmktPm5yX2xpOyBpKyspIHsKICAgICAgICAgICAgbnRfbGkgKmxpID0gKG50X2xpKikoYmFzZStyaS0+b2ZmX2xpW2ldKzQpOwogICAgICAgICAgICBpZiAoIV9udF9kdW1wX2xmKGtleV9uYW1lLCBiYXNlLCBsaS0+bnJfa2V5cywgKG50X2xmKilsaSwgZiwgbGV2ZWwpKSBnb3RvIGVycm9yOwogICAgICAgIH0KICAgIH0gZWxzZSBnb3RvIGVycm9yMjsKCiAgICByZXR1cm4gVFJVRTsKCmVycm9yMjoKICAgIEVSUigidW5rbm93biBub2RlIGlkIDB4JTA0eCwgcGxlYXNlIHJlcG9ydCFcbiIsIGxmLT5pZCk7CiAgICByZXR1cm4gVFJVRTsKCmVycm9yMToKICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISAoaW5jb25zaXN0ZW50IG51bWJlciBvZiBzdWJrZXlzKVxuIik7CiAgICByZXR1cm4gRkFMU0U7CgplcnJvcjoKICAgIEVSUigiZXJyb3IgcmVhZGluZyBsZiBibG9ja1xuIik7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qIF9udF9kdW1wX25rIFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfbnRfZHVtcF9uayhMUFNUUiBrZXlfbmFtZSxjaGFyICpiYXNlLG50X25rICpuayxGSUxFICpmLGludCBsZXZlbCkKewogICAgdW5zaWduZWQgaW50IG47CiAgICBEV09SRCAqdmw7CiAgICBMUFNUUiBuZXdfa2V5X25hbWUgPSBOVUxMOwoKCiAgICBpZiAobmstPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5rbm93biBub2RlIGlkIDB4JTA0eCwgcGxlYXNlIHJlcG9ydCFcbiIsIG5rLT5TdWJCbG9ja0lkKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKChuay0+VHlwZSE9TlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpICYmICgoKG50X25rKikoYmFzZStuay0+cGFyZW50X29mZis0KSktPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkpIHsKICAgICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCFcbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiBjcmVhdGUgdGhlIG5ldyBrZXkgKi8KICAgIGlmIChsZXZlbCA8PSAwKSB7CiAgICAgICAgLyogY3JlYXRlIG5ldyBzdWJrZXkgbmFtZSAqLwogICAgICAgIG5ld19rZXlfbmFtZSA9IF9zdHJkdXBuQShrZXlfbmFtZSxzdHJsZW4oa2V5X25hbWUpK25rLT5uYW1lX2xlbisxKTsKICAgICAgICBpZiAoc3RyY21wKG5ld19rZXlfbmFtZSwiIikgIT0gMCkgc3RyY2F0KG5ld19rZXlfbmFtZSwiXFwiKTsKICAgICAgICBzdHJuY2F0KG5ld19rZXlfbmFtZSxuay0+bmFtZSxuay0+bmFtZV9sZW4pOwoKICAgICAgICAvKiB3cml0ZSB0aGUga2V5IHBhdGggKHNvbWV0aGluZyBsaWtlIFtTb2Z0d2FyZVxcTWljcm9zb2Z0XFwuLl0pIG9ubHkgaWY6IAogICAgICAgICAgIDEpIGtleSBoYXMgc29tZSB2YWx1ZXMKICAgICAgICAgICAyKSBrZXkgaGFzIG5vIHZhbHVlcyBhbmQgbm8gc3Via2V5cwogICAgICAgICovCiAgICAgICAgaWYgKG5rLT5ucl92YWx1ZXMgPiAwKSB7CiAgICAgICAgICAgIC8qIHRoZXJlIGFyZSBzb21lIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KICAgICAgICBpZiAoKG5rLT5ucl9zdWJrZXlzID09IDApICYmIChuay0+bnJfdmFsdWVzID09IDApKSB7CiAgICAgICAgICAgIC8qIG5vIHN1YmtleXMgYW5kIG5vIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KCiAgICAgICAgLyogbG9vcCB0cm91Z2ggdGhlIHZhbHVlIGxpc3QgKi8KICAgICAgICB2bCA9IChEV09SRCAqKShiYXNlK25rLT52YWx1ZWxpc3Rfb2ZmKzQpOwogICAgICAgIGZvciAobj0wOyBuPG5rLT5ucl92YWx1ZXM7IG4rKykgewogICAgICAgICAgICBudF92ayAqIHZrID0gKG50X3ZrKikoYmFzZSt2bFtuXSs0KTsKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF92ayhuZXdfa2V5X25hbWUsIGJhc2UsIHZrLCBmKSkgewogICAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSBlbHNlIG5ld19rZXlfbmFtZSA9IF9zdHJkdXBuQShrZXlfbmFtZSxzdHJsZW4oa2V5X25hbWUpKTsKCiAgICAvKiBsb29wIHRocm91Z2ggdGhlIHN1YmtleXMgKi8KICAgIGlmIChuay0+bnJfc3Via2V5cykgewogICAgICAgIG50X2xmICpsZiA9IChudF9sZiopKGJhc2UrbmstPmxmX29mZis0KTsKICAgICAgICBpZiAoIV9udF9kdW1wX2xmKG5ld19rZXlfbmFtZSwgYmFzZSwgbmstPm5yX3N1YmtleXMsIGxmLCBmLCBsZXZlbC0xKSkgewogICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qIGVuZCBudCBsb2FkZXIgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zZXRfcmVnaXN0cnlfbGV2ZWxzIFtJbnRlcm5hbF0KICoKICogc2V0IGxldmVsIHRvIDAgZm9yIGxvYWRpbmcgc3lzdGVtIGZpbGVzCiAqIHNldCBsZXZlbCB0byAxIGZvciBsb2FkaW5nIHVzZXIgZmlsZXMKICovCnN0YXRpYyB2b2lkIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKGludCBsZXZlbCxpbnQgc2F2aW5nLGludCBwZXJpb2QpCnsKICAgIFNFUlZFUl9TVEFSVF9SRVEoIHNldF9yZWdpc3RyeV9sZXZlbHMgKQogICAgewoJcmVxLT5jdXJyZW50ID0gbGV2ZWw7CglyZXEtPnNhdmluZyAgPSBzYXZpbmc7CiAgICAgICAgcmVxLT5wZXJpb2QgID0gcGVyaW9kOwogICAgICAgIFNFUlZFUl9DQUxMKCk7CiAgICB9CiAgICBTRVJWRVJfRU5EX1JFUTsKfQoKLyogX3NhdmVfYXRfZXhpdCBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9zYXZlX2F0X2V4aXQoSEtFWSBoa2V5LExQQ1NUUiBwYXRoKQp7CiAgICBMUENTVFIgY29uZmRpciA9IGdldF9jb25maWdfZGlyKCk7CiAgICBzaXplX3QgbGVuID0gc3RybGVuKGNvbmZkaXIpICsgc3RybGVuKHBhdGgpICsgMjsKCiAgICBpZiAobGVuID4gUkVRVUVTVF9NQVhfVkFSX1NJWkUpIHsKICAgICAgICBFUlIoICJjb25maWcgZGlyICclcycgdG9vIGxvbmdcbiIsIGNvbmZkaXIgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBTRVJWRVJfU1RBUlRfVkFSX1JFUSggc2F2ZV9yZWdpc3RyeV9hdGV4aXQsIGxlbiApCiAgICB7CiAgICAgICAgc3ByaW50Ziggc2VydmVyX2RhdGFfcHRyKHJlcSksICIlcy8lcyIsIGNvbmZkaXIsIHBhdGggKTsKICAgICAgICByZXEtPmhrZXkgPSBoa2V5OwogICAgICAgIFNFUlZFUl9DQUxMKCk7CiAgICB9CiAgICBTRVJWRVJfRU5EX1ZBUl9SRVE7Cn0KCi8qIGNvbmZpZ3VyZSBzYXZlIGZpbGVzIGFuZCBzdGFydCB0aGUgcGVyaW9kaWMgc2F2aW5nIHRpbWVyIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2luaXRfcmVnaXN0cnlfc2F2aW5nKCBIS0VZIGhrZXlfdXNlcnNfZGVmYXVsdCApCnsKICAgIGludCBhbGw7CiAgICBpbnQgcGVyaW9kOwoKICAgIGFsbCAgPSBQUk9GSUxFX0dldFdpbmVJbmlCb29sKCJyZWdpc3RyeSIsIlNhdmVPbmx5VXBkYXRlZEtleXMiLDEpOwogICAgcGVyaW9kID0gUFJPRklMRV9HZXRXaW5lSW5pSW50KCJyZWdpc3RyeSIsIlBlcmlvZGljU2F2ZSIsMCk7CgogICAgLyogc2V0IHNhdmluZyBsZXZlbCAoMCBmb3Igc2F2aW5nIGV2ZXJ5dGhpbmcsIDEgZm9yIHNhdmluZyBvbmx5IG1vZGlmaWVkIGtleXMpICovCiAgICBfc2V0X3JlZ2lzdHJ5X2xldmVscygxLCFhbGwscGVyaW9kKjEwMDApOwoKICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sKCJyZWdpc3RyeSIsIldyaXRldG9Ib21lUmVnaXN0cnlGaWxlcyIsMSkpCiAgICB7CiAgICAgICAgX3NhdmVfYXRfZXhpdChIS0VZX0NVUlJFTlRfVVNFUixTQVZFX0xPQ0FMX1JFR0JSQU5DSF9DVVJSRU5UX1VTRVIgKTsKICAgICAgICBfc2F2ZV9hdF9leGl0KEhLRVlfTE9DQUxfTUFDSElORSxTQVZFX0xPQ0FMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FKTsKICAgICAgICBfc2F2ZV9hdF9leGl0KGhrZXlfdXNlcnNfZGVmYXVsdCxTQVZFX0xPQ0FMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQpOwogICAgfQoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzIFtJbnRlcm5hbF0KICogUmVnaXN0cnkgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBzb21lIGRlZmF1bHQga2V5cy4gCiAqLwpzdGF0aWMgdm9pZCBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzKHZvaWQpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJVFJBQ0UoIih2b2lkKVxuIik7CgoJUmVnQ3JlYXRlS2V5QShIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXhBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3dzIE5UXFxDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50QnVpbGROdW1iZXIKCSAqCQkJCQkJQ3VycmVudFR5cGUKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE93bmVyCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPcmdhbml6YXRpb24KCSAqCgkgKi8KCS8qIFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTTk1QXFxQYXJhbWV0ZXJzXFxSRkMxMTU2QWdlbnQKCSAqIAkJCQkJc3RyaW5nCVN5c0NvbnRhY3QKCSAqIAkJCQkJc3RyaW5nCVN5c0xvY2F0aW9uCgkgKiAJCQkJCQlTeXNTZXJ2aWNlcwoJICovCglpZiAoLTEhPWdldGhvc3RuYW1lKGJ1ZiwyMDApKSB7CgkJUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXENvbnRyb2xcXENvbXB1dGVyTmFtZVxcQ29tcHV0ZXJOYW1lIiwmaGtleSk7CgkJUmVnU2V0VmFsdWVFeEEoaGtleSwiQ29tcHV0ZXJOYW1lIiwwLFJFR19TWixidWYsc3RybGVuKGJ1ZikrMSk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9CgogICAgICAgIFJlZ0NyZWF0ZUtleUEoSEtFWV9VU0VSUywiLkRlZmF1bHQiLCZoa2V5KTsKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKfQoKI2RlZmluZSBSRUdfRE9OVExPQUQgLTEKI2RlZmluZSBSRUdfV0lOMzEgICAgIDAKI2RlZmluZSBSRUdfV0lOOTUgICAgIDEKI2RlZmluZSBSRUdfV0lOTlQgICAgIDIKCi8qIHJldHVybiB0aGUgdHlwZSBvZiBuYXRpdmUgcmVnaXN0cnkgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9nZXRfcmVnX3R5cGUodm9pZCkKewogICAgY2hhciB3aW5kaXJbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBjaGFyIHRtcFtNQVhfUEFUSE5BTUVfTEVOXTsKICAgIGludCByZXQgPSBSRUdfV0lOMzE7CgogICAgR2V0V2luZG93c0RpcmVjdG9yeUEod2luZGlyLE1BWF9QQVRITkFNRV9MRU4pOwoKICAgIC8qIHRlc3QgJXdpbmRpciUvc3lzdGVtMzIvY29uZmlnL3N5c3RlbSAtLT4gd2lubnQgKi8KICAgIHN0cmNweSh0bXAsIHdpbmRpcik7CiAgICBzdHJuY2F0KHRtcCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc3lzdGVtIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbih0bXApIC0gMSk7CiAgICBpZihHZXRGaWxlQXR0cmlidXRlc0EodG1wKSAhPSAoRFdPUkQpLTEpIHsKICAgICAgcmV0ID0gUkVHX1dJTk5UOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0uZGF0IC0tPiB3aW45NSAqLwogICAgICBzdHJjcHkodG1wLCB3aW5kaXIpOwogICAgICBzdHJuY2F0KHRtcCwgIlxcc3lzdGVtLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4odG1wKSAtIDEpOwogICAgICBpZihHZXRGaWxlQXR0cmlidXRlc0EodG1wKSAhPSAoRFdPUkQpLTEpIHsKICAgICAgICByZXQgPSBSRUdfV0lOOTU7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoKHJldCA9PSBSRUdfV0lOTlQpICYmICghUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiV2luZSIsICJQcm9maWxlIiwgIiIsIHRtcCwgTUFYX1BBVEhOQU1FX0xFTikpKSB7CiAgICAgICBNRVNTQUdFKCJXaGVuIHlvdSBhcmUgcnVubmluZyB3aXRoIGEgbmF0aXZlIE5UIGRpcmVjdG9yeSBzcGVjaWZ5XG4iKTsKICAgICAgIE1FU1NBR0UoIidQcm9maWxlPTxwcm9maWxlZGlyZWN0b3J5Picgb3IgZGlzYWJsZSBsb2FkaW5nIG9mIFdpbmRvd3NcbiIpOwogICAgICAgTUVTU0FHRSgicmVnaXN0cnkgKExvYWRXaW5kb3dzUmVnaXN0cnlGaWxlcz1OKVxuIik7CiAgICAgICByZXQgPSBSRUdfRE9OVExPQUQ7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKI2RlZmluZSBXSU5FX1JFR19WRVJfRVJST1IgIC0xCiNkZWZpbmUgV0lORV9SRUdfVkVSXzEgICAgICAgMAojZGVmaW5lIFdJTkVfUkVHX1ZFUl8yICAgICAgIDEKI2RlZmluZSBXSU5FX1JFR19WRVJfT0xEICAgICAyCiNkZWZpbmUgV0lORV9SRUdfVkVSX1VOS05PV04gMwoKLyogcmV0dXJuIHRoZSB2ZXJzaW9uIG9mIHdpbmUgcmVnaXN0cnkgZmlsZSBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX2dldF93aW5lX3JlZ2lzdHJ5X2ZpbGVfZm9ybWF0X3ZlcnNpb24oTFBDU1RSIGZuKQp7CiAgICBGSUxFICpmOwogICAgY2hhciB0bXBbNTBdOwogICAgaW50IHZlcjsKCiAgICBpZiAoKGY9Zm9wZW4oZm4sInJ0IikpID09IE5VTEwpIHsKICAgICAgICBXQVJOKCJDb3VsZG4ndCBvcGVuICVzIGZvciByZWFkaW5nOiAlc1xuIixmbixzdHJlcnJvcihlcnJubykpOwogICAgICAgIHJldHVybiBXSU5FX1JFR19WRVJfRVJST1I7CiAgICB9CgogICAgaWYgKGZnZXRzKHRtcCw1MCxmKSA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiRXJyb3IgcmVhZGluZyAlczogJXNcbiIsZm4sc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICBmY2xvc2UoZik7CiAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl9FUlJPUjsKICAgIH0KICAgIGZjbG9zZShmKTsKCiAgICBpZiAoc3NjYW5mKHRtcCwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIiwmdmVyKSAhPSAxKSByZXR1cm4gV0lORV9SRUdfVkVSX1VOS05PV047CiAgICBzd2l0Y2ggKHZlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl8xOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBXSU5FX1JFR19WRVJfMjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl9VTktOT1dOOwogICAgfQp9CgovKiBsb2FkIHRoZSByZWdpc3RyeSBmaWxlIGluIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgbG9hZF93aW5lX3JlZ2lzdHJ5KEhLRVkgaGtleSxMUENTVFIgZm4pCnsKICAgIGludCBmaWxlX2Zvcm1hdDsKCiAgICBmaWxlX2Zvcm1hdCA9IF9nZXRfd2luZV9yZWdpc3RyeV9maWxlX2Zvcm1hdF92ZXJzaW9uKGZuKTsKICAgIHN3aXRjaCAoZmlsZV9mb3JtYXQpIHsKCiAgICAgICAgY2FzZSBXSU5FX1JFR19WRVJfMToKICAgICAgICAgICAgV0FSTigiVW5hYmxlIHRvIGxvYWQgcmVnaXN0cnkgZmlsZSAlczogb2xkIGZvcm1hdCB3aGljaCBpcyBubyBsb25nZXIgc3VwcG9ydGVkLlxuIixmbik7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVfUkVHX1ZFUl8yOiB7CiAgICAgICAgICAgIEhBTkRMRSBmaWxlOwogICAgICAgICAgICBpZiAoKGZpbGUgPSBGSUxFX0NyZWF0ZUZpbGUoIGZuLCBHRU5FUklDX1JFQUQsIDAsIE5VTEwsIE9QRU5fRVhJU1RJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFX0FUVFJJQlVURV9OT1JNQUwsIDAsIFRSVUUgKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNFUlZFUl9TVEFSVF9SRVEoIGxvYWRfcmVnaXN0cnkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlcS0+aGtleSAgICA9IGhrZXk7CiAgICAgICAgICAgICAgICAgICAgcmVxLT5maWxlICAgID0gZmlsZTsKICAgICAgICAgICAgICAgICAgICBTRVJWRVJfQ0FMTCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgU0VSVkVSX0VORF9SRVE7CiAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggZmlsZSApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBXSU5FX1JFR19WRVJfVU5LTk9XTjoKICAgICAgICAgICAgV0FSTigiVW5hYmxlIHRvIGxvYWQgcmVnaXN0cnkgZmlsZSAlczogdW5rbm93biBmb3JtYXQuXG4iLGZuKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORV9SRUdfVkVSX0VSUk9SOgogICAgICAgICAgICBicmVhazsKICAgIH0KfQoKLyogZ2VuZXJhdGUgYW5kIHJldHVybiB0aGUgbmFtZSBvZiB0aGUgdG1wIGZpbGUgYW5kIGFzc29jaWF0ZWQgc3RyZWFtIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9nZXRfdG1wX2ZuKEZJTEUgKipmKQp7CiAgICBMUFNUUiByZXQ7CiAgICBpbnQgdG1wX2ZkLGNvdW50OwoKICAgIHJldCA9IF94bWFsbG9jKDUwKTsKICAgIGZvciAoY291bnQgPSAwOzspIHsKICAgICAgICBzcHJpbnRmKHJldCwiL3RtcC9yZWclbHglMDR4LnRtcCIsKGxvbmcpZ2V0cGlkKCksY291bnQrKyk7CiAgICAgICAgaWYgKCh0bXBfZmQgPSBvcGVuKHJldCxPX0NSRUFUIHwgT19FWENMIHwgT19XUk9OTFksMDY2NikpICE9IC0xKSBicmVhazsKICAgICAgICBpZiAoZXJybm8gIT0gRUVYSVNUKSB7CiAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBlcnJvciB3aGlsZSBvcGVuKCkgY2FsbDogJXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICAgICAgZnJlZShyZXQpOwogICAgICAgICAgICAqZiA9IE5VTEw7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoKCpmID0gZmRvcGVuKHRtcF9mZCwidyIpKSA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJVbmV4cGVjdGVkIGVycm9yIHdoaWxlIGZkb3BlbigpIGNhbGw6ICVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgY2xvc2UodG1wX2ZkKTsKICAgICAgICBmcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCB3aW45NSBuYXRpdmUgcmVnaXN0cnkgZmlsZSB0byB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfY29udmVydF93aW45NV9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChMUENTVFIgZm4saW50IGxldmVsKQp7CiAgICBpbnQgZmQ7CiAgICBGSUxFICpmOwogICAgRE9TX0ZVTExfTkFNRSBmdWxsX25hbWU7CiAgICB2b2lkICpiYXNlOwogICAgTFBTVFIgcmV0ID0gTlVMTDsKICAgIHN0cnVjdCBzdGF0IHN0OwoKICAgIF93OTVjcmVnICpjcmVnOwogICAgX3c5NXJna24gKnJna247CiAgICBfdzk1ZGtlICpka2UsICpyb290X2RrZTsKCiAgICBpZiAoIURPU0ZTX0dldEZ1bGxOYW1lKCBmbiwgMCwgJmZ1bGxfbmFtZSApKSByZXR1cm4gTlVMTDsKCiAgICAvKiBtYXAgdGhlIHJlZ2lzdHJ5IGludG8gdGhlIG1lbW9yeSAqLwogICAgaWYgKChmZCA9IG9wZW4oZnVsbF9uYW1lLmxvbmdfbmFtZSwgT19SRE9OTFkgfCBPX05PTkJMT0NLKSkgPT0gLTEpIHJldHVybiBOVUxMOwogICAgaWYgKChmc3RhdChmZCwgJnN0KSA9PSAtMSkpIGdvdG8gZXJyb3IxOwogICAgaWYgKCFzdC5zdF9zaXplKSBnb3RvIGVycm9yMTsKICAgIGlmICgoYmFzZSA9IG1tYXAoTlVMTCwgc3Quc3Rfc2l6ZSwgUFJPVF9SRUFELCBNQVBfUFJJVkFURSwgZmQsIDApKSA9PSBNQVBfRkFJTEVEKSBnb3RvIGVycm9yMTsKCiAgICAvKiBjb250cm9sIHNpZ25hdHVyZSAqLwogICAgaWYgKCooTFBEV09SRCliYXNlICE9IFc5NV9SRUdfQ1JFR19JRCkgewogICAgICAgIEVSUigidW5hYmxlIHRvIGxvYWQgbmF0aXZlIHdpbjk1IHJlZ2lzdHJ5IGZpbGUgJXM6IHVua25vd24gc2lnbmF0dXJlLlxuIixmbik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBjcmVnID0gYmFzZTsKICAgIC8qIGxvYWQgdGhlIGhlYWRlciAocmdrbikgKi8KICAgIHJna24gPSAoX3c5NXJna24qKShjcmVnICsgMSk7CiAgICBpZiAocmdrbi0+aWQgIT0gVzk1X1JFR19SR0tOX0lEKSB7CiAgICAgICAgRVJSKCJzZWNvbmQgSUZGIGhlYWRlciBub3QgUkdLTiwgYnV0ICVseFxuIiwgcmdrbi0+aWQpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+cm9vdF9vZmYgIT0gMHgyMCkgewogICAgICAgIEVSUigicmdrbi0+cm9vdF9vZmYgbm90IDB4MjAsIHBsZWFzZSByZXBvcnQgIVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5sYXN0X2RrZSA+IHJna24tPnNpemUpCiAgICB7CiAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISBsYXN0X2RrZSA+IHNpemUhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIC8qIHZlcmlmeSBsYXN0IGRrZSAqLwogICAgZGtlID0gKF93OTVka2UqKSgoY2hhciopcmdrbiArIHJna24tPmxhc3RfZGtlKTsKICAgIGlmIChka2UtPngxICE9IDB4ODAwMDAwMDApCiAgICB7IC8qIHdyb25nIG1hZ2ljICovCiAgICAgIEVSUigibGFzdCBka2UgaW52YWxpZCAhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5zaXplID4gY3JlZy0+cmdkYl9vZmYpCiAgICB7CiAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISByZ2tuIHNpemUgPiByZ2RiX29mZiAhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIHJvb3RfZGtlID0gKF93OTVka2UqKSgoY2hhciopcmdrbiArIHJna24tPnJvb3Rfb2ZmKTsKICAgIGlmICggKHJvb3RfZGtlLT5wcmV2bHZsICE9IDB4ZmZmZmZmZmYpIHx8IChyb290X2RrZS0+bmV4dCAhPSAweGZmZmZmZmZmKSApCiAgICB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGludmFsaWQgcm9vdCBka2UgIVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAoIChyZXQgPSBfZ2V0X3RtcF9mbigmZikpID09IE5VTEwpIGdvdG8gZXJyb3I7CiAgICBmcHJpbnRmKGYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAyIik7CiAgICBfdzk1X2R1bXBfZGtlKCIiLGNyZWcscmdrbixyb290X2RrZSxmLGxldmVsKTsKICAgIGZjbG9zZShmKTsKCmVycm9yOgogICAgaWYocmV0ID09IE5VTEwpIHsKICAgICAgICBFUlIoIlVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW45NSByZWdpc3RyeSBmaWxlICVzLlxuIixmbik7CiAgICAgICAgRVJSKCJQbGVhc2UgcmVwb3J0IHRvIGEubW9ockBtYWlsdG8uZGUuXG4iKTsKICAgICAgICBFUlIoIk1ha2UgYSBiYWNrdXAgb2YgdGhlIGZpbGUsIHJ1biBhIGdvb2QgcmVnIGNsZWFuZXIgcHJvZ3JhbSBhbmQgdHJ5IGFnYWluIVxuIik7CiAgICB9CgogICAgbXVubWFwKGJhc2UsIHN0LnN0X3NpemUpOwplcnJvcjE6CiAgICBjbG9zZShmZCk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IHdpbm50IG5hdGl2ZSByZWdpc3RyeSBmaWxlIHRvIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9jb252ZXJ0X3dpbm50X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KExQQ1NUUiBmbixpbnQgbGV2ZWwpCnsKICAgIGludCBmZDsKICAgIEZJTEUgKmY7CiAgICBET1NfRlVMTF9OQU1FIGZ1bGxfbmFtZTsKICAgIHZvaWQgKmJhc2U7CiAgICBMUFNUUiByZXQgPSBOVUxMOwogICAgc3RydWN0IHN0YXQgc3Q7CgogICAgbnRfcmVnZiAqcmVnZjsKICAgIG50X2hiaW4gKmhiaW47CiAgICBudF9oYmluX3N1YiAqaGJpbl9zdWI7CiAgICBudF9uayAqbms7CgogICAgaWYgKCFET1NGU19HZXRGdWxsTmFtZSggZm4sIDAsICZmdWxsX25hbWUgKSkgcmV0dXJuIE5VTEw7CgogICAgLyogbWFwIHRoZSByZWdpc3RyeSBpbnRvIHRoZSBtZW1vcnkgKi8KICAgIGlmICgoZmQgPSBvcGVuKGZ1bGxfbmFtZS5sb25nX25hbWUsIE9fUkRPTkxZIHwgT19OT05CTE9DSykpID09IC0xKSByZXR1cm4gTlVMTDsKICAgIGlmICgoZnN0YXQoZmQsICZzdCkgPT0gLTEpKSBnb3RvIGVycm9yMTsKICAgIGlmICghc3Quc3Rfc2l6ZSkgZ290byBlcnJvcjE7CiAgICBpZiAoKGJhc2UgPSBtbWFwKE5VTEwsIHN0LnN0X3NpemUsIFBST1RfUkVBRCwgTUFQX1BSSVZBVEUsIGZkLCAwKSkgPT0gTUFQX0ZBSUxFRCkgZ290byBlcnJvcjE7CgogICAgLyogY29udHJvbCBzaWduYXR1cmUgKi8KICAgIGlmICgqKExQRFdPUkQpYmFzZSAhPSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmFibGUgdG8gbG9hZCBuYXRpdmUgd2lubnQgcmVnaXN0cnkgZmlsZSAlczogdW5rbm93biBzaWduYXR1cmUuXG4iLGZuKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIHN0YXJ0IGJsb2NrICovCiAgICByZWdmID0gYmFzZTsKCiAgICAvKiBoYmluIGJsb2NrICovCiAgICBoYmluID0gKG50X2hiaW4qKSgoY2hhciopIGJhc2UgKyAweDEwMDApOwogICAgaWYgKGhiaW4tPmlkICE9IE5UX1JFR19QT09MX0JMT0NLX0lEKSB7CiAgICAgIEVSUiggImhiaW4gYmxvY2sgaW52YWxpZFxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogaGJpbl9zdWIgYmxvY2sgKi8KICAgIGhiaW5fc3ViID0gKG50X2hiaW5fc3ViKikmKGhiaW4tPmhiaW5fc3ViKTsKICAgIGlmICgoaGJpbl9zdWItPmRhdGFbMF0gIT0gJ24nKSB8fCAoaGJpbl9zdWItPmRhdGFbMV0gIT0gJ2snKSkgewogICAgICBFUlIoICJoYmluX3N1YiBibG9jayBpbnZhbGlkXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBuayBibG9jayAqLwogICAgbmsgPSAobnRfbmsqKSYoaGJpbl9zdWItPmRhdGFbMF0pOwogICAgaWYgKG5rLT5UeXBlICE9IE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKSB7CiAgICAgIEVSUiggInNwZWNpYWwgbmsgYmxvY2sgbm90IGZvdW5kXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAoIChyZXQgPSBfZ2V0X3RtcF9mbigmZikpID09IE5VTEwpIGdvdG8gZXJyb3I7CiAgICBmcHJpbnRmKGYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAyIik7CiAgICBfbnRfZHVtcF9uaygiIiwoY2hhciopYmFzZSsweDEwMDAsbmssZixsZXZlbCk7CiAgICBmY2xvc2UoZik7CgplcnJvcjoKICAgIG11bm1hcChiYXNlLHN0LnN0X3NpemUpOwplcnJvcjE6CiAgICBjbG9zZShmZCk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IG5hdGl2ZSByZWdpc3RyeSB0byB3aW5lIGZvcm1hdCBhbmQgbG9hZCBpdCB2aWEgc2VydmVyIGNhbGwgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkoTFBDU1RSIGZuLEhLRVkgaGtleSxpbnQgcmVnX3R5cGUsaW50IGxldmVsKQp7CiAgICBMUFNUUiB0bXAgPSBOVUxMOwoKICAgIHN3aXRjaCAocmVnX3R5cGUpIHsKICAgICAgICBjYXNlIFJFR19XSU5OVDoKICAgICAgICAgICAgLyogRklYTUU6IGZvbGxvd2luZyBmdW5jdGlvbiBkb2Vzbid0IHJlYWxseSBjb252ZXJ0IHlldCAqLwogICAgICAgICAgICB0bXAgPSBfY29udmVydF93aW5udF9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChmbixsZXZlbCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX1dJTjk1OgogICAgICAgICAgICB0bXAgPSBfY29udmVydF93aW45NV9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChmbixsZXZlbCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX1dJTjMxOgogICAgICAgICAgICBFUlIoIkRvbid0IGtub3cgaG93IHRvIGNvbnZlcnQgbmF0aXZlIDMuMSByZWdpc3RyeSB5ZXQuXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJVbmtub3duIHJlZ2lzdHJ5IGZvcm1hdCBwYXJhbWV0ZXIgKCVkKVxuIixyZWdfdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmICh0bXAgIT0gTlVMTCkgewogICAgICAgIGxvYWRfd2luZV9yZWdpc3RyeShoa2V5LHRtcCk7CiAgICAgICAgVFJBQ0UoIkZpbGUgJXMgc3VjY2Vzc2Z1bGx5IGNvbnZlcnRlZCB0byAlcyBhbmQgbG9hZGVkIHRvIHJlZ2lzdHJ5LlxuIixmbix0bXApOwogICAgICAgIHVubGluayh0bXApOwogICAgfQogICAgZWxzZSBXQVJOKCJVbmFibGUgdG8gY29udmVydCAlcyAoZG9lc24ndCBleGlzdD8pXG4iLGZuKTsKICAgIGZyZWUodG1wKTsKfQoKLyogbG9hZCBhbGwgbmF0aXZlIHdpbmRvd3MgcmVnaXN0cnkgZmlsZXMgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfbG9hZF93aW5kb3dzX3JlZ2lzdHJ5KCBIS0VZIGhrZXlfdXNlcnNfZGVmYXVsdCApCnsKICAgIGludCByZWdfdHlwZTsKICAgIGNoYXIgd2luZGlyW01BWF9QQVRITkFNRV9MRU5dOwogICAgY2hhciBwYXRoW01BWF9QQVRITkFNRV9MRU5dOwoKICAgIEdldFdpbmRvd3NEaXJlY3RvcnlBKHdpbmRpcixNQVhfUEFUSE5BTUVfTEVOKTsKCiAgICByZWdfdHlwZSA9IF9nZXRfcmVnX3R5cGUoKTsKICAgIHN3aXRjaCAocmVnX3R5cGUpIHsKICAgICAgICBjYXNlIFJFR19XSU5OVDogewogICAgICAgICAgICBIS0VZIGhrZXk7CgogICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIG50dXNlci5kYXQgKi8KICAgICAgICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggIldpbmUiLCAiUHJvZmlsZSIsICIiLCBwYXRoLCBNQVhfUEFUSE5BTUVfTEVOKSkgewogICAgICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcbnR1c2VyLmRhdCIpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9DVVJSRU5UX1VTRVIsUkVHX1dJTk5ULDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCiAgICAgICAgICAgIGlmIChoa2V5X3VzZXJzX2RlZmF1bHQpIHsKICAgICAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0zMlxcY29uZmlnXFxkZWZhdWx0Iik7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X3VzZXJzX2RlZmF1bHQsUkVHX1dJTk5ULDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAqIEZJWE1FCiAgICAgICAgICAgICogIG1hcCBITE1cU3lzdGVtXENvbnRyb2xTZXQwMDEgdG8gSExNXFN5c3RlbVxDdXJyZW50Q29udHJvbFNldAogICAgICAgICAgICAqLwoKICAgICAgICAgICAgaWYgKCFSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwgIlNZU1RFTSIsICZoa2V5KSkgewoJICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKCSAgICAgIHN0cmNhdChwYXRoLCJcXHN5c3RlbTMyXFxjb25maWdcXHN5c3RlbSIpOwogICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXksUkVHX1dJTk5ULDEpOwogICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCAiU09GVFdBUkUiLCAmaGtleSkpIHsKICAgICAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0zMlxcY29uZmlnXFxzb2Z0d2FyZSIpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleSxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc2FtIik7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLEhLRVlfTE9DQUxfTUFDSElORSxSRUdfV0lOTlQsMCk7CgogICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0zMlxcY29uZmlnXFxzZWN1cml0eSIpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0xPQ0FMX01BQ0hJTkUsUkVHX1dJTk5ULDApOwoKICAgICAgICAgICAgLyogdGhpcyBrZXkgaXMgZ2VuZXJhdGVkIHdoZW4gdGhlIG50LWNvcmUgYm9vdGVkIHN1Y2Nlc3NmdWxseSAqLwogICAgICAgICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXENsb25lIiwmaGtleSkpIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgUkVHX1dJTjk1OgogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkoImM6XFxzeXN0ZW0uMXN0IixIS0VZX0xPQ0FMX01BQ0hJTkUsUkVHX1dJTjk1LDApOwoKICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcc3lzdGVtLmRhdCIpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0xPQ0FMX01BQ0hJTkUsUkVHX1dJTjk1LDApOwoKICAgICAgICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZygiV2luZSIsIlByb2ZpbGUiLCIiLHBhdGgsTUFYX1BBVEhOQU1FX0xFTikpIHsKCSAgICAgICAgLyogdXNlciBzcGVjaWZpYyB1c2VyLmRhdCAqLwoJICAgICAgICBzdHJuY2F0KHBhdGgsICJcXHVzZXIuZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9DVVJSRU5UX1VTRVIsUkVHX1dJTjk1LDEpOwoKCSAgICAgICAgLyogZGVmYXVsdCB1c2VyLmRhdCAqLwoJICAgICAgICBpZiAoaGtleV91c2Vyc19kZWZhdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgICAgICAgICBzdHJjYXQocGF0aCwiXFx1c2VyLmRhdCIpOwogICAgICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfdXNlcnNfZGVmYXVsdCxSRUdfV0lOOTUsMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcdXNlci5kYXQiKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLEhLRVlfQ1VSUkVOVF9VU0VSLFJFR19XSU45NSwxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBSRUdfV0lOMzE6CiAgICAgICAgICAgIC8qIEZJWE1FOiBoZXJlIHdlIHNob3VsZCBjb252ZXJ0IHRvICoucmVnIGZpbGUgc3VwcG9ydGVkIGJ5IHNlcnZlciBhbmQgY2FsbCBSRVFfTE9BRF9SRUdJU1RSWSwgc2VlIFJFR19XSU45NSBjYXNlICovCiAgICAgICAgICAgIF93MzFfbG9hZHJlZygpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBSRUdfRE9OVExPQUQ6CiAgICAgICAgICAgIFRSQUNFKCJSRUdfRE9OVExPQURcbiIpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJzd2l0Y2g6IG5vIG1hdGNoICglZClcbiIscmVnX3R5cGUpOwogICAgICAgICAgICBicmVhazsKCiAgICB9Cn0KCi8qIGxvYWQgZ2xvYmFsIHJlZ2lzdHJ5IGZpbGVzIChzdG9yZWQgaW4gL2V0Yy93aW5lKSBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9sb2FkX2dsb2JhbF9yZWdpc3RyeSh2b2lkKQp7CiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICAvKiBMb2FkIHRoZSBnbG9iYWwgSEtVIGhpdmUgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyICovCiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoIEhLRVlfVVNFUlMsIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQgKTsKCiAgICAvKiBMb2FkIHRoZSBnbG9iYWwgbWFjaGluZSBkZWZhdWx0cyBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIgKi8KICAgIGxvYWRfd2luZV9yZWdpc3RyeSggSEtFWV9MT0NBTF9NQUNISU5FLCBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSApOwp9CgovKiBsb2FkIGhvbWUgcmVnaXN0cnkgZmlsZXMgKHN0b3JlZCBpbiB+Ly53aW5lKSBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9sb2FkX2hvbWVfcmVnaXN0cnkoIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgTFBDU1RSIGNvbmZkaXIgPSBnZXRfY29uZmlnX2RpcigpOwogICAgTFBTVFIgdG1wID0gX3htYWxsb2Moc3RybGVuKGNvbmZkaXIpKzIwKTsKCiAgICBzdHJjcHkodG1wLGNvbmZkaXIpOwogICAgc3RyY2F0KHRtcCwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUKTsKICAgIGxvYWRfd2luZV9yZWdpc3RyeShoa2V5X3VzZXJzX2RlZmF1bHQsdG1wKTsKCiAgICBzdHJjcHkodG1wLGNvbmZkaXIpOwogICAgc3RyY2F0KHRtcCwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfQ1VSUkVOVF9VU0VSKTsKICAgIGxvYWRfd2luZV9yZWdpc3RyeShIS0VZX0NVUlJFTlRfVVNFUix0bXApOwoKICAgIHN0cmNweSh0bXAsY29uZmRpcik7CiAgICBzdHJjYXQodG1wLCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FKTsKICAgIGxvYWRfd2luZV9yZWdpc3RyeShIS0VZX0xPQ0FMX01BQ0hJTkUsdG1wKTsKCiAgICBmcmVlKHRtcCk7Cn0KCi8qIGxvYWQgYWxsIHJlZ2lzdHJ5IChuYXRpdmUgYW5kIGdsb2JhbCBhbmQgaG9tZSkgKi8Kdm9pZCBTSEVMTF9Mb2FkUmVnaXN0cnkoIHZvaWQgKQp7CiAgICBIS0VZIGhrZXlfdXNlcnNfZGVmYXVsdDsKCiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICBpZiAoIUNMSUVOVF9Jc0Jvb3RUaHJlYWQoKSkgcmV0dXJuOyAgLyogYWxyZWFkeSBsb2FkZWQgKi8KCiAgICBpZiAoUmVnQ3JlYXRlS2V5QShIS0VZX1VTRVJTLCIuRGVmYXVsdCIsJmhrZXlfdXNlcnNfZGVmYXVsdCkpCiAgICB7CiAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIEhLRVlfVVNFUlMvLkRlZmF1bHRcbiIgKTsKICAgICAgICBFeGl0UHJvY2VzcygxKTsKICAgIH0KCiAgICBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzKCk7CiAgICBfc2V0X3JlZ2lzdHJ5X2xldmVscygwLDAsMCk7CiAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgiUmVnaXN0cnkiLCJMb2FkV2luZG93c1JlZ2lzdHJ5RmlsZXMiLDEpKQogICAgICAgIF9sb2FkX3dpbmRvd3NfcmVnaXN0cnkoIGhrZXlfdXNlcnNfZGVmYXVsdCApOwogICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woIlJlZ2lzdHJ5IiwiTG9hZEdsb2JhbFJlZ2lzdHJ5RmlsZXMiLDEpKQogICAgICAgIF9sb2FkX2dsb2JhbF9yZWdpc3RyeSgpOwogICAgX3NldF9yZWdpc3RyeV9sZXZlbHMoMSwwLDApOwogICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woIlJlZ2lzdHJ5IiwiTG9hZEhvbWVSZWdpc3RyeUZpbGVzIiwxKSkKICAgICAgICBfbG9hZF9ob21lX3JlZ2lzdHJ5KCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKICAgIF9pbml0X3JlZ2lzdHJ5X3NhdmluZyggaGtleV91c2Vyc19kZWZhdWx0ICk7CiAgICBSZWdDbG9zZUtleShoa2V5X3VzZXJzX2RlZmF1bHQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgQVBJIEZVTkNUSU9OUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdGbHVzaEtleSBbQURWQVBJMzIuQF0KICogSW1tZWRpYXRlbHkgd3JpdGVzIGtleSB0byByZWdpc3RyeS4KICogT25seSByZXR1cm5zIGFmdGVyIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiB0byBkaXNrLgogKgogKiBGSVhNRTogZG9lcyBpdCByZWFsbHkgd2FpdCB1bnRpbCBkYXRhIGlzIHdyaXR0ZW4gPwogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byB3cml0ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0ZsdXNoS2V5KCBIS0VZIGhrZXkgKQp7CiAgICBGSVhNRSggIigleCk6IHN0dWJcbiIsIGhrZXkgKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXlBIFtBRFZBUEkzMi5AXQogKi8KTE9ORyBXSU5BUEkgUmVnVW5Mb2FkS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXkgKQp7CiAgICBGSVhNRSgiKCV4LCVzKTogc3R1YlxuIixoa2V5LCBkZWJ1Z3N0cl9hKGxwU3ViS2V5KSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleVcgW0FEVkFQSTMyLkBdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgIFtJXSBIYW5kbGUgb2Yga2V5IHdoZXJlIHJlc3RvcmUgYmVnaW5zCiAqICAgIGxwRmlsZSAgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgY29udGFpbmluZyBzYXZlZCB0cmVlCiAqICAgIGR3RmxhZ3MgW0ldIE9wdGlvbmFsIGZsYWdzCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIFRSQUNFKCIoJXgsJXMsJWxkKVxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBJdCBzZWVtcyB0byBkbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscEZpbGUgfHwgISpscEZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIEZJWE1FKCIoJXgsJXMsJWxkKTogc3R1YlxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBDaGVjayBmb3IgZmlsZSBleGlzdGVuY2UgKi8KCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleUEgW0FEVkFQSTMyLkBdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgTFBXU1RSIGxwRmlsZVcgPSBIRUFQX3N0cmR1cEF0b1coIEdldFByb2Nlc3NIZWFwKCksIDAsIGxwRmlsZSApOwogICAgTE9ORyByZXQgPSBSZWdSZXN0b3JlS2V5VyggaGtleSwgbHBGaWxlVywgZHdGbGFncyApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxwRmlsZVcgKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1JlcGxhY2VLZXlBIFtBRFZBUEkzMi5AXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5LCBMUENTVFIgbHBOZXdGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBPbGRGaWxlICkKewogICAgRklYTUUoIigleCwlcywlcywlcyk6IHN0dWJcbiIsIGhrZXksIGRlYnVnc3RyX2EobHBTdWJLZXkpLAogICAgICAgICAgZGVidWdzdHJfYShscE5ld0ZpbGUpLGRlYnVnc3RyX2EobHBPbGRGaWxlKSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCgoKCgovKiAxNi1iaXQgZnVuY3Rpb25zICovCgovKiAwIGFuZCAxIGFyZSB2YWxpZCByb290a2V5cyBpbiB3aW4xNiBzaGVsbC5kbGwgYW5kIGFyZSB1c2VkIGJ5CiAqIHNvbWUgcHJvZ3JhbXMuIERvIG5vdCByZW1vdmUgdGhvc2UgY2FzZXMuIC1NTQogKi8Kc3RhdGljIGlubGluZSB2b2lkIGZpeF93aW4xNl9oa2V5KCBIS0VZICpoa2V5ICkKewogICAgaWYgKCpoa2V5ID09IDAgfHwgKmhrZXkgPT0gMSkgKmhrZXkgPSBIS0VZX0NMQVNTRVNfUk9PVDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRW51bUtleSAgIFtLRVJORUwuMjE2XQogKiAgICAgICAgICAgUmVnRW51bUtleSAgIFtTSEVMTC43XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXkxNiggSEtFWSBoa2V5LCBEV09SRCBpbmRleCwgTFBTVFIgbmFtZSwgRFdPUkQgbmFtZV9sZW4gKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdFbnVtS2V5QSggaGtleSwgaW5kZXgsIG5hbWUsIG5hbWVfbGVuICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ09wZW5LZXkgICBbS0VSTkVMLjIxN10KICogICAgICAgICAgIFJlZ09wZW5LZXkgICBbU0hFTEwuMV0KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQSEtFWSByZXRrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdPcGVuS2V5QSggaGtleSwgbmFtZSwgcmV0a2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0NyZWF0ZUtleSAgIFtLRVJORUwuMjE4XQogKiAgICAgICAgICAgUmVnQ3JlYXRlS2V5ICAgW1NIRUxMLjJdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQSEtFWSByZXRrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdDcmVhdGVLZXlBKCBoa2V5LCBuYW1lLCByZXRrZXkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRGVsZXRlS2V5ICAgW0tFUk5FTC4yMTldCiAqICAgICAgICAgICBSZWdEZWxldGVLZXkgICBbU0hFTEwuNF0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0RlbGV0ZUtleUEoIGhrZXksIG5hbWUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnQ2xvc2VLZXkgICBbS0VSTkVMLjIyMF0KICogICAgICAgICAgIFJlZ0Nsb3NlS2V5ICAgW1NIRUxMLjNdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ2xvc2VLZXkxNiggSEtFWSBoa2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnQ2xvc2VLZXkoIGhrZXkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnU2V0VmFsdWUgICBbS0VSTkVMLjIyMV0KICogICAgICAgICAgIFJlZ1NldFZhbHVlICAgW1NIRUxMLjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgRFdPUkQgdHlwZSwgTFBDU1RSIGRhdGEsIERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVBKCBoa2V5LCBuYW1lLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdEZWxldGVWYWx1ZSAgW0tFUk5FTC4yMjJdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUxNiggSEtFWSBoa2V5LCBMUFNUUiBuYW1lICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRGVsZXRlVmFsdWVBKCBoa2V5LCBuYW1lICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0VudW1WYWx1ZSAgIFtLRVJORUwuMjIzXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1WYWx1ZTE2KCBIS0VZIGhrZXksIERXT1JEIGluZGV4LCBMUFNUUiB2YWx1ZSwgTFBEV09SRCB2YWxfY291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCByZXNlcnZlZCwgTFBEV09SRCB0eXBlLCBMUEJZVEUgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0VudW1WYWx1ZUEoIGhrZXksIGluZGV4LCB2YWx1ZSwgdmFsX2NvdW50LCByZXNlcnZlZCwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnUXVlcnlWYWx1ZSAgIFtLRVJORUwuMjI0XQogKiAgICAgICAgICAgUmVnUXVlcnlWYWx1ZSAgIFtTSEVMTC42XQogKgogKiBOT1RFUwogKiAgICBJcyB0aGlzIEhBQ0sgc3RpbGwgYXBwbGljYWJsZT8KICoKICogSEFDSwogKiAgICBUaGUgMTZiaXQgUmVnUXVlcnlWYWx1ZSBkb2Vzbid0IGhhbmRsZSBzZWxlY3RvcmJsb2NrcyBhbnl3YXksIHNvIHdlIGp1c3QKICogICAgbWFzayBvdXQgdGhlIGhpZ2ggMTYgYml0LiAgVGhpcyAobm90IHNvIG11Y2ggaW5jaWRlbnRseSkgaG9wZWZ1bGx5IGZpeGVzCiAqICAgIEFsZHVzIEZINCkKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQU1RSIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIGlmIChjb3VudCkgKmNvdW50ICY9IDB4ZmZmZjsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlQSggaGtleSwgbmFtZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnUXVlcnlWYWx1ZUV4ICAgW0tFUk5FTC4yMjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQRFdPUkQgcmVzZXJ2ZWQsIExQRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeEEoIGhrZXksIG5hbWUsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdTZXRWYWx1ZUV4ICAgW0tFUk5FTC4yMjZdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBEV09SRCByZXNlcnZlZCwgRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09OU1QgQllURSAqZGF0YSwgRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIGlmICghY291bnQgJiYgKHR5cGU9PVJFR19TWikpIGNvdW50ID0gc3RybGVuKGRhdGEpOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlRXhBKCBoa2V5LCBuYW1lLCByZXNlcnZlZCwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRmx1c2hLZXkgICBbS0VSTkVMLjIyN10KICovCkRXT1JEIFdJTkFQSSBSZWdGbHVzaEtleTE2KCBIS0VZIGhrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdGbHVzaEtleSggaGtleSApOwp9Cg==