LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBOT1RFUwogKiAgICBXaGVuIGNoYW5naW5nIHRoaXMgZmlsZSwgcGxlYXNlIHJlLXJ1biB0aGUgcmVndGVzdCBwcm9ncmFtIHRvIGVuc3VyZQogKiAgICB0aGUgY29uZGl0aW9ucyBhcmUgaGFuZGxlZCBwcm9wZXJseS4KICoKICogVE9ETwogKiAgICBTZWN1cml0eSBhY2Nlc3MKICogICAgT3B0aW9uIGhhbmRsaW5nCiAqICAgIFRpbWUgZm9yIFJlZ0VudW1LZXkqLCBSZWdRdWVyeUluZm9LZXkqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9TWVNfSU9DVExfSAojaW5jbHVkZSA8c3lzL2lvY3RsLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9MSU5VWF9IRFJFR19ICiMgaW5jbHVkZSA8bGludXgvaGRyZWcuaD4KI2VuZGlmCgojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKI2luY2x1ZGUgIm50c3RhdHVzLmgiCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5pb2N0bC5oIgojaW5jbHVkZSAibnRkZHNjc2kuaCIKCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9saWJyYXJ5LmgiCiNpbmNsdWRlICJ3aW5lL3NlcnZlci5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocmVnKTsKCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCAgIi93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUgIi93aW5lLnN5c3RlbXJlZyIKCiNkZWZpbmUgTUFYX1BBVEhOQU1FX0xFTiAgIDEwMjQKCnN0YXRpYyBjb25zdCBXQ0hBUiBDbGFzc2VzUm9vdFdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbCcsJ2EnLCdzJywncycsJ2UnLCdzJywwfTsKCiNkZWZpbmUgSVNfT1BUSU9OX0ZBTFNFKGNoKSBcCiAgICAoKGNoKSA9PSAnbicgfHwgKGNoKSA9PSAnTicgfHwgKGNoKSA9PSAnZicgfHwgKGNoKSA9PSAnRicgfHwgKGNoKSA9PSAnMCcpCgovKiBfeG1hbGxvYyBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkICpfeG1hbGxvYyggc2l6ZV90IHNpemUgKQp7CiAgICB2b2lkICpyZXM7CgogICAgcmVzID0gbWFsbG9jIChzaXplID8gc2l6ZSA6IDEpOwogICAgaWYgKHJlcyA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiVmlydHVhbCBtZW1vcnkgZXhoYXVzdGVkLlxuIik7CiAgICAgICAgZXhpdCAoMSk7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9CgovKiBfeHN0cmR1cCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfeHN0cmR1cChMUENTVFIgc3RyKQp7CiAgICBMUFNUUiByZXQ7CiAgICBzaXplX3QgbGVuID0gc3RybGVuKHN0cikgKyAxOwoKICAgIGlmICghc3RyKSByZXR1cm4gTlVMTDsKICAgIHJldCA9IF94bWFsbG9jKCBsZW4gKTsKICAgIG1lbWNweSggcmV0LCBzdHIsIGxlbiApOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCBhbnNpIHN0cmluZyB0byB1bmljb2RlIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQV1NUUiBfc3RyZHVwbkF0b1coTFBDU1RSIHN0ckEsc2l6ZV90IGxlbkEpCnsKICAgIExQV1NUUiByZXQ7CiAgICBEV09SRCBsZW47CgogICAgaWYgKCFzdHJBKSByZXR1cm4gTlVMTDsKICAgIGlmIChSdGxNdWx0aUJ5dGVUb1VuaWNvZGVTaXplKCAmbGVuLCBzdHJBLCBsZW5BICkgIT0gU1RBVFVTX1NVQ0NFU1MpIHJldHVybiBOVUxMOwoKICAgIHJldCA9IF94bWFsbG9jKGxlbitzaXplb2YoV0NIQVIpKTsKICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4ocmV0LCBsZW4sIE5VTEwsIHN0ckEsIGxlbkEpOwogICAgcmV0W2xlbiAvIHNpemVvZihXQ0hBUildID0gMDsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGR1bXAgYSBVbmljb2RlIHN0cmluZyB3aXRoIHByb3BlciBlc2NhcGluZyBbSW50ZXJuYWxdICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvdW5pY29kZS5jICovCnN0YXRpYyBpbnQgX2R1bXBfc3RyVyhjb25zdCBXQ0hBUiAqc3RyLHNpemVfdCBsZW4sRklMRSAqZixjb25zdCBjaGFyIGVzY2FwZVsyXSkKewogICAgc3RhdGljIGNvbnN0IGNoYXIgZXNjYXBlc1szMl0gPSAiLi4uLi4uLmFidG52ZnIuLi4uLi4uLi4uLi4uZS4uLi4iOwogICAgY2hhciBidWZmZXJbMjU2XTsKICAgIExQU1RSIHBvcyA9IGJ1ZmZlcjsKICAgIGludCBjb3VudCA9IDA7CgogICAgZm9yICg7IGxlbjsgc3RyKyssIGxlbi0tKQogICAgewogICAgICAgIGlmIChwb3MgPiBidWZmZXIgKyBzaXplb2YoYnVmZmVyKSAtIDgpCiAgICAgICAgewogICAgICAgICAgICBmd3JpdGUoIGJ1ZmZlciwgcG9zIC0gYnVmZmVyLCAxLCBmICk7CiAgICAgICAgICAgIGNvdW50ICs9IHBvcyAtIGJ1ZmZlcjsKICAgICAgICAgICAgcG9zID0gYnVmZmVyOwogICAgICAgIH0KICAgICAgICBpZiAoKnN0ciA+IDEyNykgIC8qIGhleCBlc2NhcGUgKi8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChsZW4gPiAxICYmIHN0clsxXSA8IDEyOCAmJiBpc3hkaWdpdCgoY2hhcilzdHJbMV0pKQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxceCUwNHgiLCAqc3RyICk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXHgleCIsICpzdHIgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyIDwgMzIpICAvKiBvY3RhbCBvciBDIGVzY2FwZSAqLwogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEqc3RyICYmIGxlbiA9PSAxKSBjb250aW51ZTsgIC8qIGRvIG5vdCBvdXRwdXQgdGVybWluYXRpbmcgTlVMTCAqLwogICAgICAgICAgICBpZiAoZXNjYXBlc1sqc3RyXSAhPSAnLicpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlYyIsIGVzY2FwZXNbKnN0cl0gKTsKICAgICAgICAgICAgZWxzZSBpZiAobGVuID4gMSAmJiBzdHJbMV0gPj0gJzAnICYmIHN0clsxXSA8PSAnNycpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlMDNvIiwgKnN0ciApOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlbyIsICpzdHIgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyID09ICdcXCcgfHwgKnN0ciA9PSBlc2NhcGVbMF0gfHwgKnN0ciA9PSBlc2NhcGVbMV0pICpwb3MrKyA9ICdcXCc7CiAgICAgICAgKnBvcysrID0gKnN0cjsKICAgIH0KICAgIGZ3cml0ZSggYnVmZmVyLCBwb3MgLSBidWZmZXIsIDEsIGYgKTsKICAgIGNvdW50ICs9IHBvcyAtIGJ1ZmZlcjsKICAgIHJldHVybiBjb3VudDsKfQoKLyogY29udmVydCBhbnNpIHN0cmluZyB0byB1bmljb2RlIGFuZCBkdW1wIHdpdGggcHJvcGVyIGVzY2FwaW5nIFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfZHVtcF9zdHJBdG9XKExQQ1NUUiBzdHJBLHNpemVfdCBsZW4sRklMRSAqZixjb25zdCBjaGFyIGVzY2FwZVsyXSkKewogICAgV0NIQVIgKnN0clc7CiAgICBpbnQgcmV0OwoKICAgIGlmIChzdHJBID09IE5VTEwpIHJldHVybiAwOwogICAgc3RyVyA9IF9zdHJkdXBuQXRvVyhzdHJBLGxlbik7CiAgICByZXQgPSBfZHVtcF9zdHJXKHN0clcsbGVuLGYsZXNjYXBlKTsKICAgIGZyZWUoc3RyVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBhIGtleSB2YWx1ZSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3JlZ2lzdHJ5LmMgKi8Kc3RydWN0IGtleV92YWx1ZSB7CiAgICBXQ0hBUiAgICAgICAgICAgICpuYW1lVzsgICAvKiB2YWx1ZSBuYW1lICovCiAgICBpbnQgICAgICAgICAgICAgICB0eXBlOyAgICAvKiB2YWx1ZSB0eXBlICovCiAgICBzaXplX3QgICAgICAgICAgICBsZW47ICAgICAvKiB2YWx1ZSBkYXRhIGxlbmd0aCBpbiBieXRlcyAqLwogICAgdm9pZCAgICAgICAgICAgICAqZGF0YTsgICAgLyogcG9pbnRlciB0byB2YWx1ZSBkYXRhICovCn07CgovKiBkdW1wIGEgdmFsdWUgdG8gYSB0ZXh0IGZpbGUgKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci9yZWdpc3RyeS5jICovCnN0YXRpYyB2b2lkIF9kdW1wX3ZhbHVlKHN0cnVjdCBrZXlfdmFsdWUgKnZhbHVlLEZJTEUgKmYpCnsKICAgIGludCBpLCBjb3VudDsKCiAgICBpZiAodmFsdWUtPm5hbWVXWzBdKSB7CiAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICBjb3VudCA9IDEgKyBfZHVtcF9zdHJXKHZhbHVlLT5uYW1lVyxzdHJsZW5XKHZhbHVlLT5uYW1lVyksZiwiXCJcIiIpOwogICAgICAgIGNvdW50ICs9IGZwcmludGYoIGYsICJcIj0iICk7CiAgICB9CiAgICBlbHNlIGNvdW50ID0gZnByaW50ZiggZiwgIkA9IiApOwoKICAgIHN3aXRjaCh2YWx1ZS0+dHlwZSkgewogICAgICAgIGNhc2UgUkVHX1NaOgogICAgICAgIGNhc2UgUkVHX0VYUEFORF9TWjoKICAgICAgICBjYXNlIFJFR19NVUxUSV9TWjoKICAgICAgICAgICAgaWYgKHZhbHVlLT50eXBlICE9IFJFR19TWikgZnByaW50ZiggZiwgInN0ciglZCk6IiwgdmFsdWUtPnR5cGUgKTsKICAgICAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICAgICAgaWYgKHZhbHVlLT5kYXRhKSBfZHVtcF9zdHJXKHZhbHVlLT5kYXRhLHZhbHVlLT5sZW4vc2l6ZW9mKFdDSEFSKSxmLCJcIlwiIik7CiAgICAgICAgICAgIGZwdXRjKCAnXCInLCBmICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX0RXT1JEOgogICAgICAgICAgICBpZiAodmFsdWUtPmxlbiA9PSBzaXplb2YoRFdPUkQpKSB7CiAgICAgICAgICAgICAgICBEV09SRCBkdzsKICAgICAgICAgICAgICAgIG1lbWNweSggJmR3LCB2YWx1ZS0+ZGF0YSwgc2l6ZW9mKERXT1JEKSApOwogICAgICAgICAgICAgICAgZnByaW50ZiggZiwgImR3b3JkOiUwOGx4IiwgZHcgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGVsc2UgZmFsbCB0aHJvdWdoICovCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgaWYgKHZhbHVlLT50eXBlID09IFJFR19CSU5BUlkpIGNvdW50ICs9IGZwcmludGYoIGYsICJoZXg6IiApOwogICAgICAgICAgICBlbHNlIGNvdW50ICs9IGZwcmludGYoIGYsICJoZXgoJXgpOiIsIHZhbHVlLT50eXBlICk7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS0+bGVuOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvdW50ICs9IGZwcmludGYoIGYsICIlMDJ4IiwgKigodW5zaWduZWQgY2hhciAqKXZhbHVlLT5kYXRhICsgaSkgKTsKICAgICAgICAgICAgICAgIGlmIChpIDwgdmFsdWUtPmxlbi0xKSB7CiAgICAgICAgICAgICAgICAgICAgZnB1dGMoICcsJywgZiApOwogICAgICAgICAgICAgICAgICAgIGlmICgrK2NvdW50ID4gNzYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZnByaW50ZiggZiwgIlxcXG4gICIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGZwdXRjKCAnXG4nLCBmICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewogICAgY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCiAgICB1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCiAgICB1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwogICAgdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwogICAgdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCiAgICB1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCiAgICB1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCiAgICB1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7CiAgICB1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwogICAgdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX3czMV9kdW1wdHJlZSh1bnNpZ25lZCBzaG9ydCBpZHgsIHVuc2lnbmVkIGNoYXIgKnR4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYiwgc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgIEhLRVkgaGtleSwgVUxPTkcgbGFzdG1vZGlmaWVkLCBpbnQgbGV2ZWwpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBjbGFzc2VzV1tdID0geycuJywnYycsJ2wnLCdhJywncycsJ3MnLCdlJywncycsMH07CiAgICBzdHJ1Y3QgX3czMV9kaXJlbnQgKmRpcjsKICAgIHN0cnVjdCBfdzMxX2tleWVudCAqa2V5OwogICAgc3RydWN0IF93MzFfdmFsZW50ICp2YWw7CiAgICBIS0VZIHN1YmtleSA9IDA7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVcsIHZhbHVlVzsKICAgIHN0YXRpYyBXQ0hBUiB0YWlsWzQwMF07CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5OwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmdmFsdWVXLCBOVUxMICk7CgogICAgd2hpbGUgKGlkeCE9MCkgewogICAgICAgIGRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgogICAgICAgIGlmIChkaXItPmtleV9pZHgpIHsKICAgICAgICAgICAgRFdPUkQgbGVuOwogICAgICAgICAgICBrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgogICAgICAgICAgICBSdGxNdWx0aUJ5dGVUb1VuaWNvZGVOKCB0YWlsLCBzaXplb2YodGFpbCktc2l6ZW9mKFdDSEFSKSwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnR4dFtrZXktPnN0cmluZ19vZmZdLCBrZXktPmxlbmd0aCk7CiAgICAgICAgICAgIHRhaWxbbGVuL3NpemVvZihXQ0hBUildID0gMDsKCiAgICAgICAgICAgIC8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUKICAgICAgICAgICAgICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCFsZXZlbCAmJiAhc3RyY21wVyh0YWlsLGNsYXNzZXNXKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsaGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CiAgICAgICAgICAgICAgICBpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc3Via2V5KSBOdENsb3NlKCBzdWJrZXkgKTsKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdGFpbCApOwogICAgICAgICAgICBpZiAoTnRDcmVhdGVLZXkoICZzdWJrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKSBzdWJrZXkgPSAwOwoKICAgICAgICAgICAgLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCiAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKICAgICAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCkgewogICAgICAgICAgICAgICAgICAgIERXT1JEIGxlbjsKICAgICAgICAgICAgICAgICAgICB2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CiAgICAgICAgICAgICAgICAgICAgUnRsTXVsdGlCeXRlVG9Vbmljb2RlTiggdGFpbCwgc2l6ZW9mKHRhaWwpIC0gc2l6ZW9mKFdDSEFSKSwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdHh0W3ZhbC0+c3RyaW5nX29mZl0sIHZhbC0+bGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICB0YWlsW2xlbi9zaXplb2YoV0NIQVIpXSA9IDA7CiAgICAgICAgICAgICAgICAgICAgTnRTZXRWYWx1ZUtleSggc3Via2V5LCAmdmFsdWVXLCAwLCBSRUdfU1osIHRhaWwsIGxlbiArIHNpemVvZihXQ0hBUikgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBUUkFDRSgic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKICAgICAgICBfdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxzdWJrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwogICAgICAgIGlkeD1kaXItPnNpYmxpbmdfaWR4OwogICAgfQogICAgaWYgKHN1YmtleSkgTnRDbG9zZSggc3Via2V5ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93MzFfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfdzMxX2xvYWRyZWcoIGNvbnN0IFdDSEFSICpwYXRoICkKewogICAgSEFORExFICAgICAgICAgICAgICAgICAgICAgIGhmOwogICAgSEtFWSAgICAgICAgICAgICAgICAgICAgICAgIHJvb3Q7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyAgICAgICAgICAgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HICAgICAgICAgICAgICBuYW1lVzsKICAgIHN0cnVjdCBfdzMxX2hlYWRlciAgICAgICAgICBoZWFkOwogICAgc3RydWN0IF93MzFfdGFiZW50KiAgICAgICAgIHRhYiA9IE5VTEw7CiAgICB1bnNpZ25lZCBjaGFyKiAgICAgICAgICAgICAgdHh0ID0gTlVMTDsKICAgIHVuc2lnbmVkIGludAkJbGVuOwogICAgVUxPTkcJCQlsYXN0bW9kaWZpZWQ7CiAgICBOVFNUQVRVUyAgICAgICAgICAgICAgICAgICAgc3RhdHVzOwogICAgSU9fU1RBVFVTX0JMT0NLICAgICAgICAgICAgIGlvc2I7CiAgICBGSUxFX1BPU0lUSU9OX0lORk9STUFUSU9OICAgZnBpOwogICAgRklMRV9CQVNJQ19JTkZPUk1BVElPTiAgICAgIGZiaTsKCiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICBoZiA9IENyZWF0ZUZpbGVXKCBwYXRoLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwogICAgaWYgKGhmPT1JTlZBTElEX0hBTkRMRV9WQUxVRSkgcmV0dXJuOwoKICAgIC8qIHJlYWQgJiBkdW1wIGhlYWRlciAqLwogICAgaWYgKE50UmVhZEZpbGUoaGYsIDAsIE5VTEwsIE5VTEwsICZpb3NiLCAKICAgICAgICAgICAgICAgICAgICZoZWFkLCBzaXplb2YoaGVhZCksIE5VTEwsIE5VTEwpICE9IFNUQVRVU19TVUNDRVNTIHx8CiAgICAgICAgaW9zYi5JbmZvcm1hdGlvbiAhPSBzaXplb2YoaGVhZCkpCiAgICB7CiAgICAgICAgRVJSKCJyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwogICAgICAgIGdvdG8gZG9uZTsKICAgIH0KICAgIGlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpICE9IDApCiAgICB7CiAgICAgICAgRVJSKCJyZWcuZGF0IGhhcyBiYWQgc2lnbmF0dXJlLlxuIik7CiAgICAgICAgZ290byBkb25lOwogICAgfQoKICAgIGxlbiA9IGhlYWQudGFiY250ICogc2l6ZW9mKHN0cnVjdCBfdzMxX3RhYmVudCk7CiAgICAvKiByZWFkIGFuZCBkdW1wIGluZGV4IHRhYmxlICovCiAgICB0YWIgPSBfeG1hbGxvYyhsZW4pOwogICAgaWYgKE50UmVhZEZpbGUoaGYsIDAsIE5VTEwsIE5VTEwsICZpb3NiLAogICAgICAgICAgICAgICAgICAgdGFiLCBsZW4sIE5VTEwsIE5VTEwpICE9IFNUQVRVU19TVUNDRVNTIHx8CiAgICAgICAgaW9zYi5JbmZvcm1hdGlvbiAhPSBsZW4pIAogICAgewogICAgICAgIEVSUigiY291bGRuJ3QgcmVhZCBpbmRleCB0YWJsZSAoJWQgYnl0ZXMpLlxuIixsZW4pOwogICAgICAgIGdvdG8gZG9uZTsKICAgIH0KCiAgICAvKiByZWFkIHRleHQgKi8KICAgIHR4dCA9IF94bWFsbG9jKGhlYWQudGV4dHNpemUpOwogICAgZnBpLkN1cnJlbnRCeXRlT2Zmc2V0LnUuTG93UGFydCA9IGhlYWQudGV4dG9mZjsKICAgIGZwaS5DdXJyZW50Qnl0ZU9mZnNldC51LkhpZ2hQYXJ0ID0gMDsKICAgIGlmIChOdFNldEluZm9ybWF0aW9uRmlsZShoZiwgJmlvc2IsICZmcGksIHNpemVvZihmcGkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlUG9zaXRpb25JbmZvcm1hdGlvbikgIT0gU1RBVFVTX1NVQ0NFU1MpCiAgICB7CiAgICAgICAgRVJSKCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOwogICAgICAgIGdvdG8gZG9uZTsKICAgIH0KICAgIHN0YXR1cyA9IE50UmVhZEZpbGUoaGYsIDAsIE5VTEwsIE5VTEwsICZpb3NiLCB0eHQsIGhlYWQudGV4dHNpemUsIE5VTEwsIE5VTEwpOwogICAgaWYgKCEoc3RhdHVzID09IFNUQVRVU19TVUNDRVNTIHx8IHN0YXR1cyA9PSBTVEFUVVNfRU5EX09GX0ZJTEUpIHx8CiAgICAgICAgaW9zYi5JbmZvcm1hdGlvbiAhPSBoZWFkLnRleHRzaXplKQogICAgewogICAgICAgIEVSUigidGV4dGJsb2NrIHRvbyBzaG9ydCAoJWQgaW5zdGVhZCBvZiAlbGQpLlxuIiwgbGVuLCBoZWFkLnRleHRzaXplKTsKICAgICAgICBnb3RvIGRvbmU7CiAgICB9CiAgICBpZiAoTnRRdWVyeUluZm9ybWF0aW9uRmlsZShoZiwgJmlvc2IsICZmYmksIHNpemVvZihmYmkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZUJhc2ljSW5mb3JtYXRpb24pICE9IFNUQVRVU19TVUNDRVNTKQogICAgewogICAgICAgIEVSUigiQ291bGRuJ3QgZ2V0IGJhc2ljIGluZm9ybWF0aW9uLlxuIik7CiAgICAgICAgZ290byBkb25lOwogICAgfQogICAgUnRsVGltZVRvU2Vjb25kc1NpbmNlMTk3MCgmZmJpLkxhc3RXcml0ZVRpbWUsICZsYXN0bW9kaWZpZWQpOwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBDbGFzc2VzUm9vdFcgKTsKCiAgICBpZiAoIU50Q3JlYXRlS2V5KCAmcm9vdCwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICB7CiAgICAgICAgX3czMV9kdW1wdHJlZSh0YWJbMF0udzEsdHh0LHRhYiwmaGVhZCxyb290LGxhc3Rtb2RpZmllZCwwKTsKICAgICAgICBOdENsb3NlKCByb290ICk7CiAgICB9CiBkb25lOgogICAgaWYgKHRhYikgZnJlZSh0YWIpOwogICAgaWYgKHR4dCkgZnJlZSh0eHQpOwogICAgTnRDbG9zZShoZik7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dzIDk1IHJlZ2lzdHJ5IGxvYWRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBTRUNUSU9OIDE6IG1haW4gaGVhZGVyCiAqCiAqIG9uY2UgYXQgb2Zmc2V0IDAKICovCiNkZWZpbmUJVzk1X1JFR19DUkVHX0lECTB4NDc0NTUyNDMKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogIkNSRUciID0gVzk1X1JFR19DUkVHX0lEICovCiAgICBEV09SRAl2ZXJzaW9uOwkvKiA/Pz8/IDB4MDAwMTAwMDAgKi8KICAgIERXT1JECXJnZGJfb2ZmOwkvKiAweDA4IE9mZnNldCBvZiAxc3QgUkdEQi1ibG9jayAqLwogICAgRFdPUkQJdWsyOwkJLyogMHgwYyAqLwogICAgV09SRAlyZ2RiX251bTsJLyogMHgxMCAjIG9mIFJHREItYmxvY2tzICovCiAgICBXT1JECXVrMzsKICAgIERXT1JECXVrWzNdOwogICAgLyogcmdrbiAqLwp9IF93OTVjcmVnOwoKLyogU0VDVElPTiAyOiBEaXJlY3RvcnkgaW5mb3JtYXRpb24gKHRyZWUgc3RydWN0dXJlKQogKgogKiBvbmNlIG9uIG9mZnNldCAweDIwCiAqCiAqIHN0cnVjdHVyZTogW3Jna25dW2RrZV0qCShyZXBlYXQgdGlsbCBsYXN0X2RrZSBpcyByZWFjaGVkKQogKi8KI2RlZmluZQlXOTVfUkVHX1JHS05fSUQJMHg0ZTRiNDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiJSR0tOIiA9IFc5NV9SRUdfUkdLTl9JRCAqLwogICAgRFdPUkQJc2l6ZTsJCS8qIFNpemUgb2YgdGhlIFJHS04tYmxvY2sgKi8KICAgIERXT1JECXJvb3Rfb2ZmOwkvKiBSZWwuIE9mZnNldCBvZiB0aGUgcm9vdC1yZWNvcmQgKi8KICAgIERXT1JEICAgbGFzdF9ka2U7ICAgICAgIC8qIE9mZnNldCB0byBsYXN0IERLRSA/ICovCiAgICBEV09SRAl1a1s0XTsKfSBfdzk1cmdrbjsKCi8qIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZQogKgogKiB0aGUgMXN0IGVudHJ5IGluIGEgInVzdWFsIiByZWdpc3RyeSBmaWxlIGlzIGEgbnVsLWVudHJ5IHdpdGggc3Via2V5czogdGhlCiAqIGhpdmUgaXRzZWxmLiBJdCBsb29rcyB0aGUgc2FtZSBsaWtlIG90aGVyIGtleXMuIEV2ZW4gdGhlIElELW51bWJlciBjYW4KICogYmUgYW55IHZhbHVlLgogKgogKiBUaGUgImhhc2giLXZhbHVlIGlzIGEgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBrZXkncyBuYW1lLiBXaW5kb3dzIHdpbGwgbm90CiAqIHNlYXJjaCBmb3IgdGhlIG5hbWUsIGJ1dCBmb3IgYSBtYXRjaGluZyBoYXNoLXZhbHVlLiBpZiBpdCBmaW5kcyBvbmUsIGl0CiAqIHdpbGwgY29tcGFyZSB0aGUgYWN0dWFsIHN0cmluZyBpbmZvLCBvdGhlcndpc2UgY29udGludWUgd2l0aCB0aGUgbmV4dCBrZXkuCiAqIFRvIGNhbGN1bGF0ZSB0aGUgaGFzaCBpbml0aWFsaXplIGEgRC1Xb3JkIHdpdGggMCBhbmQgYWRkIGFsbCBBU0NJSS12YWx1ZXMKICogb2YgdGhlIHN0cmluZyB3aGljaCBhcmUgc21hbGxlciB0aGFuIDB4ODAgKDEyOCkgdG8gdGhpcyBELVdvcmQuCiAqCiAqIElmIHlvdSB3YW50IHRvIG1vZGlmeSBrZXkgbmFtZXMsIGFsc28gbW9kaWZ5IHRoZSBoYXNoLXZhbHVlcywgc2luY2UgdGhleQogKiBjYW5ub3QgYmUgZm91bmQgYWdhaW4gKGFsdGhvdWdoIHRoZXkgd291bGQgYmUgZGlzcGxheWVkIGluIFJFR0VESVQpCiAqIEVuZCBvZiBsaXN0LXBvaW50ZXJzIGFyZSBmaWxsZWQgd2l0aCAweEZGRkZGRkZGCiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuck1TIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKgogKiBUaGUgbGFzdCBES0UgKHNlZSBmaWVsZCBsYXN0X2RrZSBpbiBfdzk1X3Jna24pIGhhcyBvbmx5IDMgRFdPUkRzIHdpdGgKICogMHg4MDAwMDAwMCAoRU9MIGluZGljYXRvciA/KSBhcyB4MSwgdGhlIGhhc2ggdmFsdWUgYW5kIDB4RkZGRkZGRkYgYXMgeDMuCiAqIFRoZSByZW1haW5pbmcgc3BhY2UgYmV0d2VlbiBsYXN0X2RrZSBhbmQgdGhlIG9mZnNldCBjYWxjdWxhdGVkIGZyb20KICogcmdrbi0+c2l6ZSBzZWVtcyB0byBiZSBmcmVlIGZvciB1c2UgZm9yIG1vcmUgZGtlOnMuCiAqIFNvIGl0IHNlZW1zIGlmIG1vcmUgZGtlOnMgYXJlIGFkZGVkLCB0aGV5IGFyZSBhZGRlZCB0byB0aGF0IHNwYWNlIGFuZAogKiBsYXN0X2RrZSBpcyBncm93biwgYW5kIGluIGNhc2UgdGhhdCAiZnJlZSIgc3BhY2UgaXMgb3V0LCB0aGUgc3BhY2UKICogZ2V0cyBncm93biBhbmQgcmdrbi0+c2l6ZSBnZXRzIGFkanVzdGVkLgogKgogKiB0aGVyZSBpcyBhIG9uZSB0byBvbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gZGtlIGFuZCBka2gKICovCiAvKiBrZXkgc3RydWN0LCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJeDE7CQkvKiBGcmVlIGVudHJ5IGluZGljYXRvcig/KSAqLwogICAgRFdPUkQJaGFzaDsJCS8qIHN1bSBvZiBieXRlcyBvZiBrZXluYW1lICovCiAgICBEV09SRAl4MzsJCS8qIFJvb3Qga2V5IGluZGljYXRvcj8gdXN1YWxseSAweEZGRkZGRkZGICovCiAgICBEV09SRAlwcmV2bHZsOwkvKiBvZmZzZXQgb2YgcHJldmlvdXMga2V5ICovCiAgICBEV09SRAluZXh0c3ViOwkvKiBvZmZzZXQgb2YgY2hpbGQga2V5ICovCiAgICBEV09SRAluZXh0OwkJLyogb2Zmc2V0IG9mIHNpYmxpbmcga2V5ICovCiAgICBXT1JECW5yTFM7CQkvKiBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KICAgIFdPUkQJbnJNUzsJCS8qIG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwp9IF93OTVka2U7CgovKiBTRUNUSU9OIDM6IGtleSBpbmZvcm1hdGlvbiwgdmFsdWVzIGFuZCBkYXRhCiAqCiAqIHN0cnVjdHVyZToKICogIHNlY3Rpb246CVtibG9ja3NdKgkJKHJlcGVhdCBjcmVnLT5yZ2RiX251bSB0aW1lcykKICogIGJsb2NrczoJW3JnZGJdIFtzdWJibG9ja3NdKiAJKHJlcGVhdCB0aWxsIGJsb2NrIHNpemUgcmVhY2hlZCApCiAqICBzdWJibG9ja3M6CVtka2hdIFtka3ZdKgkJKHJlcGVhdCBka2gtPnZhbHVlcyB0aW1lcyApCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgRFdPUkQgdmFsdWUKICogYXQgb2Zmc2V0IDB4MTAgZXF1YWxzIHRoZSBvbmUgYXQgb2Zmc2V0IDB4MDQgbWludXMgdGhlIG9uZSBhdCBvZmZzZXQgMHgwOC4KICogSSBoYXZlIG5vIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKi8KCi8qIGJsb2NrIGhlYWRlciwgb25jZSBwZXIgYmxvY2sgKi8KI2RlZmluZSBXOTVfUkVHX1JHREJfSUQJMHg0MjQ0NDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CS8qIDB4MDAgJ1JHREInID0gVzk1X1JFR19SR0RCX0lEICovCiAgICBEV09SRAlzaXplOwkvKiAweDA0ICovCiAgICBEV09SRAl1azE7CS8qIDB4MDggKi8KICAgIERXT1JECXVrMjsJLyogMHgwYyAqLwogICAgRFdPUkQJdWszOwkvKiAweDEwICovCiAgICBEV09SRAl1azQ7CS8qIDB4MTQgKi8KICAgIERXT1JECXVrNTsJLyogMHgxOCAqLwogICAgRFdPUkQJdWs2OwkvKiAweDFjICovCiAgICAvKiBka2ggKi8KfSBfdzk1cmdkYjsKCi8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCksIG9uY2UgcGVyIGtleSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAluZXh0a2V5b2ZmOyAJLyogMHgwMCBvZmZzZXQgdG8gbmV4dCBka2ggKi8KICAgIFdPUkQJbnJMUzsJCS8qIDB4MDQgaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCiAgICBXT1JECW5yTVM7CQkvKiAweDA2IG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwogICAgRFdPUkQJYnl0ZXN1c2VkOwkvKiAweDA4ICovCiAgICBXT1JECWtleW5hbWVsZW47CS8qIDB4MGMgbGVuIG9mIG5hbWUgKi8KICAgIFdPUkQJdmFsdWVzOwkJLyogMHgwZSBudW1iZXIgb2YgdmFsdWVzICovCiAgICBEV09SRAl4eDE7CQkvKiAweDEwICovCiAgICBjaGFyCW5hbWVbMV07CS8qIDB4MTQgKi8KICAgIC8qIGRrdiAqLwkJLyogMHgxNCArIGtleW5hbWVsZW4gKi8KfSBfdzk1ZGtoOwoKLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlLCBvbmNlIHBlciB2YWx1ZSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAl0eXBlOwkJLyogMHgwMCAqLwogICAgRFdPUkQJeDE7CQkvKiAweDA0ICovCiAgICBXT1JECXZhbG5hbWVsZW47CS8qIDB4MDggbGVuZ3RoIG9mIG5hbWUsIDAgaXMgZGVmYXVsdCBrZXkgKi8KICAgIFdPUkQJdmFsZGF0YWxlbjsJLyogMHgwQSBsZW5ndGggb2YgZGF0YSAqLwogICAgY2hhcgluYW1lWzFdOwkvKiAweDBjICovCiAgICAvKiByYXcgZGF0YSAqLwkJLyogMHgwYyArIHZhbG5hbWVsZW4gKi8KfSBfdzk1ZGt2OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvb2t1cF9ka2ggW0ludGVybmFsXQogKgogKiBzZWVrcyB0aGUgZGtoIGJlbG9uZ2luZyB0byBhIGRrZQogKi8Kc3RhdGljIF93OTVka2ggKl93OTVfbG9va3VwX2RraChfdzk1Y3JlZyAqY3JlZyxpbnQgbnJMUyxpbnQgbnJNUykKewogICAgX3c5NXJnZGIgKiByZ2RiOwogICAgX3c5NWRraCAqIGRraDsKICAgIGludCBpOwoKICAgIC8qIGdldCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZ2RiIGRhdGFzdG9yZSAqLwogICAgcmdkYiA9IChfdzk1cmdkYiopKChjaGFyKiljcmVnK2NyZWctPnJnZGJfb2ZmKTsKCiAgICAvKiBjaGVjazogcmVxdWVzdGVkIGJsb2NrIDwgbGFzdF9ibG9jaykgKi8KICAgIGlmIChjcmVnLT5yZ2RiX251bSA8PSBuck1TKSB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJlcXVlc3RlZCBibG9jayBuby4gYmV5b25kIGVuZC5cbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogZmluZCB0aGUgcmlnaHQgYmxvY2sgKi8KICAgIGZvcihpPTA7IGk8bnJNUyA7aSsrKSB7CiAgICAgICAgaWYocmdkYi0+aWQgIT0gVzk1X1JFR19SR0RCX0lEKSB7ICAvKiBjaGVjayB0aGUgbWFnaWMgKi8KICAgICAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGJhZCBtYWdpYyAweCUwOGx4XG4iLCByZ2RiLT5pZCk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIHJnZGIgPSAoX3c5NXJnZGIqKSAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSk7CQkvKiBmaW5kIG5leHQgYmxvY2sgKi8KICAgIH0KCiAgICBka2ggPSAoX3c5NWRraCopKHJnZGIgKyAxKTsJCQkJLyogZmlyc3Qgc3ViIGJsb2NrIHdpdGhpbiB0aGUgcmdkYiAqLwoKICAgIGRvIHsKICAgICAgICBpZihuckxTPT1ka2gtPm5yTFMgKSByZXR1cm4gZGtoOwogICAgICAgIGRraCA9IChfdzk1ZGtoKikoKGNoYXIqKWRraCArIGRraC0+bmV4dGtleW9mZik7CS8qIGZpbmQgbmV4dCBzdWJibG9jayAqLwogICAgfSB3aGlsZSAoKGNoYXIgKilka2ggPCAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSkpOwoKZXJyb3I6CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2R1bXBfZGt2IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9kdW1wX2Rrdihfdzk1ZGtoICpka2gsaW50IG5yTFMsaW50IG5yTVMsRklMRSAqZikKewogICAgX3c5NWRrdiAqIGRrdjsKICAgIGludCBpOwoKICAgIC8qIGZpcnN0IHZhbHVlIGJsb2NrICovCiAgICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka2grZGtoLT5rZXluYW1lbGVuKzB4MTQpOwoKICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUgdmFsdWVzICovCiAgICBmb3IgKGk9MDsgaTwgZGtoLT52YWx1ZXM7IGkrKykgewogICAgICAgIHN0cnVjdCBrZXlfdmFsdWUgdmFsdWU7CiAgICAgICAgV0NIQVIgKnBkYXRhOwoKICAgICAgICB2YWx1ZS5uYW1lVyA9IF9zdHJkdXBuQXRvVyhka3YtPm5hbWUsZGt2LT52YWxuYW1lbGVuKTsKICAgICAgICB2YWx1ZS50eXBlID0gZGt2LT50eXBlOwogICAgICAgIHZhbHVlLmxlbiA9IGRrdi0+dmFsZGF0YWxlbjsKCiAgICAgICAgdmFsdWUuZGF0YSA9ICYoZGt2LT5uYW1lW2Rrdi0+dmFsbmFtZWxlbl0pOwogICAgICAgIHBkYXRhID0gTlVMTDsKICAgICAgICBpZiAoICh2YWx1ZS50eXBlPT1SRUdfU1opIHx8ICh2YWx1ZS50eXBlPT1SRUdfRVhQQU5EX1NaKSB8fCAodmFsdWUudHlwZT09UkVHX01VTFRJX1NaKSApIHsKICAgICAgICAgICAgcGRhdGEgPSBfc3RyZHVwbkF0b1codmFsdWUuZGF0YSx2YWx1ZS5sZW4pOwogICAgICAgICAgICB2YWx1ZS5sZW4gKj0gMjsKICAgICAgICB9CiAgICAgICAgaWYgKHBkYXRhICE9IE5VTEwpIHZhbHVlLmRhdGEgPSBwZGF0YTsKCiAgICAgICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgICAgIGZyZWUodmFsdWUubmFtZVcpOwogICAgICAgIGlmIChwZGF0YSAhPSBOVUxMKSBmcmVlKHBkYXRhKTsKCiAgICAgICAgLyogbmV4dCB2YWx1ZSAqLwogICAgICAgIGRrdiA9IChfdzk1ZGt2KikoKGNoYXIqKWRrditka3YtPnZhbG5hbWVsZW4rZGt2LT52YWxkYXRhbGVuKzB4MGMpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9kdW1wX2RrZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfZHVtcF9ka2UoTFBDU1RSIGtleV9uYW1lLF93OTVjcmVnICpjcmVnLF93OTVyZ2tuICpyZ2tuLF93OTVka2UgKmRrZSxGSUxFICpmLGludCBsZXZlbCkKewogICAgX3c5NWRraCAqIGRraDsKICAgIExQU1RSIG5ld19rZXlfbmFtZSA9IE5VTEw7CgogICAgLyogc3BlY2lhbCByb290IGtleSAqLwogICAgaWYgKGRrZS0+bnJMUyA9PSAweGZmZmYgfHwgZGtlLT5uck1TPT0weGZmZmYpCQkvKiBlZy4gdGhlIHJvb3Qga2V5IGhhcyBubyBuYW1lICovCiAgICB7CiAgICAgICAgLyogcGFyc2UgdGhlIG9uZSBzdWJrZXkgKi8KICAgICAgICBpZiAoZGtlLT5uZXh0c3ViICE9IDB4ZmZmZmZmZmYpIHJldHVybiBfdzk1X2R1bXBfZGtlKGtleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dHN1YiksZixsZXZlbCk7CiAgICAgICAgLyogaGFzIG5vIHNpYmxpbmcga2V5cyAqLwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiBzZWFyY2ggc3ViYmxvY2sgKi8KICAgIGlmICghKGRraCA9IF93OTVfbG9va3VwX2RraChjcmVnLCBka2UtPm5yTFMsIGRrZS0+bnJNUykpKSB7CiAgICAgICAgRVJSKCJka2UgcG9pbnRpbmcgdG8gbWlzc2luZyBka2ggIVxuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChsZXZlbCA8PSAwKSB7CiAgICAgICAgLyogY3JlYXRlIG5ldyBzdWJrZXkgbmFtZSAqLwogICAgICAgIHNpemVfdCBsZW4gPSBzdHJsZW4oa2V5X25hbWUpOwogICAgICAgIG5ld19rZXlfbmFtZSA9IF94bWFsbG9jKGxlbitka2gtPmtleW5hbWVsZW4rMik7CiAgICAgICAgbWVtY3B5KCBuZXdfa2V5X25hbWUsIGtleV9uYW1lLCBsZW4gKTsKICAgICAgICBpZiAobGVuKSBuZXdfa2V5X25hbWVbbGVuKytdID0gJ1xcJzsKICAgICAgICBtZW1jcHkoIG5ld19rZXlfbmFtZSArIGxlbiwgZGtoLT5uYW1lLCBka2gtPmtleW5hbWVsZW4gKTsKICAgICAgICBuZXdfa2V5X25hbWVbbGVuICsgZGtoLT5rZXluYW1lbGVuXSA9IDA7CgogICAgICAgIC8qIHdhbGsgc2libGluZyBrZXlzICovCiAgICAgICAgaWYgKGRrZS0+bmV4dCAhPSAweGZmZmZmZmZmICkgewogICAgICAgICAgICBpZiAoIV93OTVfZHVtcF9ka2Uoa2V5X25hbWUsIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0KSxmLGxldmVsKSkgewogICAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiB3cml0ZSB0aGUga2V5IHBhdGggKHNvbWV0aGluZyBsaWtlIFtTb2Z0d2FyZVxcTWljcm9zb2Z0XFwuLl0pIG9ubHkgaWY6CiAgICAgICAgICAgMSkga2V5IGhhcyBzb21lIHZhbHVlcwogICAgICAgICAgIDIpIGtleSBoYXMgbm8gdmFsdWVzIGFuZCBubyBzdWJrZXlzCiAgICAgICAgKi8KICAgICAgICBpZiAoZGtoLT52YWx1ZXMgPiAwKSB7CiAgICAgICAgICAgIC8qIHRoZXJlIGFyZSBzb21lIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgICAgICBpZiAoIV93OTVfZHVtcF9ka3YoZGtoLCBka2UtPm5yTFMsIGRrZS0+bnJNUyxmKSkgewogICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKChka2UtPm5leHRzdWIgPT0gMHhmZmZmZmZmZikgJiYgKGRraC0+dmFsdWVzID09IDApKSB7CiAgICAgICAgICAgIC8qIG5vIHN1YmtleXMgYW5kIG5vIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KICAgIH0gZWxzZSBuZXdfa2V5X25hbWUgPSBfeHN0cmR1cChrZXlfbmFtZSk7CgogICAgLyogbmV4dCBzdWIga2V5ICovCiAgICBpZiAoZGtlLT5uZXh0c3ViICE9IDB4ZmZmZmZmZmYpIHsKICAgICAgICBpZiAoIV93OTVfZHVtcF9ka2UobmV3X2tleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dHN1YiksZixsZXZlbC0xKSkgewogICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICByZXR1cm4gVFJVRTsKfQovKiBlbmQgd2luZG93cyA5NSBsb2FkZXIgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dzIE5UIHJlZ2lzdHJ5IGxvYWRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBOVCBSRUdJU1RSWSBMT0FERVIgKi8KCiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKCiNpZm5kZWYgTUFQX0ZBSUxFRAojZGVmaW5lIE1BUF9GQUlMRUQgKChMUFZPSUQpLTEpCiNlbmRpZgoKI2RlZmluZSBOVF9SRUdfQkxPQ0tfU0laRSAgICAgICAgICAgIDB4MTAwMAoKI2RlZmluZSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEICAgICAgIDB4NjY2NzY1NzIJLyogcmVnZiAqLwojZGVmaW5lIE5UX1JFR19QT09MX0JMT0NLX0lEICAgICAgICAgMHg2RTY5NjI2OAkvKiBoYmluICovCiNkZWZpbmUgTlRfUkVHX0tFWV9CTE9DS19JRCAgICAgICAgICAweDZiNmUgLyogbmsgKi8KI2RlZmluZSBOVF9SRUdfVkFMVUVfQkxPQ0tfSUQgICAgICAgIDB4NmI3NiAvKiB2ayAqLwoKLyogc3ViYmxvY2tzIG9mIG5rICovCiNkZWZpbmUgTlRfUkVHX0hBU0hfQkxPQ0tfSUQgICAgICAgICAweDY2NmMgLyogbGYgKi8KI2RlZmluZSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEICAgICAgIDB4Njk2YyAvKiBsaSAqLwojZGVmaW5lIE5UX1JFR19SSV9CTE9DS19JRAkgICAgIDB4Njk3MiAvKiByaSAqLwoKI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX1RZUEUgICAgICAgIDB4MjAKI2RlZmluZSBOVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSAgIDB4MmMKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogMHg2NjY3NjU3MiAncmVnZicqLwogICAgRFdPUkQJdWsxOwkJLyogMHgwNCAqLwogICAgRFdPUkQJdWsyOwkJLyogMHgwOCAqLwogICAgRklMRVRJTUUJRGF0ZU1vZGlmaWVkOwkvKiAweDBjICovCiAgICBEV09SRAl1azM7CQkvKiAweDE0ICovCiAgICBEV09SRAl1azQ7CQkvKiAweDE4ICovCiAgICBEV09SRAl1azU7CQkvKiAweDFjICovCiAgICBEV09SRAl1azY7CQkvKiAweDIwICovCiAgICBEV09SRAlSb290S2V5QmxvY2s7CS8qIDB4MjQgKi8KICAgIERXT1JECUJsb2NrU2l6ZTsJLyogMHgyOCAqLwogICAgRFdPUkQgICB1azdbMTE2XTsKICAgIERXT1JECUNoZWNrc3VtOyAvKiBhdCBvZmZzZXQgMHgxRkMgKi8KfSBudF9yZWdmOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJYmxvY2tzaXplOwogICAgQllURQlkYXRhWzFdOwp9IG50X2hiaW5fc3ViOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiAweDZFNjk2MjY4ICdoYmluJyAqLwogICAgRFdPUkQJb2ZmX3ByZXY7CiAgICBEV09SRAlvZmZfbmV4dDsKICAgIERXT1JECXVrMTsKICAgIERXT1JECXVrMjsJCS8qIDB4MTAgKi8KICAgIERXT1JECXVrMzsJCS8qIDB4MTQgKi8KICAgIERXT1JECXVrNDsJCS8qIDB4MTggKi8KICAgIERXT1JECXNpemU7CQkvKiAweDFDICovCiAgICBudF9oYmluX3N1YgloYmluX3N1YjsJLyogMHgyMCAqLwp9IG50X2hiaW47CgovKgogKiB0aGUgdmFsdWVfbGlzdCBjb25zaXN0cyBvZiBvZmZzZXRzIHRvIHRoZSB2YWx1ZXMgKHZrKQogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlTdWJCbG9ja0lkOwkJLyogMHgwMCAweDZCNkUgKi8KICAgIFdPUkQJVHlwZTsJCQkvKiAweDAyIGZvciB0aGUgcm9vdC1rZXk6IDB4MkMsIG90aGVyd2lzZSAweDIwKi8KICAgIEZJTEVUSU1FCXdyaXRldGltZTsJLyogMHgwNCAqLwogICAgRFdPUkQJdWsxOwkJCS8qIDB4MEMgKi8KICAgIERXT1JECXBhcmVudF9vZmY7CQkvKiAweDEwIE9mZnNldCBvZiBPd25lci9QYXJlbnQga2V5ICovCiAgICBEV09SRAlucl9zdWJrZXlzOwkJLyogMHgxNCBudW1iZXIgb2Ygc3ViLUtleXMgKi8KICAgIERXT1JECXVrODsJCQkvKiAweDE4ICovCiAgICBEV09SRAlsZl9vZmY7CQkJLyogMHgxQyBPZmZzZXQgb2YgdGhlIHN1Yi1rZXkgbGYtUmVjb3JkcyAqLwogICAgRFdPUkQJdWsyOwkJCS8qIDB4MjAgKi8KICAgIERXT1JECW5yX3ZhbHVlczsJCS8qIDB4MjQgbnVtYmVyIG9mIHZhbHVlcyAqLwogICAgRFdPUkQJdmFsdWVsaXN0X29mZjsJCS8qIDB4MjggT2Zmc2V0IG9mIHRoZSBWYWx1ZS1MaXN0ICovCiAgICBEV09SRAlvZmZfc2s7CQkJLyogMHgyYyBPZmZzZXQgb2YgdGhlIHNrLVJlY29yZCAqLwogICAgRFdPUkQJb2ZmX2NsYXNzOwkJLyogMHgzMCBPZmZzZXQgb2YgdGhlIENsYXNzLU5hbWUgKi8KICAgIERXT1JECXVrMzsJCQkvKiAweDM0ICovCiAgICBEV09SRAl1azQ7CQkJLyogMHgzOCAqLwogICAgRFdPUkQJdWs1OwkJCS8qIDB4M2MgKi8KICAgIERXT1JECXVrNjsJCQkvKiAweDQwICovCiAgICBEV09SRAl1azc7CQkJLyogMHg0NCAqLwogICAgV09SRAluYW1lX2xlbjsJCS8qIDB4NDggbmFtZS1sZW5ndGggKi8KICAgIFdPUkQJY2xhc3NfbGVuOwkJLyogMHg0YSBjbGFzcy1uYW1lIGxlbmd0aCAqLwogICAgY2hhcgluYW1lWzFdOwkJLyogMHg0YyBrZXktbmFtZSAqLwp9IG50X25rOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJb2ZmX25rOwkvKiAweDAwICovCiAgICBEV09SRAluYW1lOwkvKiAweDA0ICovCn0gaGFzaF9yZWM7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY2NmMgKi8KICAgIFdPUkQJbnJfa2V5czsJLyogMHgwNiAqLwogICAgaGFzaF9yZWMJaGFzaF9yZWNbMV07Cn0gbnRfbGY7CgovKgogbGlzdCBvZiBzdWJrZXlzIHdpdGhvdXQgaGFzaAoKIGxpIC0tKy0tPm5rCiAgICAgIHwKICAgICAgKy0tPm5rCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY5NmMgKi8KICAgIFdPUkQJbnJfa2V5czsKICAgIERXT1JECW9mZl9ua1sxXTsKfSBudF9saTsKCi8qCiB0aGlzIGlzIGEgaW50ZXJtZWRpYXRlIG5vZGUKCiByaSAtLSstLT5saS0tKy0tPm5rCiAgICAgIHwgICAgICAgKwogICAgICB8ICAgICAgICstLT5uawogICAgICB8CiAgICAgICstLT5saS0tKy0tPm5rCiAgICAgICAgICAgICAgKwoJICAgICAgKy0tPm5rCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY5NzIgKi8KICAgIFdPUkQJbnJfbGk7CQkvKiAweDAyIG51bWJlciBvZmYgb2Zmc2V0cyAqLwogICAgRFdPUkQJb2ZmX2xpWzFdOwkvKiAweDA0IHBvaW50cyB0byBsaSAqLwp9IG50X3JpOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgJ3ZrJyAqLwogICAgV09SRAluYW1fbGVuOwogICAgRFdPUkQJZGF0YV9sZW47CiAgICBEV09SRAlkYXRhX29mZjsKICAgIERXT1JECXR5cGU7CiAgICBXT1JECWZsYWc7CiAgICBXT1JECXVrMTsKICAgIGNoYXIJbmFtZVsxXTsKfSBudF92azsKCi8qCiAqIGdldHMgYSB2YWx1ZQogKgogKiB2ay0+ZmxhZzoKICogIDAgdmFsdWUgaXMgYSBkZWZhdWx0IHZhbHVlCiAqICAxIHRoZSB2YWx1ZSBoYXMgYSBuYW1lCiAqCiAqIHZrLT5kYXRhX2xlbgogKiAgbGVuIG9mIHRoZSB3aG9sZSBkYXRhIGJsb2NrCiAqICAtIHJlZ19zeiAodW5pY29kZSkKICogICAgYnl0ZXMgaW5jbHVkaW5nIHRoZSB0ZXJtaW5hdGluZyBcMCA9IDIqKG51bWJlcl9vZl9jaGFycysxKQogKiAgLSByZWdfZHdvcmQsIHJlZ19iaW5hcnk6CiAqICAgIGlmIGhpZ2hlc3QgYml0IG9mIGRhdGFfbGVuIGlzIHNldCBkYXRhX29mZiBjb250YWlucyB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQgX250X2R1bXBfdmsoTFBTVFIga2V5X25hbWUsIGNoYXIgKmJhc2UsIG50X3ZrICp2ayxGSUxFICpmKQp7CiAgICBCWVRFICpwZGF0YSA9IChCWVRFICopKGJhc2UrdmstPmRhdGFfb2ZmKzQpOyAvKiBzdGFydCBvZiBkYXRhICovCiAgICBzdHJ1Y3Qga2V5X3ZhbHVlIHZhbHVlOwoKICAgIGlmICh2ay0+aWQgIT0gTlRfUkVHX1ZBTFVFX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmtub3duIGJsb2NrIGZvdW5kICgweCUwNHgpLCBwbGVhc2UgcmVwb3J0IVxuIiwgdmstPmlkKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgdmFsdWUubmFtZVcgPSBfc3RyZHVwbkF0b1codmstPm5hbWUsdmstPm5hbV9sZW4pOwogICAgdmFsdWUudHlwZSA9IHZrLT50eXBlOwogICAgdmFsdWUubGVuID0gKHZrLT5kYXRhX2xlbiAmIDB4N2ZmZmZmZmYpOwogICAgdmFsdWUuZGF0YSA9ICh2ay0+ZGF0YV9sZW4gJiAweDgwMDAwMDAwKSA/IChMUEJZVEUpJih2ay0+ZGF0YV9vZmYpOiBwZGF0YTsKCiAgICBfZHVtcF92YWx1ZSgmdmFsdWUsZik7CiAgICBmcmVlKHZhbHVlLm5hbWVXKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyogaXQncyBjYWxsZWQgZnJvbSBfbnRfZHVtcF9sZigpICovCnN0YXRpYyBpbnQgX250X2R1bXBfbmsoTFBDU1RSIGtleV9uYW1lLGNoYXIgKmJhc2UsbnRfbmsgKm5rLEZJTEUgKmYsaW50IGxldmVsKTsKCi8qCiAqIGdldCB0aGUgc3Via2V5cwogKgogKiB0aGlzIHN0cnVjdHVyZSBjb250YWlucyB0aGUgaGFzaCBvZiBhIGtleW5hbWUgYW5kIHBvaW50cyB0byBhbGwKICogc3Via2V5cwogKgogKiBleGNlcHRpb246IGlmIHRoZSBpZCBpcyAnaWwnIHRoZXJlIGFyZSBubyBoYXNoIHZhbHVlcyBhbmQgZXZlcnkKICogZHdvcmQgaXMgYSBvZmZzZXQKICovCnN0YXRpYyBpbnQgX250X2R1bXBfbGYoTFBDU1RSIGtleV9uYW1lLCBjaGFyICpiYXNlLCBpbnQgc3Via2V5cywgbnRfbGYgKmxmLCBGSUxFICpmLCBpbnQgbGV2ZWwpCnsKICAgIGludCBpOwoKICAgIGlmIChsZi0+aWQgPT0gTlRfUkVHX0hBU0hfQkxPQ0tfSUQpIHsKICAgICAgICBpZiAoc3Via2V5cyAhPSBsZi0+bnJfa2V5cykgZ290byBlcnJvcjE7CgogICAgICAgIGZvciAoaT0wOyBpPGxmLT5ucl9rZXlzOyBpKyspCiAgICAgICAgICAgIGlmICghX250X2R1bXBfbmsoa2V5X25hbWUsIGJhc2UsIChudF9uayopKGJhc2UrbGYtPmhhc2hfcmVjW2ldLm9mZl9uays0KSwgZiwgbGV2ZWwpKSBnb3RvIGVycm9yOwogICAgfSBlbHNlIGlmIChsZi0+aWQgPT0gTlRfUkVHX05PSEFTSF9CTE9DS19JRCkgewogICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKWxmOwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCiAgICAgICAgZm9yIChpPTA7IGk8bGktPm5yX2tleXM7IGkrKykKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9uayhrZXlfbmFtZSwgYmFzZSwgKG50X25rKikoYmFzZStsaS0+b2ZmX25rW2ldKzQpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfUklfQkxPQ0tfSUQpIHsgIC8qIHJpICovCiAgICAgICAgbnRfcmkgKiByaSA9IChudF9yaSopbGY7CiAgICAgICAgaW50IGxpX3N1YmtleXMgPSAwOwoKICAgICAgICAvKiBjb3VudCBhbGwgc3Via2V5cyAqLwogICAgICAgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKSB7CiAgICAgICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmKGxpLT5pZCAhPSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKSBnb3RvIGVycm9yMjsKICAgICAgICAgICAgbGlfc3Via2V5cyArPSBsaS0+bnJfa2V5czsKICAgICAgICB9CgogICAgICAgIC8qIGNoZWNrIG51bWJlciAqLwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpX3N1YmtleXMpIGdvdG8gZXJyb3IxOwoKICAgICAgICAvKiBsb29wIHRocm91Z2ggdGhlIGtleXMgKi8KICAgICAgICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykgewogICAgICAgICAgICBudF9saSAqbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmICghX250X2R1bXBfbGYoa2V5X25hbWUsIGJhc2UsIGxpLT5ucl9rZXlzLCAobnRfbGYqKWxpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgfSBlbHNlIGdvdG8gZXJyb3IyOwoKICAgIHJldHVybiBUUlVFOwoKZXJyb3IyOgogICAgaWYgKGxmLT5pZCA9PSAweDY4NmMpCiAgICAgICAgRklYTUUoInVua25vd24gV2luIFhQIG5vZGUgaWQgMHg2ODZjOiBkbyB3ZSBuZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBpdCA/XG4iKTsKICAgIGVsc2UKICAgICAgICBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBsZi0+aWQpOwogICAgcmV0dXJuIFRSVUU7CgplcnJvcjE6CiAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgKGluY29uc2lzdGVudCBudW1iZXIgb2Ygc3Via2V5cylcbiIpOwogICAgcmV0dXJuIEZBTFNFOwoKZXJyb3I6CiAgICBFUlIoImVycm9yIHJlYWRpbmcgbGYgYmxvY2tcbiIpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKiBfbnRfZHVtcF9uayBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX250X2R1bXBfbmsoTFBDU1RSIGtleV9uYW1lLGNoYXIgKmJhc2UsbnRfbmsgKm5rLEZJTEUgKmYsaW50IGxldmVsKQp7CiAgICB1bnNpZ25lZCBpbnQgbjsKICAgIERXT1JEICp2bDsKICAgIExQU1RSIG5ld19rZXlfbmFtZSA9IE5VTEw7CgogICAgVFJBQ0UoIiVzXG4iLCBrZXlfbmFtZSk7CgogICAgaWYgKG5rLT5TdWJCbG9ja0lkICE9IE5UX1JFR19LRVlfQkxPQ0tfSUQpIHsKICAgICAgICBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBuay0+U3ViQmxvY2tJZCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICgobmstPlR5cGUhPU5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKSAmJiAoKChudF9uayopKGJhc2UrbmstPnBhcmVudF9vZmYrNCkpLT5TdWJCbG9ja0lkICE9IE5UX1JFR19LRVlfQkxPQ0tfSUQpKSB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhXG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgLyogY3JlYXRlIHRoZSBuZXcga2V5ICovCiAgICBpZiAobGV2ZWwgPD0gMCkgewogICAgICAgIC8qIGNyZWF0ZSBuZXcgc3Via2V5IG5hbWUgKi8KICAgICAgICBzaXplX3QgbGVuID0gc3RybGVuKGtleV9uYW1lKTsKICAgICAgICBuZXdfa2V5X25hbWUgPSBfeG1hbGxvYyggbGVuK25rLT5uYW1lX2xlbisyICk7CiAgICAgICAgbWVtY3B5KCBuZXdfa2V5X25hbWUsIGtleV9uYW1lLCBsZW4gKTsKICAgICAgICBpZiAobGVuKSBuZXdfa2V5X25hbWVbbGVuKytdID0gJ1xcJzsKICAgICAgICBtZW1jcHkoIG5ld19rZXlfbmFtZSArIGxlbiwgbmstPm5hbWUsIG5rLT5uYW1lX2xlbiApOwogICAgICAgIG5ld19rZXlfbmFtZVtsZW4gKyBuay0+bmFtZV9sZW5dID0gMDsKCiAgICAgICAgLyogd3JpdGUgdGhlIGtleSBwYXRoIChzb21ldGhpbmcgbGlrZSBbU29mdHdhcmVcXE1pY3Jvc29mdFxcLi5dKSBvbmx5IGlmOgogICAgICAgICAgIDEpIGtleSBoYXMgc29tZSB2YWx1ZXMKICAgICAgICAgICAyKSBrZXkgaGFzIG5vIHZhbHVlcyBhbmQgbm8gc3Via2V5cwogICAgICAgICovCiAgICAgICAgaWYgKG5rLT5ucl92YWx1ZXMgPiAwKSB7CiAgICAgICAgICAgIC8qIHRoZXJlIGFyZSBzb21lIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KICAgICAgICBpZiAoKG5rLT5ucl9zdWJrZXlzID09IDApICYmIChuay0+bnJfdmFsdWVzID09IDApKSB7CiAgICAgICAgICAgIC8qIG5vIHN1YmtleXMgYW5kIG5vIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KCiAgICAgICAgLyogbG9vcCB0cm91Z2ggdGhlIHZhbHVlIGxpc3QgKi8KICAgICAgICB2bCA9IChEV09SRCAqKShiYXNlK25rLT52YWx1ZWxpc3Rfb2ZmKzQpOwogICAgICAgIGZvciAobj0wOyBuPG5rLT5ucl92YWx1ZXM7IG4rKykgewogICAgICAgICAgICBudF92ayAqIHZrID0gKG50X3ZrKikoYmFzZSt2bFtuXSs0KTsKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF92ayhuZXdfa2V5X25hbWUsIGJhc2UsIHZrLCBmKSkgewogICAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSBlbHNlIG5ld19rZXlfbmFtZSA9IF94c3RyZHVwKGtleV9uYW1lKTsKCiAgICAvKiBsb29wIHRocm91Z2ggdGhlIHN1YmtleXMgKi8KICAgIGlmIChuay0+bnJfc3Via2V5cykgewogICAgICAgIG50X2xmICpsZiA9IChudF9sZiopKGJhc2UrbmstPmxmX29mZis0KTsKICAgICAgICBpZiAoIV9udF9kdW1wX2xmKG5ld19rZXlfbmFtZSwgYmFzZSwgbmstPm5yX3N1YmtleXMsIGxmLCBmLCBsZXZlbC0xKSkgewogICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qIGVuZCBudCBsb2FkZXIgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2FsbG9jYXRlX2RlZmF1bHRfa2V5cyBbSW50ZXJuYWxdCiAqIFJlZ2lzdHJ5IGluaXRpYWxpc2F0aW9uLCBhbGxvY2F0ZXMgc29tZSBkZWZhdWx0IGtleXMuCiAqLwpzdGF0aWMgdm9pZCBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzKHZvaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBTdGF0RGF0YVdbXSA9IHsnRCcsJ3knLCduJywnRCcsJ2EnLCd0JywnYScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUCcsJ2UnLCdyJywnZicsJ1MnLCd0JywnYScsJ3QnLCdzJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywndCcsJ2EnLCd0JywnRCcsJ2EnLCd0JywnYScsMH07CiAgICBIS0VZIGhrZXk7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CgogICAgVFJBQ0UoIih2b2lkKVxuIik7CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBTdGF0RGF0YVcgKTsKICAgIGlmICghTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkgTnRDbG9zZSggaGtleSApOwp9CgpzdGF0aWMgdm9pZCBnZXRfd2luZG93c19kaXIoV0NIQVIqIGJ1ZmZlciwgdW5zaWduZWQgbGVuKQp7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyAgIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyAgICAgIG5hbWVXLCBrZXlXOwogICAgSEtFWSAgICAgICAgICAgICAgICBoa2V5OwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgaWYgKFJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsICJNYWNoaW5lXFxTb2Z0d2FyZVxcV2luZVxcV2luZVxcQ29uZmlnXFx3aW5lIiApKQogICAgewogICAgICAgIGlmICghTnRPcGVuS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyICkpCiAgICAgICAgewogICAgICAgICAgICBjaGFyIHRtcFtNQVhfUEFUSE5BTUVfTEVOKnNpemVvZihXQ0hBUikgKyBzaXplb2YoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04pXTsKICAgICAgICAgICAgRFdPUkQgY291bnQ7CgogICAgICAgICAgICBSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJmtleVcsICJXaW5kb3dzIik7CiAgICAgICAgICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5LCAma2V5VywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgICAgICAgICAgbWVtY3B5KGJ1ZmZlciwgc3RyLCBtaW4oKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGFMZW5ndGgsIGxlbikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAma2V5VyApOwogICAgICAgIH0KICAgICAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CiAgICB9Cn0KCgojZGVmaW5lIFJFR19ET05UTE9BRCAtMQojZGVmaW5lIFJFR19XSU4zMSAgICAgMAojZGVmaW5lIFJFR19XSU45NSAgICAgMQojZGVmaW5lIFJFR19XSU5OVCAgICAgMgoKLyogcmV0dXJuIHRoZSB0eXBlIG9mIG5hdGl2ZSByZWdpc3RyeSBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX2dldF9yZWdfdHlwZShjb25zdCBXQ0hBUiogd2luZGlyKQp7CiAgICBXQ0hBUiB0bXBbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBpbnQgcmV0ID0gUkVHX1dJTjMxOwogICAgc3RhdGljIGNvbnN0IFdDSEFSIG50X3JlZ19wYXRoV1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJzMnLCcyJywnXFwnLCdjJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgd2luOXhfcmVnX3BhdGhXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnLicsJ2QnLCdhJywndCcsMH07CgogICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0zMi9jb25maWcvc3lzdGVtIC0tPiB3aW5udCAqLwogICAgc3RyY3B5Vyh0bXAsIHdpbmRpcik7CiAgICBzdHJjYXRXKHRtcCwgbnRfcmVnX3BhdGhXKTsKICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzVyh0bXApICE9IElOVkFMSURfRklMRV9BVFRSSUJVVEVTKQogICAgICByZXQgPSBSRUdfV0lOTlQ7CiAgICBlbHNlCiAgICB7CiAgICAgICAvKiB0ZXN0ICV3aW5kaXIlL3N5c3RlbS5kYXQgLS0+IHdpbjk1ICovCiAgICAgIHN0cmNweVcodG1wLCB3aW5kaXIpOwogICAgICBzdHJjYXRXKHRtcCwgd2luOXhfcmVnX3BhdGhXKTsKICAgICAgaWYoR2V0RmlsZUF0dHJpYnV0ZXNXKHRtcCkgIT0gSU5WQUxJRF9GSUxFX0FUVFJJQlVURVMpCiAgICAgICAgcmV0ID0gUkVHX1dJTjk1OwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCi8qIGxvYWQgdGhlIHJlZ2lzdHJ5IGZpbGUgaW4gd2luZSBmb3JtYXQgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBsb2FkX3dpbmVfcmVnaXN0cnkoSEtFWSBoa2V5LExQQ1NUUiBmbikKewogICAgV0NIQVIgKmJ1ZmZlcjsKICAgIEhBTkRMRSBmaWxlOwogICAgRFdPUkQgbGVuOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZTsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBJT19TVEFUVVNfQkxPQ0sgaW87CgogICAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfVU5JWENQLCAwLCBmbiwgLTEsIE5VTEwsIDAgKTsKICAgIGlmICghKGJ1ZmZlciA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSApKSkgcmV0dXJuOwogICAgTXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfVU5JWENQLCAwLCBmbiwgLTEsIGJ1ZmZlciwgbGVuICk7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWUsIGJ1ZmZlciApOwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZTsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBpZiAoIU50T3BlbkZpbGUoICZmaWxlLCBHRU5FUklDX1JFQUQsICZhdHRyLCAmaW8sIEZJTEVfU0hBUkVfUkVBRCB8IEZJTEVfU0hBUkVfV1JJVEUsCiAgICAgICAgICAgICAgICAgICAgIEZJTEVfTk9OX0RJUkVDVE9SWV9GSUxFIHwgRklMRV9TWU5DSFJPTk9VU19JT19OT05BTEVSVCApKQogICAgewogICAgICAgIFNFUlZFUl9TVEFSVF9SRVEoIGxvYWRfcmVnaXN0cnkgKQogICAgICAgIHsKICAgICAgICAgICAgcmVxLT5oa2V5ICAgID0gaGtleTsKICAgICAgICAgICAgcmVxLT5maWxlICAgID0gZmlsZTsKICAgICAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICAgICAgfQogICAgICAgIFNFUlZFUl9FTkRfUkVROwogICAgICAgIENsb3NlSGFuZGxlKCBmaWxlICk7CiAgICB9CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYnVmZmVyICk7Cn0KCi8qIGdlbmVyYXRlIGFuZCByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHRtcCBmaWxlIGFuZCBhc3NvY2lhdGVkIHN0cmVhbSBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfZ2V0X3RtcF9mbihGSUxFICoqZikKewogICAgTFBTVFIgcmV0OwogICAgaW50IHRtcF9mZCxjb3VudDsKCiAgICByZXQgPSBfeG1hbGxvYyg1MCk7CiAgICBmb3IgKGNvdW50ID0gMDs7KSB7CiAgICAgICAgc3ByaW50ZihyZXQsIi90bXAvcmVnJWx4JTA0eC50bXAiLChsb25nKWdldHBpZCgpLGNvdW50KyspOwogICAgICAgIGlmICgodG1wX2ZkID0gb3BlbihyZXQsT19DUkVBVCB8IE9fRVhDTCB8IE9fV1JPTkxZLDA2NjYpKSAhPSAtMSkgYnJlYWs7CiAgICAgICAgaWYgKGVycm5vICE9IEVFWElTVCkgewogICAgICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgZXJyb3Igd2hpbGUgb3BlbigpIGNhbGw6ICVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgIGZyZWUocmV0KTsKICAgICAgICAgICAgKmYgPSBOVUxMOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCgqZiA9IGZkb3Blbih0bXBfZmQsInciKSkgPT0gTlVMTCkgewogICAgICAgIEVSUigiVW5leHBlY3RlZCBlcnJvciB3aGlsZSBmZG9wZW4oKSBjYWxsOiAlc1xuIixzdHJlcnJvcihlcnJubykpOwogICAgICAgIGNsb3NlKHRtcF9mZCk7CiAgICAgICAgZnJlZShyZXQpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgd2luOTUgbmF0aXZlIHJlZ2lzdHJ5IGZpbGUgdG8gd2luZSBmb3JtYXQgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX2NvbnZlcnRfd2luOTVfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoTFBDV1NUUiBmbiwgaW50IGxldmVsKQp7CiAgICBIQU5ETEUgaEZpbGUsIGhNYXBwaW5nOwogICAgRklMRSAqZjsKICAgIHZvaWQgKmJhc2U7CiAgICBMUFNUUiByZXQgPSBOVUxMOwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIExBUkdFX0lOVEVHRVIgbGdfaW50OwogICAgTlRTVEFUVVMgbnRzOwogICAgU0laRV9UIGxlbjsKCiAgICBfdzk1Y3JlZyAqY3JlZzsKICAgIF93OTVyZ2tuICpyZ2tuOwogICAgX3c5NWRrZSAqZGtlLCAqcm9vdF9ka2U7CgogICAgaEZpbGUgPSBDcmVhdGVGaWxlVyggZm4sIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELCBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwICk7CiAgICBpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CgogICAgYXR0ci5MZW5ndGggICAgICAgICAgICAgICAgICAgPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgICAgICAgICAgICA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgICAgICAgICAgICAgICA9IE5VTEw7CiAgICBhdHRyLkF0dHJpYnV0ZXMgICAgICAgICAgICAgICA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciAgICAgICA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgbGdfaW50LlF1YWRQYXJ0ID0gMDsKICAgIG50cyA9IE50Q3JlYXRlU2VjdGlvbiggJmhNYXBwaW5nLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RBTkRBUkRfUklHSFRTX1JFUVVJUkVEfFNFQ1RJT05fUVVFUll8U0VDVElPTl9NQVBfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF0dHIsICZsZ19pbnQsIFBBR0VfUkVBRE9OTFksIFNFQ19DT01NSVQsIGhGaWxlICk7CiAgICBpZiAobnRzICE9IFNUQVRVU19TVUNDRVNTKSBnb3RvIGVycm9yMTsKCiAgICBiYXNlID0gTlVMTDsgbGVuID0gMDsKICAgIG50cyA9IE50TWFwVmlld09mU2VjdGlvbiggaE1hcHBpbmcsIEdldEN1cnJlbnRQcm9jZXNzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZiYXNlLCAwLCAwLCAmbGdfaW50LCAmbGVuLCBWaWV3U2hhcmUsIDAsIAoJCQkgICAgICBQQUdFX1JFQURPTkxZKTsKICAgIE50Q2xvc2UoIGhNYXBwaW5nICk7CiAgICBpZiAobnRzICE9IFNUQVRVU19TVUNDRVNTKSBnb3RvIGVycm9yMTsKCiAgICAvKiBjb250cm9sIHNpZ25hdHVyZSAqLwogICAgaWYgKCooTFBEV09SRCliYXNlICE9IFc5NV9SRUdfQ1JFR19JRCkgewogICAgICAgIEVSUigidW5hYmxlIHRvIGxvYWQgbmF0aXZlIHdpbjk1IHJlZ2lzdHJ5IGZpbGUgJXM6IHVua25vd24gc2lnbmF0dXJlLlxuIiwKICAgICAgICAgICAgZGVidWdzdHJfdyhmbikpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgY3JlZyA9IGJhc2U7CiAgICAvKiBsb2FkIHRoZSBoZWFkZXIgKHJna24pICovCiAgICByZ2tuID0gKF93OTVyZ2tuKikoY3JlZyArIDEpOwogICAgaWYgKHJna24tPmlkICE9IFc5NV9SRUdfUkdLTl9JRCkgewogICAgICAgIEVSUigic2Vjb25kIElGRiBoZWFkZXIgbm90IFJHS04sIGJ1dCAlbHhcbiIsIHJna24tPmlkKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHJna24tPnJvb3Rfb2ZmICE9IDB4MjApIHsKICAgICAgICBFUlIoInJna24tPnJvb3Rfb2ZmIG5vdCAweDIwLCBwbGVhc2UgcmVwb3J0ICFcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+bGFzdF9ka2UgPiByZ2tuLT5zaXplKQogICAgewogICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgbGFzdF9ka2UgPiBzaXplIVxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICAvKiB2ZXJpZnkgbGFzdCBka2UgKi8KICAgIGRrZSA9IChfdzk1ZGtlKikoKGNoYXIqKXJna24gKyByZ2tuLT5sYXN0X2RrZSk7CiAgICBpZiAoZGtlLT54MSAhPSAweDgwMDAwMDAwKQogICAgeyAvKiB3cm9uZyBtYWdpYyAqLwogICAgICBFUlIoImxhc3QgZGtlIGludmFsaWQgIVxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+c2l6ZSA+IGNyZWctPnJnZGJfb2ZmKQogICAgewogICAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgcmdrbiBzaXplID4gcmdkYl9vZmYgIVxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICByb290X2RrZSA9IChfdzk1ZGtlKikoKGNoYXIqKXJna24gKyByZ2tuLT5yb290X29mZik7CiAgICBpZiAoIChyb290X2RrZS0+cHJldmx2bCAhPSAweGZmZmZmZmZmKSB8fCAocm9vdF9ka2UtPm5leHQgIT0gMHhmZmZmZmZmZikgKQogICAgewogICAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISBpbnZhbGlkIHJvb3QgZGtlICFcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKCAocmV0ID0gX2dldF90bXBfZm4oJmYpKSA9PSBOVUxMKSBnb3RvIGVycm9yOwogICAgZnByaW50ZihmLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gMiIpOwogICAgX3c5NV9kdW1wX2RrZSgiIixjcmVnLHJna24scm9vdF9ka2UsZixsZXZlbCk7CiAgICBmY2xvc2UoZik7CgplcnJvcjoKICAgIGlmKHJldCA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJVbmFibGUgdG8gbG9hZCBuYXRpdmUgd2luOTUgcmVnaXN0cnkgZmlsZSAlcy5cbiIsIGRlYnVnc3RyX3coZm4pKTsKICAgICAgICBFUlIoIlBsZWFzZSByZXBvcnQgdGhpcy5cbiIpOwogICAgICAgIEVSUigiTWFrZSBhIGJhY2t1cCBvZiB0aGUgZmlsZSwgcnVuIGEgZ29vZCByZWcgY2xlYW5lciBwcm9ncmFtIGFuZCB0cnkgYWdhaW4hXG4iKTsKICAgIH0KCiAgICBOdFVubWFwVmlld09mU2VjdGlvbiggR2V0Q3VycmVudFByb2Nlc3MoKSwgYmFzZSApOwplcnJvcjE6CiAgICBOdENsb3NlKGhGaWxlKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGNvbnZlcnQgd2lubnQgbmF0aXZlIHJlZ2lzdHJ5IGZpbGUgdG8gd2luZSBmb3JtYXQgW0ludGVybmFsXSAqLwpzdGF0aWMgTFBTVFIgX2NvbnZlcnRfd2lubnRfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoTFBDV1NUUiBmbiwgaW50IGxldmVsKQp7CiAgICBGSUxFICpmOwogICAgdm9pZCAqYmFzZTsKICAgIExQU1RSIHJldCA9IE5VTEw7CiAgICBIQU5ETEUgaEZpbGU7CiAgICBIQU5ETEUgaE1hcHBpbmc7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgTEFSR0VfSU5URUdFUiBsZ19pbnQ7CiAgICBOVFNUQVRVUyBudHM7CiAgICBTSVpFX1QgbGVuOwoKICAgIG50X3JlZ2YgKnJlZ2Y7CiAgICBudF9oYmluICpoYmluOwogICAgbnRfaGJpbl9zdWIgKmhiaW5fc3ViOwogICAgbnRfbmsgKm5rOwoKICAgIFRSQUNFKCIlc1xuIiwgZGVidWdzdHJfdyhmbikpOwoKICAgIGhGaWxlID0gQ3JlYXRlRmlsZVcoIGZuLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwogICAgaWYgKCBoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSApIHJldHVybiBOVUxMOwogICAgYXR0ci5MZW5ndGggICAgICAgICAgICAgICAgICAgPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgICAgICAgICAgICA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgICAgICAgICAgICAgICA9IE5VTEw7CiAgICBhdHRyLkF0dHJpYnV0ZXMgICAgICAgICAgICAgICA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciAgICAgICA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgbGdfaW50LlF1YWRQYXJ0ID0gMDsKICAgIG50cyA9IE50Q3JlYXRlU2VjdGlvbiggJmhNYXBwaW5nLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RBTkRBUkRfUklHSFRTX1JFUVVJUkVEfFNFQ1RJT05fUVVFUll8U0VDVElPTl9NQVBfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF0dHIsICZsZ19pbnQsIFBBR0VfUkVBRE9OTFksIFNFQ19DT01NSVQsIGhGaWxlICk7CiAgICBpZiAobnRzICE9IFNUQVRVU19TVUNDRVNTKSBnb3RvIGVycm9yMTsKCiAgICBiYXNlID0gTlVMTDsgbGVuID0gMDsKICAgIG50cyA9IE50TWFwVmlld09mU2VjdGlvbiggaE1hcHBpbmcsIEdldEN1cnJlbnRQcm9jZXNzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZiYXNlLCAwLCAwLCAmbGdfaW50LCAmbGVuLCBWaWV3U2hhcmUsIDAsIAoJCQkgICAgICBQQUdFX1JFQURPTkxZKTsKICAgIE50Q2xvc2UoIGhNYXBwaW5nICk7CiAgICBpZiAobnRzICE9IFNUQVRVU19TVUNDRVNTKSBnb3RvIGVycm9yMTsKCiAgICAvKiBjb250cm9sIHNpZ25hdHVyZSAqLwogICAgaWYgKCooTFBEV09SRCliYXNlICE9IE5UX1JFR19IRUFERVJfQkxPQ0tfSUQpIHsKICAgICAgICBFUlIoInVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW5udCByZWdpc3RyeSBmaWxlICVzOiB1bmtub3duIHNpZ25hdHVyZS5cbiIsCiAgICAgICAgICAgIGRlYnVnc3RyX3coZm4pKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIHN0YXJ0IGJsb2NrICovCiAgICByZWdmID0gYmFzZTsKCiAgICAvKiBoYmluIGJsb2NrICovCiAgICBoYmluID0gKG50X2hiaW4qKSgoY2hhciopIGJhc2UgKyAweDEwMDApOwogICAgaWYgKGhiaW4tPmlkICE9IE5UX1JFR19QT09MX0JMT0NLX0lEKSB7CiAgICAgIEVSUiggImhiaW4gYmxvY2sgaW52YWxpZFxuIik7CiAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogaGJpbl9zdWIgYmxvY2sgKi8KICAgIGhiaW5fc3ViID0gKG50X2hiaW5fc3ViKikmKGhiaW4tPmhiaW5fc3ViKTsKICAgIGlmICgoaGJpbl9zdWItPmRhdGFbMF0gIT0gJ24nKSB8fCAoaGJpbl9zdWItPmRhdGFbMV0gIT0gJ2snKSkgewogICAgICBFUlIoICJoYmluX3N1YiBibG9jayBpbnZhbGlkXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBuayBibG9jayAqLwogICAgbmsgPSAobnRfbmsqKSYoaGJpbl9zdWItPmRhdGFbMF0pOwogICAgaWYgKG5rLT5UeXBlICE9IE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKSB7CiAgICAgIEVSUiggInNwZWNpYWwgbmsgYmxvY2sgbm90IGZvdW5kXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAoIChyZXQgPSBfZ2V0X3RtcF9mbigmZikpID09IE5VTEwpIGdvdG8gZXJyb3I7CiAgICBmcHJpbnRmKGYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAyIik7CiAgICBfbnRfZHVtcF9uaygiIiwoY2hhciopYmFzZSsweDEwMDAsbmssZixsZXZlbCk7CiAgICBmY2xvc2UoZik7CgplcnJvcjoKICAgIE50VW5tYXBWaWV3T2ZTZWN0aW9uKCBHZXRDdXJyZW50UHJvY2VzcygpLCBiYXNlICk7CmVycm9yMToKICAgIE50Q2xvc2UoaEZpbGUpOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCBuYXRpdmUgcmVnaXN0cnkgdG8gd2luZSBmb3JtYXQgYW5kIGxvYWQgaXQgdmlhIHNlcnZlciBjYWxsIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KExQQ1dTVFIgZm4sIEhLRVkgaGtleSwgaW50IHJlZ190eXBlLCBpbnQgbGV2ZWwpCnsKICAgIExQU1RSIHRtcCA9IE5VTEw7CgogICAgc3dpdGNoIChyZWdfdHlwZSkgewogICAgICAgIGNhc2UgUkVHX1dJTk5UOgogICAgICAgICAgICAvKiBGSVhNRTogZm9sbG93aW5nIGZ1bmN0aW9uIGRvZXNuJ3QgcmVhbGx5IGNvbnZlcnQgeWV0ICovCiAgICAgICAgICAgIHRtcCA9IF9jb252ZXJ0X3dpbm50X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KGZuLGxldmVsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfV0lOOTU6CiAgICAgICAgICAgIHRtcCA9IF9jb252ZXJ0X3dpbjk1X3JlZ2lzdHJ5X3RvX3dpbmVfZm9ybWF0KGZuLGxldmVsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfV0lOMzE6CiAgICAgICAgICAgIEVSUigiRG9uJ3Qga25vdyBob3cgdG8gY29udmVydCBuYXRpdmUgMy4xIHJlZ2lzdHJ5IHlldC5cbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoIlVua25vd24gcmVnaXN0cnkgZm9ybWF0IHBhcmFtZXRlciAoJWQpXG4iLHJlZ190eXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHRtcCAhPSBOVUxMKSB7CiAgICAgICAgbG9hZF93aW5lX3JlZ2lzdHJ5KGhrZXksdG1wKTsKICAgICAgICBUUkFDRSgiRmlsZSAlcyBzdWNjZXNzZnVsbHkgY29udmVydGVkIHRvICVzIGFuZCBsb2FkZWQgdG8gcmVnaXN0cnkuXG4iLAogICAgICAgICAgICAgIGRlYnVnc3RyX3coZm4pLCB0bXApOwogICAgICAgIHVubGluayh0bXApOwogICAgfQogICAgZWxzZSBXQVJOKCJVbmFibGUgdG8gY29udmVydCAlcyAoZG9lc24ndCBleGlzdD8pXG4iLCBkZWJ1Z3N0cl93KGZuKSk7CiAgICBmcmVlKHRtcCk7Cn0KCi8qIGxvYWQgYWxsIG5hdGl2ZSB3aW5kb3dzIHJlZ2lzdHJ5IGZpbGVzIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX2xvYWRfd2luZG93c19yZWdpc3RyeSggSEtFWSBoa2V5X2xvY2FsX21hY2hpbmUsIEhLRVkgaGtleV9jdXJyZW50X3VzZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgaW50IHJlZ190eXBlOwogICAgV0NIQVIgd2luZGlyW01BWF9QQVRITkFNRV9MRU5dOwogICAgV0NIQVIgcGF0aFtNQVhfUEFUSE5BTUVfTEVOXTsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIEhLRVkgaGtleSwgcHJvZmlsZV9rZXk7CiAgICBjaGFyIHRtcFsxMDI0XTsKICAgIERXT1JEIGR1bW15OwoKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBXaW5lV1tdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1cnLCdpJywnbicsJ2UnLCdcXCcsJ1cnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdXJywnaScsJ24nLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBQcm9maWxlV1tdID0geydQJywncicsJ28nLCdmJywnaScsJ2wnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBTeXN0ZW1bXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywnUycsJ3knLCdzJywndCcsJ2UnLCdtJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBTb2Z0d2FyZVtdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLCdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgQ2xvbmVbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywneScsJ3MnLCd0JywnZScsJ20nLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQycsJ2wnLCdvJywnbicsJ2UnLDB9OwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgV2luZVcgKTsKICAgIGlmIChOdENyZWF0ZUtleSggJnByb2ZpbGVfa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkgcHJvZmlsZV9rZXkgPSAwOwoKICAgIGdldF93aW5kb3dzX2Rpcih3aW5kaXIsIHNpemVvZih3aW5kaXIpKTsKCiAgICByZWdfdHlwZSA9IF9nZXRfcmVnX3R5cGUod2luZGlyKTsKICAgIHN3aXRjaCAocmVnX3R5cGUpIHsKICAgICAgICBjYXNlIFJFR19XSU5OVDogewogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgbnR1c2VyX2RhdFdbXSA9IHsnXFwnLCduJywndCcsJ3UnLCdzJywnZScsJ3InLCcuJywnZCcsJ2EnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIGRlZmF1bHRXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywnZCcsJ2UnLCdmJywnYScsJ3UnLCdsJywndCcsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzeXN0ZW1XW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHNvZnR3YXJlV1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJzMnLCcyJywnXFwnLCdjJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ3MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHNhbVdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdzJywnYScsJ20nLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc2VjdXJpdHlXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywncycsJ2UnLCdjJywndScsJ3InLCdpJywndCcsJ3knLDB9OwoKICAgICAgICAgICAgLyogdXNlciBzcGVjaWZpYyBudHVzZXIuZGF0ICovCiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFByb2ZpbGVXICk7CiAgICAgICAgICAgIGlmIChwcm9maWxlX2tleSAmJiAhTnRRdWVyeVZhbHVlS2V5KCBwcm9maWxlX2tleSwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcCwgc2l6ZW9mKHRtcCksICZkdW1teSApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgbnR1c2VyX2RhdFcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9jdXJyZW50X3VzZXIsUkVHX1dJTk5ULDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTUVTU0FHRSgiV2hlbiB5b3UgYXJlIHJ1bm5pbmcgd2l0aCBhIG5hdGl2ZSBOVCBkaXJlY3Rvcnkgc3BlY2lmeVxuIik7CiAgICAgICAgICAgICAgICBNRVNTQUdFKCInUHJvZmlsZT08cHJvZmlsZWRpcmVjdG9yeT4nIG9yIGRpc2FibGUgbG9hZGluZyBvZiBXaW5kb3dzXG4iKTsKICAgICAgICAgICAgICAgIE1FU1NBR0UoInJlZ2lzdHJ5IChMb2FkV2luZG93c1JlZ2lzdHJ5RmlsZXM9TilcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGRlZmF1bHQgdXNlci5kYXQgKi8KICAgICAgICAgICAgaWYgKGhrZXlfdXNlcnNfZGVmYXVsdCkgewogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBkZWZhdWx0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X3VzZXJzX2RlZmF1bHQsUkVHX1dJTk5ULDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAqIEZJWE1FCiAgICAgICAgICAgICogIG1hcCBITE1cU3lzdGVtXENvbnRyb2xTZXQwMDEgdG8gSExNXFN5c3RlbVxDdXJyZW50Q29udHJvbFNldAogICAgICAgICAgICAqLwogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBTeXN0ZW0gKTsKICAgICAgICAgICAgaWYgKCFOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHN5c3RlbVcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleSxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgICAgICBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgU29mdHdhcmUgKTsKICAgICAgICAgICAgaWYgKCFOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHNvZnR3YXJlVyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5LFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHNhbVcpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2xvY2FsX21hY2hpbmUsUkVHX1dJTk5ULDApOwoKICAgICAgICAgICAgc3RyY3B5VyhwYXRoLHdpbmRpcik7CiAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgc2VjdXJpdHlXKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9sb2NhbF9tYWNoaW5lLFJFR19XSU5OVCwwKTsKCiAgICAgICAgICAgIC8qIHRoaXMga2V5IGlzIGdlbmVyYXRlZCB3aGVuIHRoZSBudC1jb3JlIGJvb3RlZCBzdWNjZXNzZnVsbHkgKi8KICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgQ2xvbmUgKTsKICAgICAgICAgICAgaWYgKCFOdENyZWF0ZUtleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKSBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBSRUdfV0lOOTU6CiAgICAgICAgewogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3lzdGVtXzFzdFdbXSA9IHsnYycsJzonLCdcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJy4nLCcxJywncycsJ3QnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3lzdGVtX2RhdFdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCcuJywnZCcsJ2EnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIGNsYXNzZXNfZGF0V1tdID0geydcXCcsJ2MnLCdsJywnYScsJ3MnLCdzJywnZScsJ3MnLCcuJywnZCcsJ2EnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHVzZXJfZGF0V1tdID0geydcXCcsJ3UnLCdzJywnZScsJ3InLCcuJywnZCcsJ2EnLCd0JywwfTsKCiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShzeXN0ZW1fMXN0Vyxoa2V5X2xvY2FsX21hY2hpbmUsUkVHX1dJTjk1LDApOwoKICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHN5c3RlbV9kYXRXKTsKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV9sb2NhbF9tYWNoaW5lLFJFR19XSU45NSwwKTsKCiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIENsYXNzZXNSb290VyApOwogICAgICAgICAgICBpZiAoIU50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgY2xhc3Nlc19kYXRXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXksUkVHX1dJTjk1LDApOwogICAgICAgICAgICAgICAgTnRDbG9zZSggaGtleSApOwogICAgICAgICAgICB9CgogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBQcm9maWxlVyApOwogICAgICAgICAgICBpZiAocHJvZmlsZV9rZXkgJiYgIU50UXVlcnlWYWx1ZUtleSggcHJvZmlsZV9rZXksICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAsIHNpemVvZih0bXApLCAmZHVtbXkgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogdXNlciBzcGVjaWZpYyB1c2VyLmRhdCAqLwogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YSk7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHVzZXJfZGF0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2N1cnJlbnRfdXNlcixSRUdfV0lOOTUsMSk7CgoJICAgICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCgkgICAgICAgIGlmIChoa2V5X3VzZXJzX2RlZmF1bHQpIHsKICAgICAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCB1c2VyX2RhdFcpOwogICAgICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfdXNlcnNfZGVmYXVsdCxSRUdfV0lOOTUsMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHVzZXJfZGF0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2N1cnJlbnRfdXNlcixSRUdfV0lOOTUsMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIFJFR19XSU4zMToKICAgICAgICB7CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiByZWdfZGF0V1tdID0geydcXCcsJ3InLCdlJywnZycsJy4nLCdkJywnYScsJ3QnLDB9OwogICAgICAgICAgICAvKiBGSVhNRTogaGVyZSB3ZSBzaG91bGQgY29udmVydCB0byAqLnJlZyBmaWxlIHN1cHBvcnRlZCBieSBzZXJ2ZXIgYW5kIGNhbGwgUkVRX0xPQURfUkVHSVNUUlksIHNlZSBSRUdfV0lOOTUgY2FzZSAqLwogICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgcmVnX2RhdFcpOwogICAgICAgICAgICBfdzMxX2xvYWRyZWcoIHBhdGggKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIFJFR19ET05UTE9BRDoKICAgICAgICAgICAgVFJBQ0UoIlJFR19ET05UTE9BRFxuIik7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoInN3aXRjaDogbm8gbWF0Y2ggKCVkKVxuIixyZWdfdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgIH0KICAgIGlmIChwcm9maWxlX2tleSkgTnRDbG9zZSggcHJvZmlsZV9rZXkgKTsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlpbml0X2Nkcm9tX3JlZ2lzdHJ5CiAqCiAqIEluaXRpYWxpemVzIHJlZ2lzdHJ5IHRvIGNvbnRhaW4gc2NzaSBpbmZvIGFib3V0IHRoZSBjZHJvbSBpbiBOVC4KICogQWxsIGRldmljZXMgKGV2ZW4gbm90IHJlYWwgc2NzaSBvbmVzKSBoYXZlIHRoaXMgaW5mbyBpbiBOVC4KICogVE9ETzogZm9yIG5vdyBpdCBvbmx5IHdvcmtzIGZvciBub24gc2NzaSBkZXZpY2VzCiAqIE5PVEU6IHByb2dyYW1zIHVzdWFsbHkgcmVhZCB0aGVzZSByZWdpc3RyeSBlbnRyaWVzIGFmdGVyIHNlbmRpbmcgdGhlCiAqICAgICAgIElPQ1RMX1NDU0lfR0VUX0FERFJFU1MgaW9jdGwgdG8gdGhlIGNkcm9tCiAqLwpzdGF0aWMgdm9pZCBpbml0X2Nkcm9tX3JlZ2lzdHJ5KCBIQU5ETEUgaGFuZGxlICkKewogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgV0NIQVIgZGF0YVdbNTBdOwogICAgRFdPUkQgbGVuVzsKICAgIGNoYXIgYnVmZmVyWzQwXTsKICAgIERXT1JEIHZhbHVlOwogICAgY29uc3QgY2hhciAqZGF0YTsKICAgIEhLRVkgc2NzaUtleTsKICAgIEhLRVkgcG9ydEtleTsKICAgIEhLRVkgYnVzS2V5OwogICAgSEtFWSB0YXJnZXRLZXk7CiAgICBEV09SRCBkaXNwOwogICAgSU9fU1RBVFVTX0JMT0NLIGlvOwogICAgU0NTSV9BRERSRVNTIHNjc2lfYWRkcjsKCiAgICBpZiAoTnREZXZpY2VJb0NvbnRyb2xGaWxlKCBoYW5kbGUsIDAsIE5VTEwsIE5VTEwsICZpbywgSU9DVExfU0NTSV9HRVRfQUREUkVTUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIDAsICZzY3NpX2FkZHIsIHNpemVvZihzY3NpX2FkZHIpICkpCiAgICAgICAgcmV0dXJuOwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CgogICAgLyogRW5zdXJlIHRoZXJlIGlzIFNjc2kga2V5ICovCiAgICBpZiAoIVJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsICJNYWNoaW5lXFxIQVJEV0FSRVxcREVWSUNFTUFQXFxTY3NpIiApIHx8CiAgICAgICAgTnRDcmVhdGVLZXkoICZzY3NpS2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsCiAgICAgICAgICAgICAgICAgICAgIE5VTEwsIFJFR19PUFRJT05fVk9MQVRJTEUsICZkaXNwICkpCiAgICB7CiAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIERFVklDRU1BUFxcU2NzaSByZWdpc3RyeSBrZXlcbiIgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CgogICAgc25wcmludGYoYnVmZmVyLHNpemVvZihidWZmZXIpLCJTY3NpIFBvcnQgJWQiLHNjc2lfYWRkci5Qb3J0TnVtYmVyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IHNjc2lLZXk7CiAgICBpZiAoIVJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsIGJ1ZmZlciApIHx8CiAgICAgICAgTnRDcmVhdGVLZXkoICZwb3J0S2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsCiAgICAgICAgICAgICAgICAgICAgIE5VTEwsIFJFR19PUFRJT05fVk9MQVRJTEUsICZkaXNwICkpCiAgICB7CiAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIERFVklDRU1BUFxcU2NzaSBQb3J0IHJlZ2lzdHJ5IGtleVxuIiApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAmbmFtZVcgKTsKCiAgICBSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCAiRHJpdmVyIiApOwogICAgZGF0YSA9ICJhdGFwaSI7CiAgICBSdGxNdWx0aUJ5dGVUb1VuaWNvZGVOKCBkYXRhVywgNTAsICZsZW5XLCBkYXRhLCBzdHJsZW4oZGF0YSkpOwogICAgTnRTZXRWYWx1ZUtleSggcG9ydEtleSwgJm5hbWVXLCAwLCBSRUdfU1osIChCWVRFKilkYXRhVywgbGVuVyApOwogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwogICAgdmFsdWUgPSAxMDsKICAgIFJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsICJGaXJzdEJ1c1RpbWVTY2FuSW5NcyIgKTsKICAgIE50U2V0VmFsdWVLZXkoIHBvcnRLZXksJm5hbWVXLCAwLCBSRUdfRFdPUkQsIChCWVRFICopJnZhbHVlLCBzaXplb2YoRFdPUkQpKTsKICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAmbmFtZVcgKTsKICAgIHZhbHVlID0gMDsKI2lmZGVmIEhESU9fR0VUX0RNQQogICAgewogICAgICAgIGludCBmZCwgZG1hOwogICAgICAgIGlmICghd2luZV9zZXJ2ZXJfaGFuZGxlX3RvX2ZkKCBoYW5kbGUsIDAsICZmZCwgTlVMTCwgTlVMTCApKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGlvY3RsKGZkLEhESU9fR0VUX0RNQSwgJmRtYSkgIT0gLTEpIHZhbHVlID0gZG1hOwogICAgICAgICAgICB3aW5lX3NlcnZlcl9yZWxlYXNlX2ZkKCBoYW5kbGUsIGZkICk7CiAgICAgICAgfQogICAgfQojZW5kaWYKICAgIFJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsICJETUFFbmFibGVkIiApOwogICAgTnRTZXRWYWx1ZUtleSggcG9ydEtleSwmbmFtZVcsIDAsIFJFR19EV09SRCwgKEJZVEUgKikmdmFsdWUsIHNpemVvZihEV09SRCkpOwogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwoKICAgIHNucHJpbnRmKGJ1ZmZlciw0MCwiU2NzaSBCdXMgJWQiLCBzY3NpX2FkZHIuUGF0aElkKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IHBvcnRLZXk7CiAgICBpZiAoIVJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsIGJ1ZmZlciApIHx8CiAgICAgICAgTnRDcmVhdGVLZXkoICZidXNLZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwKICAgICAgICAgICAgICAgICAgICAgTlVMTCwgUkVHX09QVElPTl9WT0xBVElMRSwgJmRpc3AgKSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBjcmVhdGUgREVWSUNFTUFQXFxTY3NpIFBvcnRcXFNjc2kgQnVzIHJlZ2lzdHJ5IGtleVxuIiApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAmbmFtZVcgKTsKCiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBidXNLZXk7CiAgICBpZiAoIVJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsICJJbml0aWF0b3IgSWQgMjU1IiApIHx8CiAgICAgICAgTnRDcmVhdGVLZXkoICZ0YXJnZXRLZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwKICAgICAgICAgICAgICAgICAgICAgTlVMTCwgUkVHX09QVElPTl9WT0xBVElMRSwgJmRpc3AgKSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBjcmVhdGUgREVWSUNFTUFQXFxTY3NpIFBvcnRcXFNjc2kgQnVzXFxJbml0aWF0b3IgSWQgMjU1IHJlZ2lzdHJ5IGtleVxuIiApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAmbmFtZVcgKTsKICAgIE50Q2xvc2UoIHRhcmdldEtleSApOwoKICAgIHNucHJpbnRmKGJ1ZmZlciw0MCwiVGFyZ2V0IElkICVkIiwgc2NzaV9hZGRyLlRhcmdldElkKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IGJ1c0tleTsKICAgIGlmICghUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZuYW1lVywgYnVmZmVyICkgfHwKICAgICAgICBOdENyZWF0ZUtleSggJnRhcmdldEtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLAogICAgICAgICAgICAgICAgICAgICBOVUxMLCBSRUdfT1BUSU9OX1ZPTEFUSUxFLCAmZGlzcCApKQogICAgewogICAgICAgIEVSUigiQ2Fubm90IGNyZWF0ZSBERVZJQ0VNQVBcXFNjc2kgUG9ydFxcU2NzaSBCdXMgMFxcVGFyZ2V0IElkIHJlZ2lzdHJ5IGtleVxuIiApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAmbmFtZVcgKTsKCiAgICBSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCAiVHlwZSIgKTsKICAgIGRhdGEgPSAiQ2RSb21QZXJpcGhlcmFsIjsKICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4oIGRhdGFXLCA1MCwgJmxlblcsIGRhdGEsIHN0cmxlbihkYXRhKSk7CiAgICBOdFNldFZhbHVlS2V5KCB0YXJnZXRLZXksICZuYW1lVywgMCwgUkVHX1NaLCAoQllURSopZGF0YVcsIGxlblcgKTsKICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAmbmFtZVcgKTsKICAgIC8qIEZJWE1FIC0gbWF5YmUgcmVhZCB0aGUgcmVhbCBpZGVudGlmaWVyPz8gKi8KICAgIFJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsICJJZGVudGlmaWVyIiApOwogICAgZGF0YSA9ICJXaW5lIENEUk9NIjsKICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4oIGRhdGFXLCA1MCwgJmxlblcsIGRhdGEsIHN0cmxlbihkYXRhKSk7CiAgICBOdFNldFZhbHVlS2V5KCB0YXJnZXRLZXksICZuYW1lVywgMCwgUkVHX1NaLCAoQllURSopZGF0YVcsIGxlblcgKTsKICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAmbmFtZVcgKTsKICAgIC8qIEZJWE1FIC0gd2UgYWx3YXlzIHVzZSBDZHJvbTAgLSBkbyBub3Qga25vdyBhYm91dCB0aGUgbnQgYmVoYXZpb3VyICovCiAgICBSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCAiRGV2aWNlTmFtZSIgKTsKICAgIGRhdGEgPSAiQ2Ryb20wIjsKICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4oIGRhdGFXLCA1MCwgJmxlblcsIGRhdGEsIHN0cmxlbihkYXRhKSk7CiAgICBOdFNldFZhbHVlS2V5KCB0YXJnZXRLZXksICZuYW1lVywgMCwgUkVHX1NaLCAoQllURSopZGF0YVcsIGxlblcgKTsKICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAmbmFtZVcgKTsKCiAgICBOdENsb3NlKCB0YXJnZXRLZXkgKTsKICAgIE50Q2xvc2UoIGJ1c0tleSApOwogICAgTnRDbG9zZSggcG9ydEtleSApOwogICAgTnRDbG9zZSggc2NzaUtleSApOwp9CgoKLyogY3JlYXRlIHRoZSBoYXJkd2FyZSByZWdpc3RyeSBicmFuY2ggKi8Kc3RhdGljIHZvaWQgY3JlYXRlX2hhcmR3YXJlX2JyYW5jaCh2b2lkKQp7CiAgICBpbnQgaTsKICAgIEhBTkRMRSBoYW5kbGU7CiAgICBjaGFyIGRyaXZlW10gPSAiXFxcXC5cXEE6IjsKCiAgICAvKiBjcmVhdGUgZW50cmllcyBmb3IgY2Ryb21zICovCiAgICBmb3IgKGkgPSAwOyBpIDwgMjY7IGkrKykKICAgIHsKICAgICAgICBkcml2ZVs0XSA9ICdBJyArIGk7CiAgICAgICAgaGFuZGxlID0gQ3JlYXRlRmlsZUEoIGRyaXZlLCAwLCAwLCBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwICk7CiAgICAgICAgaWYgKGhhbmRsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgY29udGludWU7CiAgICAgICAgaW5pdF9jZHJvbV9yZWdpc3RyeSggaGFuZGxlICk7CiAgICAgICAgQ2xvc2VIYW5kbGUoIGhhbmRsZSApOwogICAgfQp9CgoKLyogY29udmVydCB0aGUgZHJpdmUgdHlwZSBlbnRyaWVzIGZyb20gdGhlIG9sZCBmb3JtYXQgdG8gdGhlIG5ldyBvbmUgKi8Kc3RhdGljIHZvaWQgY29udmVydF9kcml2ZV90eXBlcyh2b2lkKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgVHlwZVdbXSA9IHsnVCcsJ3knLCdwJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgZHJpdmVfdHlwZXNfa2V5V1tdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRCcsJ3InLCdpJywndicsJ2UnLCdzJywwIH07CiAgICBXQ0hBUiBkcml2ZVdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAnVycsJ2knLCduJywnZScsJ1xcJywnVycsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICdDJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ0QnLCdyJywnaScsJ3YnLCdlJywnICcsJ0EnLDB9OwogICAgY2hhciB0bXBbMzIqc2l6ZW9mKFdDSEFSKSArIHNpemVvZihLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTildOwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgRFdPUkQgZHVtbXk7CiAgICBVTE9ORyBkaXNwOwogICAgSEtFWSBoa2V5X29sZCwgaGtleV9uZXc7CiAgICBpbnQgaTsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgZHJpdmVfdHlwZXNfa2V5VyApOwoKICAgIGlmIChOdENyZWF0ZUtleSggJmhrZXlfbmV3LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsICZkaXNwICkpIHJldHVybjsKICAgIGlmIChkaXNwICE9IFJFR19DUkVBVEVEX05FV19LRVkpCiAgICB7CiAgICAgICAgTnRDbG9zZSggaGtleV9uZXcgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8IDI2OyBpKyspCiAgICB7CiAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgZHJpdmVXICk7CiAgICAgICAgbmFtZVcuQnVmZmVyWyhuYW1lVy5MZW5ndGggLyBzaXplb2YoV0NIQVIpKSAtIDFdID0gJ0EnICsgaTsKICAgICAgICBpZiAoTnRPcGVuS2V5KCAmaGtleV9vbGQsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciApICE9IFNUQVRVU19TVUNDRVNTKSBjb250aW51ZTsKICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBUeXBlVyApOwogICAgICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X29sZCwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgdG1wLCBzaXplb2YodG1wKSwgJmR1bW15ICkpCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiB2YWx1ZVdbXSA9IHsnQScsJzonLDB9OwogICAgICAgICAgICBXQ0hBUiAqdHlwZSA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwoKICAgICAgICAgICAgdmFsdWVXWzBdID0gJ0EnICsgaTsKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdmFsdWVXICk7CiAgICAgICAgICAgIE50U2V0VmFsdWVLZXkoIGhrZXlfbmV3LCAmbmFtZVcsIDAsIFJFR19TWiwgdHlwZSwgKHN0cmxlblcodHlwZSkgKyAxKSAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICAgICAgTUVTU0FHRSggIkNvbnZlcnRlZCBkcml2ZSB0eXBlIHRvIG5ldyBlbnRyeSBIS0xNXFxTb2Z0d2FyZVxcV2luZVxcRHJpdmVzIFwiJWM6XCIgPSAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgJ0EnICsgaSwgZGVidWdzdHJfdyh0eXBlKSApOwogICAgICAgIH0KICAgICAgICBOdENsb3NlKCBoa2V5X29sZCApOwogICAgfQogICAgTnRDbG9zZSggaGtleV9uZXcgKTsKfQoKCi8qIGNvbnZlcnQgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIGVudHJpZXMgZnJvbSB0aGUgb2xkIGZvcm1hdCB0byB0aGUgbmV3IG9uZSAqLwpzdGF0aWMgdm9pZCBjb252ZXJ0X2Vudmlyb25tZW50KCBIS0VZIGhrZXlfY3VycmVudF91c2VyICkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHdpbmVXW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVycsJ2knLCduJywnZScsJ1xcJywnVycsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ1cnLCdpJywnbicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHdpbmRvd3NXW10gPSB7J3cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN5c3RlbVdbXSA9IHsncycsJ3knLCdzJywndCcsJ2UnLCdtJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB3aW5kaXJXW10gPSB7J3cnLCdpJywnbicsJ2QnLCdpJywncicsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgd2luc3lzZGlyV1tdID0geyd3JywnaScsJ24nLCdzJywneScsJ3MnLCdkJywnaScsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGVudldbXSA9IHsnRScsJ24nLCd2JywnaScsJ3InLCdvJywnbicsJ20nLCdlJywnbicsJ3QnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHRlbXBXW10gPSB7J1QnLCdFJywnTScsJ1AnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHRtcFdbXSA9IHsnVCcsJ00nLCdQJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBwYXRoV1tdID0geydQJywnQScsJ1QnLCdIJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBwcm9maWxlV1tdID0geydwJywncicsJ28nLCdmJywnaScsJ2wnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB1c2VycHJvZmlsZVdbXSA9IHsnVScsJ1MnLCdFJywnUicsJ1AnLCdSJywnTycsJ0YnLCdJJywnTCcsJ0UnLDB9OwoKICAgIGNoYXIgYnVmZmVyWzEwMjQqc2l6ZW9mKFdDSEFSKSArIHNpemVvZihLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTildOwogICAgS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKmluZm8gPSAoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKilidWZmZXI7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBEV09SRCBkdW1teTsKICAgIFVMT05HIGRpc3A7CiAgICBIS0VZIGhrZXlfb2xkLCBoa2V5X2VudjsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgd2luZVcgKTsKCiAgICBpZiAoTnRPcGVuS2V5KCAmaGtleV9vbGQsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciApICE9IFNUQVRVU19TVUNDRVNTKSByZXR1cm47CgogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gaGtleV9jdXJyZW50X3VzZXI7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBlbnZXICk7CiAgICBpZiAoTnRDcmVhdGVLZXkoICZoa2V5X2VudiwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCAmZGlzcCApKQogICAgewogICAgICAgIE50Q2xvc2UoIGhrZXlfb2xkICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGRpc3AgIT0gUkVHX0NSRUFURURfTkVXX0tFWSkgZ290byBkb25lOwoKICAgIC8qIGNvbnZlcnQgVEVNUCAqLwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdGVtcFcgKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X29sZCwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgJmR1bW15ICkpCiAgICB7CiAgICAgICAgTnRTZXRWYWx1ZUtleSggaGtleV9lbnYsICZuYW1lVywgMCwgaW5mby0+VHlwZSwgaW5mby0+RGF0YSwgaW5mby0+RGF0YUxlbmd0aCApOwogICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIHRtcFcgKTsKICAgICAgICBOdFNldFZhbHVlS2V5KCBoa2V5X2VudiwgJm5hbWVXLCAwLCBpbmZvLT5UeXBlLCBpbmZvLT5EYXRhLCBpbmZvLT5EYXRhTGVuZ3RoICk7CiAgICAgICAgTUVTU0FHRSggIkNvbnZlcnRlZCB0ZW1wIGRpciB0byBuZXcgZW50cnkgSEtDVVxcRW52aXJvbm1lbnQgXCJURU1QXCIgPSAlc1xuIiwKICAgICAgICAgICAgICAgICBkZWJ1Z3N0cl93KCAoV0NIQVIqKWluZm8tPkRhdGEgKSApOwogICAgfQoKICAgIC8qIGNvbnZlcnQgUEFUSCAqLwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgcGF0aFcgKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X29sZCwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgJmR1bW15ICkpCiAgICB7CiAgICAgICAgTnRTZXRWYWx1ZUtleSggaGtleV9lbnYsICZuYW1lVywgMCwgaW5mby0+VHlwZSwgaW5mby0+RGF0YSwgaW5mby0+RGF0YUxlbmd0aCApOwogICAgICAgIE1FU1NBR0UoICJDb252ZXJ0ZWQgcGF0aCBkaXIgdG8gbmV3IGVudHJ5IEhLQ1VcXEVudmlyb25tZW50IFwiUEFUSFwiID0gJXNcbiIsCiAgICAgICAgICAgICAgICAgZGVidWdzdHJfdyggKFdDSEFSKilpbmZvLT5EYXRhICkgKTsKICAgIH0KCiAgICAvKiBjb252ZXJ0IFVTRVJQUk9GSUxFICovCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBwcm9maWxlVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfb2xkLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCBidWZmZXIsIHNpemVvZihidWZmZXIpLCAmZHVtbXkgKSkKICAgIHsKICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCB1c2VycHJvZmlsZVcgKTsKICAgICAgICBOdFNldFZhbHVlS2V5KCBoa2V5X2VudiwgJm5hbWVXLCAwLCBpbmZvLT5UeXBlLCBpbmZvLT5EYXRhLCBpbmZvLT5EYXRhTGVuZ3RoICk7CiAgICAgICAgTUVTU0FHRSggIkNvbnZlcnRlZCBwcm9maWxlIGRpciB0byBuZXcgZW50cnkgSEtDVVxcRW52aXJvbm1lbnQgXCJVU0VSUFJPRklMRVwiID0gJXNcbiIsCiAgICAgICAgICAgICAgICAgZGVidWdzdHJfdyggKFdDSEFSKilpbmZvLT5EYXRhICkgKTsKICAgIH0KCiAgICAvKiBjb252ZXJ0IHdpbmRpciAqLwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgd2luZG93c1cgKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X29sZCwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgJmR1bW15ICkpCiAgICB7CiAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgd2luZGlyVyApOwogICAgICAgIE50U2V0VmFsdWVLZXkoIGhrZXlfZW52LCAmbmFtZVcsIDAsIGluZm8tPlR5cGUsIGluZm8tPkRhdGEsIGluZm8tPkRhdGFMZW5ndGggKTsKICAgICAgICBNRVNTQUdFKCAiQ29udmVydGVkIHdpbmRvd3MgZGlyIHRvIG5ldyBlbnRyeSBIS0NVXFxFbnZpcm9ubWVudCBcIndpbmRpclwiID0gJXNcbiIsCiAgICAgICAgICAgICAgICAgZGVidWdzdHJfdyggKFdDSEFSKilpbmZvLT5EYXRhICkgKTsKICAgIH0KCiAgICAvKiBjb252ZXJ0IHdpbnN5c2RpciAqLwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgc3lzdGVtVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfb2xkLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCBidWZmZXIsIHNpemVvZihidWZmZXIpLCAmZHVtbXkgKSkKICAgIHsKICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCB3aW5zeXNkaXJXICk7CiAgICAgICAgTnRTZXRWYWx1ZUtleSggaGtleV9lbnYsICZuYW1lVywgMCwgaW5mby0+VHlwZSwgaW5mby0+RGF0YSwgaW5mby0+RGF0YUxlbmd0aCApOwogICAgICAgIE1FU1NBR0UoICJDb252ZXJ0ZWQgc3lzdGVtIGRpciB0byBuZXcgZW50cnkgSEtDVVxcRW52aXJvbm1lbnQgXCJ3aW5zeXNkaXJcIiA9ICVzXG4iLAogICAgICAgICAgICAgICAgIGRlYnVnc3RyX3coIChXQ0hBUiopaW5mby0+RGF0YSApICk7CiAgICB9Cgpkb25lOgogICAgTnRDbG9zZSggaGtleV9vbGQgKTsKICAgIE50Q2xvc2UoIGhrZXlfZW52ICk7Cn0KCgovKiBsb2FkIGFsbCByZWdpc3RyeSAobmF0aXZlIGFuZCBnbG9iYWwgYW5kIGhvbWUpICovCnZvaWQgU0hFTExfTG9hZFJlZ2lzdHJ5KCB2b2lkICkKewogICAgSEtFWSBoa2V5X2xvY2FsX21hY2hpbmUsIGhrZXlfdXNlcnMsIGhrZXlfdXNlcnNfZGVmYXVsdCwgaGtleV9jdXJyZW50X3VzZXIsIGhrZXlfY29uZmlnOwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgRFdPUkQgY291bnQ7CiAgICBVTE9ORyBkaXNwb3M7CiAgICBCT09MIHJlczsKICAgIGludCBhbGwsIHBlcmlvZDsKICAgIGNoYXIgdG1wWzEwMjRdOwoKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBNYWNoaW5lV1tdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBVc2VyV1tdID0geydVJywncycsJ2UnLCdyJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBEZWZhdWx0V1tdID0geycuJywnRCcsJ2UnLCdmJywnYScsJ3UnLCdsJywndCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgUmVnaXN0cnlXW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCd5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsb2FkX3dpbl9yZWdfZmlsZXNXW10gPSB7J0wnLCdvJywnYScsJ2QnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLCdGJywnaScsJ2wnLCdlJywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgbG9hZF9nbG9iYWxfcmVnX2ZpbGVzV1tdID0geydMJywnbycsJ2EnLCdkJywnRycsJ2wnLCdvJywnYicsJ2EnLCdsJywnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLCdGJywnaScsJ2wnLCdlJywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgU2F2ZU9ubHlVcGRhdGVkS2V5c1dbXSA9IHsnUycsJ2EnLCd2JywnZScsJ08nLCduJywnbCcsJ3knLCdVJywncCcsJ2QnLCdhJywndCcsJ2UnLCdkJywnSycsJ2UnLCd5JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgUGVyaW9kaWNTYXZlV1tdID0geydQJywnZScsJ3InLCdpJywnbycsJ2QnLCdpJywnYycsJ1MnLCdhJywndicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIEdsb2JhbFJlZ2lzdHJ5RGlyV1tdID0geydHJywnbCcsJ28nLCdiJywnYScsJ2wnLCdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywneScsJ0QnLCdpJywncicsMH07CgogICAgVFJBQ0UoIih2b2lkKVxuIik7CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBVc2VyVyApOwogICAgTnRDcmVhdGVLZXkoICZoa2V5X3VzZXJzLCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsICZkaXNwb3MgKTsKICAgIGlmIChkaXNwb3MgPT0gUkVHX09QRU5FRF9FWElTVElOR19LRVkpCiAgICB7CiAgICAgICAgLyogc29tZW9uZSBlbHNlIGFscmVhZHkgbG9hZGVkIHRoZSByZWdpc3RyeSAqLwogICAgICAgIE50Q2xvc2UoIGhrZXlfdXNlcnMgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgTWFjaGluZVcgKTsKICAgIE50Q3JlYXRlS2V5KCAmaGtleV9sb2NhbF9tYWNoaW5lLCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKTsKCiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5X3VzZXJzOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgRGVmYXVsdFcgKTsKICAgIGlmIChOdENyZWF0ZUtleSggJmhrZXlfdXNlcnNfZGVmYXVsdCwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICB7CiAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIEhLRVlfVVNFUlMvLkRlZmF1bHRcbiIgKTsKICAgICAgICBFeGl0UHJvY2VzcygxKTsKICAgIH0KICAgIFJ0bE9wZW5DdXJyZW50VXNlciggS0VZX0FMTF9BQ0NFU1MsICZoa2V5X2N1cnJlbnRfdXNlciApOwoKICAgIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXMoKTsKCiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgUmVnaXN0cnlXICk7CiAgICBpZiAoTnRPcGVuS2V5KCAmaGtleV9jb25maWcsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciApKSBoa2V5X2NvbmZpZyA9IDA7CgogICAgLyogbG9hZCB3aW5kb3dzIHJlZ2lzdHJ5IGlmIHJlcXVpcmVkICovCgogICAgcmVzID0gVFJVRTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IGhrZXlfY29uZmlnOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgbG9hZF93aW5fcmVnX2ZpbGVzVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgcmVzID0gIUlTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQogICAgaWYgKHJlcykgX2xvYWRfd2luZG93c19yZWdpc3RyeSggaGtleV9sb2NhbF9tYWNoaW5lLCBoa2V5X2N1cnJlbnRfdXNlciwgaGtleV91c2Vyc19kZWZhdWx0ICk7CgogICAgLyogbG9hZCBnbG9iYWwgcmVnaXN0cnkgaWYgcmVxdWlyZWQgKi8KCiAgICByZXMgPSBUUlVFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgbG9hZF9nbG9iYWxfcmVnX2ZpbGVzVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgcmVzID0gIUlTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQogICAgaWYgKHJlcykKICAgIHsKICAgICAgICAvKiBsb2FkIGdsb2JhbCByZWdpc3RyeSBmaWxlcyAoc3RvcmVkIGluIC9ldGMvd2luZSkgKi8KICAgICAgICBjaGFyICpwLCBjb25maWdmaWxlW01BWF9QQVRITkFNRV9MRU5dOwoKICAgICAgICAvKiBPdmVycmlkZSBFVENESVI/ICovCiAgICAgICAgY29uZmlnZmlsZVswXSA9IDA7CiAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgR2xvYmFsUmVnaXN0cnlEaXJXICk7CiAgICAgICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICAgICAgUnRsVW5pY29kZVRvTXVsdGlCeXRlTiggY29uZmlnZmlsZSwgc2l6ZW9mKGNvbmZpZ2ZpbGUpLCBOVUxMLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyLCAoc3RybGVuVyhzdHIpICsgMSkgKiBzaXplb2YoV0NIQVIpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGNvbmZpZ2ZpbGVbMF0gIT0gJy8nKSBzdHJjcHkoY29uZmlnZmlsZSwgRVRDRElSKTsKCiAgICAgICAgVFJBQ0UoIkdsb2JhbFJlZ2lzdHJ5RGlyIGlzICclcycuXG4iLCBjb25maWdmaWxlKTsKCiAgICAgICAgLyogTG9hZCB0aGUgZ2xvYmFsIEhLVSBoaXZlIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpciAqLwogICAgICAgIHAgPSBjb25maWdmaWxlICsgc3RybGVuKGNvbmZpZ2ZpbGUpOwogICAgICAgIHN0cmNweShwLCBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUKTsKICAgICAgICBsb2FkX3dpbmVfcmVnaXN0cnkoIGhrZXlfdXNlcnMsIGNvbmZpZ2ZpbGUgKTsKCiAgICAgICAgLyogTG9hZCB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyICovCiAgICAgICAgc3RyY3B5KHAsIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FKTsKICAgICAgICBsb2FkX3dpbmVfcmVnaXN0cnkoIGhrZXlfbG9jYWxfbWFjaGluZSwgY29uZmlnZmlsZSApOwogICAgfQoKICAgIC8qIHNldHVwIHJlZ2lzdHJ5IHNhdmluZyAqLwoKICAgIGFsbCA9IEZBTFNFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgU2F2ZU9ubHlVcGRhdGVkS2V5c1cgKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X2NvbmZpZywgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICB7CiAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgIGFsbCA9IElTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQoKICAgIHBlcmlvZCA9IDA7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBQZXJpb2RpY1NhdmVXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICBwZXJpb2QgPSAoaW50KXN0cnRvbFcoc3RyLCBOVUxMLCAxMCk7CiAgICB9CgogICAgLyogbG9hZCBob21lIHJlZ2lzdHJ5IGFuZCBzZXQgc2F2aW5nIGxldmVsICgwIGZvciBzYXZpbmcgZXZlcnl0aGluZywKICAgICAqIDEgZm9yIHNhdmluZyBvbmx5IG1vZGlmaWVkIGtleXMpICovCgogICAgU0VSVkVSX1NUQVJUX1JFUSggbG9hZF91c2VyX3JlZ2lzdHJpZXMgKQogICAgewogICAgICAgIHJlcS0+aGtleSA9IGhrZXlfY3VycmVudF91c2VyOwogICAgICAgIHJlcS0+c2F2aW5nID0gIWFsbDsKICAgICAgICByZXEtPnBlcmlvZCA9IHBlcmlvZCAqIDEwMDA7CiAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICB9CiAgICBTRVJWRVJfRU5EX1JFUTsKCiAgICAvKiBjcmVhdGUgaGFyZHdhcmUgcmVnaXN0cnkgYnJhbmNoICovCgogICAgY3JlYXRlX2hhcmR3YXJlX2JyYW5jaCgpOwoKICAgIC8qIGNvbnZlcnQga2V5cyBmcm9tIGNvbmZpZyBmaWxlIHRvIG5ldyByZWdpc3RyeSBmb3JtYXQgKi8KCiAgICBjb252ZXJ0X2RyaXZlX3R5cGVzKCk7CiAgICBjb252ZXJ0X2Vudmlyb25tZW50KCBoa2V5X2N1cnJlbnRfdXNlciApOwoKICAgIE50Q2xvc2UoaGtleV91c2Vyc19kZWZhdWx0KTsKICAgIE50Q2xvc2UoaGtleV9jdXJyZW50X3VzZXIpOwogICAgTnRDbG9zZShoa2V5X3VzZXJzKTsKICAgIE50Q2xvc2UoaGtleV9sb2NhbF9tYWNoaW5lKTsKICAgIE50Q2xvc2UoaGtleV9jb25maWcpOwp9Cg==