LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxmY250bC5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbm50LmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9zZXJ2ZXIuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgoKI2luY2x1ZGUgImRlYnVndG9vbHMuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTChyZWcpOwoKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAqLwojZGVmaW5lIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQgIEVUQ0RJUiIvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FIEVUQ0RJUiIvd2luZS5zeXN0ZW1yZWciCgovKiByZWxhdGl2ZSBpbiB+dXNlci8ud2luZS8gOiAqLwojZGVmaW5lIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0NVUlJFTlRfVVNFUiAgInVzZXIucmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCAgInVzZXJkZWYucmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUgInN5c3RlbS5yZWciCgovKiBfeG1hbGxvYyBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkICpfeG1hbGxvYyggc2l6ZV90IHNpemUgKQp7CiAgICB2b2lkICpyZXM7CgogICAgcmVzID0gbWFsbG9jIChzaXplID8gc2l6ZSA6IDEpOwogICAgaWYgKHJlcyA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiVmlydHVhbCBtZW1vcnkgZXhoYXVzdGVkLlxuIik7CiAgICAgICAgZXhpdCAoMSk7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9CgovKiBfc3RyZHVwbkEgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX3N0cmR1cG5BKExQQ1NUUiBzdHIsc2l6ZV90IGxlbikKewogICAgTFBTVFIgcmV0OwoKICAgIGlmICghc3RyKSByZXR1cm4gTlVMTDsKICAgIHJldCA9IF94bWFsbG9jKCBsZW4gKyAxICk7CiAgICBtZW1jcHkoIHJldCwgc3RyLCBsZW4gKTsKICAgIHJldFtsZW5dID0gMHgwMDsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgYW5zaSBzdHJpbmcgdG8gdW5pY29kZSBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFdTVFIgX3N0cmR1cG5BdG9XKExQQ1NUUiBzdHJBLHNpemVfdCBsZW5BKQp7CiAgICBMUFdTVFIgcmV0OwogICAgc2l6ZV90IGxlblc7CgogICAgaWYgKCFzdHJBKSByZXR1cm4gTlVMTDsKICAgIGxlblcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwwLHN0ckEsbGVuQSxOVUxMLDApOwogICAgcmV0ID0gX3htYWxsb2MobGVuVypzaXplb2YoV0NIQVIpK3NpemVvZihXQ0hBUikpOwogICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsMCxzdHJBLGxlbkEscmV0LGxlblcpOwogICAgcmV0W2xlblddID0gMDsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGR1bXAgYSBVbmljb2RlIHN0cmluZyB3aXRoIHByb3BlciBlc2NhcGluZyBbSW50ZXJuYWxdICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvdW5pY29kZS5jICovCnN0YXRpYyBpbnQgX2R1bXBfc3RyVyhjb25zdCBXQ0hBUiAqc3RyLHNpemVfdCBsZW4sRklMRSAqZixjaGFyIGVzY2FwZVsyXSkKewogICAgc3RhdGljIGNvbnN0IGNoYXIgZXNjYXBlc1szMl0gPSAiLi4uLi4uLmFidG52ZnIuLi4uLi4uLi4uLi4uZS4uLi4iOwogICAgY2hhciBidWZmZXJbMjU2XTsKICAgIExQU1RSIHBvcyA9IGJ1ZmZlcjsKICAgIGludCBjb3VudCA9IDA7CgogICAgZm9yICg7IGxlbjsgc3RyKyssIGxlbi0tKQogICAgewogICAgICAgIGlmIChwb3MgPiBidWZmZXIgKyBzaXplb2YoYnVmZmVyKSAtIDgpCiAgICAgICAgewogICAgICAgICAgICBmd3JpdGUoIGJ1ZmZlciwgcG9zIC0gYnVmZmVyLCAxLCBmICk7CiAgICAgICAgICAgIGNvdW50ICs9IHBvcyAtIGJ1ZmZlcjsKICAgICAgICAgICAgcG9zID0gYnVmZmVyOwogICAgICAgIH0KICAgICAgICBpZiAoKnN0ciA+IDEyNykgIC8qIGhleCBlc2NhcGUgKi8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChsZW4gPiAxICYmIHN0clsxXSA8IDEyOCAmJiBpc3hkaWdpdCgoY2hhcilzdHJbMV0pKQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxceCUwNHgiLCAqc3RyICk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXHgleCIsICpzdHIgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyIDwgMzIpICAvKiBvY3RhbCBvciBDIGVzY2FwZSAqLwogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEqc3RyICYmIGxlbiA9PSAxKSBjb250aW51ZTsgIC8qIGRvIG5vdCBvdXRwdXQgdGVybWluYXRpbmcgTlVMTCAqLwogICAgICAgICAgICBpZiAoZXNjYXBlc1sqc3RyXSAhPSAnLicpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlYyIsIGVzY2FwZXNbKnN0cl0gKTsKICAgICAgICAgICAgZWxzZSBpZiAobGVuID4gMSAmJiBzdHJbMV0gPj0gJzAnICYmIHN0clsxXSA8PSAnNycpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlMDNvIiwgKnN0ciApOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlbyIsICpzdHIgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyID09ICdcXCcgfHwgKnN0ciA9PSBlc2NhcGVbMF0gfHwgKnN0ciA9PSBlc2NhcGVbMV0pICpwb3MrKyA9ICdcXCc7CiAgICAgICAgKnBvcysrID0gKnN0cjsKICAgIH0KICAgIGZ3cml0ZSggYnVmZmVyLCBwb3MgLSBidWZmZXIsIDEsIGYgKTsKICAgIGNvdW50ICs9IHBvcyAtIGJ1ZmZlcjsKICAgIHJldHVybiBjb3VudDsKfQoKLyogY29udmVydCBhbnNpIHN0cmluZyB0byB1bmljb2RlIGFuZCBkdW1wIHdpdGggcHJvcGVyIGVzY2FwaW5nIFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfZHVtcF9zdHJBdG9XKExQQ1NUUiBzdHJBLHNpemVfdCBsZW4sRklMRSAqZixjaGFyIGVzY2FwZVsyXSkKewogICAgV0NIQVIgKnN0clc7CiAgICBpbnQgcmV0OwoKICAgIGlmIChzdHJBID09IE5VTEwpIHJldHVybiAwOwogICAgc3RyVyA9IF9zdHJkdXBuQXRvVyhzdHJBLGxlbik7CiAgICByZXQgPSBfZHVtcF9zdHJXKHN0clcsbGVuLGYsZXNjYXBlKTsKICAgIGZyZWUoc3RyVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBhIGtleSB2YWx1ZSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3JlZ2lzdHJ5LmMgKi8Kc3RydWN0IGtleV92YWx1ZSB7CiAgICBXQ0hBUiAgICAgICAgICAgICpuYW1lVzsgICAvKiB2YWx1ZSBuYW1lICovCiAgICBpbnQgICAgICAgICAgICAgICB0eXBlOyAgICAvKiB2YWx1ZSB0eXBlICovCiAgICBzaXplX3QgICAgICAgICAgICBsZW47ICAgICAvKiB2YWx1ZSBkYXRhIGxlbmd0aCBpbiBieXRlcyAqLwogICAgdm9pZCAgICAgICAgICAgICAqZGF0YTsgICAgLyogcG9pbnRlciB0byB2YWx1ZSBkYXRhICovCn07CgovKiBkdW1wIGEgdmFsdWUgdG8gYSB0ZXh0IGZpbGUgKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci9yZWdpc3RyeS5jICovCnN0YXRpYyB2b2lkIF9kdW1wX3ZhbHVlKHN0cnVjdCBrZXlfdmFsdWUgKnZhbHVlLEZJTEUgKmYpCnsKICAgIGludCBpLCBjb3VudDsKCiAgICBpZiAodmFsdWUtPm5hbWVXWzBdKSB7CiAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICBjb3VudCA9IDEgKyBfZHVtcF9zdHJXKHZhbHVlLT5uYW1lVyxzdHJsZW5XKHZhbHVlLT5uYW1lVyksZiwiXCJcIiIpOwogICAgICAgIGNvdW50ICs9IGZwcmludGYoIGYsICJcIj0iICk7CiAgICB9CiAgICBlbHNlIGNvdW50ID0gZnByaW50ZiggZiwgIkA9IiApOwoKICAgIHN3aXRjaCh2YWx1ZS0+dHlwZSkgewogICAgICAgIGNhc2UgUkVHX1NaOgogICAgICAgIGNhc2UgUkVHX0VYUEFORF9TWjoKICAgICAgICBjYXNlIFJFR19NVUxUSV9TWjoKICAgICAgICAgICAgaWYgKHZhbHVlLT50eXBlICE9IFJFR19TWikgZnByaW50ZiggZiwgInN0ciglZCk6IiwgdmFsdWUtPnR5cGUgKTsKICAgICAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICAgICAgaWYgKHZhbHVlLT5kYXRhKSBfZHVtcF9zdHJXKHZhbHVlLT5kYXRhLHZhbHVlLT5sZW4vc2l6ZW9mKFdDSEFSKSxmLCJcIlwiIik7CiAgICAgICAgICAgIGZwdXRjKCAnXCInLCBmICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX0RXT1JEOgogICAgICAgICAgICBpZiAodmFsdWUtPmxlbiA9PSBzaXplb2YoRFdPUkQpKSB7CiAgICAgICAgICAgICAgICBEV09SRCBkdzsKICAgICAgICAgICAgICAgIG1lbWNweSggJmR3LCB2YWx1ZS0+ZGF0YSwgc2l6ZW9mKERXT1JEKSApOwogICAgICAgICAgICAgICAgZnByaW50ZiggZiwgImR3b3JkOiUwOGx4IiwgZHcgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGVsc2UgZmFsbCB0aHJvdWdoICovCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgaWYgKHZhbHVlLT50eXBlID09IFJFR19CSU5BUlkpIGNvdW50ICs9IGZwcmludGYoIGYsICJoZXg6IiApOwogICAgICAgICAgICBlbHNlIGNvdW50ICs9IGZwcmludGYoIGYsICJoZXgoJXgpOiIsIHZhbHVlLT50eXBlICk7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS0+bGVuOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvdW50ICs9IGZwcmludGYoIGYsICIlMDJ4IiwgKigodW5zaWduZWQgY2hhciAqKXZhbHVlLT5kYXRhICsgaSkgKTsKICAgICAgICAgICAgICAgIGlmIChpIDwgdmFsdWUtPmxlbi0xKSB7CiAgICAgICAgICAgICAgICAgICAgZnB1dGMoICcsJywgZiApOwogICAgICAgICAgICAgICAgICAgIGlmICgrK2NvdW50ID4gNzYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZnByaW50ZiggZiwgIlxcXG4gICIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGZwdXRjKCAnXG4nLCBmICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewogICAgY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCiAgICB1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCiAgICB1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwogICAgdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwogICAgdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCiAgICB1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCiAgICB1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCiAgICB1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7CiAgICB1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwogICAgdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgIFtJbnRlcm5hbF0gKi8Kdm9pZCBfdzMxX2R1bXB0cmVlKHVuc2lnbmVkIHNob3J0IGlkeCx1bnNpZ25lZCBjaGFyICp0eHQsc3RydWN0IF93MzFfdGFiZW50ICp0YWIsc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLEhLRVkgaGtleSx0aW1lX3QgbGFzdG1vZGlmaWVkLCBpbnQgbGV2ZWwpCnsKICAgIHN0cnVjdCBfdzMxX2RpcmVudCAqZGlyOwogICAgc3RydWN0IF93MzFfa2V5ZW50ICprZXk7CiAgICBzdHJ1Y3QgX3czMV92YWxlbnQgKnZhbDsKICAgIEhLRVkgc3Via2V5ID0gMDsKICAgIHN0YXRpYyBjaGFyCXRhaWxbNDAwXTsKCiAgICB3aGlsZSAoaWR4IT0wKSB7CiAgICAgICAgZGlyPShzdHJ1Y3QgX3czMV9kaXJlbnQqKSZ0YWJbaWR4XTsKCiAgICAgICAgaWYgKGRpci0+a2V5X2lkeCkgewogICAgICAgICAgICBrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgogICAgICAgICAgICBtZW1jcHkodGFpbCwmdHh0W2tleS0+c3RyaW5nX29mZl0sa2V5LT5sZW5ndGgpOwogICAgICAgICAgICB0YWlsW2tleS0+bGVuZ3RoXT0nXDAnOwogICAgICAgICAgICAvKiBhbGwgdG9wbGV2ZWwgZW50cmllcyBBTkQgdGhlIGVudHJpZXMgaW4gdGhlIAogICAgICAgICAgICAgKiB0b3BsZXZlbCBzdWJkaXJlY3RvcnkgYmVsb25nIHRvIFxTT0ZUV0FSRVxDbGFzc2VzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoIWxldmVsICYmICFzdHJjbXAodGFpbCwiLmNsYXNzZXMiKSkgewogICAgICAgICAgICAgICAgX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsaGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CiAgICAgICAgICAgICAgICBpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKICAgICAgICAgICAgaWYgKFJlZ0NyZWF0ZUtleUEoIGhrZXksIHRhaWwsICZzdWJrZXkgKSAhPSBFUlJPUl9TVUNDRVNTKSBzdWJrZXkgPSAwOwogICAgICAgICAgICAvKiBvbmx5IGFkZCBpZiBsZWFmIG5vZGUgb3IgdmFsdWVkIG5vZGUgKi8KICAgICAgICAgICAgaWYgKGRpci0+dmFsdWVfaWR4IT0wfHxkaXItPmNoaWxkX2lkeD09MCkgewogICAgICAgICAgICAgICAgaWYgKGRpci0+dmFsdWVfaWR4KSB7CiAgICAgICAgICAgICAgICAgICAgdmFsPShzdHJ1Y3QgX3czMV92YWxlbnQqKSZ0YWJbZGlyLT52YWx1ZV9pZHhdOwogICAgICAgICAgICAgICAgICAgIG1lbWNweSh0YWlsLCZ0eHRbdmFsLT5zdHJpbmdfb2ZmXSx2YWwtPmxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgdGFpbFt2YWwtPmxlbmd0aF09J1wwJzsKICAgICAgICAgICAgICAgICAgICBSZWdTZXRWYWx1ZUEoIHN1YmtleSwgTlVMTCwgUkVHX1NaLCB0YWlsLCAwICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgVFJBQ0UoInN0cmFuZ2U6IG5vIGRpcmVjdG9yeSBrZXkgbmFtZSwgaWR4PSUwNHhcbiIsIGlkeCk7CiAgICAgICAgX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsc3Via2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKICAgICAgICBpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKICAgIH0KICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3czMV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnZvaWQgX3czMV9sb2FkcmVnKHZvaWQpIAp7CiAgICBIRklMRSBoZjsKICAgIHN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwogICAgc3RydWN0IF93MzFfdGFiZW50CSp0YWI7CiAgICB1bnNpZ25lZCBjaGFyCQkqdHh0OwogICAgdW5zaWduZWQgaW50CQlsZW47CiAgICBPRlNUUlVDVAkJb2ZzOwogICAgQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZpbmZvOwogICAgdGltZV90CQkJbGFzdG1vZGlmaWVkOwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGhmID0gT3BlbkZpbGUoInJlZy5kYXQiLCZvZnMsT0ZfUkVBRCk7CiAgICBpZiAoaGY9PUhGSUxFX0VSUk9SKSByZXR1cm47CgogICAgLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCiAgICBpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQoaGYsJmhlYWQsc2l6ZW9mKGhlYWQpKSkgewogICAgICAgIEVSUigicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKICAgICAgICBfbGNsb3NlKGhmKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSE9MCkgewogICAgICAgIEVSUigicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwogICAgLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwogICAgdGFiID0gX3htYWxsb2MobGVuKTsKICAgIGlmIChsZW4hPV9scmVhZChoZix0YWIsbGVuKSkgewogICAgICAgIEVSUigiY291bGRuJ3QgcmVhZCAlZCBieXRlcy5cbiIsbGVuKTsgCiAgICAgICAgZnJlZSh0YWIpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvKiByZWFkIHRleHQgKi8KICAgIHR4dCA9IF94bWFsbG9jKGhlYWQudGV4dHNpemUpOwogICAgaWYgKC0xPT1fbGxzZWVrKGhmLGhlYWQudGV4dG9mZixTRUVLX1NFVCkpIHsKICAgICAgICBFUlIoImNvdWxkbid0IHNlZWsgdG8gdGV4dGJsb2NrLlxuIik7IAogICAgICAgIGZyZWUodGFiKTsKICAgICAgICBmcmVlKHR4dCk7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGhlYWQudGV4dHNpemUhPV9scmVhZChoZix0eHQsaGVhZC50ZXh0c2l6ZSkpIHsKICAgICAgICBFUlIoInRleHRibG9jayB0b28gc2hvcnQgKCVkIGluc3RlYWQgb2YgJWxkKS5cbiIsbGVuLGhlYWQudGV4dHNpemUpOyAKICAgICAgICBmcmVlKHRhYik7CiAgICAgICAgZnJlZSh0eHQpOwogICAgICAgIF9sY2xvc2UoaGYpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmLCZoZmluZm8pKSB7CiAgICAgICAgRVJSKCJHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7IAogICAgICAgIGZyZWUodGFiKTsKICAgICAgICBmcmVlKHR4dCk7CiAgICAgICAgX2xjbG9zZShoZik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgbGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwogICAgX3czMV9kdW1wdHJlZSh0YWJbMF0udzEsdHh0LHRhYiwmaGVhZCxIS0VZX0NMQVNTRVNfUk9PVCxsYXN0bW9kaWZpZWQsMCk7CiAgICBmcmVlKHRhYik7CiAgICBmcmVlKHR4dCk7CiAgICBfbGNsb3NlKGhmKTsKICAgIHJldHVybjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd3MgOTUgcmVnaXN0cnkgbG9hZGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIFNFQ1RJT04gMTogbWFpbiBoZWFkZXIKICoKICogb25jZSBhdCBvZmZzZXQgMAogKi8KI2RlZmluZQlXOTVfUkVHX0NSRUdfSUQJMHg0NzQ1NTI0MwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiAiQ1JFRyIgPSBXOTVfUkVHX0NSRUdfSUQgKi8KICAgIERXT1JECXZlcnNpb247CS8qID8/Pz8gMHgwMDAxMDAwMCAqLwogICAgRFdPUkQJcmdkYl9vZmY7CS8qIDB4MDggT2Zmc2V0IG9mIDFzdCBSR0RCLWJsb2NrICovCiAgICBEV09SRAl1azI7CQkvKiAweDBjICovCiAgICBXT1JECXJnZGJfbnVtOwkvKiAweDEwICMgb2YgUkdEQi1ibG9ja3MgKi8KICAgIFdPUkQJdWszOwogICAgRFdPUkQJdWtbM107CiAgICAvKiByZ2tuICovCn0gX3c5NWNyZWc7CgovKiBTRUNUSU9OIDI6IERpcmVjdG9yeSBpbmZvcm1hdGlvbiAodHJlZSBzdHJ1Y3R1cmUpCiAqCiAqIG9uY2Ugb24gb2Zmc2V0IDB4MjAKICoKICogc3RydWN0dXJlOiBbcmdrbl1bZGtlXSoJKHJlcGVhdCB0aWxsIGxhc3RfZGtlIGlzIHJlYWNoZWQpCiAqLwojZGVmaW5lCVc5NV9SRUdfUkdLTl9JRAkweDRlNGI0NzUyCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qIlJHS04iID0gVzk1X1JFR19SR0tOX0lEICovCiAgICBEV09SRAlzaXplOwkJLyogU2l6ZSBvZiB0aGUgUkdLTi1ibG9jayAqLwogICAgRFdPUkQJcm9vdF9vZmY7CS8qIFJlbC4gT2Zmc2V0IG9mIHRoZSByb290LXJlY29yZCAqLwogICAgRFdPUkQgICBsYXN0X2RrZTsgICAgICAgLyogT2Zmc2V0IHRvIGxhc3QgREtFID8gKi8KICAgIERXT1JECXVrWzRdOwp9IF93OTVyZ2tuOwoKLyogRGlzayBLZXkgRW50cnkgU3RydWN0dXJlCiAqCiAqIHRoZSAxc3QgZW50cnkgaW4gYSAidXN1YWwiIHJlZ2lzdHJ5IGZpbGUgaXMgYSBudWwtZW50cnkgd2l0aCBzdWJrZXlzOiB0aGUKICogaGl2ZSBpdHNlbGYuIEl0IGxvb2tzIHRoZSBzYW1lIGxpa2Ugb3RoZXIga2V5cy4gRXZlbiB0aGUgSUQtbnVtYmVyIGNhbgogKiBiZSBhbnkgdmFsdWUuCiAqCiAqIFRoZSAiaGFzaCItdmFsdWUgaXMgYSB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIGtleSdzIG5hbWUuIFdpbmRvd3Mgd2lsbCBub3QKICogc2VhcmNoIGZvciB0aGUgbmFtZSwgYnV0IGZvciBhIG1hdGNoaW5nIGhhc2gtdmFsdWUuIGlmIGl0IGZpbmRzIG9uZSwgaXQKICogd2lsbCBjb21wYXJlIHRoZSBhY3R1YWwgc3RyaW5nIGluZm8sIG90aGVyd2lzZSBjb250aW51ZSB3aXRoIHRoZSBuZXh0IGtleS4KICogVG8gY2FsY3VsYXRlIHRoZSBoYXNoIGluaXRpYWxpemUgYSBELVdvcmQgd2l0aCAwIGFuZCBhZGQgYWxsIEFTQ0lJLXZhbHVlcyAKICogb2YgdGhlIHN0cmluZyB3aGljaCBhcmUgc21hbGxlciB0aGFuIDB4ODAgKDEyOCkgdG8gdGhpcyBELVdvcmQuICAgCiAqCiAqIElmIHlvdSB3YW50IHRvIG1vZGlmeSBrZXkgbmFtZXMsIGFsc28gbW9kaWZ5IHRoZSBoYXNoLXZhbHVlcywgc2luY2UgdGhleQogKiBjYW5ub3QgYmUgZm91bmQgYWdhaW4gKGFsdGhvdWdoIHRoZXkgd291bGQgYmUgZGlzcGxheWVkIGluIFJFR0VESVQpCiAqIEVuZCBvZiBsaXN0LXBvaW50ZXJzIGFyZSBmaWxsZWQgd2l0aCAweEZGRkZGRkZGCiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuck1TIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKgogKiBUaGUgbGFzdCBES0UgKHNlZSBmaWVsZCBsYXN0X2RrZSBpbiBfdzk1X3Jna24pIGhhcyBvbmx5IDMgRFdPUkRzIHdpdGgKICogMHg4MDAwMDAwMCAoRU9MIGluZGljYXRvciA/KSBhcyB4MSwgdGhlIGhhc2ggdmFsdWUgYW5kIDB4RkZGRkZGRkYgYXMgeDMuCiAqIFRoZSByZW1haW5pbmcgc3BhY2UgYmV0d2VlbiBsYXN0X2RrZSBhbmQgdGhlIG9mZnNldCBjYWxjdWxhdGVkIGZyb20KICogcmdrbi0+c2l6ZSBzZWVtcyB0byBiZSBmcmVlIGZvciB1c2UgZm9yIG1vcmUgZGtlOnMuCiAqIFNvIGl0IHNlZW1zIGlmIG1vcmUgZGtlOnMgYXJlIGFkZGVkLCB0aGV5IGFyZSBhZGRlZCB0byB0aGF0IHNwYWNlIGFuZAogKiBsYXN0X2RrZSBpcyBncm93biwgYW5kIGluIGNhc2UgdGhhdCAiZnJlZSIgc3BhY2UgaXMgb3V0LCB0aGUgc3BhY2UKICogZ2V0cyBncm93biBhbmQgcmdrbi0+c2l6ZSBnZXRzIGFkanVzdGVkLgogKgogKiB0aGVyZSBpcyBhIG9uZSB0byBvbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gZGtlIGFuZCBka2gKICovCiAvKiBrZXkgc3RydWN0LCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJeDE7CQkvKiBGcmVlIGVudHJ5IGluZGljYXRvcig/KSAqLwogICAgRFdPUkQJaGFzaDsJCS8qIHN1bSBvZiBieXRlcyBvZiBrZXluYW1lICovCiAgICBEV09SRAl4MzsJCS8qIFJvb3Qga2V5IGluZGljYXRvcj8gdXN1YWxseSAweEZGRkZGRkZGICovCiAgICBEV09SRAlwcmV2bHZsOwkvKiBvZmZzZXQgb2YgcHJldmlvdXMga2V5ICovCiAgICBEV09SRAluZXh0c3ViOwkvKiBvZmZzZXQgb2YgY2hpbGQga2V5ICovCiAgICBEV09SRAluZXh0OwkJLyogb2Zmc2V0IG9mIHNpYmxpbmcga2V5ICovCiAgICBXT1JECW5yTFM7CQkvKiBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KICAgIFdPUkQJbnJNUzsJCS8qIG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwp9IF93OTVka2U7CgovKiBTRUNUSU9OIDM6IGtleSBpbmZvcm1hdGlvbiwgdmFsdWVzIGFuZCBkYXRhCiAqCiAqIHN0cnVjdHVyZToKICogIHNlY3Rpb246CVtibG9ja3NdKgkJKHJlcGVhdCBjcmVnLT5yZ2RiX251bSB0aW1lcykKICogIGJsb2NrczoJW3JnZGJdIFtzdWJibG9ja3NdKiAJKHJlcGVhdCB0aWxsIGJsb2NrIHNpemUgcmVhY2hlZCApCiAqICBzdWJibG9ja3M6CVtka2hdIFtka3ZdKgkJKHJlcGVhdCBka2gtPnZhbHVlcyB0aW1lcyApCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgRFdPUkQgdmFsdWUKICogYXQgb2Zmc2V0IDB4MTAgZXF1YWxzIHRoZSBvbmUgYXQgb2Zmc2V0IDB4MDQgbWludXMgdGhlIG9uZSBhdCBvZmZzZXQgMHgwOC4KICogSSBoYXZlIG5vIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKi8KCi8qIGJsb2NrIGhlYWRlciwgb25jZSBwZXIgYmxvY2sgKi8KI2RlZmluZSBXOTVfUkVHX1JHREJfSUQJMHg0MjQ0NDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CS8qIDB4MDAgJ1JHREInID0gVzk1X1JFR19SR0RCX0lEICovCiAgICBEV09SRAlzaXplOwkvKiAweDA0ICovCiAgICBEV09SRAl1azE7CS8qIDB4MDggKi8KICAgIERXT1JECXVrMjsJLyogMHgwYyAqLwogICAgRFdPUkQJdWszOwkvKiAweDEwICovCiAgICBEV09SRAl1azQ7CS8qIDB4MTQgKi8KICAgIERXT1JECXVrNTsJLyogMHgxOCAqLwogICAgRFdPUkQJdWs2OwkvKiAweDFjICovCiAgICAvKiBka2ggKi8KfSBfdzk1cmdkYjsKCi8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCksIG9uY2UgcGVyIGtleSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAluZXh0a2V5b2ZmOyAJLyogMHgwMCBvZmZzZXQgdG8gbmV4dCBka2ggKi8KICAgIFdPUkQJbnJMUzsJCS8qIDB4MDQgaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCiAgICBXT1JECW5yTVM7CQkvKiAweDA2IG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwogICAgRFdPUkQJYnl0ZXN1c2VkOwkvKiAweDA4ICovCiAgICBXT1JECWtleW5hbWVsZW47CS8qIDB4MGMgbGVuIG9mIG5hbWUgKi8KICAgIFdPUkQJdmFsdWVzOwkJLyogMHgwZSBudW1iZXIgb2YgdmFsdWVzICovCiAgICBEV09SRAl4eDE7CQkvKiAweDEwICovCiAgICBjaGFyCW5hbWVbMV07CS8qIDB4MTQgKi8KICAgIC8qIGRrdiAqLwkJLyogMHgxNCArIGtleW5hbWVsZW4gKi8KfSBfdzk1ZGtoOwoKLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlLCBvbmNlIHBlciB2YWx1ZSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAl0eXBlOwkJLyogMHgwMCAqLwogICAgRFdPUkQJeDE7CQkvKiAweDA0ICovCiAgICBXT1JECXZhbG5hbWVsZW47CS8qIDB4MDggbGVuZ3RoIG9mIG5hbWUsIDAgaXMgZGVmYXVsdCBrZXkgKi8KICAgIFdPUkQJdmFsZGF0YWxlbjsJLyogMHgwQSBsZW5ndGggb2YgZGF0YSAqLwogICAgY2hhcgluYW1lWzFdOwkvKiAweDBjICovCiAgICAvKiByYXcgZGF0YSAqLwkJLyogMHgwYyArIHZhbG5hbWVsZW4gKi8KfSBfdzk1ZGt2OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvb2t1cF9ka2ggW0ludGVybmFsXQogKgogKiBzZWVrcyB0aGUgZGtoIGJlbG9uZ2luZyB0byBhIGRrZQogKi8Kc3RhdGljIF93OTVka2ggKl93OTVfbG9va3VwX2RraChfdzk1Y3JlZyAqY3JlZyxpbnQgbnJMUyxpbnQgbnJNUykKewogICAgX3c5NXJnZGIgKiByZ2RiOwogICAgX3c5NWRraCAqIGRraDsKICAgIGludCBpOwoKICAgIC8qIGdldCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZ2RiIGRhdGFzdG9yZSAqLwogICAgcmdkYiA9IChfdzk1cmdkYiopKChjaGFyKiljcmVnK2NyZWctPnJnZGJfb2ZmKTsKCiAgICAvKiBjaGVjazogcmVxdWVzdGVkIGJsb2NrIDwgbGFzdF9ibG9jaykgKi8KICAgIGlmIChjcmVnLT5yZ2RiX251bSA8PSBuck1TKSB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJlcXVlc3RlZCBibG9jayBuby4gYmV5b25kIGVuZC5cbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogZmluZCB0aGUgcmlnaHQgYmxvY2sgKi8KICAgIGZvcihpPTA7IGk8bnJNUyA7aSsrKSB7CiAgICAgICAgaWYocmdkYi0+aWQgIT0gVzk1X1JFR19SR0RCX0lEKSB7ICAvKiBjaGVjayB0aGUgbWFnaWMgKi8KICAgICAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGJhZCBtYWdpYyAweCUwOGx4XG4iLCByZ2RiLT5pZCk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIHJnZGIgPSAoX3c5NXJnZGIqKSAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSk7CQkvKiBmaW5kIG5leHQgYmxvY2sgKi8KICAgIH0KCiAgICBka2ggPSAoX3c5NWRraCopKHJnZGIgKyAxKTsJCQkJLyogZmlyc3Qgc3ViIGJsb2NrIHdpdGhpbiB0aGUgcmdkYiAqLwoKICAgIGRvIHsKICAgICAgICBpZihuckxTPT1ka2gtPm5yTFMgKSByZXR1cm4gZGtoOwogICAgICAgIGRraCA9IChfdzk1ZGtoKikoKGNoYXIqKWRraCArIGRraC0+bmV4dGtleW9mZik7CS8qIGZpbmQgbmV4dCBzdWJibG9jayAqLwogICAgfSB3aGlsZSAoKGNoYXIgKilka2ggPCAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSkpOwoKZXJyb3I6CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2R1bXBfZGt2IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9kdW1wX2Rrdihfdzk1ZGtoICpka2gsaW50IG5yTFMsaW50IG5yTVMsRklMRSAqZikKewogICAgX3c5NWRrdiAqIGRrdjsKICAgIGludCBpOwoKICAgIC8qIGZpcnN0IHZhbHVlIGJsb2NrICovCiAgICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka2grZGtoLT5rZXluYW1lbGVuKzB4MTQpOwoKICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUgdmFsdWVzICovCiAgICBmb3IgKGk9MDsgaTwgZGtoLT52YWx1ZXM7IGkrKykgewogICAgICAgIHN0cnVjdCBrZXlfdmFsdWUgdmFsdWU7CiAgICAgICAgV0NIQVIgKnBkYXRhOwoKICAgICAgICB2YWx1ZS5uYW1lVyA9IF9zdHJkdXBuQXRvVyhka3YtPm5hbWUsZGt2LT52YWxuYW1lbGVuKTsKICAgICAgICB2YWx1ZS50eXBlID0gZGt2LT50eXBlOwogICAgICAgIHZhbHVlLmxlbiA9IGRrdi0+dmFsZGF0YWxlbjsKCiAgICAgICAgdmFsdWUuZGF0YSA9ICYoZGt2LT5uYW1lW2Rrdi0+dmFsbmFtZWxlbl0pOwogICAgICAgIHBkYXRhID0gTlVMTDsKICAgICAgICBpZiAoICh2YWx1ZS50eXBlPT1SRUdfU1opIHx8ICh2YWx1ZS50eXBlPT1SRUdfRVhQQU5EX1NaKSB8fCAodmFsdWUudHlwZT09UkVHX01VTFRJX1NaKSApIHsKICAgICAgICAgICAgcGRhdGEgPSBfc3RyZHVwbkF0b1codmFsdWUuZGF0YSx2YWx1ZS5sZW4pOwogICAgICAgICAgICB2YWx1ZS5sZW4gKj0gMjsKICAgICAgICB9CiAgICAgICAgaWYgKHBkYXRhICE9IE5VTEwpIHZhbHVlLmRhdGEgPSBwZGF0YTsKCiAgICAgICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgICAgIGZyZWUodmFsdWUubmFtZVcpOwogICAgICAgIGlmIChwZGF0YSAhPSBOVUxMKSBmcmVlKHBkYXRhKTsKCiAgICAgICAgLyogbmV4dCB2YWx1ZSAqLwogICAgICAgIGRrdiA9IChfdzk1ZGt2KikoKGNoYXIqKWRrditka3YtPnZhbG5hbWVsZW4rZGt2LT52YWxkYXRhbGVuKzB4MGMpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9kdW1wX2RrZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfZHVtcF9ka2UoTFBTVFIga2V5X25hbWUsX3c5NWNyZWcgKmNyZWcsX3c5NXJna24gKnJna24sX3c5NWRrZSAqZGtlLEZJTEUgKmYsaW50IGxldmVsKQp7CiAgICBfdzk1ZGtoICogZGtoOwogICAgTFBTVFIgbmV3X2tleV9uYW1lID0gTlVMTDsKCiAgICAvKiBzcGVjaWFsIHJvb3Qga2V5ICovCiAgICBpZiAoZGtlLT5uckxTID09IDB4ZmZmZiB8fCBka2UtPm5yTVM9PTB4ZmZmZikJCS8qIGVnLiB0aGUgcm9vdCBrZXkgaGFzIG5vIG5hbWUgKi8KICAgIHsKICAgICAgICAvKiBwYXJzZSB0aGUgb25lIHN1YmtleSAqLwogICAgICAgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgcmV0dXJuIF93OTVfZHVtcF9ka2Uoa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSxmLGxldmVsKTsKICAgICAgICAvKiBoYXMgbm8gc2libGluZyBrZXlzICovCiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIHNlYXJjaCBzdWJibG9jayAqLwogICAgaWYgKCEoZGtoID0gX3c5NV9sb29rdXBfZGtoKGNyZWcsIGRrZS0+bnJMUywgZGtlLT5uck1TKSkpIHsKICAgICAgICBFUlIoImRrZSBwb2ludGluZyB0byBtaXNzaW5nIGRraCAhXG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGxldmVsIDw9IDApIHsKICAgICAgICAvKiBjcmVhdGUgbmV3IHN1YmtleSBuYW1lICovCiAgICAgICAgbmV3X2tleV9uYW1lID0gX3N0cmR1cG5BKGtleV9uYW1lLHN0cmxlbihrZXlfbmFtZSkrZGtoLT5rZXluYW1lbGVuKzEpOwogICAgICAgIGlmIChzdHJjbXAobmV3X2tleV9uYW1lLCIiKSAhPSAwKSBzdHJjYXQobmV3X2tleV9uYW1lLCJcXCIpOwogICAgICAgIHN0cm5jYXQobmV3X2tleV9uYW1lLGRraC0+bmFtZSxka2gtPmtleW5hbWVsZW4pOwoKICAgICAgICAvKiB3YWxrIHNpYmxpbmcga2V5cyAqLwogICAgICAgIGlmIChka2UtPm5leHQgIT0gMHhmZmZmZmZmZiApIHsKICAgICAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGtlKGtleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dCksZixsZXZlbCkpIHsKICAgICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogd3JpdGUgdGhlIGtleSBwYXRoIChzb21ldGhpbmcgbGlrZSBbU29mdHdhcmVcXE1pY3Jvc29mdFxcLi5dKSBvbmx5IGlmOiAKICAgICAgICAgICAxKSBrZXkgaGFzIHNvbWUgdmFsdWVzCiAgICAgICAgICAgMikga2V5IGhhcyBubyB2YWx1ZXMgYW5kIG5vIHN1YmtleXMKICAgICAgICAqLwogICAgICAgIGlmIChka2gtPnZhbHVlcyA+IDApIHsKICAgICAgICAgICAgLyogdGhlcmUgYXJlIHNvbWUgdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgICAgIGlmICghX3c5NV9kdW1wX2Rrdihka2gsIGRrZS0+bnJMUywgZGtlLT5uck1TLGYpKSB7CiAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoKGRrZS0+bmV4dHN1YiA9PSAweGZmZmZmZmZmKSAmJiAoZGtoLT52YWx1ZXMgPT0gMCkpIHsKICAgICAgICAgICAgLyogbm8gc3Via2V5cyBhbmQgbm8gdmFsdWVzICovCiAgICAgICAgICAgIGZwcmludGYoZiwiXG5bIik7CiAgICAgICAgICAgIF9kdW1wX3N0ckF0b1cobmV3X2tleV9uYW1lLHN0cmxlbihuZXdfa2V5X25hbWUpLGYsIltdIik7CiAgICAgICAgICAgIGZwcmludGYoZiwiXVxuIik7CiAgICAgICAgfQogICAgfSBlbHNlIG5ld19rZXlfbmFtZSA9IF9zdHJkdXBuQShrZXlfbmFtZSxzdHJsZW4oa2V5X25hbWUpKTsKCiAgICAvKiBuZXh0IHN1YiBrZXkgKi8KICAgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgewogICAgICAgIGlmICghX3c5NV9kdW1wX2RrZShuZXdfa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSxmLGxldmVsLTEpKSB7CiAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgIHJldHVybiBUUlVFOwp9Ci8qIGVuZCB3aW5kb3dzIDk1IGxvYWRlciAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd3MgTlQgcmVnaXN0cnkgbG9hZGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIE5UIFJFR0lTVFJZIExPQURFUiAqLwoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKI2lmbmRlZiBNQVBfRkFJTEVECiNkZWZpbmUgTUFQX0ZBSUxFRCAoKExQVk9JRCktMSkKI2VuZGlmCgojZGVmaW5lIE5UX1JFR19CTE9DS19TSVpFICAgICAgICAgICAgMHgxMDAwCgojZGVmaW5lIE5UX1JFR19IRUFERVJfQkxPQ0tfSUQgICAgICAgMHg2NjY3NjU3MgkvKiByZWdmICovCiNkZWZpbmUgTlRfUkVHX1BPT0xfQkxPQ0tfSUQgICAgICAgICAweDZFNjk2MjY4CS8qIGhiaW4gKi8KI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX0lEICAgICAgICAgIDB4NmI2ZSAvKiBuayAqLwojZGVmaW5lIE5UX1JFR19WQUxVRV9CTE9DS19JRCAgICAgICAgMHg2Yjc2IC8qIHZrICovCgovKiBzdWJibG9ja3Mgb2YgbmsgKi8KI2RlZmluZSBOVF9SRUdfSEFTSF9CTE9DS19JRCAgICAgICAgIDB4NjY2YyAvKiBsZiAqLwojZGVmaW5lIE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQgICAgICAgMHg2OTZjIC8qIGxpICovCiNkZWZpbmUgTlRfUkVHX1JJX0JMT0NLX0lECSAgICAgMHg2OTcyIC8qIHJpICovCgojZGVmaW5lIE5UX1JFR19LRVlfQkxPQ0tfVFlQRSAgICAgICAgMHgyMAojZGVmaW5lIE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFICAgMHgyYwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiAweDY2Njc2NTcyICdyZWdmJyovCiAgICBEV09SRAl1azE7CQkvKiAweDA0ICovCiAgICBEV09SRAl1azI7CQkvKiAweDA4ICovCiAgICBGSUxFVElNRQlEYXRlTW9kaWZpZWQ7CS8qIDB4MGMgKi8KICAgIERXT1JECXVrMzsJCS8qIDB4MTQgKi8KICAgIERXT1JECXVrNDsJCS8qIDB4MTggKi8KICAgIERXT1JECXVrNTsJCS8qIDB4MWMgKi8KICAgIERXT1JECXVrNjsJCS8qIDB4MjAgKi8KICAgIERXT1JECVJvb3RLZXlCbG9jazsJLyogMHgyNCAqLwogICAgRFdPUkQJQmxvY2tTaXplOwkvKiAweDI4ICovCiAgICBEV09SRCAgIHVrN1sxMTZdOwkKICAgIERXT1JECUNoZWNrc3VtOyAvKiBhdCBvZmZzZXQgMHgxRkMgKi8KfSBudF9yZWdmOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJYmxvY2tzaXplOwogICAgQllURQlkYXRhWzFdOwp9IG50X2hiaW5fc3ViOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiAweDZFNjk2MjY4ICdoYmluJyAqLwogICAgRFdPUkQJb2ZmX3ByZXY7CiAgICBEV09SRAlvZmZfbmV4dDsKICAgIERXT1JECXVrMTsKICAgIERXT1JECXVrMjsJCS8qIDB4MTAgKi8KICAgIERXT1JECXVrMzsJCS8qIDB4MTQgKi8KICAgIERXT1JECXVrNDsJCS8qIDB4MTggKi8KICAgIERXT1JECXNpemU7CQkvKiAweDFDICovCiAgICBudF9oYmluX3N1YgloYmluX3N1YjsJLyogMHgyMCAqLwp9IG50X2hiaW47CgovKgogKiB0aGUgdmFsdWVfbGlzdCBjb25zaXN0cyBvZiBvZmZzZXRzIHRvIHRoZSB2YWx1ZXMgKHZrKQogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlTdWJCbG9ja0lkOwkJLyogMHgwMCAweDZCNkUgKi8KICAgIFdPUkQJVHlwZTsJCQkvKiAweDAyIGZvciB0aGUgcm9vdC1rZXk6IDB4MkMsIG90aGVyd2lzZSAweDIwKi8KICAgIEZJTEVUSU1FCXdyaXRldGltZTsJLyogMHgwNCAqLwogICAgRFdPUkQJdWsxOwkJCS8qIDB4MEMgKi8KICAgIERXT1JECXBhcmVudF9vZmY7CQkvKiAweDEwIE9mZnNldCBvZiBPd25lci9QYXJlbnQga2V5ICovCiAgICBEV09SRAlucl9zdWJrZXlzOwkJLyogMHgxNCBudW1iZXIgb2Ygc3ViLUtleXMgKi8KICAgIERXT1JECXVrODsJCQkvKiAweDE4ICovCiAgICBEV09SRAlsZl9vZmY7CQkJLyogMHgxQyBPZmZzZXQgb2YgdGhlIHN1Yi1rZXkgbGYtUmVjb3JkcyAqLwogICAgRFdPUkQJdWsyOwkJCS8qIDB4MjAgKi8KICAgIERXT1JECW5yX3ZhbHVlczsJCS8qIDB4MjQgbnVtYmVyIG9mIHZhbHVlcyAqLwogICAgRFdPUkQJdmFsdWVsaXN0X29mZjsJCS8qIDB4MjggT2Zmc2V0IG9mIHRoZSBWYWx1ZS1MaXN0ICovCiAgICBEV09SRAlvZmZfc2s7CQkJLyogMHgyYyBPZmZzZXQgb2YgdGhlIHNrLVJlY29yZCAqLwogICAgRFdPUkQJb2ZmX2NsYXNzOwkJLyogMHgzMCBPZmZzZXQgb2YgdGhlIENsYXNzLU5hbWUgKi8KICAgIERXT1JECXVrMzsJCQkvKiAweDM0ICovCiAgICBEV09SRAl1azQ7CQkJLyogMHgzOCAqLwogICAgRFdPUkQJdWs1OwkJCS8qIDB4M2MgKi8KICAgIERXT1JECXVrNjsJCQkvKiAweDQwICovCiAgICBEV09SRAl1azc7CQkJLyogMHg0NCAqLwogICAgV09SRAluYW1lX2xlbjsJCS8qIDB4NDggbmFtZS1sZW5ndGggKi8KICAgIFdPUkQJY2xhc3NfbGVuOwkJLyogMHg0YSBjbGFzcy1uYW1lIGxlbmd0aCAqLwogICAgY2hhcgluYW1lWzFdOwkJLyogMHg0YyBrZXktbmFtZSAqLwp9IG50X25rOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJb2ZmX25rOwkvKiAweDAwICovCiAgICBEV09SRAluYW1lOwkvKiAweDA0ICovCn0gaGFzaF9yZWM7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY2NmMgKi8KICAgIFdPUkQJbnJfa2V5czsJLyogMHgwNiAqLwogICAgaGFzaF9yZWMJaGFzaF9yZWNbMV07Cn0gbnRfbGY7CgovKgogbGlzdCBvZiBzdWJrZXlzIHdpdGhvdXQgaGFzaAoKIGxpIC0tKy0tPm5rCiAgICAgIHwKICAgICAgKy0tPm5rCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY5NmMgKi8KICAgIFdPUkQJbnJfa2V5czsKICAgIERXT1JECW9mZl9ua1sxXTsKfSBudF9saTsKCi8qCiB0aGlzIGlzIGEgaW50ZXJtZWRpYXRlIG5vZGUKCiByaSAtLSstLT5saS0tKy0tPm5rCiAgICAgIHwgICAgICAgKwogICAgICB8ICAgICAgICstLT5uawogICAgICB8CiAgICAgICstLT5saS0tKy0tPm5rCiAgICAgICAgICAgICAgKwoJICAgICAgKy0tPm5rCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY5NzIgKi8KICAgIFdPUkQJbnJfbGk7CQkvKiAweDAyIG51bWJlciBvZmYgb2Zmc2V0cyAqLwogICAgRFdPUkQJb2ZmX2xpWzFdOwkvKiAweDA0IHBvaW50cyB0byBsaSAqLwp9IG50X3JpOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgJ3ZrJyAqLwogICAgV09SRAluYW1fbGVuOwogICAgRFdPUkQJZGF0YV9sZW47CiAgICBEV09SRAlkYXRhX29mZjsKICAgIERXT1JECXR5cGU7CiAgICBXT1JECWZsYWc7CiAgICBXT1JECXVrMTsKICAgIGNoYXIJbmFtZVsxXTsKfSBudF92azsKCi8qCiAqIGdldHMgYSB2YWx1ZQogKgogKiB2ay0+ZmxhZzoKICogIDAgdmFsdWUgaXMgYSBkZWZhdWx0IHZhbHVlCiAqICAxIHRoZSB2YWx1ZSBoYXMgYSBuYW1lCiAqCiAqIHZrLT5kYXRhX2xlbgogKiAgbGVuIG9mIHRoZSB3aG9sZSBkYXRhIGJsb2NrCiAqICAtIHJlZ19zeiAodW5pY29kZSkKICogICAgYnl0ZXMgaW5jbHVkaW5nIHRoZSB0ZXJtaW5hdGluZyBcMCA9IDIqKG51bWJlcl9vZl9jaGFycysxKQogKiAgLSByZWdfZHdvcmQsIHJlZ19iaW5hcnk6CiAqICAgIGlmIGhpZ2hlc3QgYml0IG9mIGRhdGFfbGVuIGlzIHNldCBkYXRhX29mZiBjb250YWlucyB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQgX250X2R1bXBfdmsoTFBTVFIga2V5X25hbWUsIGNoYXIgKmJhc2UsIG50X3ZrICp2ayxGSUxFICpmKQp7CiAgICBCWVRFICpwZGF0YSA9IChCWVRFICopKGJhc2UrdmstPmRhdGFfb2ZmKzQpOyAvKiBzdGFydCBvZiBkYXRhICovCiAgICBzdHJ1Y3Qga2V5X3ZhbHVlIHZhbHVlOwoKICAgIGlmICh2ay0+aWQgIT0gTlRfUkVHX1ZBTFVFX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmtub3duIGJsb2NrIGZvdW5kICgweCUwNHgpLCBwbGVhc2UgcmVwb3J0IVxuIiwgdmstPmlkKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgdmFsdWUubmFtZVcgPSBfc3RyZHVwbkF0b1codmstPm5hbWUsdmstPm5hbV9sZW4pOwogICAgdmFsdWUudHlwZSA9IHZrLT50eXBlOwogICAgdmFsdWUubGVuID0gKHZrLT5kYXRhX2xlbiAmIDB4N2ZmZmZmZmYpOwogICAgdmFsdWUuZGF0YSA9ICh2ay0+ZGF0YV9sZW4gJiAweDgwMDAwMDAwKSA/IChMUEJZVEUpJih2ay0+ZGF0YV9vZmYpOiBwZGF0YTsKCiAgICBfZHVtcF92YWx1ZSgmdmFsdWUsZik7CiAgICBmcmVlKHZhbHVlLm5hbWVXKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyogaXQncyBjYWxsZWQgZnJvbSBfbnRfZHVtcF9sZigpICovCnN0YXRpYyBpbnQgX250X2R1bXBfbmsoTFBTVFIga2V5X25hbWUsY2hhciAqYmFzZSxudF9uayAqbmssRklMRSAqZixpbnQgbGV2ZWwpOwoKLyoKICogZ2V0IHRoZSBzdWJrZXlzCiAqCiAqIHRoaXMgc3RydWN0dXJlIGNvbnRhaW5zIHRoZSBoYXNoIG9mIGEga2V5bmFtZSBhbmQgcG9pbnRzIHRvIGFsbAogKiBzdWJrZXlzCiAqCiAqIGV4Y2VwdGlvbjogaWYgdGhlIGlkIGlzICdpbCcgdGhlcmUgYXJlIG5vIGhhc2ggdmFsdWVzIGFuZCBldmVyeSAKICogZHdvcmQgaXMgYSBvZmZzZXQKICovCnN0YXRpYyBpbnQgX250X2R1bXBfbGYoTFBTVFIga2V5X25hbWUsIGNoYXIgKmJhc2UsIGludCBzdWJrZXlzLCBudF9sZiAqbGYsIEZJTEUgKmYsIGludCBsZXZlbCkKewogICAgaW50IGk7CiAgICAKICAgIGlmIChsZi0+aWQgPT0gTlRfUkVHX0hBU0hfQkxPQ0tfSUQpIHsKICAgICAgICBpZiAoc3Via2V5cyAhPSBsZi0+bnJfa2V5cykgZ290byBlcnJvcjE7CiAgICAKICAgICAgICBmb3IgKGk9MDsgaTxsZi0+bnJfa2V5czsgaSsrKSAKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9uayhrZXlfbmFtZSwgYmFzZSwgKG50X25rKikoYmFzZStsZi0+aGFzaF9yZWNbaV0ub2ZmX25rKzQpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKSB7CiAgICAgICAgbnRfbGkgKiBsaSA9IChudF9saSopbGY7CiAgICAgICAgaWYgKHN1YmtleXMgIT0gbGktPm5yX2tleXMpIGdvdG8gZXJyb3IxOwoKICAgICAgICBmb3IgKGk9MDsgaTxsaS0+bnJfa2V5czsgaSsrKQogICAgICAgICAgICBpZiAoIV9udF9kdW1wX25rKGtleV9uYW1lLCBiYXNlLCAobnRfbmsqKShiYXNlK2xpLT5vZmZfbmtbaV0rNCksIGYsIGxldmVsKSkgZ290byBlcnJvcjsKICAgIH0gZWxzZSBpZiAobGYtPmlkID09IE5UX1JFR19SSV9CTE9DS19JRCkgeyAgLyogcmkgKi8KICAgICAgICBudF9yaSAqIHJpID0gKG50X3JpKilsZjsKICAgICAgICBpbnQgbGlfc3Via2V5cyA9IDA7CgogICAgICAgIC8qIGNvdW50IGFsbCBzdWJrZXlzICovCiAgICAgICAgZm9yIChpPTA7IGk8cmktPm5yX2xpOyBpKyspIHsKICAgICAgICAgICAgbnRfbGkgKiBsaSA9IChudF9saSopKGJhc2UrcmktPm9mZl9saVtpXSs0KTsKICAgICAgICAgICAgaWYobGktPmlkICE9IE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQpIGdvdG8gZXJyb3IyOwogICAgICAgICAgICBsaV9zdWJrZXlzICs9IGxpLT5ucl9rZXlzOwogICAgICAgIH0KCiAgICAgICAgLyogY2hlY2sgbnVtYmVyICovCiAgICAgICAgaWYgKHN1YmtleXMgIT0gbGlfc3Via2V5cykgZ290byBlcnJvcjE7CgogICAgICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUga2V5cyAqLwogICAgICAgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKSB7CiAgICAgICAgICAgIG50X2xpICpsaSA9IChudF9saSopKGJhc2UrcmktPm9mZl9saVtpXSs0KTsKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9sZihrZXlfbmFtZSwgYmFzZSwgbGktPm5yX2tleXMsIChudF9sZiopbGksIGYsIGxldmVsKSkgZ290byBlcnJvcjsKICAgICAgICB9CiAgICB9IGVsc2UgZ290byBlcnJvcjI7CgogICAgcmV0dXJuIFRSVUU7CgplcnJvcjI6CiAgICBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBsZi0+aWQpOwogICAgcmV0dXJuIFRSVUU7CgplcnJvcjE6CiAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgKGluY29uc2lzdGVudCBudW1iZXIgb2Ygc3Via2V5cylcbiIpOwogICAgcmV0dXJuIEZBTFNFOwoKZXJyb3I6CiAgICBFUlIoImVycm9yIHJlYWRpbmcgbGYgYmxvY2tcbiIpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKiBfbnRfZHVtcF9uayBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX250X2R1bXBfbmsoTFBTVFIga2V5X25hbWUsY2hhciAqYmFzZSxudF9uayAqbmssRklMRSAqZixpbnQgbGV2ZWwpCnsKICAgIHVuc2lnbmVkIGludCBuOwogICAgRFdPUkQgKnZsOwogICAgTFBTVFIgbmV3X2tleV9uYW1lID0gTlVMTDsKCgogICAgaWYgKG5rLT5TdWJCbG9ja0lkICE9IE5UX1JFR19LRVlfQkxPQ0tfSUQpIHsKICAgICAgICBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBuay0+U3ViQmxvY2tJZCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICgobmstPlR5cGUhPU5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKSAmJiAoKChudF9uayopKGJhc2UrbmstPnBhcmVudF9vZmYrNCkpLT5TdWJCbG9ja0lkICE9IE5UX1JFR19LRVlfQkxPQ0tfSUQpKSB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhXG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgLyogY3JlYXRlIHRoZSBuZXcga2V5ICovCiAgICBpZiAobGV2ZWwgPD0gMCkgewogICAgICAgIC8qIGNyZWF0ZSBuZXcgc3Via2V5IG5hbWUgKi8KICAgICAgICBuZXdfa2V5X25hbWUgPSBfc3RyZHVwbkEoa2V5X25hbWUsc3RybGVuKGtleV9uYW1lKStuay0+bmFtZV9sZW4rMSk7CiAgICAgICAgaWYgKHN0cmNtcChuZXdfa2V5X25hbWUsIiIpICE9IDApIHN0cmNhdChuZXdfa2V5X25hbWUsIlxcIik7CiAgICAgICAgc3RybmNhdChuZXdfa2V5X25hbWUsbmstPm5hbWUsbmstPm5hbWVfbGVuKTsKCiAgICAgICAgLyogd3JpdGUgdGhlIGtleSBwYXRoIChzb21ldGhpbmcgbGlrZSBbU29mdHdhcmVcXE1pY3Jvc29mdFxcLi5dKSBvbmx5IGlmOiAKICAgICAgICAgICAxKSBrZXkgaGFzIHNvbWUgdmFsdWVzCiAgICAgICAgICAgMikga2V5IGhhcyBubyB2YWx1ZXMgYW5kIG5vIHN1YmtleXMKICAgICAgICAqLwogICAgICAgIGlmIChuay0+bnJfdmFsdWVzID4gMCkgewogICAgICAgICAgICAvKiB0aGVyZSBhcmUgc29tZSB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKChuay0+bnJfc3Via2V5cyA9PSAwKSAmJiAobmstPm5yX3ZhbHVlcyA9PSAwKSkgewogICAgICAgICAgICAvKiBubyBzdWJrZXlzIGFuZCBubyB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICB9CgogICAgICAgIC8qIGxvb3AgdHJvdWdoIHRoZSB2YWx1ZSBsaXN0ICovCiAgICAgICAgdmwgPSAoRFdPUkQgKikoYmFzZStuay0+dmFsdWVsaXN0X29mZis0KTsKICAgICAgICBmb3IgKG49MDsgbjxuay0+bnJfdmFsdWVzOyBuKyspIHsKICAgICAgICAgICAgbnRfdmsgKiB2ayA9IChudF92ayopKGJhc2Urdmxbbl0rNCk7CiAgICAgICAgICAgIGlmICghX250X2R1bXBfdmsobmV3X2tleV9uYW1lLCBiYXNlLCB2aywgZikpIHsKICAgICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSBuZXdfa2V5X25hbWUgPSBfc3RyZHVwbkEoa2V5X25hbWUsc3RybGVuKGtleV9uYW1lKSk7CgogICAgLyogbG9vcCB0aHJvdWdoIHRoZSBzdWJrZXlzICovCiAgICBpZiAobmstPm5yX3N1YmtleXMpIHsKICAgICAgICBudF9sZiAqbGYgPSAobnRfbGYqKShiYXNlK25rLT5sZl9vZmYrNCk7CiAgICAgICAgaWYgKCFfbnRfZHVtcF9sZihuZXdfa2V5X25hbWUsIGJhc2UsIG5rLT5ucl9zdWJrZXlzLCBsZiwgZiwgbGV2ZWwtMSkpIHsKICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgIHJldHVybiBUUlVFOwp9CgovKiBlbmQgbnQgbG9hZGVyICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2V0X3JlZ2lzdHJ5X2xldmVscyBbSW50ZXJuYWxdCiAqCiAqIHNldCBsZXZlbCB0byAwIGZvciBsb2FkaW5nIHN5c3RlbSBmaWxlcwogKiBzZXQgbGV2ZWwgdG8gMSBmb3IgbG9hZGluZyB1c2VyIGZpbGVzCiAqLwpzdGF0aWMgdm9pZCBfc2V0X3JlZ2lzdHJ5X2xldmVscyhpbnQgbGV2ZWwsaW50IHNhdmluZyxpbnQgcGVyaW9kKQp7CiAgICBTRVJWRVJfU1RBUlRfUkVRKCBzZXRfcmVnaXN0cnlfbGV2ZWxzICkKICAgIHsKCXJlcS0+Y3VycmVudCA9IGxldmVsOwoJcmVxLT5zYXZpbmcgID0gc2F2aW5nOwogICAgICAgIHJlcS0+cGVyaW9kICA9IHBlcmlvZDsKICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgIH0KICAgIFNFUlZFUl9FTkRfUkVROwp9CgovKiBfc2F2ZV9hdF9leGl0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX3NhdmVfYXRfZXhpdChIS0VZIGhrZXksTFBDU1RSIHBhdGgpCnsKICAgIExQQ1NUUiBjb25mZGlyID0gZ2V0X2NvbmZpZ19kaXIoKTsKCiAgICBTRVJWRVJfU1RBUlRfUkVRKCBzYXZlX3JlZ2lzdHJ5X2F0ZXhpdCApCiAgICB7CiAgICAgICAgcmVxLT5oa2V5ID0gaGtleTsKICAgICAgICB3aW5lX3NlcnZlcl9hZGRfZGF0YSggcmVxLCBjb25mZGlyLCBzdHJsZW4oY29uZmRpcikgKTsKICAgICAgICB3aW5lX3NlcnZlcl9hZGRfZGF0YSggcmVxLCBwYXRoLCBzdHJsZW4ocGF0aCkrMSApOwogICAgICAgIHdpbmVfc2VydmVyX2NhbGwoIHJlcSApOwogICAgfQogICAgU0VSVkVSX0VORF9SRVE7Cn0KCi8qIGNvbmZpZ3VyZSBzYXZlIGZpbGVzIGFuZCBzdGFydCB0aGUgcGVyaW9kaWMgc2F2aW5nIHRpbWVyIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2luaXRfcmVnaXN0cnlfc2F2aW5nKCBIS0VZIGhrZXlfdXNlcnNfZGVmYXVsdCApCnsKICAgIGludCBhbGw7CiAgICBpbnQgcGVyaW9kOwoKICAgIGFsbCAgPSBQUk9GSUxFX0dldFdpbmVJbmlCb29sKCJyZWdpc3RyeSIsIlNhdmVPbmx5VXBkYXRlZEtleXMiLDEpOwogICAgcGVyaW9kID0gUFJPRklMRV9HZXRXaW5lSW5pSW50KCJyZWdpc3RyeSIsIlBlcmlvZGljU2F2ZSIsMCk7CgogICAgLyogc2V0IHNhdmluZyBsZXZlbCAoMCBmb3Igc2F2aW5nIGV2ZXJ5dGhpbmcsIDEgZm9yIHNhdmluZyBvbmx5IG1vZGlmaWVkIGtleXMpICovCiAgICBfc2V0X3JlZ2lzdHJ5X2xldmVscygxLCFhbGwscGVyaW9kKjEwMDApOwoKICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sKCJyZWdpc3RyeSIsIldyaXRldG9Ib21lUmVnaXN0cnlGaWxlcyIsMSkpCiAgICB7CiAgICAgICAgX3NhdmVfYXRfZXhpdChIS0VZX0NVUlJFTlRfVVNFUiwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfQ1VSUkVOVF9VU0VSICk7CiAgICAgICAgX3NhdmVfYXRfZXhpdChIS0VZX0xPQ0FMX01BQ0hJTkUsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUpOwogICAgICAgIF9zYXZlX2F0X2V4aXQoaGtleV91c2Vyc19kZWZhdWx0LCIvIiBTQVZFX0xPQ0FMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQpOwogICAgfQoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzIFtJbnRlcm5hbF0KICogUmVnaXN0cnkgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBzb21lIGRlZmF1bHQga2V5cy4gCiAqLwpzdGF0aWMgdm9pZCBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzKHZvaWQpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJVFJBQ0UoIih2b2lkKVxuIik7CgoJUmVnQ3JlYXRlS2V5QShIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXhBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3dzIE5UXFxDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50QnVpbGROdW1iZXIKCSAqCQkJCQkJQ3VycmVudFR5cGUKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE93bmVyCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPcmdhbml6YXRpb24KCSAqCgkgKi8KCS8qIFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTTk1QXFxQYXJhbWV0ZXJzXFxSRkMxMTU2QWdlbnQKCSAqIAkJCQkJc3RyaW5nCVN5c0NvbnRhY3QKCSAqIAkJCQkJc3RyaW5nCVN5c0xvY2F0aW9uCgkgKiAJCQkJCQlTeXNTZXJ2aWNlcwoJICovCglpZiAoLTEhPWdldGhvc3RuYW1lKGJ1ZiwyMDApKSB7CgkJUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXENvbnRyb2xcXENvbXB1dGVyTmFtZVxcQ29tcHV0ZXJOYW1lIiwmaGtleSk7CgkJUmVnU2V0VmFsdWVFeEEoaGtleSwiQ29tcHV0ZXJOYW1lIiwwLFJFR19TWixidWYsc3RybGVuKGJ1ZikrMSk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9CgogICAgICAgIFJlZ0NyZWF0ZUtleUEoSEtFWV9VU0VSUywiLkRlZmF1bHQiLCZoa2V5KTsKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKfQoKI2RlZmluZSBSRUdfRE9OVExPQUQgLTEKI2RlZmluZSBSRUdfV0lOMzEgICAgIDAKI2RlZmluZSBSRUdfV0lOOTUgICAgIDEKI2RlZmluZSBSRUdfV0lOTlQgICAgIDIKCi8qIHJldHVybiB0aGUgdHlwZSBvZiBuYXRpdmUgcmVnaXN0cnkgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9nZXRfcmVnX3R5cGUodm9pZCkKewogICAgY2hhciB3aW5kaXJbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBjaGFyIHRtcFtNQVhfUEFUSE5BTUVfTEVOXTsKICAgIGludCByZXQgPSBSRUdfV0lOMzE7CgogICAgR2V0V2luZG93c0RpcmVjdG9yeUEod2luZGlyLE1BWF9QQVRITkFNRV9MRU4pOwoKICAgIC8qIHRlc3QgJXdpbmRpciUvc3lzdGVtMzIvY29uZmlnL3N5c3RlbSAtLT4gd2lubnQgKi8KICAgIHN0cmNweSh0bXAsIHdpbmRpcik7CiAgICBzdHJuY2F0KHRtcCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc3lzdGVtIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbih0bXApIC0gMSk7CiAgICBpZihHZXRGaWxlQXR0cmlidXRlc0EodG1wKSAhPSAoRFdPUkQpLTEpIHsKICAgICAgcmV0ID0gUkVHX1dJTk5UOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0uZGF0IC0tPiB3aW45NSAqLwogICAgICBzdHJjcHkodG1wLCB3aW5kaXIpOwogICAgICBzdHJuY2F0KHRtcCwgIlxcc3lzdGVtLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4odG1wKSAtIDEpOwogICAgICBpZihHZXRGaWxlQXR0cmlidXRlc0EodG1wKSAhPSAoRFdPUkQpLTEpIHsKICAgICAgICByZXQgPSBSRUdfV0lOOTU7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoKHJldCA9PSBSRUdfV0lOTlQpICYmICghUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiV2luZSIsICJQcm9maWxlIiwgIiIsIHRtcCwgTUFYX1BBVEhOQU1FX0xFTikpKSB7CiAgICAgICBNRVNTQUdFKCJXaGVuIHlvdSBhcmUgcnVubmluZyB3aXRoIGEgbmF0aXZlIE5UIGRpcmVjdG9yeSBzcGVjaWZ5XG4iKTsKICAgICAgIE1FU1NBR0UoIidQcm9maWxlPTxwcm9maWxlZGlyZWN0b3J5Picgb3IgZGlzYWJsZSBsb2FkaW5nIG9mIFdpbmRvd3NcbiIpOwogICAgICAgTUVTU0FHRSgicmVnaXN0cnkgKExvYWRXaW5kb3dzUmVnaXN0cnlGaWxlcz1OKVxuIik7CiAgICAgICByZXQgPSBSRUdfRE9OVExPQUQ7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKI2RlZmluZSBXSU5FX1JFR19WRVJfRVJST1IgIC0xCiNkZWZpbmUgV0lORV9SRUdfVkVSXzEgICAgICAgMAojZGVmaW5lIFdJTkVfUkVHX1ZFUl8yICAgICAgIDEKI2RlZmluZSBXSU5FX1JFR19WRVJfT0xEICAgICAyCiNkZWZpbmUgV0lORV9SRUdfVkVSX1VOS05PV04gMwoKLyogcmV0dXJuIHRoZSB2ZXJzaW9uIG9mIHdpbmUgcmVnaXN0cnkgZmlsZSBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX2dldF93aW5lX3JlZ2lzdHJ5X2ZpbGVfZm9ybWF0X3ZlcnNpb24oTFBDU1RSIGZuKQp7CiAgICBGSUxFICpmOwogICAgY2hhciB0bXBbNTBdOwogICAgaW50IHZlcjsKCiAgICBpZiAoKGY9Zm9wZW4oZm4sInJ0IikpID09IE5VTEwpIHsKICAgICAgICBXQVJOKCJDb3VsZG4ndCBvcGVuICVzIGZvciByZWFkaW5nOiAlc1xuIixmbixzdHJlcnJvcihlcnJubykpOwogICAgICAgIHJldHVybiBXSU5FX1JFR19WRVJfRVJST1I7CiAgICB9CgogICAgaWYgKGZnZXRzKHRtcCw1MCxmKSA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiRXJyb3IgcmVhZGluZyAlczogJXNcbiIsZm4sc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICBmY2xvc2UoZik7CiAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl9FUlJPUjsKICAgIH0KICAgIGZjbG9zZShmKTsKCiAgICBpZiAoc3NjYW5mKHRtcCwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIiwmdmVyKSAhPSAxKSByZXR1cm4gV0lORV9SRUdfVkVSX1VOS05PV047CiAgICBzd2l0Y2ggKHZlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl8xOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBXSU5FX1JFR19WRVJfMjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIFdJTkVfUkVHX1ZFUl9VTktOT1dOOwogICAgfQp9CgovKiBsb2FkIHRoZSByZWdpc3RyeSBmaWxlIGluIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgbG9hZF93aW5lX3JlZ2lzdHJ5KEhLRVkgaGtleSxMUENTVFIgZm4pCnsKICAgIGludCBmaWxlX2Zvcm1hdDsKCiAgICBmaWxlX2Zvcm1hdCA9IF9nZXRfd2luZV9yZWdpc3RyeV9maWxlX2Zvcm1hdF92ZXJzaW9uKGZuKTsKICAgIHN3aXRjaCAoZmlsZV9mb3JtYXQpIHsKCiAgICAgICAgY2FzZSBXSU5FX1JFR19WRVJfMToKICAgICAgICAgICAgV0FSTigiVW5hYmxlIHRvIGxvYWQgcmVnaXN0cnkgZmlsZSAlczogb2xkIGZvcm1hdCB3aGljaCBpcyBubyBsb25nZXIgc3VwcG9ydGVkLlxuIixmbik7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVfUkVHX1ZFUl8yOiB7CiAgICAgICAgICAgIEhBTkRMRSBmaWxlOwogICAgICAgICAgICBpZiAoKGZpbGUgPSBGSUxFX0NyZWF0ZUZpbGUoIGZuLCBHRU5FUklDX1JFQUQsIDAsIE5VTEwsIE9QRU5fRVhJU1RJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFX0FUVFJJQlVURV9OT1JNQUwsIDAsIFRSVUUsIERSSVZFX1VOS05PV04gKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNFUlZFUl9TVEFSVF9SRVEoIGxvYWRfcmVnaXN0cnkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlcS0+aGtleSAgICA9IGhrZXk7CiAgICAgICAgICAgICAgICAgICAgcmVxLT5maWxlICAgID0gZmlsZTsKICAgICAgICAgICAgICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFNFUlZFUl9FTkRfUkVROwogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGZpbGUgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgV0lORV9SRUdfVkVSX1VOS05PV046CiAgICAgICAgICAgIFdBUk4oIlVuYWJsZSB0byBsb2FkIHJlZ2lzdHJ5IGZpbGUgJXM6IHVua25vd24gZm9ybWF0LlxuIixmbik7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVfUkVHX1ZFUl9FUlJPUjoKICAgICAgICAgICAgYnJlYWs7CiAgICB9Cn0KCi8qIGdlbmVyYXRlIGFuZCByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHRtcCBmaWxlIGFuZCBhc3NvY2lhdGVkIHN0cmVhbSBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfZ2V0X3RtcF9mbihGSUxFICoqZikKewogICAgTFBTVFIgcmV0OwogICAgaW50IHRtcF9mZCxjb3VudDsKCiAgICByZXQgPSBfeG1hbGxvYyg1MCk7CiAgICBmb3IgKGNvdW50ID0gMDs7KSB7CiAgICAgICAgc3ByaW50ZihyZXQsIi90bXAvcmVnJWx4JTA0eC50bXAiLChsb25nKWdldHBpZCgpLGNvdW50KyspOwogICAgICAgIGlmICgodG1wX2ZkID0gb3BlbihyZXQsT19DUkVBVCB8IE9fRVhDTCB8IE9fV1JPTkxZLDA2NjYpKSAhPSAtMSkgYnJlYWs7CiAgICAgICAgaWYgKGVycm5vICE9IEVFWElTVCkgewogICAgICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgZXJyb3Igd2hpbGUgb3BlbigpIGNhbGw6ICVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgIGZyZWUocmV0KTsKICAgICAgICAgICAgKmYgPSBOVUxMOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCgqZiA9IGZkb3Blbih0bXBfZmQsInciKSkgPT0gTlVMTCkgewogICAgICAgIEVSUigiVW5leHBlY3RlZCBlcnJvciB3aGlsZSBmZG9wZW4oKSBjYWxsOiAlc1xuIixzdHJlcnJvcihlcnJubykpOwogICAgICAgIGNsb3NlKHRtcF9mZCk7CiAgICAgICAgZnJlZShyZXQpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgd2luOTUgbmF0aXZlIHJlZ2lzdHJ5IGZpbGUgdG8gd2luZSBmb3JtYXQgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX2NvbnZlcnRfd2luOTVfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoTFBDU1RSIGZuLGludCBsZXZlbCkKewogICAgaW50IGZkOwogICAgRklMRSAqZjsKICAgIERPU19GVUxMX05BTUUgZnVsbF9uYW1lOwogICAgdm9pZCAqYmFzZTsKICAgIExQU1RSIHJldCA9IE5VTEw7CiAgICBzdHJ1Y3Qgc3RhdCBzdDsKCiAgICBfdzk1Y3JlZyAqY3JlZzsKICAgIF93OTVyZ2tuICpyZ2tuOwogICAgX3c5NWRrZSAqZGtlLCAqcm9vdF9ka2U7CgogICAgaWYgKCFET1NGU19HZXRGdWxsTmFtZSggZm4sIDAsICZmdWxsX25hbWUgKSkgcmV0dXJuIE5VTEw7CgogICAgLyogbWFwIHRoZSByZWdpc3RyeSBpbnRvIHRoZSBtZW1vcnkgKi8KICAgIGlmICgoZmQgPSBvcGVuKGZ1bGxfbmFtZS5sb25nX25hbWUsIE9fUkRPTkxZIHwgT19OT05CTE9DSykpID09IC0xKSByZXR1cm4gTlVMTDsKICAgIGlmICgoZnN0YXQoZmQsICZzdCkgPT0gLTEpKSBnb3RvIGVycm9yMTsKICAgIGlmICghc3Quc3Rfc2l6ZSkgZ290byBlcnJvcjE7CiAgICBpZiAoKGJhc2UgPSBtbWFwKE5VTEwsIHN0LnN0X3NpemUsIFBST1RfUkVBRCwgTUFQX1BSSVZBVEUsIGZkLCAwKSkgPT0gTUFQX0ZBSUxFRCkgZ290byBlcnJvcjE7CgogICAgLyogY29udHJvbCBzaWduYXR1cmUgKi8KICAgIGlmICgqKExQRFdPUkQpYmFzZSAhPSBXOTVfUkVHX0NSRUdfSUQpIHsKICAgICAgICBFUlIoInVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW45NSByZWdpc3RyeSBmaWxlICVzOiB1bmtub3duIHNpZ25hdHVyZS5cbiIsZm4pOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgY3JlZyA9IGJhc2U7CiAgICAvKiBsb2FkIHRoZSBoZWFkZXIgKHJna24pICovCiAgICByZ2tuID0gKF93OTVyZ2tuKikoY3JlZyArIDEpOwogICAgaWYgKHJna24tPmlkICE9IFc5NV9SRUdfUkdLTl9JRCkgewogICAgICAgIEVSUigic2Vjb25kIElGRiBoZWFkZXIgbm90IFJHS04sIGJ1dCAlbHhcbiIsIHJna24tPmlkKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHJna24tPnJvb3Rfb2ZmICE9IDB4MjApIHsKICAgICAgICBFUlIoInJna24tPnJvb3Rfb2ZmIG5vdCAweDIwLCBwbGVhc2UgcmVwb3J0ICFcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+bGFzdF9ka2UgPiByZ2tuLT5zaXplKQogICAgewogICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgbGFzdF9ka2UgPiBzaXplIVxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICAvKiB2ZXJpZnkgbGFzdCBka2UgKi8KICAgIGRrZSA9IChfdzk1ZGtlKikoKGNoYXIqKXJna24gKyByZ2tuLT5sYXN0X2RrZSk7CiAgICBpZiAoZGtlLT54MSAhPSAweDgwMDAwMDAwKQogICAgeyAvKiB3cm9uZyBtYWdpYyAqLwogICAgICBFUlIoImxhc3QgZGtlIGludmFsaWQgIVxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+c2l6ZSA+IGNyZWctPnJnZGJfb2ZmKQogICAgewogICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgcmdrbiBzaXplID4gcmdkYl9vZmYgIVxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICByb290X2RrZSA9IChfdzk1ZGtlKikoKGNoYXIqKXJna24gKyByZ2tuLT5yb290X29mZik7CiAgICBpZiAoIChyb290X2RrZS0+cHJldmx2bCAhPSAweGZmZmZmZmZmKSB8fCAocm9vdF9ka2UtPm5leHQgIT0gMHhmZmZmZmZmZikgKQogICAgewogICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISBpbnZhbGlkIHJvb3QgZGtlICFcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKCAocmV0ID0gX2dldF90bXBfZm4oJmYpKSA9PSBOVUxMKSBnb3RvIGVycm9yOwogICAgZnByaW50ZihmLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gMiIpOwogICAgX3c5NV9kdW1wX2RrZSgiIixjcmVnLHJna24scm9vdF9ka2UsZixsZXZlbCk7CiAgICBmY2xvc2UoZik7CgplcnJvcjoKICAgIGlmKHJldCA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJVbmFibGUgdG8gbG9hZCBuYXRpdmUgd2luOTUgcmVnaXN0cnkgZmlsZSAlcy5cbiIsZm4pOwogICAgICAgIEVSUigiUGxlYXNlIHJlcG9ydCB0byBhLm1vaHJAbWFpbHRvLmRlLlxuIik7CiAgICAgICAgRVJSKCJNYWtlIGEgYmFja3VwIG9mIHRoZSBmaWxlLCBydW4gYSBnb29kIHJlZyBjbGVhbmVyIHByb2dyYW0gYW5kIHRyeSBhZ2FpbiFcbiIpOwogICAgfQoKICAgIG11bm1hcChiYXNlLCBzdC5zdF9zaXplKTsKZXJyb3IxOgogICAgY2xvc2UoZmQpOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCB3aW5udCBuYXRpdmUgcmVnaXN0cnkgZmlsZSB0byB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfY29udmVydF93aW5udF9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChMUENTVFIgZm4saW50IGxldmVsKQp7CiAgICBpbnQgZmQ7CiAgICBGSUxFICpmOwogICAgRE9TX0ZVTExfTkFNRSBmdWxsX25hbWU7CiAgICB2b2lkICpiYXNlOwogICAgTFBTVFIgcmV0ID0gTlVMTDsKICAgIHN0cnVjdCBzdGF0IHN0OwoKICAgIG50X3JlZ2YgKnJlZ2Y7CiAgICBudF9oYmluICpoYmluOwogICAgbnRfaGJpbl9zdWIgKmhiaW5fc3ViOwogICAgbnRfbmsgKm5rOwoKICAgIGlmICghRE9TRlNfR2V0RnVsbE5hbWUoIGZuLCAwLCAmZnVsbF9uYW1lICkpIHJldHVybiBOVUxMOwoKICAgIC8qIG1hcCB0aGUgcmVnaXN0cnkgaW50byB0aGUgbWVtb3J5ICovCiAgICBpZiAoKGZkID0gb3BlbihmdWxsX25hbWUubG9uZ19uYW1lLCBPX1JET05MWSB8IE9fTk9OQkxPQ0spKSA9PSAtMSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoKGZzdGF0KGZkLCAmc3QpID09IC0xKSkgZ290byBlcnJvcjE7CiAgICBpZiAoIXN0LnN0X3NpemUpIGdvdG8gZXJyb3IxOwogICAgaWYgKChiYXNlID0gbW1hcChOVUxMLCBzdC5zdF9zaXplLCBQUk9UX1JFQUQsIE1BUF9QUklWQVRFLCBmZCwgMCkpID09IE1BUF9GQUlMRUQpIGdvdG8gZXJyb3IxOwoKICAgIC8qIGNvbnRyb2wgc2lnbmF0dXJlICovCiAgICBpZiAoKihMUERXT1JEKWJhc2UgIT0gTlRfUkVHX0hFQURFUl9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5hYmxlIHRvIGxvYWQgbmF0aXZlIHdpbm50IHJlZ2lzdHJ5IGZpbGUgJXM6IHVua25vd24gc2lnbmF0dXJlLlxuIixmbik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBzdGFydCBibG9jayAqLwogICAgcmVnZiA9IGJhc2U7CgogICAgLyogaGJpbiBibG9jayAqLwogICAgaGJpbiA9IChudF9oYmluKikoKGNoYXIqKSBiYXNlICsgMHgxMDAwKTsKICAgIGlmIChoYmluLT5pZCAhPSBOVF9SRUdfUE9PTF9CTE9DS19JRCkgewogICAgICBFUlIoICJoYmluIGJsb2NrIGludmFsaWRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIGhiaW5fc3ViIGJsb2NrICovCiAgICBoYmluX3N1YiA9IChudF9oYmluX3N1YiopJihoYmluLT5oYmluX3N1Yik7CiAgICBpZiAoKGhiaW5fc3ViLT5kYXRhWzBdICE9ICduJykgfHwgKGhiaW5fc3ViLT5kYXRhWzFdICE9ICdrJykpIHsKICAgICAgRVJSKCAiaGJpbl9zdWIgYmxvY2sgaW52YWxpZFxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogbmsgYmxvY2sgKi8KICAgIG5rID0gKG50X25rKikmKGhiaW5fc3ViLT5kYXRhWzBdKTsKICAgIGlmIChuay0+VHlwZSAhPSBOVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSkgewogICAgICBFUlIoICJzcGVjaWFsIG5rIGJsb2NrIG5vdCBmb3VuZFxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKCAocmV0ID0gX2dldF90bXBfZm4oJmYpKSA9PSBOVUxMKSBnb3RvIGVycm9yOwogICAgZnByaW50ZihmLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gMiIpOwogICAgX250X2R1bXBfbmsoIiIsKGNoYXIqKWJhc2UrMHgxMDAwLG5rLGYsbGV2ZWwpOwogICAgZmNsb3NlKGYpOwoKZXJyb3I6CiAgICBtdW5tYXAoYmFzZSxzdC5zdF9zaXplKTsKZXJyb3IxOgogICAgY2xvc2UoZmQpOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCBuYXRpdmUgcmVnaXN0cnkgdG8gd2luZSBmb3JtYXQgYW5kIGxvYWQgaXQgdmlhIHNlcnZlciBjYWxsIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KExQQ1NUUiBmbixIS0VZIGhrZXksaW50IHJlZ190eXBlLGludCBsZXZlbCkKewogICAgTFBTVFIgdG1wID0gTlVMTDsKCiAgICBzd2l0Y2ggKHJlZ190eXBlKSB7CiAgICAgICAgY2FzZSBSRUdfV0lOTlQ6CiAgICAgICAgICAgIC8qIEZJWE1FOiBmb2xsb3dpbmcgZnVuY3Rpb24gZG9lc24ndCByZWFsbHkgY29udmVydCB5ZXQgKi8KICAgICAgICAgICAgdG1wID0gX2NvbnZlcnRfd2lubnRfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoZm4sbGV2ZWwpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19XSU45NToKICAgICAgICAgICAgdG1wID0gX2NvbnZlcnRfd2luOTVfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoZm4sbGV2ZWwpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19XSU4zMToKICAgICAgICAgICAgRVJSKCJEb24ndCBrbm93IGhvdyB0byBjb252ZXJ0IG5hdGl2ZSAzLjEgcmVnaXN0cnkgeWV0LlxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiVW5rbm93biByZWdpc3RyeSBmb3JtYXQgcGFyYW1ldGVyICglZClcbiIscmVnX3R5cGUpOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAodG1wICE9IE5VTEwpIHsKICAgICAgICBsb2FkX3dpbmVfcmVnaXN0cnkoaGtleSx0bXApOwogICAgICAgIFRSQUNFKCJGaWxlICVzIHN1Y2Nlc3NmdWxseSBjb252ZXJ0ZWQgdG8gJXMgYW5kIGxvYWRlZCB0byByZWdpc3RyeS5cbiIsZm4sdG1wKTsKICAgICAgICB1bmxpbmsodG1wKTsKICAgIH0KICAgIGVsc2UgV0FSTigiVW5hYmxlIHRvIGNvbnZlcnQgJXMgKGRvZXNuJ3QgZXhpc3Q/KVxuIixmbik7CiAgICBmcmVlKHRtcCk7Cn0KCi8qIGxvYWQgYWxsIG5hdGl2ZSB3aW5kb3dzIHJlZ2lzdHJ5IGZpbGVzIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2xvYWRfd2luZG93c19yZWdpc3RyeSggSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQgKQp7CiAgICBpbnQgcmVnX3R5cGU7CiAgICBjaGFyIHdpbmRpcltNQVhfUEFUSE5BTUVfTEVOXTsKICAgIGNoYXIgcGF0aFtNQVhfUEFUSE5BTUVfTEVOXTsKCiAgICBHZXRXaW5kb3dzRGlyZWN0b3J5QSh3aW5kaXIsTUFYX1BBVEhOQU1FX0xFTik7CgogICAgcmVnX3R5cGUgPSBfZ2V0X3JlZ190eXBlKCk7CiAgICBzd2l0Y2ggKHJlZ190eXBlKSB7CiAgICAgICAgY2FzZSBSRUdfV0lOTlQ6IHsKICAgICAgICAgICAgSEtFWSBoa2V5OwoKICAgICAgICAgICAgLyogdXNlciBzcGVjaWZpYyBudHVzZXIuZGF0ICovCiAgICAgICAgICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJXaW5lIiwgIlByb2ZpbGUiLCAiIiwgcGF0aCwgTUFYX1BBVEhOQU1FX0xFTikpIHsKICAgICAgICAgICAgICAgIHN0cmNhdChwYXRoLCJcXG50dXNlci5kYXQiKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLEhLRVlfQ1VSUkVOVF9VU0VSLFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogZGVmYXVsdCB1c2VyLmRhdCAqLwogICAgICAgICAgICBpZiAoaGtleV91c2Vyc19kZWZhdWx0KSB7CiAgICAgICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcc3lzdGVtMzJcXGNvbmZpZ1xcZGVmYXVsdCIpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV91c2Vyc19kZWZhdWx0LFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgKiBGSVhNRQogICAgICAgICAgICAqICBtYXAgSExNXFN5c3RlbVxDb250cm9sU2V0MDAxIHRvIEhMTVxTeXN0ZW1cQ3VycmVudENvbnRyb2xTZXQKICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmICghUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsICJTWVNURU0iLCAmaGtleSkpIHsKCSAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CgkgICAgICBzdHJjYXQocGF0aCwiXFxzeXN0ZW0zMlxcY29uZmlnXFxzeXN0ZW0iKTsKICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5LFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwgIlNPRlRXQVJFIiwgJmhrZXkpKSB7CiAgICAgICAgICAgICAgICBzdHJjcHkocGF0aCx3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc29mdHdhcmUiKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXksUkVHX1dJTk5ULDEpOwogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgIHN0cmNhdChwYXRoLCJcXHN5c3RlbTMyXFxjb25maWdcXHNhbSIpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0xPQ0FMX01BQ0hJTkUsUkVHX1dJTk5ULDApOwoKICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc2VjdXJpdHkiKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9MT0NBTF9NQUNISU5FLFJFR19XSU5OVCwwKTsKCiAgICAgICAgICAgIC8qIHRoaXMga2V5IGlzIGdlbmVyYXRlZCB3aGVuIHRoZSBudC1jb3JlIGJvb3RlZCBzdWNjZXNzZnVsbHkgKi8KICAgICAgICAgICAgaWYgKCFSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDbG9uZSIsJmhrZXkpKSBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIFJFR19XSU45NToKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KCJjOlxcc3lzdGVtLjFzdCIsSEtFWV9MT0NBTF9NQUNISU5FLFJFR19XSU45NSwwKTsKCiAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgIHN0cmNhdChwYXRoLCJcXHN5c3RlbS5kYXQiKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsSEtFWV9MT0NBTF9NQUNISU5FLFJFR19XSU45NSwwKTsKCiAgICAgICAgICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoIldpbmUiLCJQcm9maWxlIiwiIixwYXRoLE1BWF9QQVRITkFNRV9MRU4pKSB7CgkgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgdXNlci5kYXQgKi8KCSAgICAgICAgc3RybmNhdChwYXRoLCAiXFx1c2VyLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLEhLRVlfQ1VSUkVOVF9VU0VSLFJFR19XSU45NSwxKTsKCgkgICAgICAgIC8qIGRlZmF1bHQgdXNlci5kYXQgKi8KCSAgICAgICAgaWYgKGhrZXlfdXNlcnNfZGVmYXVsdCkgewogICAgICAgICAgICAgICAgICAgIHN0cmNweShwYXRoLHdpbmRpcik7CiAgICAgICAgICAgICAgICAgICAgc3RyY2F0KHBhdGgsIlxcdXNlci5kYXQiKTsKICAgICAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X3VzZXJzX2RlZmF1bHQsUkVHX1dJTjk1LDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3RyY3B5KHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdChwYXRoLCJcXHVzZXIuZGF0Iik7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxIS0VZX0NVUlJFTlRfVVNFUixSRUdfV0lOOTUsMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgUkVHX1dJTjMxOgogICAgICAgICAgICAvKiBGSVhNRTogaGVyZSB3ZSBzaG91bGQgY29udmVydCB0byAqLnJlZyBmaWxlIHN1cHBvcnRlZCBieSBzZXJ2ZXIgYW5kIGNhbGwgUkVRX0xPQURfUkVHSVNUUlksIHNlZSBSRUdfV0lOOTUgY2FzZSAqLwogICAgICAgICAgICBfdzMxX2xvYWRyZWcoKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgUkVHX0RPTlRMT0FEOgogICAgICAgICAgICBUUkFDRSgiUkVHX0RPTlRMT0FEXG4iKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigic3dpdGNoOiBubyBtYXRjaCAoJWQpXG4iLHJlZ190eXBlKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgfQp9CgovKiBsb2FkIGdsb2JhbCByZWdpc3RyeSBmaWxlcyAoc3RvcmVkIGluIC9ldGMvd2luZSkgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfbG9hZF9nbG9iYWxfcmVnaXN0cnkodm9pZCkKewogICAgVFJBQ0UoIih2b2lkKVxuIik7CgogICAgLyogTG9hZCB0aGUgZ2xvYmFsIEhLVSBoaXZlIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpciAqLwogICAgbG9hZF93aW5lX3JlZ2lzdHJ5KCBIS0VZX1VTRVJTLCBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUICk7CgogICAgLyogTG9hZCB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyICovCiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoIEhLRVlfTE9DQUxfTUFDSElORSwgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUgKTsKfQoKLyogbG9hZCBob21lIHJlZ2lzdHJ5IGZpbGVzIChzdG9yZWQgaW4gfi8ud2luZSkgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfbG9hZF9ob21lX3JlZ2lzdHJ5KCBIS0VZIGhrZXlfdXNlcnNfZGVmYXVsdCApCnsKICAgIExQQ1NUUiBjb25mZGlyID0gZ2V0X2NvbmZpZ19kaXIoKTsKICAgIExQU1RSIHRtcCA9IF94bWFsbG9jKHN0cmxlbihjb25mZGlyKSsyMCk7CgogICAgc3RyY3B5KHRtcCxjb25mZGlyKTsKICAgIHN0cmNhdCh0bXAsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCk7CiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoaGtleV91c2Vyc19kZWZhdWx0LHRtcCk7CgogICAgc3RyY3B5KHRtcCxjb25mZGlyKTsKICAgIHN0cmNhdCh0bXAsIi8iIFNBVkVfTE9DQUxfUkVHQlJBTkNIX0NVUlJFTlRfVVNFUik7CiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoSEtFWV9DVVJSRU5UX1VTRVIsdG1wKTsKCiAgICBzdHJjcHkodG1wLGNvbmZkaXIpOwogICAgc3RyY2F0KHRtcCwiLyIgU0FWRV9MT0NBTF9SRUdCUkFOQ0hfTE9DQUxfTUFDSElORSk7CiAgICBsb2FkX3dpbmVfcmVnaXN0cnkoSEtFWV9MT0NBTF9NQUNISU5FLHRtcCk7CgogICAgZnJlZSh0bXApOwp9CgovKiBsb2FkIGFsbCByZWdpc3RyeSAobmF0aXZlIGFuZCBnbG9iYWwgYW5kIGhvbWUpICovCnZvaWQgU0hFTExfTG9hZFJlZ2lzdHJ5KCB2b2lkICkKewogICAgSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQ7CgogICAgVFJBQ0UoIih2b2lkKVxuIik7CgogICAgaWYgKCFDTElFTlRfSXNCb290VGhyZWFkKCkpIHJldHVybjsgIC8qIGFscmVhZHkgbG9hZGVkICovCgogICAgaWYgKFJlZ0NyZWF0ZUtleUEoSEtFWV9VU0VSUywiLkRlZmF1bHQiLCZoa2V5X3VzZXJzX2RlZmF1bHQpKQogICAgewogICAgICAgIEVSUigiQ2Fubm90IGNyZWF0ZSBIS0VZX1VTRVJTLy5EZWZhdWx0XG4iICk7CiAgICAgICAgRXhpdFByb2Nlc3MoMSk7CiAgICB9CgogICAgX2FsbG9jYXRlX2RlZmF1bHRfa2V5cygpOwogICAgX3NldF9yZWdpc3RyeV9sZXZlbHMoMCwwLDApOwogICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woIlJlZ2lzdHJ5IiwiTG9hZFdpbmRvd3NSZWdpc3RyeUZpbGVzIiwxKSkKICAgICAgICBfbG9hZF93aW5kb3dzX3JlZ2lzdHJ5KCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sKCJSZWdpc3RyeSIsIkxvYWRHbG9iYWxSZWdpc3RyeUZpbGVzIiwxKSkKICAgICAgICBfbG9hZF9nbG9iYWxfcmVnaXN0cnkoKTsKICAgIF9zZXRfcmVnaXN0cnlfbGV2ZWxzKDEsMCwwKTsKICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sKCJSZWdpc3RyeSIsIkxvYWRIb21lUmVnaXN0cnlGaWxlcyIsMSkpCiAgICAgICAgX2xvYWRfaG9tZV9yZWdpc3RyeSggaGtleV91c2Vyc19kZWZhdWx0ICk7CiAgICBfaW5pdF9yZWdpc3RyeV9zYXZpbmcoIGhrZXlfdXNlcnNfZGVmYXVsdCApOwogICAgUmVnQ2xvc2VLZXkoaGtleV91c2Vyc19kZWZhdWx0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgIEFQSSBGVU5DVElPTlMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRmx1c2hLZXkgW0FEVkFQSTMyLkBdCiAqIEltbWVkaWF0ZWx5IHdyaXRlcyBrZXkgdG8gcmVnaXN0cnkuCiAqIE9ubHkgcmV0dXJucyBhZnRlciBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gdG8gZGlzay4KICoKICogRklYTUU6IGRvZXMgaXQgcmVhbGx5IHdhaXQgdW50aWwgZGF0YSBpcyB3cml0dGVuID8KICoKICogUEFSQU1TCiAqICAgIGhrZXkgW0ldIEhhbmRsZSBvZiBrZXkgdG8gd3JpdGUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdGbHVzaEtleSggSEtFWSBoa2V5ICkKewogICAgRklYTUUoICIoJXgpOiBzdHViXG4iLCBoa2V5ICk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnVW5Mb2FkS2V5QSBbQURWQVBJMzIuQF0KICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5ICkKewogICAgRklYTUUoIigleCwlcyk6IHN0dWJcbiIsaGtleSwgZGVidWdzdHJfYShscFN1YktleSkpOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1JlcGxhY2VLZXlBIFtBRFZBUEkzMi5AXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5LCBMUENTVFIgbHBOZXdGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBPbGRGaWxlICkKewogICAgRklYTUUoIigleCwlcywlcywlcyk6IHN0dWJcbiIsIGhrZXksIGRlYnVnc3RyX2EobHBTdWJLZXkpLAogICAgICAgICAgZGVidWdzdHJfYShscE5ld0ZpbGUpLGRlYnVnc3RyX2EobHBPbGRGaWxlKSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCgoKCgovKiAxNi1iaXQgZnVuY3Rpb25zICovCgovKiAwIGFuZCAxIGFyZSB2YWxpZCByb290a2V5cyBpbiB3aW4xNiBzaGVsbC5kbGwgYW5kIGFyZSB1c2VkIGJ5CiAqIHNvbWUgcHJvZ3JhbXMuIERvIG5vdCByZW1vdmUgdGhvc2UgY2FzZXMuIC1NTQogKi8Kc3RhdGljIGlubGluZSB2b2lkIGZpeF93aW4xNl9oa2V5KCBIS0VZICpoa2V5ICkKewogICAgaWYgKCpoa2V5ID09IDAgfHwgKmhrZXkgPT0gMSkgKmhrZXkgPSBIS0VZX0NMQVNTRVNfUk9PVDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRW51bUtleSAgIFtLRVJORUwuMjE2XQogKiAgICAgICAgICAgUmVnRW51bUtleSAgIFtTSEVMTC43XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXkxNiggSEtFWSBoa2V5LCBEV09SRCBpbmRleCwgTFBTVFIgbmFtZSwgRFdPUkQgbmFtZV9sZW4gKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdFbnVtS2V5QSggaGtleSwgaW5kZXgsIG5hbWUsIG5hbWVfbGVuICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ09wZW5LZXkgICBbS0VSTkVMLjIxN10KICogICAgICAgICAgIFJlZ09wZW5LZXkgICBbU0hFTEwuMV0KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQSEtFWSByZXRrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdPcGVuS2V5QSggaGtleSwgbmFtZSwgcmV0a2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0NyZWF0ZUtleSAgIFtLRVJORUwuMjE4XQogKiAgICAgICAgICAgUmVnQ3JlYXRlS2V5ICAgW1NIRUxMLjJdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQSEtFWSByZXRrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdDcmVhdGVLZXlBKCBoa2V5LCBuYW1lLCByZXRrZXkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRGVsZXRlS2V5ICAgW0tFUk5FTC4yMTldCiAqICAgICAgICAgICBSZWdEZWxldGVLZXkgICBbU0hFTEwuNF0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0RlbGV0ZUtleUEoIGhrZXksIG5hbWUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnQ2xvc2VLZXkgICBbS0VSTkVMLjIyMF0KICogICAgICAgICAgIFJlZ0Nsb3NlS2V5ICAgW1NIRUxMLjNdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ2xvc2VLZXkxNiggSEtFWSBoa2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnQ2xvc2VLZXkoIGhrZXkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnU2V0VmFsdWUgICBbS0VSTkVMLjIyMV0KICogICAgICAgICAgIFJlZ1NldFZhbHVlICAgW1NIRUxMLjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgRFdPUkQgdHlwZSwgTFBDU1RSIGRhdGEsIERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVBKCBoa2V5LCBuYW1lLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdEZWxldGVWYWx1ZSAgW0tFUk5FTC4yMjJdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUxNiggSEtFWSBoa2V5LCBMUFNUUiBuYW1lICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRGVsZXRlVmFsdWVBKCBoa2V5LCBuYW1lICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0VudW1WYWx1ZSAgIFtLRVJORUwuMjIzXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1WYWx1ZTE2KCBIS0VZIGhrZXksIERXT1JEIGluZGV4LCBMUFNUUiB2YWx1ZSwgTFBEV09SRCB2YWxfY291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCByZXNlcnZlZCwgTFBEV09SRCB0eXBlLCBMUEJZVEUgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0VudW1WYWx1ZUEoIGhrZXksIGluZGV4LCB2YWx1ZSwgdmFsX2NvdW50LCByZXNlcnZlZCwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnUXVlcnlWYWx1ZSAgIFtLRVJORUwuMjI0XQogKiAgICAgICAgICAgUmVnUXVlcnlWYWx1ZSAgIFtTSEVMTC42XQogKgogKiBOT1RFUwogKiAgICBJcyB0aGlzIEhBQ0sgc3RpbGwgYXBwbGljYWJsZT8KICoKICogSEFDSwogKiAgICBUaGUgMTZiaXQgUmVnUXVlcnlWYWx1ZSBkb2Vzbid0IGhhbmRsZSBzZWxlY3RvcmJsb2NrcyBhbnl3YXksIHNvIHdlIGp1c3QKICogICAgbWFzayBvdXQgdGhlIGhpZ2ggMTYgYml0LiAgVGhpcyAobm90IHNvIG11Y2ggaW5jaWRlbnRseSkgaG9wZWZ1bGx5IGZpeGVzCiAqICAgIEFsZHVzIEZINCkKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQU1RSIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIGlmIChjb3VudCkgKmNvdW50ICY9IDB4ZmZmZjsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlQSggaGtleSwgbmFtZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnUXVlcnlWYWx1ZUV4ICAgW0tFUk5FTC4yMjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQRFdPUkQgcmVzZXJ2ZWQsIExQRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeEEoIGhrZXksIG5hbWUsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdTZXRWYWx1ZUV4ICAgW0tFUk5FTC4yMjZdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBEV09SRCByZXNlcnZlZCwgRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09OU1QgQllURSAqZGF0YSwgRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIGlmICghY291bnQgJiYgKHR5cGU9PVJFR19TWikpIGNvdW50ID0gc3RybGVuKGRhdGEpOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlRXhBKCBoa2V5LCBuYW1lLCByZXNlcnZlZCwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRmx1c2hLZXkgICBbS0VSTkVMLjIyN10KICovCkRXT1JEIFdJTkFQSSBSZWdGbHVzaEtleTE2KCBIS0VZIGhrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdGbHVzaEtleSggaGtleSApOwp9Cg==