LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBOT1RFUwogKiAgICBXaGVuIGNoYW5naW5nIHRoaXMgZmlsZSwgcGxlYXNlIHJlLXJ1biB0aGUgcmVndGVzdCBwcm9ncmFtIHRvIGVuc3VyZQogKiAgICB0aGUgY29uZGl0aW9ucyBhcmUgaGFuZGxlZCBwcm9wZXJseS4KICoKICogVE9ETwogKiAgICBTZWN1cml0eSBhY2Nlc3MKICogICAgT3B0aW9uIGhhbmRsaW5nCiAqICAgIFRpbWUgZm9yIFJlZ0VudW1LZXkqLCBSZWdRdWVyeUluZm9LZXkqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9TWVNfSU9DVExfSAojaW5jbHVkZSA8c3lzL2lvY3RsLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9MSU5VWF9IRFJFR19ICiMgaW5jbHVkZSA8bGludXgvaGRyZWcuaD4KI2VuZGlmCgojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKI2luY2x1ZGUgIm50c3RhdHVzLmgiCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5pb2N0bC5oIgojaW5jbHVkZSAibnRkZHNjc2kuaCIKCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9saWJyYXJ5LmgiCiNpbmNsdWRlICJ3aW5lL3NlcnZlci5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocmVnKTsKCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCAgIi93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUgIi93aW5lLnN5c3RlbXJlZyIKCiNkZWZpbmUgTUFYX1BBVEhOQU1FX0xFTiAgIDEwMjQKCnN0YXRpYyBjb25zdCBXQ0hBUiBDbGFzc2VzUm9vdFdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbCcsJ2EnLCdzJywncycsJ2UnLCdzJywwfTsKCiNkZWZpbmUgSVNfT1BUSU9OX0ZBTFNFKGNoKSBcCiAgICAoKGNoKSA9PSAnbicgfHwgKGNoKSA9PSAnTicgfHwgKGNoKSA9PSAnZicgfHwgKGNoKSA9PSAnRicgfHwgKGNoKSA9PSAnMCcpCgovKiBfeG1hbGxvYyBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkICpfeG1hbGxvYyggc2l6ZV90IHNpemUgKQp7CiAgICB2b2lkICpyZXM7CgogICAgcmVzID0gbWFsbG9jIChzaXplID8gc2l6ZSA6IDEpOwogICAgaWYgKHJlcyA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiVmlydHVhbCBtZW1vcnkgZXhoYXVzdGVkLlxuIik7CiAgICAgICAgZXhpdCAoMSk7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9CgovKiBfeHN0cmR1cCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfeHN0cmR1cChMUENTVFIgc3RyKQp7CiAgICBMUFNUUiByZXQ7CiAgICBzaXplX3QgbGVuID0gc3RybGVuKHN0cikgKyAxOwoKICAgIGlmICghc3RyKSByZXR1cm4gTlVMTDsKICAgIHJldCA9IF94bWFsbG9jKCBsZW4gKTsKICAgIG1lbWNweSggcmV0LCBzdHIsIGxlbiApOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCBhbnNpIHN0cmluZyB0byB1bmljb2RlIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQV1NUUiBfc3RyZHVwbkF0b1coTFBDU1RSIHN0ckEsc2l6ZV90IGxlbkEpCnsKICAgIExQV1NUUiByZXQ7CiAgICBEV09SRCBsZW47CgogICAgaWYgKCFzdHJBKSByZXR1cm4gTlVMTDsKICAgIGlmIChSdGxNdWx0aUJ5dGVUb1VuaWNvZGVTaXplKCAmbGVuLCBzdHJBLCBsZW5BICkgIT0gU1RBVFVTX1NVQ0NFU1MpIHJldHVybiBOVUxMOwoKICAgIHJldCA9IF94bWFsbG9jKGxlbitzaXplb2YoV0NIQVIpKTsKICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4ocmV0LCBsZW4sIE5VTEwsIHN0ckEsIGxlbkEpOwogICAgcmV0W2xlbiAvIHNpemVvZihXQ0hBUildID0gMDsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGR1bXAgYSBVbmljb2RlIHN0cmluZyB3aXRoIHByb3BlciBlc2NhcGluZyBbSW50ZXJuYWxdICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvdW5pY29kZS5jICovCnN0YXRpYyBpbnQgX2R1bXBfc3RyVyhjb25zdCBXQ0hBUiAqc3RyLHNpemVfdCBsZW4sRklMRSAqZixjb25zdCBjaGFyIGVzY2FwZVsyXSkKewogICAgc3RhdGljIGNvbnN0IGNoYXIgZXNjYXBlc1szMl0gPSAiLi4uLi4uLmFidG52ZnIuLi4uLi4uLi4uLi4uZS4uLi4iOwogICAgY2hhciBidWZmZXJbMjU2XTsKICAgIExQU1RSIHBvcyA9IGJ1ZmZlcjsKICAgIGludCBjb3VudCA9IDA7CgogICAgZm9yICg7IGxlbjsgc3RyKyssIGxlbi0tKQogICAgewogICAgICAgIGlmIChwb3MgPiBidWZmZXIgKyBzaXplb2YoYnVmZmVyKSAtIDgpCiAgICAgICAgewogICAgICAgICAgICBmd3JpdGUoIGJ1ZmZlciwgcG9zIC0gYnVmZmVyLCAxLCBmICk7CiAgICAgICAgICAgIGNvdW50ICs9IHBvcyAtIGJ1ZmZlcjsKICAgICAgICAgICAgcG9zID0gYnVmZmVyOwogICAgICAgIH0KICAgICAgICBpZiAoKnN0ciA+IDEyNykgIC8qIGhleCBlc2NhcGUgKi8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChsZW4gPiAxICYmIHN0clsxXSA8IDEyOCAmJiBpc3hkaWdpdCgoY2hhcilzdHJbMV0pKQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxceCUwNHgiLCAqc3RyICk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXHgleCIsICpzdHIgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyIDwgMzIpICAvKiBvY3RhbCBvciBDIGVzY2FwZSAqLwogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEqc3RyICYmIGxlbiA9PSAxKSBjb250aW51ZTsgIC8qIGRvIG5vdCBvdXRwdXQgdGVybWluYXRpbmcgTlVMTCAqLwogICAgICAgICAgICBpZiAoZXNjYXBlc1sqc3RyXSAhPSAnLicpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlYyIsIGVzY2FwZXNbKnN0cl0gKTsKICAgICAgICAgICAgZWxzZSBpZiAobGVuID4gMSAmJiBzdHJbMV0gPj0gJzAnICYmIHN0clsxXSA8PSAnNycpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlMDNvIiwgKnN0ciApOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlbyIsICpzdHIgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyID09ICdcXCcgfHwgKnN0ciA9PSBlc2NhcGVbMF0gfHwgKnN0ciA9PSBlc2NhcGVbMV0pICpwb3MrKyA9ICdcXCc7CiAgICAgICAgKnBvcysrID0gKnN0cjsKICAgIH0KICAgIGZ3cml0ZSggYnVmZmVyLCBwb3MgLSBidWZmZXIsIDEsIGYgKTsKICAgIGNvdW50ICs9IHBvcyAtIGJ1ZmZlcjsKICAgIHJldHVybiBjb3VudDsKfQoKLyogY29udmVydCBhbnNpIHN0cmluZyB0byB1bmljb2RlIGFuZCBkdW1wIHdpdGggcHJvcGVyIGVzY2FwaW5nIFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfZHVtcF9zdHJBdG9XKExQQ1NUUiBzdHJBLHNpemVfdCBsZW4sRklMRSAqZixjb25zdCBjaGFyIGVzY2FwZVsyXSkKewogICAgV0NIQVIgKnN0clc7CiAgICBpbnQgcmV0OwoKICAgIGlmIChzdHJBID09IE5VTEwpIHJldHVybiAwOwogICAgc3RyVyA9IF9zdHJkdXBuQXRvVyhzdHJBLGxlbik7CiAgICByZXQgPSBfZHVtcF9zdHJXKHN0clcsbGVuLGYsZXNjYXBlKTsKICAgIGZyZWUoc3RyVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBhIGtleSB2YWx1ZSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3JlZ2lzdHJ5LmMgKi8Kc3RydWN0IGtleV92YWx1ZSB7CiAgICBXQ0hBUiAgICAgICAgICAgICpuYW1lVzsgICAvKiB2YWx1ZSBuYW1lICovCiAgICBpbnQgICAgICAgICAgICAgICB0eXBlOyAgICAvKiB2YWx1ZSB0eXBlICovCiAgICBzaXplX3QgICAgICAgICAgICBsZW47ICAgICAvKiB2YWx1ZSBkYXRhIGxlbmd0aCBpbiBieXRlcyAqLwogICAgdm9pZCAgICAgICAgICAgICAqZGF0YTsgICAgLyogcG9pbnRlciB0byB2YWx1ZSBkYXRhICovCn07CgovKiBkdW1wIGEgdmFsdWUgdG8gYSB0ZXh0IGZpbGUgKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci9yZWdpc3RyeS5jICovCnN0YXRpYyB2b2lkIF9kdW1wX3ZhbHVlKHN0cnVjdCBrZXlfdmFsdWUgKnZhbHVlLEZJTEUgKmYpCnsKICAgIGludCBpLCBjb3VudDsKCiAgICBpZiAodmFsdWUtPm5hbWVXWzBdKSB7CiAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICBjb3VudCA9IDEgKyBfZHVtcF9zdHJXKHZhbHVlLT5uYW1lVyxzdHJsZW5XKHZhbHVlLT5uYW1lVyksZiwiXCJcIiIpOwogICAgICAgIGNvdW50ICs9IGZwcmludGYoIGYsICJcIj0iICk7CiAgICB9CiAgICBlbHNlIGNvdW50ID0gZnByaW50ZiggZiwgIkA9IiApOwoKICAgIHN3aXRjaCh2YWx1ZS0+dHlwZSkgewogICAgICAgIGNhc2UgUkVHX1NaOgogICAgICAgIGNhc2UgUkVHX0VYUEFORF9TWjoKICAgICAgICBjYXNlIFJFR19NVUxUSV9TWjoKICAgICAgICAgICAgaWYgKHZhbHVlLT50eXBlICE9IFJFR19TWikgZnByaW50ZiggZiwgInN0ciglZCk6IiwgdmFsdWUtPnR5cGUgKTsKICAgICAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICAgICAgaWYgKHZhbHVlLT5kYXRhKSBfZHVtcF9zdHJXKHZhbHVlLT5kYXRhLHZhbHVlLT5sZW4vc2l6ZW9mKFdDSEFSKSxmLCJcIlwiIik7CiAgICAgICAgICAgIGZwdXRjKCAnXCInLCBmICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX0RXT1JEOgogICAgICAgICAgICBpZiAodmFsdWUtPmxlbiA9PSBzaXplb2YoRFdPUkQpKSB7CiAgICAgICAgICAgICAgICBEV09SRCBkdzsKICAgICAgICAgICAgICAgIG1lbWNweSggJmR3LCB2YWx1ZS0+ZGF0YSwgc2l6ZW9mKERXT1JEKSApOwogICAgICAgICAgICAgICAgZnByaW50ZiggZiwgImR3b3JkOiUwOGx4IiwgZHcgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGVsc2UgZmFsbCB0aHJvdWdoICovCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgaWYgKHZhbHVlLT50eXBlID09IFJFR19CSU5BUlkpIGNvdW50ICs9IGZwcmludGYoIGYsICJoZXg6IiApOwogICAgICAgICAgICBlbHNlIGNvdW50ICs9IGZwcmludGYoIGYsICJoZXgoJXgpOiIsIHZhbHVlLT50eXBlICk7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS0+bGVuOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvdW50ICs9IGZwcmludGYoIGYsICIlMDJ4IiwgKigodW5zaWduZWQgY2hhciAqKXZhbHVlLT5kYXRhICsgaSkgKTsKICAgICAgICAgICAgICAgIGlmIChpIDwgdmFsdWUtPmxlbi0xKSB7CiAgICAgICAgICAgICAgICAgICAgZnB1dGMoICcsJywgZiApOwogICAgICAgICAgICAgICAgICAgIGlmICgrK2NvdW50ID4gNzYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZnByaW50ZiggZiwgIlxcXG4gICIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGZwdXRjKCAnXG4nLCBmICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewogICAgY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCiAgICB1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCiAgICB1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwogICAgdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwogICAgdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCiAgICB1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCiAgICB1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCiAgICB1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7CiAgICB1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwogICAgdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX3czMV9kdW1wdHJlZSh1bnNpZ25lZCBzaG9ydCBpZHgsIHVuc2lnbmVkIGNoYXIgKnR4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYiwgc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgIEhLRVkgaGtleSwgVUxPTkcgbGFzdG1vZGlmaWVkLCBpbnQgbGV2ZWwpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBjbGFzc2VzV1tdID0geycuJywnYycsJ2wnLCdhJywncycsJ3MnLCdlJywncycsMH07CiAgICBzdHJ1Y3QgX3czMV9kaXJlbnQgKmRpcjsKICAgIHN0cnVjdCBfdzMxX2tleWVudCAqa2V5OwogICAgc3RydWN0IF93MzFfdmFsZW50ICp2YWw7CiAgICBIS0VZIHN1YmtleSA9IDA7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVcsIHZhbHVlVzsKICAgIHN0YXRpYyBXQ0hBUiB0YWlsWzQwMF07CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5OwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmdmFsdWVXLCBOVUxMICk7CgogICAgd2hpbGUgKGlkeCE9MCkgewogICAgICAgIGRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgogICAgICAgIGlmIChkaXItPmtleV9pZHgpIHsKICAgICAgICAgICAgRFdPUkQgbGVuOwogICAgICAgICAgICBrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgogICAgICAgICAgICBSdGxNdWx0aUJ5dGVUb1VuaWNvZGVOKCB0YWlsLCBzaXplb2YodGFpbCktc2l6ZW9mKFdDSEFSKSwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnR4dFtrZXktPnN0cmluZ19vZmZdLCBrZXktPmxlbmd0aCk7CiAgICAgICAgICAgIHRhaWxbbGVuL3NpemVvZihXQ0hBUildID0gMDsKCiAgICAgICAgICAgIC8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUKICAgICAgICAgICAgICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCFsZXZlbCAmJiAhc3RyY21wVyh0YWlsLGNsYXNzZXNXKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsaGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CiAgICAgICAgICAgICAgICBpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc3Via2V5KSBOdENsb3NlKCBzdWJrZXkgKTsKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdGFpbCApOwogICAgICAgICAgICBpZiAoTnRDcmVhdGVLZXkoICZzdWJrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKSBzdWJrZXkgPSAwOwoKICAgICAgICAgICAgLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCiAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKICAgICAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCkgewogICAgICAgICAgICAgICAgICAgIERXT1JEIGxlbjsKICAgICAgICAgICAgICAgICAgICB2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CiAgICAgICAgICAgICAgICAgICAgUnRsTXVsdGlCeXRlVG9Vbmljb2RlTiggdGFpbCwgc2l6ZW9mKHRhaWwpIC0gc2l6ZW9mKFdDSEFSKSwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdHh0W3ZhbC0+c3RyaW5nX29mZl0sIHZhbC0+bGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICB0YWlsW2xlbi9zaXplb2YoV0NIQVIpXSA9IDA7CiAgICAgICAgICAgICAgICAgICAgTnRTZXRWYWx1ZUtleSggc3Via2V5LCAmdmFsdWVXLCAwLCBSRUdfU1osIHRhaWwsIGxlbiArIHNpemVvZihXQ0hBUikgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBUUkFDRSgic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKICAgICAgICBfdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxzdWJrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwogICAgICAgIGlkeD1kaXItPnNpYmxpbmdfaWR4OwogICAgfQogICAgaWYgKHN1YmtleSkgTnRDbG9zZSggc3Via2V5ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93MzFfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfdzMxX2xvYWRyZWcodm9pZCkKewogICAgSEFORExFICAgICAgICAgICAgICAgICAgICAgIGhmOwogICAgSEtFWSAgICAgICAgICAgICAgICAgICAgICAgIHJvb3Q7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyAgICAgICAgICAgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HICAgICAgICAgICAgICBuYW1lVzsKICAgIHN0cnVjdCBfdzMxX2hlYWRlciAgICAgICAgICBoZWFkOwogICAgc3RydWN0IF93MzFfdGFiZW50KiAgICAgICAgIHRhYiA9IE5VTEw7CiAgICB1bnNpZ25lZCBjaGFyKiAgICAgICAgICAgICAgdHh0ID0gTlVMTDsKICAgIHVuc2lnbmVkIGludAkJbGVuOwogICAgT0ZTVFJVQ1QJCSAgICAgICAgb2ZzOwogICAgVUxPTkcJCQlsYXN0bW9kaWZpZWQ7CiAgICBOVFNUQVRVUyAgICAgICAgICAgICAgICAgICAgc3RhdHVzOwogICAgSU9fU1RBVFVTX0JMT0NLICAgICAgICAgICAgIGlvc2I7CiAgICBGSUxFX1BPU0lUSU9OX0lORk9STUFUSU9OICAgZnBpOwogICAgRklMRV9CQVNJQ19JTkZPUk1BVElPTiAgICAgIGZiaTsKCiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICBoZiA9IChIQU5ETEUpT3BlbkZpbGUoInJlZy5kYXQiLCZvZnMsT0ZfUkVBRCk7CiAgICBpZiAoaGY9PShIQU5ETEUpSEZJTEVfRVJST1IpIHJldHVybjsKCiAgICAvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KICAgIGlmIChOdFJlYWRGaWxlKGhmLCAwLCBOVUxMLCBOVUxMLCAmaW9zYiwgCiAgICAgICAgICAgICAgICAgICAmaGVhZCwgc2l6ZW9mKGhlYWQpLCBOVUxMLCBOVUxMKSAhPSBTVEFUVVNfU1VDQ0VTUyB8fAogICAgICAgIGlvc2IuSW5mb3JtYXRpb24gIT0gc2l6ZW9mKGhlYWQpKQogICAgewogICAgICAgIEVSUigicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKICAgICAgICBnb3RvIGRvbmU7CiAgICB9CiAgICBpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSAhPSAwKQogICAgewogICAgICAgIEVSUigicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwogICAgICAgIGdvdG8gZG9uZTsKICAgIH0KCiAgICBsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwogICAgLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwogICAgdGFiID0gX3htYWxsb2MobGVuKTsKICAgIGlmIChOdFJlYWRGaWxlKGhmLCAwLCBOVUxMLCBOVUxMLCAmaW9zYiwKICAgICAgICAgICAgICAgICAgIHRhYiwgbGVuLCBOVUxMLCBOVUxMKSAhPSBTVEFUVVNfU1VDQ0VTUyB8fAogICAgICAgIGlvc2IuSW5mb3JtYXRpb24gIT0gbGVuKSAKICAgIHsKICAgICAgICBFUlIoImNvdWxkbid0IHJlYWQgaW5kZXggdGFibGUgKCVkIGJ5dGVzKS5cbiIsbGVuKTsKICAgICAgICBnb3RvIGRvbmU7CiAgICB9CgogICAgLyogcmVhZCB0ZXh0ICovCiAgICB0eHQgPSBfeG1hbGxvYyhoZWFkLnRleHRzaXplKTsKICAgIGZwaS5DdXJyZW50Qnl0ZU9mZnNldC51Lkxvd1BhcnQgPSBoZWFkLnRleHRvZmY7CiAgICBmcGkuQ3VycmVudEJ5dGVPZmZzZXQudS5IaWdoUGFydCA9IDA7CiAgICBpZiAoTnRTZXRJbmZvcm1hdGlvbkZpbGUoaGYsICZpb3NiLCAmZnBpLCBzaXplb2YoZnBpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZVBvc2l0aW9uSW5mb3JtYXRpb24pICE9IFNUQVRVU19TVUNDRVNTKQogICAgewogICAgICAgIEVSUigiY291bGRuJ3Qgc2VlayB0byB0ZXh0YmxvY2suXG4iKTsKICAgICAgICBnb3RvIGRvbmU7CiAgICB9CiAgICBzdGF0dXMgPSBOdFJlYWRGaWxlKGhmLCAwLCBOVUxMLCBOVUxMLCAmaW9zYiwgdHh0LCBoZWFkLnRleHRzaXplLCBOVUxMLCBOVUxMKTsKICAgIGlmICghKHN0YXR1cyA9PSBTVEFUVVNfU1VDQ0VTUyB8fCBzdGF0dXMgPT0gU1RBVFVTX0VORF9PRl9GSUxFKSB8fAogICAgICAgIGlvc2IuSW5mb3JtYXRpb24gIT0gaGVhZC50ZXh0c2l6ZSkKICAgIHsKICAgICAgICBFUlIoInRleHRibG9jayB0b28gc2hvcnQgKCVkIGluc3RlYWQgb2YgJWxkKS5cbiIsIGxlbiwgaGVhZC50ZXh0c2l6ZSk7CiAgICAgICAgZ290byBkb25lOwogICAgfQogICAgaWYgKE50UXVlcnlJbmZvcm1hdGlvbkZpbGUoaGYsICZpb3NiLCAmZmJpLCBzaXplb2YoZmJpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVCYXNpY0luZm9ybWF0aW9uKSAhPSBTVEFUVVNfU1VDQ0VTUykKICAgIHsKICAgICAgICBFUlIoIkNvdWxkbid0IGdldCBiYXNpYyBpbmZvcm1hdGlvbi5cbiIpOwogICAgICAgIGdvdG8gZG9uZTsKICAgIH0KICAgIFJ0bFRpbWVUb1NlY29uZHNTaW5jZTE5NzAoJmZiaS5MYXN0V3JpdGVUaW1lLCAmbGFzdG1vZGlmaWVkKTsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgQ2xhc3Nlc1Jvb3RXICk7CgogICAgaWYgKCFOdENyZWF0ZUtleSggJnJvb3QsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKQogICAgewogICAgICAgIF93MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQscm9vdCxsYXN0bW9kaWZpZWQsMCk7CiAgICAgICAgTnRDbG9zZSggcm9vdCApOwogICAgfQogZG9uZToKICAgIGlmICh0YWIpIGZyZWUodGFiKTsKICAgIGlmICh0eHQpIGZyZWUodHh0KTsKICAgIE50Q2xvc2UoaGYpOwogICAgcmV0dXJuOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93cyA5NSByZWdpc3RyeSBsb2FkZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogU0VDVElPTiAxOiBtYWluIGhlYWRlcgogKgogKiBvbmNlIGF0IG9mZnNldCAwCiAqLwojZGVmaW5lCVc5NV9SRUdfQ1JFR19JRAkweDQ3NDU1MjQzCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qICJDUkVHIiA9IFc5NV9SRUdfQ1JFR19JRCAqLwogICAgRFdPUkQJdmVyc2lvbjsJLyogPz8/PyAweDAwMDEwMDAwICovCiAgICBEV09SRAlyZ2RiX29mZjsJLyogMHgwOCBPZmZzZXQgb2YgMXN0IFJHREItYmxvY2sgKi8KICAgIERXT1JECXVrMjsJCS8qIDB4MGMgKi8KICAgIFdPUkQJcmdkYl9udW07CS8qIDB4MTAgIyBvZiBSR0RCLWJsb2NrcyAqLwogICAgV09SRAl1azM7CiAgICBEV09SRAl1a1szXTsKICAgIC8qIHJna24gKi8KfSBfdzk1Y3JlZzsKCi8qIFNFQ1RJT04gMjogRGlyZWN0b3J5IGluZm9ybWF0aW9uICh0cmVlIHN0cnVjdHVyZSkKICoKICogb25jZSBvbiBvZmZzZXQgMHgyMAogKgogKiBzdHJ1Y3R1cmU6IFtyZ2tuXVtka2VdKgkocmVwZWF0IHRpbGwgbGFzdF9ka2UgaXMgcmVhY2hlZCkKICovCiNkZWZpbmUJVzk1X1JFR19SR0tOX0lECTB4NGU0YjQ3NTIKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyoiUkdLTiIgPSBXOTVfUkVHX1JHS05fSUQgKi8KICAgIERXT1JECXNpemU7CQkvKiBTaXplIG9mIHRoZSBSR0tOLWJsb2NrICovCiAgICBEV09SRAlyb290X29mZjsJLyogUmVsLiBPZmZzZXQgb2YgdGhlIHJvb3QtcmVjb3JkICovCiAgICBEV09SRCAgIGxhc3RfZGtlOyAgICAgICAvKiBPZmZzZXQgdG8gbGFzdCBES0UgPyAqLwogICAgRFdPUkQJdWtbNF07Cn0gX3c5NXJna247CgovKiBEaXNrIEtleSBFbnRyeSBTdHJ1Y3R1cmUKICoKICogdGhlIDFzdCBlbnRyeSBpbiBhICJ1c3VhbCIgcmVnaXN0cnkgZmlsZSBpcyBhIG51bC1lbnRyeSB3aXRoIHN1YmtleXM6IHRoZQogKiBoaXZlIGl0c2VsZi4gSXQgbG9va3MgdGhlIHNhbWUgbGlrZSBvdGhlciBrZXlzLiBFdmVuIHRoZSBJRC1udW1iZXIgY2FuCiAqIGJlIGFueSB2YWx1ZS4KICoKICogVGhlICJoYXNoIi12YWx1ZSBpcyBhIHZhbHVlIHJlcHJlc2VudGluZyB0aGUga2V5J3MgbmFtZS4gV2luZG93cyB3aWxsIG5vdAogKiBzZWFyY2ggZm9yIHRoZSBuYW1lLCBidXQgZm9yIGEgbWF0Y2hpbmcgaGFzaC12YWx1ZS4gaWYgaXQgZmluZHMgb25lLCBpdAogKiB3aWxsIGNvbXBhcmUgdGhlIGFjdHVhbCBzdHJpbmcgaW5mbywgb3RoZXJ3aXNlIGNvbnRpbnVlIHdpdGggdGhlIG5leHQga2V5LgogKiBUbyBjYWxjdWxhdGUgdGhlIGhhc2ggaW5pdGlhbGl6ZSBhIEQtV29yZCB3aXRoIDAgYW5kIGFkZCBhbGwgQVNDSUktdmFsdWVzCiAqIG9mIHRoZSBzdHJpbmcgd2hpY2ggYXJlIHNtYWxsZXIgdGhhbiAweDgwICgxMjgpIHRvIHRoaXMgRC1Xb3JkLgogKgogKiBJZiB5b3Ugd2FudCB0byBtb2RpZnkga2V5IG5hbWVzLCBhbHNvIG1vZGlmeSB0aGUgaGFzaC12YWx1ZXMsIHNpbmNlIHRoZXkKICogY2Fubm90IGJlIGZvdW5kIGFnYWluIChhbHRob3VnaCB0aGV5IHdvdWxkIGJlIGRpc3BsYXllZCBpbiBSRUdFRElUKQogKiBFbmQgb2YgbGlzdC1wb2ludGVycyBhcmUgZmlsbGVkIHdpdGggMHhGRkZGRkZGRgogKgogKiBEaXNrIGtleXMgYXJlIGxheWVkIG91dCBmbGF0IC4uLiBCdXQsIHNvbWV0aW1lcywgbnJMUyBhbmQgbnJNUyBhcmUgYm90aAogKiAweEZGRkYsIHdoaWNoIG1lYW5zIHNraXBwaW5nIG92ZXIgbmV4dGtleW9mZnNldCBieXRlcyAoaW5jbHVkaW5nIHRoaXMKICogc3RydWN0dXJlKSBhbmQgcmVhZGluZyBhbm90aGVyIFJHREJfc2VjdGlvbi4KICoKICogVGhlIGxhc3QgREtFIChzZWUgZmllbGQgbGFzdF9ka2UgaW4gX3c5NV9yZ2tuKSBoYXMgb25seSAzIERXT1JEcyB3aXRoCiAqIDB4ODAwMDAwMDAgKEVPTCBpbmRpY2F0b3IgPykgYXMgeDEsIHRoZSBoYXNoIHZhbHVlIGFuZCAweEZGRkZGRkZGIGFzIHgzLgogKiBUaGUgcmVtYWluaW5nIHNwYWNlIGJldHdlZW4gbGFzdF9ka2UgYW5kIHRoZSBvZmZzZXQgY2FsY3VsYXRlZCBmcm9tCiAqIHJna24tPnNpemUgc2VlbXMgdG8gYmUgZnJlZSBmb3IgdXNlIGZvciBtb3JlIGRrZTpzLgogKiBTbyBpdCBzZWVtcyBpZiBtb3JlIGRrZTpzIGFyZSBhZGRlZCwgdGhleSBhcmUgYWRkZWQgdG8gdGhhdCBzcGFjZSBhbmQKICogbGFzdF9ka2UgaXMgZ3Jvd24sIGFuZCBpbiBjYXNlIHRoYXQgImZyZWUiIHNwYWNlIGlzIG91dCwgdGhlIHNwYWNlCiAqIGdldHMgZ3Jvd24gYW5kIHJna24tPnNpemUgZ2V0cyBhZGp1c3RlZC4KICoKICogdGhlcmUgaXMgYSBvbmUgdG8gb25lIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGRrZSBhbmQgZGtoCiAqLwogLyoga2V5IHN0cnVjdCwgb25jZSBwZXIga2V5ICovCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECXgxOwkJLyogRnJlZSBlbnRyeSBpbmRpY2F0b3IoPykgKi8KICAgIERXT1JECWhhc2g7CQkvKiBzdW0gb2YgYnl0ZXMgb2Yga2V5bmFtZSAqLwogICAgRFdPUkQJeDM7CQkvKiBSb290IGtleSBpbmRpY2F0b3I/IHVzdWFsbHkgMHhGRkZGRkZGRiAqLwogICAgRFdPUkQJcHJldmx2bDsJLyogb2Zmc2V0IG9mIHByZXZpb3VzIGtleSAqLwogICAgRFdPUkQJbmV4dHN1YjsJLyogb2Zmc2V0IG9mIGNoaWxkIGtleSAqLwogICAgRFdPUkQJbmV4dDsJCS8qIG9mZnNldCBvZiBzaWJsaW5nIGtleSAqLwogICAgV09SRAluckxTOwkJLyogaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCiAgICBXT1JECW5yTVM7CQkvKiBudW1iZXIgb2YgdGhlIHJnZGIgYmxvY2sgKi8KfSBfdzk1ZGtlOwoKLyogU0VDVElPTiAzOiBrZXkgaW5mb3JtYXRpb24sIHZhbHVlcyBhbmQgZGF0YQogKgogKiBzdHJ1Y3R1cmU6CiAqICBzZWN0aW9uOglbYmxvY2tzXSoJCShyZXBlYXQgY3JlZy0+cmdkYl9udW0gdGltZXMpCiAqICBibG9ja3M6CVtyZ2RiXSBbc3ViYmxvY2tzXSogCShyZXBlYXQgdGlsbCBibG9jayBzaXplIHJlYWNoZWQgKQogKiAgc3ViYmxvY2tzOglbZGtoXSBbZGt2XSoJCShyZXBlYXQgZGtoLT52YWx1ZXMgdGltZXMgKQogKgogKiBBbiBpbnRlcmVzdGluZyByZWxhdGlvbnNoaXAgZXhpc3RzIGluIFJHREJfc2VjdGlvbi4gVGhlIERXT1JEIHZhbHVlCiAqIGF0IG9mZnNldCAweDEwIGVxdWFscyB0aGUgb25lIGF0IG9mZnNldCAweDA0IG1pbnVzIHRoZSBvbmUgYXQgb2Zmc2V0IDB4MDguCiAqIEkgaGF2ZSBubyBpZGVhIGF0IHRoZSBtb21lbnQgd2hhdCB0aGlzIG1lYW5zLiAgKEtldmluIENvemVucykKICovCgovKiBibG9jayBoZWFkZXIsIG9uY2UgcGVyIGJsb2NrICovCiNkZWZpbmUgVzk1X1JFR19SR0RCX0lECTB4NDI0NDQ3NTIKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkvKiAweDAwICdSR0RCJyA9IFc5NV9SRUdfUkdEQl9JRCAqLwogICAgRFdPUkQJc2l6ZTsJLyogMHgwNCAqLwogICAgRFdPUkQJdWsxOwkvKiAweDA4ICovCiAgICBEV09SRAl1azI7CS8qIDB4MGMgKi8KICAgIERXT1JECXVrMzsJLyogMHgxMCAqLwogICAgRFdPUkQJdWs0OwkvKiAweDE0ICovCiAgICBEV09SRAl1azU7CS8qIDB4MTggKi8KICAgIERXT1JECXVrNjsJLyogMHgxYyAqLwogICAgLyogZGtoICovCn0gX3c5NXJnZGI7CgovKiBEaXNrIEtleSBIZWFkZXIgc3RydWN0dXJlIChSR0RCIHBhcnQpLCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZglzdHJ1Y3QgewogICAgRFdPUkQJbmV4dGtleW9mZjsgCS8qIDB4MDAgb2Zmc2V0IHRvIG5leHQgZGtoICovCiAgICBXT1JECW5yTFM7CQkvKiAweDA0IGlkIGluc2lkZSB0aGUgcmdkYiBibG9jayAqLwogICAgV09SRAluck1TOwkJLyogMHgwNiBudW1iZXIgb2YgdGhlIHJnZGIgYmxvY2sgKi8KICAgIERXT1JECWJ5dGVzdXNlZDsJLyogMHgwOCAqLwogICAgV09SRAlrZXluYW1lbGVuOwkvKiAweDBjIGxlbiBvZiBuYW1lICovCiAgICBXT1JECXZhbHVlczsJCS8qIDB4MGUgbnVtYmVyIG9mIHZhbHVlcyAqLwogICAgRFdPUkQJeHgxOwkJLyogMHgxMCAqLwogICAgY2hhcgluYW1lWzFdOwkvKiAweDE0ICovCiAgICAvKiBka3YgKi8JCS8qIDB4MTQgKyBrZXluYW1lbGVuICovCn0gX3c5NWRraDsKCi8qIERpc2sgS2V5IFZhbHVlIHN0cnVjdHVyZSwgb25jZSBwZXIgdmFsdWUgKi8KdHlwZWRlZglzdHJ1Y3QgewogICAgRFdPUkQJdHlwZTsJCS8qIDB4MDAgKi8KICAgIERXT1JECXgxOwkJLyogMHgwNCAqLwogICAgV09SRAl2YWxuYW1lbGVuOwkvKiAweDA4IGxlbmd0aCBvZiBuYW1lLCAwIGlzIGRlZmF1bHQga2V5ICovCiAgICBXT1JECXZhbGRhdGFsZW47CS8qIDB4MEEgbGVuZ3RoIG9mIGRhdGEgKi8KICAgIGNoYXIJbmFtZVsxXTsJLyogMHgwYyAqLwogICAgLyogcmF3IGRhdGEgKi8JCS8qIDB4MGMgKyB2YWxuYW1lbGVuICovCn0gX3c5NWRrdjsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9sb29rdXBfZGtoIFtJbnRlcm5hbF0KICoKICogc2Vla3MgdGhlIGRraCBiZWxvbmdpbmcgdG8gYSBka2UKICovCnN0YXRpYyBfdzk1ZGtoICpfdzk1X2xvb2t1cF9ka2goX3c5NWNyZWcgKmNyZWcsaW50IG5yTFMsaW50IG5yTVMpCnsKICAgIF93OTVyZ2RiICogcmdkYjsKICAgIF93OTVka2ggKiBka2g7CiAgICBpbnQgaTsKCiAgICAvKiBnZXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgcmdkYiBkYXRhc3RvcmUgKi8KICAgIHJnZGIgPSAoX3c5NXJnZGIqKSgoY2hhciopY3JlZytjcmVnLT5yZ2RiX29mZik7CgogICAgLyogY2hlY2s6IHJlcXVlc3RlZCBibG9jayA8IGxhc3RfYmxvY2spICovCiAgICBpZiAoY3JlZy0+cmdkYl9udW0gPD0gbnJNUykgewogICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISByZXF1ZXN0ZWQgYmxvY2sgbm8uIGJleW9uZCBlbmQuXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIGZpbmQgdGhlIHJpZ2h0IGJsb2NrICovCiAgICBmb3IoaT0wOyBpPG5yTVMgO2krKykgewogICAgICAgIGlmKHJnZGItPmlkICE9IFc5NV9SRUdfUkdEQl9JRCkgeyAgLyogY2hlY2sgdGhlIG1hZ2ljICovCiAgICAgICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISBiYWQgbWFnaWMgMHglMDhseFxuIiwgcmdkYi0+aWQpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KICAgICAgICByZ2RiID0gKF93OTVyZ2RiKikgKChjaGFyKilyZ2RiK3JnZGItPnNpemUpOwkJLyogZmluZCBuZXh0IGJsb2NrICovCiAgICB9CgogICAgZGtoID0gKF93OTVka2gqKShyZ2RiICsgMSk7CQkJCS8qIGZpcnN0IHN1YiBibG9jayB3aXRoaW4gdGhlIHJnZGIgKi8KCiAgICBkbyB7CiAgICAgICAgaWYobnJMUz09ZGtoLT5uckxTICkgcmV0dXJuIGRraDsKICAgICAgICBka2ggPSAoX3c5NWRraCopKChjaGFyKilka2ggKyBka2gtPm5leHRrZXlvZmYpOwkvKiBmaW5kIG5leHQgc3ViYmxvY2sgKi8KICAgIH0gd2hpbGUgKChjaGFyICopZGtoIDwgKChjaGFyKilyZ2RiK3JnZGItPnNpemUpKTsKCmVycm9yOgogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9kdW1wX2RrdiBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfZHVtcF9ka3YoX3c5NWRraCAqZGtoLGludCBuckxTLGludCBuck1TLEZJTEUgKmYpCnsKICAgIF93OTVka3YgKiBka3Y7CiAgICBpbnQgaTsKCiAgICAvKiBmaXJzdCB2YWx1ZSBibG9jayAqLwogICAgZGt2ID0gKF93OTVka3YqKSgoY2hhciopZGtoK2RraC0+a2V5bmFtZWxlbisweDE0KTsKCiAgICAvKiBsb29wIHRocm91Z2ggdGhlIHZhbHVlcyAqLwogICAgZm9yIChpPTA7IGk8IGRraC0+dmFsdWVzOyBpKyspIHsKICAgICAgICBzdHJ1Y3Qga2V5X3ZhbHVlIHZhbHVlOwogICAgICAgIFdDSEFSICpwZGF0YTsKCiAgICAgICAgdmFsdWUubmFtZVcgPSBfc3RyZHVwbkF0b1coZGt2LT5uYW1lLGRrdi0+dmFsbmFtZWxlbik7CiAgICAgICAgdmFsdWUudHlwZSA9IGRrdi0+dHlwZTsKICAgICAgICB2YWx1ZS5sZW4gPSBka3YtPnZhbGRhdGFsZW47CgogICAgICAgIHZhbHVlLmRhdGEgPSAmKGRrdi0+bmFtZVtka3YtPnZhbG5hbWVsZW5dKTsKICAgICAgICBwZGF0YSA9IE5VTEw7CiAgICAgICAgaWYgKCAodmFsdWUudHlwZT09UkVHX1NaKSB8fCAodmFsdWUudHlwZT09UkVHX0VYUEFORF9TWikgfHwgKHZhbHVlLnR5cGU9PVJFR19NVUxUSV9TWikgKSB7CiAgICAgICAgICAgIHBkYXRhID0gX3N0cmR1cG5BdG9XKHZhbHVlLmRhdGEsdmFsdWUubGVuKTsKICAgICAgICAgICAgdmFsdWUubGVuICo9IDI7CiAgICAgICAgfQogICAgICAgIGlmIChwZGF0YSAhPSBOVUxMKSB2YWx1ZS5kYXRhID0gcGRhdGE7CgogICAgICAgIF9kdW1wX3ZhbHVlKCZ2YWx1ZSxmKTsKICAgICAgICBmcmVlKHZhbHVlLm5hbWVXKTsKICAgICAgICBpZiAocGRhdGEgIT0gTlVMTCkgZnJlZShwZGF0YSk7CgogICAgICAgIC8qIG5leHQgdmFsdWUgKi8KICAgICAgICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka3YrZGt2LT52YWxuYW1lbGVuK2Rrdi0+dmFsZGF0YWxlbisweDBjKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfZHVtcF9ka2UgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfdzk1X2R1bXBfZGtlKExQQ1NUUiBrZXlfbmFtZSxfdzk1Y3JlZyAqY3JlZyxfdzk1cmdrbiAqcmdrbixfdzk1ZGtlICpka2UsRklMRSAqZixpbnQgbGV2ZWwpCnsKICAgIF93OTVka2ggKiBka2g7CiAgICBMUFNUUiBuZXdfa2V5X25hbWUgPSBOVUxMOwoKICAgIC8qIHNwZWNpYWwgcm9vdCBrZXkgKi8KICAgIGlmIChka2UtPm5yTFMgPT0gMHhmZmZmIHx8IGRrZS0+bnJNUz09MHhmZmZmKQkJLyogZWcuIHRoZSByb290IGtleSBoYXMgbm8gbmFtZSAqLwogICAgewogICAgICAgIC8qIHBhcnNlIHRoZSBvbmUgc3Via2V5ICovCiAgICAgICAgaWYgKGRrZS0+bmV4dHN1YiAhPSAweGZmZmZmZmZmKSByZXR1cm4gX3c5NV9kdW1wX2RrZShrZXlfbmFtZSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHRzdWIpLGYsbGV2ZWwpOwogICAgICAgIC8qIGhhcyBubyBzaWJsaW5nIGtleXMgKi8KICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgLyogc2VhcmNoIHN1YmJsb2NrICovCiAgICBpZiAoIShka2ggPSBfdzk1X2xvb2t1cF9ka2goY3JlZywgZGtlLT5uckxTLCBka2UtPm5yTVMpKSkgewogICAgICAgIEVSUigiZGtlIHBvaW50aW5nIHRvIG1pc3NpbmcgZGtoICFcbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAobGV2ZWwgPD0gMCkgewogICAgICAgIC8qIGNyZWF0ZSBuZXcgc3Via2V5IG5hbWUgKi8KICAgICAgICBzaXplX3QgbGVuID0gc3RybGVuKGtleV9uYW1lKTsKICAgICAgICBuZXdfa2V5X25hbWUgPSBfeG1hbGxvYyhsZW4rZGtoLT5rZXluYW1lbGVuKzIpOwogICAgICAgIG1lbWNweSggbmV3X2tleV9uYW1lLCBrZXlfbmFtZSwgbGVuICk7CiAgICAgICAgaWYgKGxlbikgbmV3X2tleV9uYW1lW2xlbisrXSA9ICdcXCc7CiAgICAgICAgbWVtY3B5KCBuZXdfa2V5X25hbWUgKyBsZW4sIGRraC0+bmFtZSwgZGtoLT5rZXluYW1lbGVuICk7CiAgICAgICAgbmV3X2tleV9uYW1lW2xlbiArIGRraC0+a2V5bmFtZWxlbl0gPSAwOwoKICAgICAgICAvKiB3YWxrIHNpYmxpbmcga2V5cyAqLwogICAgICAgIGlmIChka2UtPm5leHQgIT0gMHhmZmZmZmZmZiApIHsKICAgICAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGtlKGtleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dCksZixsZXZlbCkpIHsKICAgICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogd3JpdGUgdGhlIGtleSBwYXRoIChzb21ldGhpbmcgbGlrZSBbU29mdHdhcmVcXE1pY3Jvc29mdFxcLi5dKSBvbmx5IGlmOgogICAgICAgICAgIDEpIGtleSBoYXMgc29tZSB2YWx1ZXMKICAgICAgICAgICAyKSBrZXkgaGFzIG5vIHZhbHVlcyBhbmQgbm8gc3Via2V5cwogICAgICAgICovCiAgICAgICAgaWYgKGRraC0+dmFsdWVzID4gMCkgewogICAgICAgICAgICAvKiB0aGVyZSBhcmUgc29tZSB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGt2KGRraCwgZGtlLT5uckxTLCBka2UtPm5yTVMsZikpIHsKICAgICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgoZGtlLT5uZXh0c3ViID09IDB4ZmZmZmZmZmYpICYmIChka2gtPnZhbHVlcyA9PSAwKSkgewogICAgICAgICAgICAvKiBubyBzdWJrZXlzIGFuZCBubyB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICB9CiAgICB9IGVsc2UgbmV3X2tleV9uYW1lID0gX3hzdHJkdXAoa2V5X25hbWUpOwoKICAgIC8qIG5leHQgc3ViIGtleSAqLwogICAgaWYgKGRrZS0+bmV4dHN1YiAhPSAweGZmZmZmZmZmKSB7CiAgICAgICAgaWYgKCFfdzk1X2R1bXBfZGtlKG5ld19rZXlfbmFtZSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHRzdWIpLGYsbGV2ZWwtMSkpIHsKICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgcmV0dXJuIFRSVUU7Cn0KLyogZW5kIHdpbmRvd3MgOTUgbG9hZGVyICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93cyBOVCByZWdpc3RyeSBsb2FkZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogTlQgUkVHSVNUUlkgTE9BREVSICovCgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgojaWZuZGVmIE1BUF9GQUlMRUQKI2RlZmluZSBNQVBfRkFJTEVEICgoTFBWT0lEKS0xKQojZW5kaWYKCiNkZWZpbmUgTlRfUkVHX0JMT0NLX1NJWkUgICAgICAgICAgICAweDEwMDAKCiNkZWZpbmUgTlRfUkVHX0hFQURFUl9CTE9DS19JRCAgICAgICAweDY2Njc2NTcyCS8qIHJlZ2YgKi8KI2RlZmluZSBOVF9SRUdfUE9PTF9CTE9DS19JRCAgICAgICAgIDB4NkU2OTYyNjgJLyogaGJpbiAqLwojZGVmaW5lIE5UX1JFR19LRVlfQkxPQ0tfSUQgICAgICAgICAgMHg2YjZlIC8qIG5rICovCiNkZWZpbmUgTlRfUkVHX1ZBTFVFX0JMT0NLX0lEICAgICAgICAweDZiNzYgLyogdmsgKi8KCi8qIHN1YmJsb2NrcyBvZiBuayAqLwojZGVmaW5lIE5UX1JFR19IQVNIX0JMT0NLX0lEICAgICAgICAgMHg2NjZjIC8qIGxmICovCiNkZWZpbmUgTlRfUkVHX05PSEFTSF9CTE9DS19JRCAgICAgICAweDY5NmMgLyogbGkgKi8KI2RlZmluZSBOVF9SRUdfUklfQkxPQ0tfSUQJICAgICAweDY5NzIgLyogcmkgKi8KCiNkZWZpbmUgTlRfUkVHX0tFWV9CTE9DS19UWVBFICAgICAgICAweDIwCiNkZWZpbmUgTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUgICAweDJjCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEV09SRAlpZDsJCS8qIDB4NjY2NzY1NzIgJ3JlZ2YnKi8KICAgIERXT1JECXVrMTsJCS8qIDB4MDQgKi8KICAgIERXT1JECXVrMjsJCS8qIDB4MDggKi8KICAgIEZJTEVUSU1FCURhdGVNb2RpZmllZDsJLyogMHgwYyAqLwogICAgRFdPUkQJdWszOwkJLyogMHgxNCAqLwogICAgRFdPUkQJdWs0OwkJLyogMHgxOCAqLwogICAgRFdPUkQJdWs1OwkJLyogMHgxYyAqLwogICAgRFdPUkQJdWs2OwkJLyogMHgyMCAqLwogICAgRFdPUkQJUm9vdEtleUJsb2NrOwkvKiAweDI0ICovCiAgICBEV09SRAlCbG9ja1NpemU7CS8qIDB4MjggKi8KICAgIERXT1JEICAgdWs3WzExNl07CiAgICBEV09SRAlDaGVja3N1bTsgLyogYXQgb2Zmc2V0IDB4MUZDICovCn0gbnRfcmVnZjsKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWJsb2Nrc2l6ZTsKICAgIEJZVEUJZGF0YVsxXTsKfSBudF9oYmluX3N1YjsKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogMHg2RTY5NjI2OCAnaGJpbicgKi8KICAgIERXT1JECW9mZl9wcmV2OwogICAgRFdPUkQJb2ZmX25leHQ7CiAgICBEV09SRAl1azE7CiAgICBEV09SRAl1azI7CQkvKiAweDEwICovCiAgICBEV09SRAl1azM7CQkvKiAweDE0ICovCiAgICBEV09SRAl1azQ7CQkvKiAweDE4ICovCiAgICBEV09SRAlzaXplOwkJLyogMHgxQyAqLwogICAgbnRfaGJpbl9zdWIJaGJpbl9zdWI7CS8qIDB4MjAgKi8KfSBudF9oYmluOwoKLyoKICogdGhlIHZhbHVlX2xpc3QgY29uc2lzdHMgb2Ygb2Zmc2V0cyB0byB0aGUgdmFsdWVzICh2aykKICovCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJU3ViQmxvY2tJZDsJCS8qIDB4MDAgMHg2QjZFICovCiAgICBXT1JECVR5cGU7CQkJLyogMHgwMiBmb3IgdGhlIHJvb3Qta2V5OiAweDJDLCBvdGhlcndpc2UgMHgyMCovCiAgICBGSUxFVElNRQl3cml0ZXRpbWU7CS8qIDB4MDQgKi8KICAgIERXT1JECXVrMTsJCQkvKiAweDBDICovCiAgICBEV09SRAlwYXJlbnRfb2ZmOwkJLyogMHgxMCBPZmZzZXQgb2YgT3duZXIvUGFyZW50IGtleSAqLwogICAgRFdPUkQJbnJfc3Via2V5czsJCS8qIDB4MTQgbnVtYmVyIG9mIHN1Yi1LZXlzICovCiAgICBEV09SRAl1azg7CQkJLyogMHgxOCAqLwogICAgRFdPUkQJbGZfb2ZmOwkJCS8qIDB4MUMgT2Zmc2V0IG9mIHRoZSBzdWIta2V5IGxmLVJlY29yZHMgKi8KICAgIERXT1JECXVrMjsJCQkvKiAweDIwICovCiAgICBEV09SRAlucl92YWx1ZXM7CQkvKiAweDI0IG51bWJlciBvZiB2YWx1ZXMgKi8KICAgIERXT1JECXZhbHVlbGlzdF9vZmY7CQkvKiAweDI4IE9mZnNldCBvZiB0aGUgVmFsdWUtTGlzdCAqLwogICAgRFdPUkQJb2ZmX3NrOwkJCS8qIDB4MmMgT2Zmc2V0IG9mIHRoZSBzay1SZWNvcmQgKi8KICAgIERXT1JECW9mZl9jbGFzczsJCS8qIDB4MzAgT2Zmc2V0IG9mIHRoZSBDbGFzcy1OYW1lICovCiAgICBEV09SRAl1azM7CQkJLyogMHgzNCAqLwogICAgRFdPUkQJdWs0OwkJCS8qIDB4MzggKi8KICAgIERXT1JECXVrNTsJCQkvKiAweDNjICovCiAgICBEV09SRAl1azY7CQkJLyogMHg0MCAqLwogICAgRFdPUkQJdWs3OwkJCS8qIDB4NDQgKi8KICAgIFdPUkQJbmFtZV9sZW47CQkvKiAweDQ4IG5hbWUtbGVuZ3RoICovCiAgICBXT1JECWNsYXNzX2xlbjsJCS8qIDB4NGEgY2xhc3MtbmFtZSBsZW5ndGggKi8KICAgIGNoYXIJbmFtZVsxXTsJCS8qIDB4NGMga2V5LW5hbWUgKi8KfSBudF9uazsKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECW9mZl9uazsJLyogMHgwMCAqLwogICAgRFdPUkQJbmFtZTsJLyogMHgwNCAqLwp9IGhhc2hfcmVjOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgMHg2NjZjICovCiAgICBXT1JECW5yX2tleXM7CS8qIDB4MDYgKi8KICAgIGhhc2hfcmVjCWhhc2hfcmVjWzFdOwp9IG50X2xmOwoKLyoKIGxpc3Qgb2Ygc3Via2V5cyB3aXRob3V0IGhhc2gKCiBsaSAtLSstLT5uawogICAgICB8CiAgICAgICstLT5uawogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgMHg2OTZjICovCiAgICBXT1JECW5yX2tleXM7CiAgICBEV09SRAlvZmZfbmtbMV07Cn0gbnRfbGk7CgovKgogdGhpcyBpcyBhIGludGVybWVkaWF0ZSBub2RlCgogcmkgLS0rLS0+bGktLSstLT5uawogICAgICB8ICAgICAgICsKICAgICAgfCAgICAgICArLS0+bmsKICAgICAgfAogICAgICArLS0+bGktLSstLT5uawogICAgICAgICAgICAgICsKCSAgICAgICstLT5uawogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgMHg2OTcyICovCiAgICBXT1JECW5yX2xpOwkJLyogMHgwMiBudW1iZXIgb2ZmIG9mZnNldHMgKi8KICAgIERXT1JECW9mZl9saVsxXTsJLyogMHgwNCBwb2ludHMgdG8gbGkgKi8KfSBudF9yaTsKCnR5cGVkZWYgc3RydWN0IHsKICAgIFdPUkQJaWQ7CQkvKiAweDAwICd2aycgKi8KICAgIFdPUkQJbmFtX2xlbjsKICAgIERXT1JECWRhdGFfbGVuOwogICAgRFdPUkQJZGF0YV9vZmY7CiAgICBEV09SRAl0eXBlOwogICAgV09SRAlmbGFnOwogICAgV09SRAl1azE7CiAgICBjaGFyCW5hbWVbMV07Cn0gbnRfdms7CgovKgogKiBnZXRzIGEgdmFsdWUKICoKICogdmstPmZsYWc6CiAqICAwIHZhbHVlIGlzIGEgZGVmYXVsdCB2YWx1ZQogKiAgMSB0aGUgdmFsdWUgaGFzIGEgbmFtZQogKgogKiB2ay0+ZGF0YV9sZW4KICogIGxlbiBvZiB0aGUgd2hvbGUgZGF0YSBibG9jawogKiAgLSByZWdfc3ogKHVuaWNvZGUpCiAqICAgIGJ5dGVzIGluY2x1ZGluZyB0aGUgdGVybWluYXRpbmcgXDAgPSAyKihudW1iZXJfb2ZfY2hhcnMrMSkKICogIC0gcmVnX2R3b3JkLCByZWdfYmluYXJ5OgogKiAgICBpZiBoaWdoZXN0IGJpdCBvZiBkYXRhX2xlbiBpcyBzZXQgZGF0YV9vZmYgY29udGFpbnMgdGhlIHZhbHVlCiAqLwpzdGF0aWMgaW50IF9udF9kdW1wX3ZrKExQU1RSIGtleV9uYW1lLCBjaGFyICpiYXNlLCBudF92ayAqdmssRklMRSAqZikKewogICAgQllURSAqcGRhdGEgPSAoQllURSAqKShiYXNlK3ZrLT5kYXRhX29mZis0KTsgLyogc3RhcnQgb2YgZGF0YSAqLwogICAgc3RydWN0IGtleV92YWx1ZSB2YWx1ZTsKCiAgICBpZiAodmstPmlkICE9IE5UX1JFR19WQUxVRV9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5rbm93biBibG9jayBmb3VuZCAoMHglMDR4KSwgcGxlYXNlIHJlcG9ydCFcbiIsIHZrLT5pZCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHZhbHVlLm5hbWVXID0gX3N0cmR1cG5BdG9XKHZrLT5uYW1lLHZrLT5uYW1fbGVuKTsKICAgIHZhbHVlLnR5cGUgPSB2ay0+dHlwZTsKICAgIHZhbHVlLmxlbiA9ICh2ay0+ZGF0YV9sZW4gJiAweDdmZmZmZmZmKTsKICAgIHZhbHVlLmRhdGEgPSAodmstPmRhdGFfbGVuICYgMHg4MDAwMDAwMCkgPyAoTFBCWVRFKSYodmstPmRhdGFfb2ZmKTogcGRhdGE7CgogICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgZnJlZSh2YWx1ZS5uYW1lVyk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qIGl0J3MgY2FsbGVkIGZyb20gX250X2R1bXBfbGYoKSAqLwpzdGF0aWMgaW50IF9udF9kdW1wX25rKExQQ1NUUiBrZXlfbmFtZSxjaGFyICpiYXNlLG50X25rICpuayxGSUxFICpmLGludCBsZXZlbCk7CgovKgogKiBnZXQgdGhlIHN1YmtleXMKICoKICogdGhpcyBzdHJ1Y3R1cmUgY29udGFpbnMgdGhlIGhhc2ggb2YgYSBrZXluYW1lIGFuZCBwb2ludHMgdG8gYWxsCiAqIHN1YmtleXMKICoKICogZXhjZXB0aW9uOiBpZiB0aGUgaWQgaXMgJ2lsJyB0aGVyZSBhcmUgbm8gaGFzaCB2YWx1ZXMgYW5kIGV2ZXJ5CiAqIGR3b3JkIGlzIGEgb2Zmc2V0CiAqLwpzdGF0aWMgaW50IF9udF9kdW1wX2xmKExQQ1NUUiBrZXlfbmFtZSwgY2hhciAqYmFzZSwgaW50IHN1YmtleXMsIG50X2xmICpsZiwgRklMRSAqZiwgaW50IGxldmVsKQp7CiAgICBpbnQgaTsKCiAgICBpZiAobGYtPmlkID09IE5UX1JFR19IQVNIX0JMT0NLX0lEKSB7CiAgICAgICAgaWYgKHN1YmtleXMgIT0gbGYtPm5yX2tleXMpIGdvdG8gZXJyb3IxOwoKICAgICAgICBmb3IgKGk9MDsgaTxsZi0+bnJfa2V5czsgaSsrKQogICAgICAgICAgICBpZiAoIV9udF9kdW1wX25rKGtleV9uYW1lLCBiYXNlLCAobnRfbmsqKShiYXNlK2xmLT5oYXNoX3JlY1tpXS5vZmZfbmsrNCksIGYsIGxldmVsKSkgZ290byBlcnJvcjsKICAgIH0gZWxzZSBpZiAobGYtPmlkID09IE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQpIHsKICAgICAgICBudF9saSAqIGxpID0gKG50X2xpKilsZjsKICAgICAgICBpZiAoc3Via2V5cyAhPSBsaS0+bnJfa2V5cykgZ290byBlcnJvcjE7CgogICAgICAgIGZvciAoaT0wOyBpPGxpLT5ucl9rZXlzOyBpKyspCiAgICAgICAgICAgIGlmICghX250X2R1bXBfbmsoa2V5X25hbWUsIGJhc2UsIChudF9uayopKGJhc2UrbGktPm9mZl9ua1tpXSs0KSwgZiwgbGV2ZWwpKSBnb3RvIGVycm9yOwogICAgfSBlbHNlIGlmIChsZi0+aWQgPT0gTlRfUkVHX1JJX0JMT0NLX0lEKSB7ICAvKiByaSAqLwogICAgICAgIG50X3JpICogcmkgPSAobnRfcmkqKWxmOwogICAgICAgIGludCBsaV9zdWJrZXlzID0gMDsKCiAgICAgICAgLyogY291bnQgYWxsIHN1YmtleXMgKi8KICAgICAgICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykgewogICAgICAgICAgICBudF9saSAqIGxpID0gKG50X2xpKikoYmFzZStyaS0+b2ZmX2xpW2ldKzQpOwogICAgICAgICAgICBpZihsaS0+aWQgIT0gTlRfUkVHX05PSEFTSF9CTE9DS19JRCkgZ290byBlcnJvcjI7CiAgICAgICAgICAgIGxpX3N1YmtleXMgKz0gbGktPm5yX2tleXM7CiAgICAgICAgfQoKICAgICAgICAvKiBjaGVjayBudW1iZXIgKi8KICAgICAgICBpZiAoc3Via2V5cyAhPSBsaV9zdWJrZXlzKSBnb3RvIGVycm9yMTsKCiAgICAgICAgLyogbG9vcCB0aHJvdWdoIHRoZSBrZXlzICovCiAgICAgICAgZm9yIChpPTA7IGk8cmktPm5yX2xpOyBpKyspIHsKICAgICAgICAgICAgbnRfbGkgKmxpID0gKG50X2xpKikoYmFzZStyaS0+b2ZmX2xpW2ldKzQpOwogICAgICAgICAgICBpZiAoIV9udF9kdW1wX2xmKGtleV9uYW1lLCBiYXNlLCBsaS0+bnJfa2V5cywgKG50X2xmKilsaSwgZiwgbGV2ZWwpKSBnb3RvIGVycm9yOwogICAgICAgIH0KICAgIH0gZWxzZSBnb3RvIGVycm9yMjsKCiAgICByZXR1cm4gVFJVRTsKCmVycm9yMjoKICAgIGlmIChsZi0+aWQgPT0gMHg2ODZjKQogICAgICAgIEZJWE1FKCJ1bmtub3duIFdpbiBYUCBub2RlIGlkIDB4Njg2YzogZG8gd2UgbmVlZCB0byBhZGQgc3VwcG9ydCBmb3IgaXQgP1xuIik7CiAgICBlbHNlCiAgICAgICAgRVJSKCJ1bmtub3duIG5vZGUgaWQgMHglMDR4LCBwbGVhc2UgcmVwb3J0IVxuIiwgbGYtPmlkKTsKICAgIHJldHVybiBUUlVFOwoKZXJyb3IxOgogICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIChpbmNvbnNpc3RlbnQgbnVtYmVyIG9mIHN1YmtleXMpXG4iKTsKICAgIHJldHVybiBGQUxTRTsKCmVycm9yOgogICAgRVJSKCJlcnJvciByZWFkaW5nIGxmIGJsb2NrXG4iKTsKICAgIHJldHVybiBGQUxTRTsKfQoKLyogX250X2R1bXBfbmsgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9udF9kdW1wX25rKExQQ1NUUiBrZXlfbmFtZSxjaGFyICpiYXNlLG50X25rICpuayxGSUxFICpmLGludCBsZXZlbCkKewogICAgdW5zaWduZWQgaW50IG47CiAgICBEV09SRCAqdmw7CiAgICBMUFNUUiBuZXdfa2V5X25hbWUgPSBOVUxMOwoKICAgIFRSQUNFKCIlc1xuIiwga2V5X25hbWUpOwoKICAgIGlmIChuay0+U3ViQmxvY2tJZCAhPSBOVF9SRUdfS0VZX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmtub3duIG5vZGUgaWQgMHglMDR4LCBwbGVhc2UgcmVwb3J0IVxuIiwgbmstPlN1YkJsb2NrSWQpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoKG5rLT5UeXBlIT1OVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSkgJiYgKCgobnRfbmsqKShiYXNlK25rLT5wYXJlbnRfb2ZmKzQpKS0+U3ViQmxvY2tJZCAhPSBOVF9SRUdfS0VZX0JMT0NLX0lEKSkgewogICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0IVxuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIGNyZWF0ZSB0aGUgbmV3IGtleSAqLwogICAgaWYgKGxldmVsIDw9IDApIHsKICAgICAgICAvKiBjcmVhdGUgbmV3IHN1YmtleSBuYW1lICovCiAgICAgICAgc2l6ZV90IGxlbiA9IHN0cmxlbihrZXlfbmFtZSk7CiAgICAgICAgbmV3X2tleV9uYW1lID0gX3htYWxsb2MoIGxlbituay0+bmFtZV9sZW4rMiApOwogICAgICAgIG1lbWNweSggbmV3X2tleV9uYW1lLCBrZXlfbmFtZSwgbGVuICk7CiAgICAgICAgaWYgKGxlbikgbmV3X2tleV9uYW1lW2xlbisrXSA9ICdcXCc7CiAgICAgICAgbWVtY3B5KCBuZXdfa2V5X25hbWUgKyBsZW4sIG5rLT5uYW1lLCBuay0+bmFtZV9sZW4gKTsKICAgICAgICBuZXdfa2V5X25hbWVbbGVuICsgbmstPm5hbWVfbGVuXSA9IDA7CgogICAgICAgIC8qIHdyaXRlIHRoZSBrZXkgcGF0aCAoc29tZXRoaW5nIGxpa2UgW1NvZnR3YXJlXFxNaWNyb3NvZnRcXC4uXSkgb25seSBpZjoKICAgICAgICAgICAxKSBrZXkgaGFzIHNvbWUgdmFsdWVzCiAgICAgICAgICAgMikga2V5IGhhcyBubyB2YWx1ZXMgYW5kIG5vIHN1YmtleXMKICAgICAgICAqLwogICAgICAgIGlmIChuay0+bnJfdmFsdWVzID4gMCkgewogICAgICAgICAgICAvKiB0aGVyZSBhcmUgc29tZSB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKChuay0+bnJfc3Via2V5cyA9PSAwKSAmJiAobmstPm5yX3ZhbHVlcyA9PSAwKSkgewogICAgICAgICAgICAvKiBubyBzdWJrZXlzIGFuZCBubyB2YWx1ZXMgKi8KICAgICAgICAgICAgZnByaW50ZihmLCJcblsiKTsKICAgICAgICAgICAgX2R1bXBfc3RyQXRvVyhuZXdfa2V5X25hbWUsc3RybGVuKG5ld19rZXlfbmFtZSksZiwiW10iKTsKICAgICAgICAgICAgZnByaW50ZihmLCJdXG4iKTsKICAgICAgICB9CgogICAgICAgIC8qIGxvb3AgdHJvdWdoIHRoZSB2YWx1ZSBsaXN0ICovCiAgICAgICAgdmwgPSAoRFdPUkQgKikoYmFzZStuay0+dmFsdWVsaXN0X29mZis0KTsKICAgICAgICBmb3IgKG49MDsgbjxuay0+bnJfdmFsdWVzOyBuKyspIHsKICAgICAgICAgICAgbnRfdmsgKiB2ayA9IChudF92ayopKGJhc2Urdmxbbl0rNCk7CiAgICAgICAgICAgIGlmICghX250X2R1bXBfdmsobmV3X2tleV9uYW1lLCBiYXNlLCB2aywgZikpIHsKICAgICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSBuZXdfa2V5X25hbWUgPSBfeHN0cmR1cChrZXlfbmFtZSk7CgogICAgLyogbG9vcCB0aHJvdWdoIHRoZSBzdWJrZXlzICovCiAgICBpZiAobmstPm5yX3N1YmtleXMpIHsKICAgICAgICBudF9sZiAqbGYgPSAobnRfbGYqKShiYXNlK25rLT5sZl9vZmYrNCk7CiAgICAgICAgaWYgKCFfbnRfZHVtcF9sZihuZXdfa2V5X25hbWUsIGJhc2UsIG5rLT5ucl9zdWJrZXlzLCBsZiwgZiwgbGV2ZWwtMSkpIHsKICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgIHJldHVybiBUUlVFOwp9CgovKiBlbmQgbnQgbG9hZGVyICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXMgW0ludGVybmFsXQogKiBSZWdpc3RyeSBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIHNvbWUgZGVmYXVsdCBrZXlzLgogKi8Kc3RhdGljIHZvaWQgX2FsbG9jYXRlX2RlZmF1bHRfa2V5cyh2b2lkKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgU3RhdERhdGFXW10gPSB7J0QnLCd5JywnbicsJ0QnLCdhJywndCcsJ2EnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1AnLCdlJywncicsJ2YnLCdTJywndCcsJ2EnLCd0JywncycsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUycsJ3QnLCdhJywndCcsJ0QnLCdhJywndCcsJ2EnLDB9OwogICAgSEtFWSBoa2V5OwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwoKICAgIFRSQUNFKCIodm9pZClcbiIpOwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgU3RhdERhdGFXICk7CiAgICBpZiAoIU50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpIE50Q2xvc2UoIGhrZXkgKTsKfQoKc3RhdGljIHZvaWQgZ2V0X3dpbmRvd3NfZGlyKFdDSEFSKiBidWZmZXIsIHVuc2lnbmVkIGxlbikKewogICAgT0JKRUNUX0FUVFJJQlVURVMgICBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgICAgICBuYW1lVywga2V5VzsKICAgIEhLRVkgICAgICAgICAgICAgICAgaGtleTsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwoKICAgIGlmIChSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCAiTWFjaGluZVxcU29mdHdhcmVcXFdpbmVcXFdpbmVcXENvbmZpZ1xcd2luZSIgKSkKICAgIHsKICAgICAgICBpZiAoIU50T3BlbktleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciApKQogICAgICAgIHsKICAgICAgICAgICAgY2hhciB0bXBbTUFYX1BBVEhOQU1FX0xFTipzaXplb2YoV0NIQVIpICsgc2l6ZW9mKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OKV07CiAgICAgICAgICAgIERXT1JEIGNvdW50OwoKICAgICAgICAgICAgUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZrZXlXLCAiV2luZG93cyIpOwogICAgICAgICAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleSwgJmtleVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICAgICAgICAgIG1lbWNweShidWZmZXIsIHN0ciwgbWluKCgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhTGVuZ3RoLCBsZW4pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJmtleVcgKTsKICAgICAgICB9CiAgICAgICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwogICAgfQp9CgoKI2RlZmluZSBSRUdfRE9OVExPQUQgLTEKI2RlZmluZSBSRUdfV0lOMzEgICAgIDAKI2RlZmluZSBSRUdfV0lOOTUgICAgIDEKI2RlZmluZSBSRUdfV0lOTlQgICAgIDIKCi8qIHJldHVybiB0aGUgdHlwZSBvZiBuYXRpdmUgcmVnaXN0cnkgW0ludGVybmFsXSAqLwpzdGF0aWMgaW50IF9nZXRfcmVnX3R5cGUoY29uc3QgV0NIQVIqIHdpbmRpcikKewogICAgV0NIQVIgdG1wW01BWF9QQVRITkFNRV9MRU5dOwogICAgaW50IHJldCA9IFJFR19XSU4zMTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBudF9yZWdfcGF0aFdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHdpbjl4X3JlZ19wYXRoV1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJy4nLCdkJywnYScsJ3QnLDB9OwoKICAgIC8qIHRlc3QgJXdpbmRpciUvc3lzdGVtMzIvY29uZmlnL3N5c3RlbSAtLT4gd2lubnQgKi8KICAgIHN0cmNweVcodG1wLCB3aW5kaXIpOwogICAgc3RyY2F0Vyh0bXAsIG50X3JlZ19wYXRoVyk7CiAgICBpZihHZXRGaWxlQXR0cmlidXRlc1codG1wKSAhPSBJTlZBTElEX0ZJTEVfQVRUUklCVVRFUykKICAgICAgcmV0ID0gUkVHX1dJTk5UOwogICAgZWxzZQogICAgewogICAgICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0uZGF0IC0tPiB3aW45NSAqLwogICAgICBzdHJjcHlXKHRtcCwgd2luZGlyKTsKICAgICAgc3RyY2F0Vyh0bXAsIHdpbjl4X3JlZ19wYXRoVyk7CiAgICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzVyh0bXApICE9IElOVkFMSURfRklMRV9BVFRSSUJVVEVTKQogICAgICAgIHJldCA9IFJFR19XSU45NTsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgovKiBsb2FkIHRoZSByZWdpc3RyeSBmaWxlIGluIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgbG9hZF93aW5lX3JlZ2lzdHJ5KEhLRVkgaGtleSxMUENTVFIgZm4pCnsKICAgIFdDSEFSICpidWZmZXI7CiAgICBIQU5ETEUgZmlsZTsKICAgIERXT1JEIGxlbjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWU7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgSU9fU1RBVFVTX0JMT0NLIGlvOwoKICAgIGxlbiA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoIENQX1VOSVhDUCwgMCwgZm4sIC0xLCBOVUxMLCAwICk7CiAgICBpZiAoIShidWZmZXIgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbiAqIHNpemVvZihXQ0hBUikgKSkpIHJldHVybjsKICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoIENQX1VOSVhDUCwgMCwgZm4sIC0xLCBidWZmZXIsIGxlbiApOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lLCBidWZmZXIgKTsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWU7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgaWYgKCFOdE9wZW5GaWxlKCAmZmlsZSwgR0VORVJJQ19SRUFELCAmYXR0ciwgJmlvLCBGSUxFX1NIQVJFX1JFQUQgfCBGSUxFX1NIQVJFX1dSSVRFLAogICAgICAgICAgICAgICAgICAgICBGSUxFX05PTl9ESVJFQ1RPUllfRklMRSB8IEZJTEVfU1lOQ0hST05PVVNfSU9fTk9OQUxFUlQgKSkKICAgIHsKICAgICAgICBTRVJWRVJfU1RBUlRfUkVRKCBsb2FkX3JlZ2lzdHJ5ICkKICAgICAgICB7CiAgICAgICAgICAgIHJlcS0+aGtleSAgICA9IGhrZXk7CiAgICAgICAgICAgIHJlcS0+ZmlsZSAgICA9IGZpbGU7CiAgICAgICAgICAgIHdpbmVfc2VydmVyX2NhbGwoIHJlcSApOwogICAgICAgIH0KICAgICAgICBTRVJWRVJfRU5EX1JFUTsKICAgICAgICBDbG9zZUhhbmRsZSggZmlsZSApOwogICAgfQogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1ZmZlciApOwp9CgovKiBnZW5lcmF0ZSBhbmQgcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSB0bXAgZmlsZSBhbmQgYXNzb2NpYXRlZCBzdHJlYW0gW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX2dldF90bXBfZm4oRklMRSAqKmYpCnsKICAgIExQU1RSIHJldDsKICAgIGludCB0bXBfZmQsY291bnQ7CgogICAgcmV0ID0gX3htYWxsb2MoNTApOwogICAgZm9yIChjb3VudCA9IDA7OykgewogICAgICAgIHNwcmludGYocmV0LCIvdG1wL3JlZyVseCUwNHgudG1wIiwobG9uZylnZXRwaWQoKSxjb3VudCsrKTsKICAgICAgICBpZiAoKHRtcF9mZCA9IG9wZW4ocmV0LE9fQ1JFQVQgfCBPX0VYQ0wgfCBPX1dST05MWSwwNjY2KSkgIT0gLTEpIGJyZWFrOwogICAgICAgIGlmIChlcnJubyAhPSBFRVhJU1QpIHsKICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIGVycm9yIHdoaWxlIG9wZW4oKSBjYWxsOiAlc1xuIixzdHJlcnJvcihlcnJubykpOwogICAgICAgICAgICBmcmVlKHJldCk7CiAgICAgICAgICAgICpmID0gTlVMTDsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIGlmICgoKmYgPSBmZG9wZW4odG1wX2ZkLCJ3IikpID09IE5VTEwpIHsKICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgZXJyb3Igd2hpbGUgZmRvcGVuKCkgY2FsbDogJXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICBjbG9zZSh0bXBfZmQpOwogICAgICAgIGZyZWUocmV0KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IHdpbjk1IG5hdGl2ZSByZWdpc3RyeSBmaWxlIHRvIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9jb252ZXJ0X3dpbjk1X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KExQQ1dTVFIgZm4sIGludCBsZXZlbCkKewogICAgSEFORExFIGhGaWxlLCBoTWFwcGluZzsKICAgIEZJTEUgKmY7CiAgICB2b2lkICpiYXNlOwogICAgTFBTVFIgcmV0ID0gTlVMTDsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBMQVJHRV9JTlRFR0VSIGxnX2ludDsKICAgIE5UU1RBVFVTIG50czsKICAgIFNJWkVfVCBsZW47CgogICAgX3c5NWNyZWcgKmNyZWc7CiAgICBfdzk1cmdrbiAqcmdrbjsKICAgIF93OTVka2UgKmRrZSwgKnJvb3RfZGtlOwoKICAgIGhGaWxlID0gQ3JlYXRlRmlsZVcoIGZuLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwogICAgaWYgKCBoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSApIHJldHVybiBOVUxMOwoKICAgIGF0dHIuTGVuZ3RoICAgICAgICAgICAgICAgICAgID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ICAgICAgICAgICAgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lICAgICAgICAgICAgICAgPSBOVUxMOwogICAgYXR0ci5BdHRyaWJ1dGVzICAgICAgICAgICAgICAgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgICAgICAgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwoKICAgIGxnX2ludC5RdWFkUGFydCA9IDA7CiAgICBudHMgPSBOdENyZWF0ZVNlY3Rpb24oICZoTWFwcGluZywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUQU5EQVJEX1JJR0hUU19SRVFVSVJFRHxTRUNUSU9OX1FVRVJZfFNFQ1RJT05fTUFQX1JFQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICZhdHRyLCAmbGdfaW50LCBQQUdFX1JFQURPTkxZLCBTRUNfQ09NTUlULCBoRmlsZSApOwogICAgaWYgKG50cyAhPSBTVEFUVVNfU1VDQ0VTUykgZ290byBlcnJvcjE7CgogICAgYmFzZSA9IE5VTEw7IGxlbiA9IDA7CiAgICBudHMgPSBOdE1hcFZpZXdPZlNlY3Rpb24oIGhNYXBwaW5nLCBHZXRDdXJyZW50UHJvY2VzcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYmFzZSwgMCwgMCwgJmxnX2ludCwgJmxlbiwgVmlld1NoYXJlLCAwLCAKCQkJICAgICAgUEFHRV9SRUFET05MWSk7CiAgICBOdENsb3NlKCBoTWFwcGluZyApOwogICAgaWYgKG50cyAhPSBTVEFUVVNfU1VDQ0VTUykgZ290byBlcnJvcjE7CgogICAgLyogY29udHJvbCBzaWduYXR1cmUgKi8KICAgIGlmICgqKExQRFdPUkQpYmFzZSAhPSBXOTVfUkVHX0NSRUdfSUQpIHsKICAgICAgICBFUlIoInVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW45NSByZWdpc3RyeSBmaWxlICVzOiB1bmtub3duIHNpZ25hdHVyZS5cbiIsCiAgICAgICAgICAgIGRlYnVnc3RyX3coZm4pKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGNyZWcgPSBiYXNlOwogICAgLyogbG9hZCB0aGUgaGVhZGVyIChyZ2tuKSAqLwogICAgcmdrbiA9IChfdzk1cmdrbiopKGNyZWcgKyAxKTsKICAgIGlmIChyZ2tuLT5pZCAhPSBXOTVfUkVHX1JHS05fSUQpIHsKICAgICAgICBFUlIoInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJWx4XG4iLCByZ2tuLT5pZCk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5yb290X29mZiAhPSAweDIwKSB7CiAgICAgICAgRVJSKCJyZ2tuLT5yb290X29mZiBub3QgMHgyMCwgcGxlYXNlIHJlcG9ydCAhXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHJna24tPmxhc3RfZGtlID4gcmdrbi0+c2l6ZSkKICAgIHsKICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGxhc3RfZGtlID4gc2l6ZSFcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQogICAgLyogdmVyaWZ5IGxhc3QgZGtlICovCiAgICBka2UgPSAoX3c5NWRrZSopKChjaGFyKilyZ2tuICsgcmdrbi0+bGFzdF9ka2UpOwogICAgaWYgKGRrZS0+eDEgIT0gMHg4MDAwMDAwMCkKICAgIHsgLyogd3JvbmcgbWFnaWMgKi8KICAgICAgRVJSKCJsYXN0IGRrZSBpbnZhbGlkICFcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHJna24tPnNpemUgPiBjcmVnLT5yZ2RiX29mZikKICAgIHsKICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJna24gc2l6ZSA+IHJnZGJfb2ZmICFcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQogICAgcm9vdF9ka2UgPSAoX3c5NWRrZSopKChjaGFyKilyZ2tuICsgcmdrbi0+cm9vdF9vZmYpOwogICAgaWYgKCAocm9vdF9ka2UtPnByZXZsdmwgIT0gMHhmZmZmZmZmZikgfHwgKHJvb3RfZGtlLT5uZXh0ICE9IDB4ZmZmZmZmZmYpICkKICAgIHsKICAgICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgaW52YWxpZCByb290IGRrZSAhXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGlmICggKHJldCA9IF9nZXRfdG1wX2ZuKCZmKSkgPT0gTlVMTCkgZ290byBlcnJvcjsKICAgIGZwcmludGYoZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uIDIiKTsKICAgIF93OTVfZHVtcF9ka2UoIiIsY3JlZyxyZ2tuLHJvb3RfZGtlLGYsbGV2ZWwpOwogICAgZmNsb3NlKGYpOwoKZXJyb3I6CiAgICBpZihyZXQgPT0gTlVMTCkgewogICAgICAgIEVSUigiVW5hYmxlIHRvIGxvYWQgbmF0aXZlIHdpbjk1IHJlZ2lzdHJ5IGZpbGUgJXMuXG4iLCBkZWJ1Z3N0cl93KGZuKSk7CiAgICAgICAgRVJSKCJQbGVhc2UgcmVwb3J0IHRoaXMuXG4iKTsKICAgICAgICBFUlIoIk1ha2UgYSBiYWNrdXAgb2YgdGhlIGZpbGUsIHJ1biBhIGdvb2QgcmVnIGNsZWFuZXIgcHJvZ3JhbSBhbmQgdHJ5IGFnYWluIVxuIik7CiAgICB9CgogICAgTnRVbm1hcFZpZXdPZlNlY3Rpb24oIEdldEN1cnJlbnRQcm9jZXNzKCksIGJhc2UgKTsKZXJyb3IxOgogICAgTnRDbG9zZShoRmlsZSk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IHdpbm50IG5hdGl2ZSByZWdpc3RyeSBmaWxlIHRvIHdpbmUgZm9ybWF0IFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9jb252ZXJ0X3dpbm50X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KExQQ1dTVFIgZm4sIGludCBsZXZlbCkKewogICAgRklMRSAqZjsKICAgIHZvaWQgKmJhc2U7CiAgICBMUFNUUiByZXQgPSBOVUxMOwogICAgSEFORExFIGhGaWxlOwogICAgSEFORExFIGhNYXBwaW5nOwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIExBUkdFX0lOVEVHRVIgbGdfaW50OwogICAgTlRTVEFUVVMgbnRzOwogICAgU0laRV9UIGxlbjsKCiAgICBudF9yZWdmICpyZWdmOwogICAgbnRfaGJpbiAqaGJpbjsKICAgIG50X2hiaW5fc3ViICpoYmluX3N1YjsKICAgIG50X25rICpuazsKCiAgICBUUkFDRSgiJXNcbiIsIGRlYnVnc3RyX3coZm4pKTsKCiAgICBoRmlsZSA9IENyZWF0ZUZpbGVXKCBmbiwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIDAgKTsKICAgIGlmICggaEZpbGUgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUgKSByZXR1cm4gTlVMTDsKICAgIGF0dHIuTGVuZ3RoICAgICAgICAgICAgICAgICAgID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ICAgICAgICAgICAgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lICAgICAgICAgICAgICAgPSBOVUxMOwogICAgYXR0ci5BdHRyaWJ1dGVzICAgICAgICAgICAgICAgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgICAgICAgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwoKICAgIGxnX2ludC5RdWFkUGFydCA9IDA7CiAgICBudHMgPSBOdENyZWF0ZVNlY3Rpb24oICZoTWFwcGluZywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUQU5EQVJEX1JJR0hUU19SRVFVSVJFRHxTRUNUSU9OX1FVRVJZfFNFQ1RJT05fTUFQX1JFQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICZhdHRyLCAmbGdfaW50LCBQQUdFX1JFQURPTkxZLCBTRUNfQ09NTUlULCBoRmlsZSApOwogICAgaWYgKG50cyAhPSBTVEFUVVNfU1VDQ0VTUykgZ290byBlcnJvcjE7CgogICAgYmFzZSA9IE5VTEw7IGxlbiA9IDA7CiAgICBudHMgPSBOdE1hcFZpZXdPZlNlY3Rpb24oIGhNYXBwaW5nLCBHZXRDdXJyZW50UHJvY2VzcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYmFzZSwgMCwgMCwgJmxnX2ludCwgJmxlbiwgVmlld1NoYXJlLCAwLCAKCQkJICAgICAgUEFHRV9SRUFET05MWSk7CiAgICBOdENsb3NlKCBoTWFwcGluZyApOwogICAgaWYgKG50cyAhPSBTVEFUVVNfU1VDQ0VTUykgZ290byBlcnJvcjE7CgogICAgLyogY29udHJvbCBzaWduYXR1cmUgKi8KICAgIGlmICgqKExQRFdPUkQpYmFzZSAhPSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmFibGUgdG8gbG9hZCBuYXRpdmUgd2lubnQgcmVnaXN0cnkgZmlsZSAlczogdW5rbm93biBzaWduYXR1cmUuXG4iLAogICAgICAgICAgICBkZWJ1Z3N0cl93KGZuKSk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBzdGFydCBibG9jayAqLwogICAgcmVnZiA9IGJhc2U7CgogICAgLyogaGJpbiBibG9jayAqLwogICAgaGJpbiA9IChudF9oYmluKikoKGNoYXIqKSBiYXNlICsgMHgxMDAwKTsKICAgIGlmIChoYmluLT5pZCAhPSBOVF9SRUdfUE9PTF9CTE9DS19JRCkgewogICAgICBFUlIoICJoYmluIGJsb2NrIGludmFsaWRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIGhiaW5fc3ViIGJsb2NrICovCiAgICBoYmluX3N1YiA9IChudF9oYmluX3N1YiopJihoYmluLT5oYmluX3N1Yik7CiAgICBpZiAoKGhiaW5fc3ViLT5kYXRhWzBdICE9ICduJykgfHwgKGhiaW5fc3ViLT5kYXRhWzFdICE9ICdrJykpIHsKICAgICAgRVJSKCAiaGJpbl9zdWIgYmxvY2sgaW52YWxpZFxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogbmsgYmxvY2sgKi8KICAgIG5rID0gKG50X25rKikmKGhiaW5fc3ViLT5kYXRhWzBdKTsKICAgIGlmIChuay0+VHlwZSAhPSBOVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSkgewogICAgICBFUlIoICJzcGVjaWFsIG5rIGJsb2NrIG5vdCBmb3VuZFxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKCAocmV0ID0gX2dldF90bXBfZm4oJmYpKSA9PSBOVUxMKSBnb3RvIGVycm9yOwogICAgZnByaW50ZihmLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gMiIpOwogICAgX250X2R1bXBfbmsoIiIsKGNoYXIqKWJhc2UrMHgxMDAwLG5rLGYsbGV2ZWwpOwogICAgZmNsb3NlKGYpOwoKZXJyb3I6CiAgICBOdFVubWFwVmlld09mU2VjdGlvbiggR2V0Q3VycmVudFByb2Nlc3MoKSwgYmFzZSApOwplcnJvcjE6CiAgICBOdENsb3NlKGhGaWxlKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgbmF0aXZlIHJlZ2lzdHJ5IHRvIHdpbmUgZm9ybWF0IGFuZCBsb2FkIGl0IHZpYSBzZXJ2ZXIgY2FsbCBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShMUENXU1RSIGZuLCBIS0VZIGhrZXksIGludCByZWdfdHlwZSwgaW50IGxldmVsKQp7CiAgICBMUFNUUiB0bXAgPSBOVUxMOwoKICAgIHN3aXRjaCAocmVnX3R5cGUpIHsKICAgICAgICBjYXNlIFJFR19XSU5OVDoKICAgICAgICAgICAgLyogRklYTUU6IGZvbGxvd2luZyBmdW5jdGlvbiBkb2Vzbid0IHJlYWxseSBjb252ZXJ0IHlldCAqLwogICAgICAgICAgICB0bXAgPSBfY29udmVydF93aW5udF9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChmbixsZXZlbCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX1dJTjk1OgogICAgICAgICAgICB0bXAgPSBfY29udmVydF93aW45NV9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChmbixsZXZlbCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX1dJTjMxOgogICAgICAgICAgICBFUlIoIkRvbid0IGtub3cgaG93IHRvIGNvbnZlcnQgbmF0aXZlIDMuMSByZWdpc3RyeSB5ZXQuXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJVbmtub3duIHJlZ2lzdHJ5IGZvcm1hdCBwYXJhbWV0ZXIgKCVkKVxuIixyZWdfdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmICh0bXAgIT0gTlVMTCkgewogICAgICAgIGxvYWRfd2luZV9yZWdpc3RyeShoa2V5LHRtcCk7CiAgICAgICAgVFJBQ0UoIkZpbGUgJXMgc3VjY2Vzc2Z1bGx5IGNvbnZlcnRlZCB0byAlcyBhbmQgbG9hZGVkIHRvIHJlZ2lzdHJ5LlxuIiwKICAgICAgICAgICAgICBkZWJ1Z3N0cl93KGZuKSwgdG1wKTsKICAgICAgICB1bmxpbmsodG1wKTsKICAgIH0KICAgIGVsc2UgV0FSTigiVW5hYmxlIHRvIGNvbnZlcnQgJXMgKGRvZXNuJ3QgZXhpc3Q/KVxuIiwgZGVidWdzdHJfdyhmbikpOwogICAgZnJlZSh0bXApOwp9CgovKiBsb2FkIGFsbCBuYXRpdmUgd2luZG93cyByZWdpc3RyeSBmaWxlcyBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIF9sb2FkX3dpbmRvd3NfcmVnaXN0cnkoIEhLRVkgaGtleV9sb2NhbF9tYWNoaW5lLCBIS0VZIGhrZXlfY3VycmVudF91c2VyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIS0VZIGhrZXlfdXNlcnNfZGVmYXVsdCApCnsKICAgIGludCByZWdfdHlwZTsKICAgIFdDSEFSIHdpbmRpcltNQVhfUEFUSE5BTUVfTEVOXTsKICAgIFdDSEFSIHBhdGhbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBIS0VZIGhrZXksIHByb2ZpbGVfa2V5OwogICAgY2hhciB0bXBbMTAyNF07CiAgICBEV09SRCBkdW1teTsKCiAgICBzdGF0aWMgY29uc3QgV0NIQVIgV2luZVdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLCdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywnVycsJ2knLCduJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgUHJvZmlsZVdbXSA9IHsnUCcsJ3InLCdvJywnZicsJ2knLCdsJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgU3lzdGVtW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsJ1MnLCd5JywncycsJ3QnLCdlJywnbScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgU29mdHdhcmVbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIENsb25lW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUycsJ3knLCdzJywndCcsJ2UnLCdtJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0MnLCdsJywnbycsJ24nLCdlJywwfTsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFdpbmVXICk7CiAgICBpZiAoTnRDcmVhdGVLZXkoICZwcm9maWxlX2tleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpIHByb2ZpbGVfa2V5ID0gMDsKCiAgICBnZXRfd2luZG93c19kaXIod2luZGlyLCBzaXplb2Yod2luZGlyKSk7CgogICAgcmVnX3R5cGUgPSBfZ2V0X3JlZ190eXBlKHdpbmRpcik7CiAgICBzd2l0Y2ggKHJlZ190eXBlKSB7CiAgICAgICAgY2FzZSBSRUdfV0lOTlQ6IHsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIG50dXNlcl9kYXRXW10gPSB7J1xcJywnbicsJ3QnLCd1JywncycsJ2UnLCdyJywnLicsJ2QnLCdhJywndCcsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBkZWZhdWx0V1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJzMnLCcyJywnXFwnLCdjJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ2QnLCdlJywnZicsJ2EnLCd1JywnbCcsJ3QnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3lzdGVtV1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJzMnLCcyJywnXFwnLCdjJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzb2Z0d2FyZVdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdzJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzYW1XW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywncycsJ2EnLCdtJywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHNlY3VyaXR5V1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJzMnLCcyJywnXFwnLCdjJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ3MnLCdlJywnYycsJ3UnLCdyJywnaScsJ3QnLCd5JywwfTsKCiAgICAgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgbnR1c2VyLmRhdCAqLwogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBQcm9maWxlVyApOwogICAgICAgICAgICBpZiAocHJvZmlsZV9rZXkgJiYgIU50UXVlcnlWYWx1ZUtleSggcHJvZmlsZV9rZXksICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAsIHNpemVvZih0bXApLCAmZHVtbXkgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YSk7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIG50dXNlcl9kYXRXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfY3VycmVudF91c2VyLFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE1FU1NBR0UoIldoZW4geW91IGFyZSBydW5uaW5nIHdpdGggYSBuYXRpdmUgTlQgZGlyZWN0b3J5IHNwZWNpZnlcbiIpOwogICAgICAgICAgICAgICAgTUVTU0FHRSgiJ1Byb2ZpbGU9PHByb2ZpbGVkaXJlY3Rvcnk+JyBvciBkaXNhYmxlIGxvYWRpbmcgb2YgV2luZG93c1xuIik7CiAgICAgICAgICAgICAgICBNRVNTQUdFKCJyZWdpc3RyeSAoTG9hZFdpbmRvd3NSZWdpc3RyeUZpbGVzPU4pXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCiAgICAgICAgICAgIGlmIChoa2V5X3VzZXJzX2RlZmF1bHQpIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgZGVmYXVsdFcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV91c2Vyc19kZWZhdWx0LFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgKiBGSVhNRQogICAgICAgICAgICAqICBtYXAgSExNXFN5c3RlbVxDb250cm9sU2V0MDAxIHRvIEhMTVxTeXN0ZW1cQ3VycmVudENvbnRyb2xTZXQKICAgICAgICAgICAgKi8KICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgU3lzdGVtICk7CiAgICAgICAgICAgIGlmICghTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBzeXN0ZW1XKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXksUkVHX1dJTk5ULDEpOwogICAgICAgICAgICAgICAgTnRDbG9zZSggaGtleSApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFNvZnR3YXJlICk7CiAgICAgICAgICAgIGlmICghTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBzb2Z0d2FyZVcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleSxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgICAgICBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBzYW1XKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9sb2NhbF9tYWNoaW5lLFJFR19XSU5OVCwwKTsKCiAgICAgICAgICAgIHN0cmNweVcocGF0aCx3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHNlY3VyaXR5Vyk7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfbG9jYWxfbWFjaGluZSxSRUdfV0lOTlQsMCk7CgogICAgICAgICAgICAvKiB0aGlzIGtleSBpcyBnZW5lcmF0ZWQgd2hlbiB0aGUgbnQtY29yZSBib290ZWQgc3VjY2Vzc2Z1bGx5ICovCiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIENsb25lICk7CiAgICAgICAgICAgIGlmICghTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkgTnRDbG9zZSggaGtleSApOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgUkVHX1dJTjk1OgogICAgICAgIHsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHN5c3RlbV8xc3RXW10gPSB7J2MnLCc6JywnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCcuJywnMScsJ3MnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHN5c3RlbV9kYXRXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnLicsJ2QnLCdhJywndCcsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBjbGFzc2VzX2RhdFdbXSA9IHsnXFwnLCdjJywnbCcsJ2EnLCdzJywncycsJ2UnLCdzJywnLicsJ2QnLCdhJywndCcsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB1c2VyX2RhdFdbXSA9IHsnXFwnLCd1JywncycsJ2UnLCdyJywnLicsJ2QnLCdhJywndCcsMH07CgogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkoc3lzdGVtXzFzdFcsaGtleV9sb2NhbF9tYWNoaW5lLFJFR19XSU45NSwwKTsKCiAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBzeXN0ZW1fZGF0Vyk7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfbG9jYWxfbWFjaGluZSxSRUdfV0lOOTUsMCk7CgogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBDbGFzc2VzUm9vdFcgKTsKICAgICAgICAgICAgaWYgKCFOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIGNsYXNzZXNfZGF0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5LFJFR19XSU45NSwwKTsKICAgICAgICAgICAgICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgUHJvZmlsZVcgKTsKICAgICAgICAgICAgaWYgKHByb2ZpbGVfa2V5ICYmICFOdFF1ZXJ5VmFsdWVLZXkoIHByb2ZpbGVfa2V5LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wLCBzaXplb2YodG1wKSwgJmR1bW15ICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgdXNlci5kYXQgKi8KICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGEpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCB1c2VyX2RhdFcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9jdXJyZW50X3VzZXIsUkVHX1dJTjk1LDEpOwoKCSAgICAgICAgLyogZGVmYXVsdCB1c2VyLmRhdCAqLwoJICAgICAgICBpZiAoaGtleV91c2Vyc19kZWZhdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgdXNlcl9kYXRXKTsKICAgICAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X3VzZXJzX2RlZmF1bHQsUkVHX1dJTjk1LDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCB1c2VyX2RhdFcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9jdXJyZW50X3VzZXIsUkVHX1dJTjk1LDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBSRUdfV0lOMzE6CiAgICAgICAgICAgIC8qIEZJWE1FOiBoZXJlIHdlIHNob3VsZCBjb252ZXJ0IHRvICoucmVnIGZpbGUgc3VwcG9ydGVkIGJ5IHNlcnZlciBhbmQgY2FsbCBSRVFfTE9BRF9SRUdJU1RSWSwgc2VlIFJFR19XSU45NSBjYXNlICovCiAgICAgICAgICAgIF93MzFfbG9hZHJlZygpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBSRUdfRE9OVExPQUQ6CiAgICAgICAgICAgIFRSQUNFKCJSRUdfRE9OVExPQURcbiIpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJzd2l0Y2g6IG5vIG1hdGNoICglZClcbiIscmVnX3R5cGUpOwogICAgICAgICAgICBicmVhazsKCiAgICB9CiAgICBpZiAocHJvZmlsZV9rZXkpIE50Q2xvc2UoIHByb2ZpbGVfa2V5ICk7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJaW5pdF9jZHJvbV9yZWdpc3RyeQogKgogKiBJbml0aWFsaXplcyByZWdpc3RyeSB0byBjb250YWluIHNjc2kgaW5mbyBhYm91dCB0aGUgY2Ryb20gaW4gTlQuCiAqIEFsbCBkZXZpY2VzIChldmVuIG5vdCByZWFsIHNjc2kgb25lcykgaGF2ZSB0aGlzIGluZm8gaW4gTlQuCiAqIFRPRE86IGZvciBub3cgaXQgb25seSB3b3JrcyBmb3Igbm9uIHNjc2kgZGV2aWNlcwogKiBOT1RFOiBwcm9ncmFtcyB1c3VhbGx5IHJlYWQgdGhlc2UgcmVnaXN0cnkgZW50cmllcyBhZnRlciBzZW5kaW5nIHRoZQogKiAgICAgICBJT0NUTF9TQ1NJX0dFVF9BRERSRVNTIGlvY3RsIHRvIHRoZSBjZHJvbQogKi8Kc3RhdGljIHZvaWQgaW5pdF9jZHJvbV9yZWdpc3RyeSggSEFORExFIGhhbmRsZSApCnsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIFdDSEFSIGRhdGFXWzUwXTsKICAgIERXT1JEIGxlblc7CiAgICBjaGFyIGJ1ZmZlcls0MF07CiAgICBEV09SRCB2YWx1ZTsKICAgIGNvbnN0IGNoYXIgKmRhdGE7CiAgICBIS0VZIHNjc2lLZXk7CiAgICBIS0VZIHBvcnRLZXk7CiAgICBIS0VZIGJ1c0tleTsKICAgIEhLRVkgdGFyZ2V0S2V5OwogICAgRFdPUkQgZGlzcDsKICAgIElPX1NUQVRVU19CTE9DSyBpbzsKICAgIFNDU0lfQUREUkVTUyBzY3NpX2FkZHI7CgogICAgaWYgKE50RGV2aWNlSW9Db250cm9sRmlsZSggaGFuZGxlLCAwLCBOVUxMLCBOVUxMLCAmaW8sIElPQ1RMX1NDU0lfR0VUX0FERFJFU1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAwLCAmc2NzaV9hZGRyLCBzaXplb2Yoc2NzaV9hZGRyKSApKQogICAgICAgIHJldHVybjsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwoKICAgIC8qIEVuc3VyZSB0aGVyZSBpcyBTY3NpIGtleSAqLwogICAgaWYgKCFSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCAiTWFjaGluZVxcSEFSRFdBUkVcXERFVklDRU1BUFxcU2NzaSIgKSB8fAogICAgICAgIE50Q3JlYXRlS2V5KCAmc2NzaUtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLAogICAgICAgICAgICAgICAgICAgICBOVUxMLCBSRUdfT1BUSU9OX1ZPTEFUSUxFLCAmZGlzcCApKQogICAgewogICAgICAgIEVSUigiQ2Fubm90IGNyZWF0ZSBERVZJQ0VNQVBcXFNjc2kgcmVnaXN0cnkga2V5XG4iICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwoKICAgIHNucHJpbnRmKGJ1ZmZlcixzaXplb2YoYnVmZmVyKSwiU2NzaSBQb3J0ICVkIixzY3NpX2FkZHIuUG9ydE51bWJlcik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBzY3NpS2V5OwogICAgaWYgKCFSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCBidWZmZXIgKSB8fAogICAgICAgIE50Q3JlYXRlS2V5KCAmcG9ydEtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLAogICAgICAgICAgICAgICAgICAgICBOVUxMLCBSRUdfT1BUSU9OX1ZPTEFUSUxFLCAmZGlzcCApKQogICAgewogICAgICAgIEVSUigiQ2Fubm90IGNyZWF0ZSBERVZJQ0VNQVBcXFNjc2kgUG9ydCByZWdpc3RyeSBrZXlcbiIgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CgogICAgUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZuYW1lVywgIkRyaXZlciIgKTsKICAgIGRhdGEgPSAiYXRhcGkiOwogICAgUnRsTXVsdGlCeXRlVG9Vbmljb2RlTiggZGF0YVcsIDUwLCAmbGVuVywgZGF0YSwgc3RybGVuKGRhdGEpKTsKICAgIE50U2V0VmFsdWVLZXkoIHBvcnRLZXksICZuYW1lVywgMCwgUkVHX1NaLCAoQllURSopZGF0YVcsIGxlblcgKTsKICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAmbmFtZVcgKTsKICAgIHZhbHVlID0gMTA7CiAgICBSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCAiRmlyc3RCdXNUaW1lU2NhbkluTXMiICk7CiAgICBOdFNldFZhbHVlS2V5KCBwb3J0S2V5LCZuYW1lVywgMCwgUkVHX0RXT1JELCAoQllURSAqKSZ2YWx1ZSwgc2l6ZW9mKERXT1JEKSk7CiAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CiAgICB2YWx1ZSA9IDA7CiNpZmRlZiBIRElPX0dFVF9ETUEKICAgIHsKICAgICAgICBpbnQgZmQsIGRtYTsKICAgICAgICBpZiAoIXdpbmVfc2VydmVyX2hhbmRsZV90b19mZCggaGFuZGxlLCAwLCAmZmQsIE5VTEwsIE5VTEwgKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChpb2N0bChmZCxIRElPX0dFVF9ETUEsICZkbWEpICE9IC0xKSB2YWx1ZSA9IGRtYTsKICAgICAgICAgICAgd2luZV9zZXJ2ZXJfcmVsZWFzZV9mZCggaGFuZGxlLCBmZCApOwogICAgICAgIH0KICAgIH0KI2VuZGlmCiAgICBSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCAiRE1BRW5hYmxlZCIgKTsKICAgIE50U2V0VmFsdWVLZXkoIHBvcnRLZXksJm5hbWVXLCAwLCBSRUdfRFdPUkQsIChCWVRFICopJnZhbHVlLCBzaXplb2YoRFdPUkQpKTsKICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAmbmFtZVcgKTsKCiAgICBzbnByaW50ZihidWZmZXIsNDAsIlNjc2kgQnVzICVkIiwgc2NzaV9hZGRyLlBhdGhJZCk7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBwb3J0S2V5OwogICAgaWYgKCFSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCBidWZmZXIgKSB8fAogICAgICAgIE50Q3JlYXRlS2V5KCAmYnVzS2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsCiAgICAgICAgICAgICAgICAgICAgIE5VTEwsIFJFR19PUFRJT05fVk9MQVRJTEUsICZkaXNwICkpCiAgICB7CiAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIERFVklDRU1BUFxcU2NzaSBQb3J0XFxTY3NpIEJ1cyByZWdpc3RyeSBrZXlcbiIgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CgogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gYnVzS2V5OwogICAgaWYgKCFSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCAiSW5pdGlhdG9yIElkIDI1NSIgKSB8fAogICAgICAgIE50Q3JlYXRlS2V5KCAmdGFyZ2V0S2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsCiAgICAgICAgICAgICAgICAgICAgIE5VTEwsIFJFR19PUFRJT05fVk9MQVRJTEUsICZkaXNwICkpCiAgICB7CiAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIERFVklDRU1BUFxcU2NzaSBQb3J0XFxTY3NpIEJ1c1xcSW5pdGlhdG9yIElkIDI1NSByZWdpc3RyeSBrZXlcbiIgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CiAgICBOdENsb3NlKCB0YXJnZXRLZXkgKTsKCiAgICBzbnByaW50ZihidWZmZXIsNDAsIlRhcmdldCBJZCAlZCIsIHNjc2lfYWRkci5UYXJnZXRJZCk7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBidXNLZXk7CiAgICBpZiAoIVJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsIGJ1ZmZlciApIHx8CiAgICAgICAgTnRDcmVhdGVLZXkoICZ0YXJnZXRLZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwKICAgICAgICAgICAgICAgICAgICAgTlVMTCwgUkVHX09QVElPTl9WT0xBVElMRSwgJmRpc3AgKSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBjcmVhdGUgREVWSUNFTUFQXFxTY3NpIFBvcnRcXFNjc2kgQnVzIDBcXFRhcmdldCBJZCByZWdpc3RyeSBrZXlcbiIgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CgogICAgUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZuYW1lVywgIlR5cGUiICk7CiAgICBkYXRhID0gIkNkUm9tUGVyaXBoZXJhbCI7CiAgICBSdGxNdWx0aUJ5dGVUb1VuaWNvZGVOKCBkYXRhVywgNTAsICZsZW5XLCBkYXRhLCBzdHJsZW4oZGF0YSkpOwogICAgTnRTZXRWYWx1ZUtleSggdGFyZ2V0S2V5LCAmbmFtZVcsIDAsIFJFR19TWiwgKEJZVEUqKWRhdGFXLCBsZW5XICk7CiAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CiAgICAvKiBGSVhNRSAtIG1heWJlIHJlYWQgdGhlIHJlYWwgaWRlbnRpZmllcj8/ICovCiAgICBSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCAiSWRlbnRpZmllciIgKTsKICAgIGRhdGEgPSAiV2luZSBDRFJPTSI7CiAgICBSdGxNdWx0aUJ5dGVUb1VuaWNvZGVOKCBkYXRhVywgNTAsICZsZW5XLCBkYXRhLCBzdHJsZW4oZGF0YSkpOwogICAgTnRTZXRWYWx1ZUtleSggdGFyZ2V0S2V5LCAmbmFtZVcsIDAsIFJFR19TWiwgKEJZVEUqKWRhdGFXLCBsZW5XICk7CiAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CiAgICAvKiBGSVhNRSAtIHdlIGFsd2F5cyB1c2UgQ2Ryb20wIC0gZG8gbm90IGtub3cgYWJvdXQgdGhlIG50IGJlaGF2aW91ciAqLwogICAgUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZuYW1lVywgIkRldmljZU5hbWUiICk7CiAgICBkYXRhID0gIkNkcm9tMCI7CiAgICBSdGxNdWx0aUJ5dGVUb1VuaWNvZGVOKCBkYXRhVywgNTAsICZsZW5XLCBkYXRhLCBzdHJsZW4oZGF0YSkpOwogICAgTnRTZXRWYWx1ZUtleSggdGFyZ2V0S2V5LCAmbmFtZVcsIDAsIFJFR19TWiwgKEJZVEUqKWRhdGFXLCBsZW5XICk7CiAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CgogICAgTnRDbG9zZSggdGFyZ2V0S2V5ICk7CiAgICBOdENsb3NlKCBidXNLZXkgKTsKICAgIE50Q2xvc2UoIHBvcnRLZXkgKTsKICAgIE50Q2xvc2UoIHNjc2lLZXkgKTsKfQoKCi8qIGNyZWF0ZSB0aGUgaGFyZHdhcmUgcmVnaXN0cnkgYnJhbmNoICovCnN0YXRpYyB2b2lkIGNyZWF0ZV9oYXJkd2FyZV9icmFuY2godm9pZCkKewogICAgaW50IGk7CiAgICBIQU5ETEUgaGFuZGxlOwogICAgY2hhciBkcml2ZVtdID0gIlxcXFwuXFxBOiI7CgogICAgLyogY3JlYXRlIGVudHJpZXMgZm9yIGNkcm9tcyAqLwogICAgZm9yIChpID0gMDsgaSA8IDI2OyBpKyspCiAgICB7CiAgICAgICAgZHJpdmVbNF0gPSAnQScgKyBpOwogICAgICAgIGhhbmRsZSA9IENyZWF0ZUZpbGVBKCBkcml2ZSwgMCwgMCwgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwogICAgICAgIGlmIChoYW5kbGUgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIGNvbnRpbnVlOwogICAgICAgIGluaXRfY2Ryb21fcmVnaXN0cnkoIGhhbmRsZSApOwogICAgICAgIENsb3NlSGFuZGxlKCBoYW5kbGUgKTsKICAgIH0KfQoKCi8qIGNvbnZlcnQgdGhlIGRyaXZlIHR5cGUgZW50cmllcyBmcm9tIHRoZSBvbGQgZm9ybWF0IHRvIHRoZSBuZXcgb25lICovCnN0YXRpYyB2b2lkIGNvbnZlcnRfZHJpdmVfdHlwZXModm9pZCkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIFR5cGVXW10gPSB7J1QnLCd5JywncCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGRyaXZlX3R5cGVzX2tleVdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVycsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0QnLCdyJywnaScsJ3YnLCdlJywncycsMCB9OwogICAgV0NIQVIgZHJpdmVXW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgJ1cnLCdpJywnbicsJ2UnLCdcXCcsJ1cnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAnQycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdEJywncicsJ2knLCd2JywnZScsJyAnLCdBJywwfTsKICAgIGNoYXIgdG1wWzMyKnNpemVvZihXQ0hBUikgKyBzaXplb2YoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04pXTsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIERXT1JEIGR1bW15OwogICAgVUxPTkcgZGlzcDsKICAgIEhLRVkgaGtleV9vbGQsIGhrZXlfbmV3OwogICAgaW50IGk7CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIGRyaXZlX3R5cGVzX2tleVcgKTsKCiAgICBpZiAoTnRDcmVhdGVLZXkoICZoa2V5X25ldywgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCAmZGlzcCApKSByZXR1cm47CiAgICBpZiAoZGlzcCAhPSBSRUdfQ1JFQVRFRF9ORVdfS0VZKSByZXR1cm47CgogICAgZm9yIChpID0gMDsgaSA8IDI2OyBpKyspCiAgICB7CiAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgZHJpdmVXICk7CiAgICAgICAgbmFtZVcuQnVmZmVyWyhuYW1lVy5MZW5ndGggLyBzaXplb2YoV0NIQVIpKSAtIDFdID0gJ0EnICsgaTsKICAgICAgICBpZiAoTnRPcGVuS2V5KCAmaGtleV9vbGQsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciApICE9IFNUQVRVU19TVUNDRVNTKSBjb250aW51ZTsKICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBUeXBlVyApOwogICAgICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X29sZCwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgdG1wLCBzaXplb2YodG1wKSwgJmR1bW15ICkpCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiB2YWx1ZVdbXSA9IHsnQScsJzonLDB9OwogICAgICAgICAgICBXQ0hBUiAqdHlwZSA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwoKICAgICAgICAgICAgdmFsdWVXWzBdID0gJ0EnICsgaTsKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdmFsdWVXICk7CiAgICAgICAgICAgIE50U2V0VmFsdWVLZXkoIGhrZXlfbmV3LCAmbmFtZVcsIDAsIFJFR19TWiwgdHlwZSwgKHN0cmxlblcodHlwZSkgKyAxKSAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICAgICAgTUVTU0FHRSggIkNvbnZlcnRlZCBkcml2ZSB0eXBlIHRvIG5ldyBlbnRyeSBIS0xNXFxTb2Z0d2FyZVxcV2luZVxcRHJpdmVzIFwiJWM6XCIgPSAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgJ0EnICsgaSwgZGVidWdzdHJfdyh0eXBlKSApOwogICAgICAgIH0KICAgICAgICBOdENsb3NlKCBoa2V5X29sZCApOwogICAgfQogICAgTnRDbG9zZSggaGtleV9uZXcgKTsKfQoKCi8qIGxvYWQgYWxsIHJlZ2lzdHJ5IChuYXRpdmUgYW5kIGdsb2JhbCBhbmQgaG9tZSkgKi8Kdm9pZCBTSEVMTF9Mb2FkUmVnaXN0cnkoIHZvaWQgKQp7CiAgICBIS0VZIGhrZXlfbG9jYWxfbWFjaGluZSwgaGtleV91c2VycywgaGtleV91c2Vyc19kZWZhdWx0LCBoa2V5X2N1cnJlbnRfdXNlciwgaGtleV9jb25maWc7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBEV09SRCBjb3VudDsKICAgIFVMT05HIGRpc3BvczsKICAgIEJPT0wgcmVzOwogICAgaW50IGFsbCwgcGVyaW9kOwogICAgY2hhciB0bXBbMTAyNF07CgogICAgc3RhdGljIGNvbnN0IFdDSEFSIE1hY2hpbmVXW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFVzZXJXW10gPSB7J1UnLCdzJywnZScsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIERlZmF1bHRXW10gPSB7Jy4nLCdEJywnZScsJ2YnLCdhJywndScsJ2wnLCd0JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBSZWdpc3RyeVdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1cnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1cnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGxvYWRfd2luX3JlZ19maWxlc1dbXSA9IHsnTCcsJ28nLCdhJywnZCcsJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywneScsJ0YnLCdpJywnbCcsJ2UnLCdzJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsb2FkX2dsb2JhbF9yZWdfZmlsZXNXW10gPSB7J0wnLCdvJywnYScsJ2QnLCdHJywnbCcsJ28nLCdiJywnYScsJ2wnLCdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywneScsJ0YnLCdpJywnbCcsJ2UnLCdzJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBTYXZlT25seVVwZGF0ZWRLZXlzV1tdID0geydTJywnYScsJ3YnLCdlJywnTycsJ24nLCdsJywneScsJ1UnLCdwJywnZCcsJ2EnLCd0JywnZScsJ2QnLCdLJywnZScsJ3knLCdzJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBQZXJpb2RpY1NhdmVXW10gPSB7J1AnLCdlJywncicsJ2knLCdvJywnZCcsJ2knLCdjJywnUycsJ2EnLCd2JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgR2xvYmFsUmVnaXN0cnlEaXJXW10gPSB7J0cnLCdsJywnbycsJ2InLCdhJywnbCcsJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCd5JywnRCcsJ2knLCdyJywwfTsKCiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFVzZXJXICk7CiAgICBOdENyZWF0ZUtleSggJmhrZXlfdXNlcnMsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgJmRpc3BvcyApOwogICAgaWYgKGRpc3BvcyA9PSBSRUdfT1BFTkVEX0VYSVNUSU5HX0tFWSkKICAgIHsKICAgICAgICAvKiBzb21lb25lIGVsc2UgYWxyZWFkeSBsb2FkZWQgdGhlIHJlZ2lzdHJ5ICovCiAgICAgICAgTnRDbG9zZSggaGtleV91c2VycyApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBNYWNoaW5lVyApOwogICAgTnRDcmVhdGVLZXkoICZoa2V5X2xvY2FsX21hY2hpbmUsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApOwoKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IGhrZXlfdXNlcnM7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBEZWZhdWx0VyApOwogICAgaWYgKE50Q3JlYXRlS2V5KCAmaGtleV91c2Vyc19kZWZhdWx0LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBjcmVhdGUgSEtFWV9VU0VSUy8uRGVmYXVsdFxuIiApOwogICAgICAgIEV4aXRQcm9jZXNzKDEpOwogICAgfQogICAgUnRsT3BlbkN1cnJlbnRVc2VyKCBLRVlfQUxMX0FDQ0VTUywgJmhrZXlfY3VycmVudF91c2VyICk7CgogICAgX2FsbG9jYXRlX2RlZmF1bHRfa2V5cygpOwoKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBSZWdpc3RyeVcgKTsKICAgIGlmIChOdE9wZW5LZXkoICZoa2V5X2NvbmZpZywgS0VZX0FMTF9BQ0NFU1MsICZhdHRyICkpIGhrZXlfY29uZmlnID0gMDsKCiAgICAvKiBsb2FkIHdpbmRvd3MgcmVnaXN0cnkgaWYgcmVxdWlyZWQgKi8KCiAgICByZXMgPSBUUlVFOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gaGtleV9jb25maWc7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBsb2FkX3dpbl9yZWdfZmlsZXNXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICByZXMgPSAhSVNfT1BUSU9OX0ZBTFNFKHN0clswXSk7CiAgICB9CiAgICBpZiAocmVzKSBfbG9hZF93aW5kb3dzX3JlZ2lzdHJ5KCBoa2V5X2xvY2FsX21hY2hpbmUsIGhrZXlfY3VycmVudF91c2VyLCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKCiAgICAvKiBsb2FkIGdsb2JhbCByZWdpc3RyeSBpZiByZXF1aXJlZCAqLwoKICAgIHJlcyA9IFRSVUU7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBsb2FkX2dsb2JhbF9yZWdfZmlsZXNXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICByZXMgPSAhSVNfT1BUSU9OX0ZBTFNFKHN0clswXSk7CiAgICB9CiAgICBpZiAocmVzKQogICAgewogICAgICAgIC8qIGxvYWQgZ2xvYmFsIHJlZ2lzdHJ5IGZpbGVzIChzdG9yZWQgaW4gL2V0Yy93aW5lKSAqLwogICAgICAgIGNoYXIgKnAsIGNvbmZpZ2ZpbGVbTUFYX1BBVEhOQU1FX0xFTl07CgogICAgICAgIC8qIE92ZXJyaWRlIEVUQ0RJUj8gKi8KICAgICAgICBjb25maWdmaWxlWzBdID0gMDsKICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBHbG9iYWxSZWdpc3RyeURpclcgKTsKICAgICAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgICAgIHsKICAgICAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgICAgICBSdGxVbmljb2RlVG9NdWx0aUJ5dGVOKCBjb25maWdmaWxlLCBzaXplb2YoY29uZmlnZmlsZSksIE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIsIChzdHJsZW5XKHN0cikgKyAxKSAqIHNpemVvZihXQ0hBUikpOwogICAgICAgIH0KICAgICAgICBpZiAoY29uZmlnZmlsZVswXSAhPSAnLycpIHN0cmNweShjb25maWdmaWxlLCBFVENESVIpOwoKICAgICAgICBUUkFDRSgiR2xvYmFsUmVnaXN0cnlEaXIgaXMgJyVzJy5cbiIsIGNvbmZpZ2ZpbGUpOwoKICAgICAgICAvKiBMb2FkIHRoZSBnbG9iYWwgSEtVIGhpdmUgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyICovCiAgICAgICAgcCA9IGNvbmZpZ2ZpbGUgKyBzdHJsZW4oY29uZmlnZmlsZSk7CiAgICAgICAgc3RyY3B5KHAsIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9VU0VSX0RFRkFVTFQpOwogICAgICAgIGxvYWRfd2luZV9yZWdpc3RyeSggaGtleV91c2VycywgY29uZmlnZmlsZSApOwoKICAgICAgICAvKiBMb2FkIHRoZSBnbG9iYWwgbWFjaGluZSBkZWZhdWx0cyBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIgKi8KICAgICAgICBzdHJjcHkocCwgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUpOwogICAgICAgIGxvYWRfd2luZV9yZWdpc3RyeSggaGtleV9sb2NhbF9tYWNoaW5lLCBjb25maWdmaWxlICk7CiAgICB9CgogICAgLyogc2V0dXAgcmVnaXN0cnkgc2F2aW5nICovCgogICAgYWxsID0gRkFMU0U7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBTYXZlT25seVVwZGF0ZWRLZXlzVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgYWxsID0gSVNfT1BUSU9OX0ZBTFNFKHN0clswXSk7CiAgICB9CgogICAgcGVyaW9kID0gMDsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFBlcmlvZGljU2F2ZVcgKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X2NvbmZpZywgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICB7CiAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgIHBlcmlvZCA9IChpbnQpc3RydG9sVyhzdHIsIE5VTEwsIDEwKTsKICAgIH0KCiAgICAvKiBsb2FkIGhvbWUgcmVnaXN0cnkgYW5kIHNldCBzYXZpbmcgbGV2ZWwgKDAgZm9yIHNhdmluZyBldmVyeXRoaW5nLAogICAgICogMSBmb3Igc2F2aW5nIG9ubHkgbW9kaWZpZWQga2V5cykgKi8KCiAgICBTRVJWRVJfU1RBUlRfUkVRKCBsb2FkX3VzZXJfcmVnaXN0cmllcyApCiAgICB7CiAgICAgICAgcmVxLT5oa2V5ID0gaGtleV9jdXJyZW50X3VzZXI7CiAgICAgICAgcmVxLT5zYXZpbmcgPSAhYWxsOwogICAgICAgIHJlcS0+cGVyaW9kID0gcGVyaW9kICogMTAwMDsKICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgIH0KICAgIFNFUlZFUl9FTkRfUkVROwoKICAgIC8qIGNyZWF0ZSBoYXJkd2FyZSByZWdpc3RyeSBicmFuY2ggKi8KCiAgICBjcmVhdGVfaGFyZHdhcmVfYnJhbmNoKCk7CgogICAgLyogY29udmVydCBrZXlzIGZyb20gY29uZmlnIGZpbGUgdG8gbmV3IHJlZ2lzdHJ5IGZvcm1hdCAqLwoKICAgIGNvbnZlcnRfZHJpdmVfdHlwZXMoKTsKCiAgICBOdENsb3NlKGhrZXlfdXNlcnNfZGVmYXVsdCk7CiAgICBOdENsb3NlKGhrZXlfY3VycmVudF91c2VyKTsKICAgIE50Q2xvc2UoaGtleV91c2Vycyk7CiAgICBOdENsb3NlKGhrZXlfbG9jYWxfbWFjaGluZSk7CiAgICBOdENsb3NlKGhrZXlfY29uZmlnKTsKfQo=