LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBOT1RFUwogKiAgICBXaGVuIGNoYW5naW5nIHRoaXMgZmlsZSwgcGxlYXNlIHJlLXJ1biB0aGUgcmVndGVzdCBwcm9ncmFtIHRvIGVuc3VyZQogKiAgICB0aGUgY29uZGl0aW9ucyBhcmUgaGFuZGxlZCBwcm9wZXJseS4KICoKICogVE9ETwogKiAgICBTZWN1cml0eSBhY2Nlc3MKICogICAgT3B0aW9uIGhhbmRsaW5nCiAqICAgIFRpbWUgZm9yIFJlZ0VudW1LZXkqLCBSZWdRdWVyeUluZm9LZXkqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9TWVNfSU9DVExfSAojaW5jbHVkZSA8c3lzL2lvY3RsLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9MSU5VWF9IRFJFR19ICiMgaW5jbHVkZSA8bGludXgvaGRyZWcuaD4KI2VuZGlmCgojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKI2luY2x1ZGUgIm50c3RhdHVzLmgiCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5pb2N0bC5oIgojaW5jbHVkZSAibnRkZHNjc2kuaCIKCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9saWJyYXJ5LmgiCiNpbmNsdWRlICJ3aW5lL3NlcnZlci5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocmVnKTsKCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX1VTRVJfREVGQVVMVCAgIi93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9HTE9CQUxfUkVHQlJBTkNIX0xPQ0FMX01BQ0hJTkUgIi93aW5lLnN5c3RlbXJlZyIKCiNkZWZpbmUgTUFYX1BBVEhOQU1FX0xFTiAgIDEwMjQKCnN0YXRpYyBjb25zdCBXQ0hBUiBDbGFzc2VzUm9vdFdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbCcsJ2EnLCdzJywncycsJ2UnLCdzJywwfTsKCiNkZWZpbmUgSVNfT1BUSU9OX0ZBTFNFKGNoKSBcCiAgICAoKGNoKSA9PSAnbicgfHwgKGNoKSA9PSAnTicgfHwgKGNoKSA9PSAnZicgfHwgKGNoKSA9PSAnRicgfHwgKGNoKSA9PSAnMCcpCgovKiBfeG1hbGxvYyBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkICpfeG1hbGxvYyggc2l6ZV90IHNpemUgKQp7CiAgICB2b2lkICpyZXM7CgogICAgcmVzID0gbWFsbG9jIChzaXplID8gc2l6ZSA6IDEpOwogICAgaWYgKHJlcyA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiVmlydHVhbCBtZW1vcnkgZXhoYXVzdGVkLlxuIik7CiAgICAgICAgZXhpdCAoMSk7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9CgovKiBfeHN0cmR1cCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfeHN0cmR1cChMUENTVFIgc3RyKQp7CiAgICBMUFNUUiByZXQ7CiAgICBzaXplX3QgbGVuID0gc3RybGVuKHN0cikgKyAxOwoKICAgIGlmICghc3RyKSByZXR1cm4gTlVMTDsKICAgIHJldCA9IF94bWFsbG9jKCBsZW4gKTsKICAgIG1lbWNweSggcmV0LCBzdHIsIGxlbiApOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCBhbnNpIHN0cmluZyB0byB1bmljb2RlIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQV1NUUiBfc3RyZHVwbkF0b1coTFBDU1RSIHN0ckEsc2l6ZV90IGxlbkEpCnsKICAgIExQV1NUUiByZXQ7CiAgICBEV09SRCBsZW47CgogICAgaWYgKCFzdHJBKSByZXR1cm4gTlVMTDsKICAgIGlmIChSdGxNdWx0aUJ5dGVUb1VuaWNvZGVTaXplKCAmbGVuLCBzdHJBLCBsZW5BICkgIT0gU1RBVFVTX1NVQ0NFU1MpIHJldHVybiBOVUxMOwoKICAgIHJldCA9IF94bWFsbG9jKGxlbitzaXplb2YoV0NIQVIpKTsKICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4ocmV0LCBsZW4sIE5VTEwsIHN0ckEsIGxlbkEpOwogICAgcmV0W2xlbiAvIHNpemVvZihXQ0hBUildID0gMDsKICAgIHJldHVybiByZXQ7Cn0KCi8qIGR1bXAgYSBVbmljb2RlIHN0cmluZyB3aXRoIHByb3BlciBlc2NhcGluZyBbSW50ZXJuYWxdICovCi8qIEZJWE1FOiB0aGlzIGNvZGUgZHVwbGljYXRlcyBzZXJ2ZXIvdW5pY29kZS5jICovCnN0YXRpYyBpbnQgX2R1bXBfc3RyVyhjb25zdCBXQ0hBUiAqc3RyLHNpemVfdCBsZW4sRklMRSAqZixjb25zdCBjaGFyIGVzY2FwZVsyXSkKewogICAgc3RhdGljIGNvbnN0IGNoYXIgZXNjYXBlc1szMl0gPSAiLi4uLi4uLmFidG52ZnIuLi4uLi4uLi4uLi4uZS4uLi4iOwogICAgY2hhciBidWZmZXJbMjU2XTsKICAgIExQU1RSIHBvcyA9IGJ1ZmZlcjsKICAgIGludCBjb3VudCA9IDA7CgogICAgZm9yICg7IGxlbjsgc3RyKyssIGxlbi0tKQogICAgewogICAgICAgIGlmIChwb3MgPiBidWZmZXIgKyBzaXplb2YoYnVmZmVyKSAtIDgpCiAgICAgICAgewogICAgICAgICAgICBmd3JpdGUoIGJ1ZmZlciwgcG9zIC0gYnVmZmVyLCAxLCBmICk7CiAgICAgICAgICAgIGNvdW50ICs9IHBvcyAtIGJ1ZmZlcjsKICAgICAgICAgICAgcG9zID0gYnVmZmVyOwogICAgICAgIH0KICAgICAgICBpZiAoKnN0ciA+IDEyNykgIC8qIGhleCBlc2NhcGUgKi8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChsZW4gPiAxICYmIHN0clsxXSA8IDEyOCAmJiBpc3hkaWdpdCgoY2hhcilzdHJbMV0pKQogICAgICAgICAgICAgICAgcG9zICs9IHNwcmludGYoIHBvcywgIlxceCUwNHgiLCAqc3RyICk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBvcyArPSBzcHJpbnRmKCBwb3MsICJcXHgleCIsICpzdHIgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyIDwgMzIpICAvKiBvY3RhbCBvciBDIGVzY2FwZSAqLwogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEqc3RyICYmIGxlbiA9PSAxKSBjb250aW51ZTsgIC8qIGRvIG5vdCBvdXRwdXQgdGVybWluYXRpbmcgTlVMTCAqLwogICAgICAgICAgICBpZiAoZXNjYXBlc1sqc3RyXSAhPSAnLicpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlYyIsIGVzY2FwZXNbKnN0cl0gKTsKICAgICAgICAgICAgZWxzZSBpZiAobGVuID4gMSAmJiBzdHJbMV0gPj0gJzAnICYmIHN0clsxXSA8PSAnNycpCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlMDNvIiwgKnN0ciApOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwb3MgKz0gc3ByaW50ZiggcG9zLCAiXFwlbyIsICpzdHIgKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgqc3RyID09ICdcXCcgfHwgKnN0ciA9PSBlc2NhcGVbMF0gfHwgKnN0ciA9PSBlc2NhcGVbMV0pICpwb3MrKyA9ICdcXCc7CiAgICAgICAgKnBvcysrID0gKnN0cjsKICAgIH0KICAgIGZ3cml0ZSggYnVmZmVyLCBwb3MgLSBidWZmZXIsIDEsIGYgKTsKICAgIGNvdW50ICs9IHBvcyAtIGJ1ZmZlcjsKICAgIHJldHVybiBjb3VudDsKfQoKLyogY29udmVydCBhbnNpIHN0cmluZyB0byB1bmljb2RlIGFuZCBkdW1wIHdpdGggcHJvcGVyIGVzY2FwaW5nIFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfZHVtcF9zdHJBdG9XKExQQ1NUUiBzdHJBLHNpemVfdCBsZW4sRklMRSAqZixjb25zdCBjaGFyIGVzY2FwZVsyXSkKewogICAgV0NIQVIgKnN0clc7CiAgICBpbnQgcmV0OwoKICAgIGlmIChzdHJBID09IE5VTEwpIHJldHVybiAwOwogICAgc3RyVyA9IF9zdHJkdXBuQXRvVyhzdHJBLGxlbik7CiAgICByZXQgPSBfZHVtcF9zdHJXKHN0clcsbGVuLGYsZXNjYXBlKTsKICAgIGZyZWUoc3RyVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBhIGtleSB2YWx1ZSAqLwovKiBGSVhNRTogdGhpcyBjb2RlIGR1cGxpY2F0ZXMgc2VydmVyL3JlZ2lzdHJ5LmMgKi8Kc3RydWN0IGtleV92YWx1ZSB7CiAgICBXQ0hBUiAgICAgICAgICAgICpuYW1lVzsgICAvKiB2YWx1ZSBuYW1lICovCiAgICBpbnQgICAgICAgICAgICAgICB0eXBlOyAgICAvKiB2YWx1ZSB0eXBlICovCiAgICBzaXplX3QgICAgICAgICAgICBsZW47ICAgICAvKiB2YWx1ZSBkYXRhIGxlbmd0aCBpbiBieXRlcyAqLwogICAgdm9pZCAgICAgICAgICAgICAqZGF0YTsgICAgLyogcG9pbnRlciB0byB2YWx1ZSBkYXRhICovCn07CgovKiBkdW1wIGEgdmFsdWUgdG8gYSB0ZXh0IGZpbGUgKi8KLyogRklYTUU6IHRoaXMgY29kZSBkdXBsaWNhdGVzIHNlcnZlci9yZWdpc3RyeS5jICovCnN0YXRpYyB2b2lkIF9kdW1wX3ZhbHVlKHN0cnVjdCBrZXlfdmFsdWUgKnZhbHVlLEZJTEUgKmYpCnsKICAgIGludCBpLCBjb3VudDsKCiAgICBpZiAodmFsdWUtPm5hbWVXWzBdKSB7CiAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICBjb3VudCA9IDEgKyBfZHVtcF9zdHJXKHZhbHVlLT5uYW1lVyxzdHJsZW5XKHZhbHVlLT5uYW1lVyksZiwiXCJcIiIpOwogICAgICAgIGNvdW50ICs9IGZwcmludGYoIGYsICJcIj0iICk7CiAgICB9CiAgICBlbHNlIGNvdW50ID0gZnByaW50ZiggZiwgIkA9IiApOwoKICAgIHN3aXRjaCh2YWx1ZS0+dHlwZSkgewogICAgICAgIGNhc2UgUkVHX1NaOgogICAgICAgIGNhc2UgUkVHX0VYUEFORF9TWjoKICAgICAgICBjYXNlIFJFR19NVUxUSV9TWjoKICAgICAgICAgICAgaWYgKHZhbHVlLT50eXBlICE9IFJFR19TWikgZnByaW50ZiggZiwgInN0ciglZCk6IiwgdmFsdWUtPnR5cGUgKTsKICAgICAgICAgICAgZnB1dGMoICdcIicsIGYgKTsKICAgICAgICAgICAgaWYgKHZhbHVlLT5kYXRhKSBfZHVtcF9zdHJXKHZhbHVlLT5kYXRhLHZhbHVlLT5sZW4vc2l6ZW9mKFdDSEFSKSxmLCJcIlwiIik7CiAgICAgICAgICAgIGZwdXRjKCAnXCInLCBmICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX0RXT1JEOgogICAgICAgICAgICBpZiAodmFsdWUtPmxlbiA9PSBzaXplb2YoRFdPUkQpKSB7CiAgICAgICAgICAgICAgICBEV09SRCBkdzsKICAgICAgICAgICAgICAgIG1lbWNweSggJmR3LCB2YWx1ZS0+ZGF0YSwgc2l6ZW9mKERXT1JEKSApOwogICAgICAgICAgICAgICAgZnByaW50ZiggZiwgImR3b3JkOiUwOGx4IiwgZHcgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGVsc2UgZmFsbCB0aHJvdWdoICovCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgaWYgKHZhbHVlLT50eXBlID09IFJFR19CSU5BUlkpIGNvdW50ICs9IGZwcmludGYoIGYsICJoZXg6IiApOwogICAgICAgICAgICBlbHNlIGNvdW50ICs9IGZwcmludGYoIGYsICJoZXgoJXgpOiIsIHZhbHVlLT50eXBlICk7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS0+bGVuOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvdW50ICs9IGZwcmludGYoIGYsICIlMDJ4IiwgKigodW5zaWduZWQgY2hhciAqKXZhbHVlLT5kYXRhICsgaSkgKTsKICAgICAgICAgICAgICAgIGlmIChpIDwgdmFsdWUtPmxlbi0xKSB7CiAgICAgICAgICAgICAgICAgICAgZnB1dGMoICcsJywgZiApOwogICAgICAgICAgICAgICAgICAgIGlmICgrK2NvdW50ID4gNzYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZnByaW50ZiggZiwgIlxcXG4gICIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGZwdXRjKCAnXG4nLCBmICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewogICAgY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCiAgICB1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCiAgICB1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwogICAgdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwogICAgdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCiAgICB1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCiAgICB1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCiAgICB1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7CiAgICB1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCiAgICB1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKICAgIHVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwogICAgdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwogICAgdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7CiAgICB1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCiAgICB1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KICAgIHVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KICAgIHVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgIFtJbnRlcm5hbF0gKi8Kc3RhdGljIHZvaWQgX3czMV9kdW1wdHJlZSh1bnNpZ25lZCBzaG9ydCBpZHgsIGNoYXIgKnR4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYiwgc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgIEhLRVkgaGtleSwgVUxPTkcgbGFzdG1vZGlmaWVkLCBpbnQgbGV2ZWwpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBjbGFzc2VzV1tdID0geycuJywnYycsJ2wnLCdhJywncycsJ3MnLCdlJywncycsMH07CiAgICBzdHJ1Y3QgX3czMV9kaXJlbnQgKmRpcjsKICAgIHN0cnVjdCBfdzMxX2tleWVudCAqa2V5OwogICAgc3RydWN0IF93MzFfdmFsZW50ICp2YWw7CiAgICBIS0VZIHN1YmtleSA9IDA7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVcsIHZhbHVlVzsKICAgIHN0YXRpYyBXQ0hBUiB0YWlsWzQwMF07CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5OwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmdmFsdWVXLCBOVUxMICk7CgogICAgd2hpbGUgKGlkeCE9MCkgewogICAgICAgIGRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgogICAgICAgIGlmIChkaXItPmtleV9pZHgpIHsKICAgICAgICAgICAgRFdPUkQgbGVuOwogICAgICAgICAgICBrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgogICAgICAgICAgICBSdGxNdWx0aUJ5dGVUb1VuaWNvZGVOKCB0YWlsLCBzaXplb2YodGFpbCktc2l6ZW9mKFdDSEFSKSwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnR4dFtrZXktPnN0cmluZ19vZmZdLCBrZXktPmxlbmd0aCk7CiAgICAgICAgICAgIHRhaWxbbGVuL3NpemVvZihXQ0hBUildID0gMDsKCiAgICAgICAgICAgIC8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUKICAgICAgICAgICAgICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCFsZXZlbCAmJiAhc3RyY21wVyh0YWlsLGNsYXNzZXNXKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsaGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CiAgICAgICAgICAgICAgICBpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc3Via2V5KSBOdENsb3NlKCBzdWJrZXkgKTsKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdGFpbCApOwogICAgICAgICAgICBpZiAoTnRDcmVhdGVLZXkoICZzdWJrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKSBzdWJrZXkgPSAwOwoKICAgICAgICAgICAgLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCiAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKICAgICAgICAgICAgICAgIGlmIChkaXItPnZhbHVlX2lkeCkgewogICAgICAgICAgICAgICAgICAgIERXT1JEIGxlbjsKICAgICAgICAgICAgICAgICAgICB2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CiAgICAgICAgICAgICAgICAgICAgUnRsTXVsdGlCeXRlVG9Vbmljb2RlTiggdGFpbCwgc2l6ZW9mKHRhaWwpIC0gc2l6ZW9mKFdDSEFSKSwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdHh0W3ZhbC0+c3RyaW5nX29mZl0sIHZhbC0+bGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICB0YWlsW2xlbi9zaXplb2YoV0NIQVIpXSA9IDA7CiAgICAgICAgICAgICAgICAgICAgTnRTZXRWYWx1ZUtleSggc3Via2V5LCAmdmFsdWVXLCAwLCBSRUdfU1osIHRhaWwsIGxlbiArIHNpemVvZihXQ0hBUikgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBUUkFDRSgic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKICAgICAgICBfdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxzdWJrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwogICAgICAgIGlkeD1kaXItPnNpYmxpbmdfaWR4OwogICAgfQogICAgaWYgKHN1YmtleSkgTnRDbG9zZSggc3Via2V5ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93MzFfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfdzMxX2xvYWRyZWcoIGNvbnN0IFdDSEFSICpwYXRoICkKewogICAgSEFORExFICAgICAgICAgICAgICAgICAgICAgIGhmOwogICAgSEtFWSAgICAgICAgICAgICAgICAgICAgICAgIHJvb3Q7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyAgICAgICAgICAgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HICAgICAgICAgICAgICBuYW1lVzsKICAgIHN0cnVjdCBfdzMxX2hlYWRlciAgICAgICAgICBoZWFkOwogICAgc3RydWN0IF93MzFfdGFiZW50KiAgICAgICAgIHRhYiA9IE5VTEw7CiAgICBjaGFyKiAgICAgICAgICAgICAgICAgICAgICAgdHh0ID0gTlVMTDsKICAgIHVuc2lnbmVkIGludAkJbGVuOwogICAgVUxPTkcJCQlsYXN0bW9kaWZpZWQ7CiAgICBOVFNUQVRVUyAgICAgICAgICAgICAgICAgICAgc3RhdHVzOwogICAgSU9fU1RBVFVTX0JMT0NLICAgICAgICAgICAgIGlvc2I7CiAgICBGSUxFX1BPU0lUSU9OX0lORk9STUFUSU9OICAgZnBpOwogICAgRklMRV9CQVNJQ19JTkZPUk1BVElPTiAgICAgIGZiaTsKCiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICBoZiA9IENyZWF0ZUZpbGVXKCBwYXRoLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwogICAgaWYgKGhmPT1JTlZBTElEX0hBTkRMRV9WQUxVRSkgcmV0dXJuOwoKICAgIC8qIHJlYWQgJiBkdW1wIGhlYWRlciAqLwogICAgaWYgKE50UmVhZEZpbGUoaGYsIDAsIE5VTEwsIE5VTEwsICZpb3NiLCAKICAgICAgICAgICAgICAgICAgICZoZWFkLCBzaXplb2YoaGVhZCksIE5VTEwsIE5VTEwpICE9IFNUQVRVU19TVUNDRVNTIHx8CiAgICAgICAgaW9zYi5JbmZvcm1hdGlvbiAhPSBzaXplb2YoaGVhZCkpCiAgICB7CiAgICAgICAgRVJSKCJyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwogICAgICAgIGdvdG8gZG9uZTsKICAgIH0KICAgIGlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpICE9IDApCiAgICB7CiAgICAgICAgRVJSKCJyZWcuZGF0IGhhcyBiYWQgc2lnbmF0dXJlLlxuIik7CiAgICAgICAgZ290byBkb25lOwogICAgfQoKICAgIGxlbiA9IGhlYWQudGFiY250ICogc2l6ZW9mKHN0cnVjdCBfdzMxX3RhYmVudCk7CiAgICAvKiByZWFkIGFuZCBkdW1wIGluZGV4IHRhYmxlICovCiAgICB0YWIgPSBfeG1hbGxvYyhsZW4pOwogICAgaWYgKE50UmVhZEZpbGUoaGYsIDAsIE5VTEwsIE5VTEwsICZpb3NiLAogICAgICAgICAgICAgICAgICAgdGFiLCBsZW4sIE5VTEwsIE5VTEwpICE9IFNUQVRVU19TVUNDRVNTIHx8CiAgICAgICAgaW9zYi5JbmZvcm1hdGlvbiAhPSBsZW4pIAogICAgewogICAgICAgIEVSUigiY291bGRuJ3QgcmVhZCBpbmRleCB0YWJsZSAoJWQgYnl0ZXMpLlxuIixsZW4pOwogICAgICAgIGdvdG8gZG9uZTsKICAgIH0KCiAgICAvKiByZWFkIHRleHQgKi8KICAgIHR4dCA9IF94bWFsbG9jKGhlYWQudGV4dHNpemUpOwogICAgZnBpLkN1cnJlbnRCeXRlT2Zmc2V0LnUuTG93UGFydCA9IGhlYWQudGV4dG9mZjsKICAgIGZwaS5DdXJyZW50Qnl0ZU9mZnNldC51LkhpZ2hQYXJ0ID0gMDsKICAgIGlmIChOdFNldEluZm9ybWF0aW9uRmlsZShoZiwgJmlvc2IsICZmcGksIHNpemVvZihmcGkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlUG9zaXRpb25JbmZvcm1hdGlvbikgIT0gU1RBVFVTX1NVQ0NFU1MpCiAgICB7CiAgICAgICAgRVJSKCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOwogICAgICAgIGdvdG8gZG9uZTsKICAgIH0KICAgIHN0YXR1cyA9IE50UmVhZEZpbGUoaGYsIDAsIE5VTEwsIE5VTEwsICZpb3NiLCB0eHQsIGhlYWQudGV4dHNpemUsIE5VTEwsIE5VTEwpOwogICAgaWYgKCEoc3RhdHVzID09IFNUQVRVU19TVUNDRVNTIHx8IHN0YXR1cyA9PSBTVEFUVVNfRU5EX09GX0ZJTEUpIHx8CiAgICAgICAgaW9zYi5JbmZvcm1hdGlvbiAhPSBoZWFkLnRleHRzaXplKQogICAgewogICAgICAgIEVSUigidGV4dGJsb2NrIHRvbyBzaG9ydCAoJWQgaW5zdGVhZCBvZiAlbGQpLlxuIiwgbGVuLCBoZWFkLnRleHRzaXplKTsKICAgICAgICBnb3RvIGRvbmU7CiAgICB9CiAgICBpZiAoTnRRdWVyeUluZm9ybWF0aW9uRmlsZShoZiwgJmlvc2IsICZmYmksIHNpemVvZihmYmkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZUJhc2ljSW5mb3JtYXRpb24pICE9IFNUQVRVU19TVUNDRVNTKQogICAgewogICAgICAgIEVSUigiQ291bGRuJ3QgZ2V0IGJhc2ljIGluZm9ybWF0aW9uLlxuIik7CiAgICAgICAgZ290byBkb25lOwogICAgfQogICAgUnRsVGltZVRvU2Vjb25kc1NpbmNlMTk3MCgmZmJpLkxhc3RXcml0ZVRpbWUsICZsYXN0bW9kaWZpZWQpOwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBDbGFzc2VzUm9vdFcgKTsKCiAgICBpZiAoIU50Q3JlYXRlS2V5KCAmcm9vdCwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICB7CiAgICAgICAgX3czMV9kdW1wdHJlZSh0YWJbMF0udzEsdHh0LHRhYiwmaGVhZCxyb290LGxhc3Rtb2RpZmllZCwwKTsKICAgICAgICBOdENsb3NlKCByb290ICk7CiAgICB9CiBkb25lOgogICAgaWYgKHRhYikgZnJlZSh0YWIpOwogICAgaWYgKHR4dCkgZnJlZSh0eHQpOwogICAgTnRDbG9zZShoZik7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dzIDk1IHJlZ2lzdHJ5IGxvYWRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBTRUNUSU9OIDE6IG1haW4gaGVhZGVyCiAqCiAqIG9uY2UgYXQgb2Zmc2V0IDAKICovCiNkZWZpbmUJVzk1X1JFR19DUkVHX0lECTB4NDc0NTUyNDMKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogIkNSRUciID0gVzk1X1JFR19DUkVHX0lEICovCiAgICBEV09SRAl2ZXJzaW9uOwkvKiA/Pz8/IDB4MDAwMTAwMDAgKi8KICAgIERXT1JECXJnZGJfb2ZmOwkvKiAweDA4IE9mZnNldCBvZiAxc3QgUkdEQi1ibG9jayAqLwogICAgRFdPUkQJdWsyOwkJLyogMHgwYyAqLwogICAgV09SRAlyZ2RiX251bTsJLyogMHgxMCAjIG9mIFJHREItYmxvY2tzICovCiAgICBXT1JECXVrMzsKICAgIERXT1JECXVrWzNdOwogICAgLyogcmdrbiAqLwp9IF93OTVjcmVnOwoKLyogU0VDVElPTiAyOiBEaXJlY3RvcnkgaW5mb3JtYXRpb24gKHRyZWUgc3RydWN0dXJlKQogKgogKiBvbmNlIG9uIG9mZnNldCAweDIwCiAqCiAqIHN0cnVjdHVyZTogW3Jna25dW2RrZV0qCShyZXBlYXQgdGlsbCBsYXN0X2RrZSBpcyByZWFjaGVkKQogKi8KI2RlZmluZQlXOTVfUkVHX1JHS05fSUQJMHg0ZTRiNDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiJSR0tOIiA9IFc5NV9SRUdfUkdLTl9JRCAqLwogICAgRFdPUkQJc2l6ZTsJCS8qIFNpemUgb2YgdGhlIFJHS04tYmxvY2sgKi8KICAgIERXT1JECXJvb3Rfb2ZmOwkvKiBSZWwuIE9mZnNldCBvZiB0aGUgcm9vdC1yZWNvcmQgKi8KICAgIERXT1JEICAgbGFzdF9ka2U7ICAgICAgIC8qIE9mZnNldCB0byBsYXN0IERLRSA/ICovCiAgICBEV09SRAl1a1s0XTsKfSBfdzk1cmdrbjsKCi8qIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZQogKgogKiB0aGUgMXN0IGVudHJ5IGluIGEgInVzdWFsIiByZWdpc3RyeSBmaWxlIGlzIGEgbnVsLWVudHJ5IHdpdGggc3Via2V5czogdGhlCiAqIGhpdmUgaXRzZWxmLiBJdCBsb29rcyB0aGUgc2FtZSBsaWtlIG90aGVyIGtleXMuIEV2ZW4gdGhlIElELW51bWJlciBjYW4KICogYmUgYW55IHZhbHVlLgogKgogKiBUaGUgImhhc2giLXZhbHVlIGlzIGEgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBrZXkncyBuYW1lLiBXaW5kb3dzIHdpbGwgbm90CiAqIHNlYXJjaCBmb3IgdGhlIG5hbWUsIGJ1dCBmb3IgYSBtYXRjaGluZyBoYXNoLXZhbHVlLiBpZiBpdCBmaW5kcyBvbmUsIGl0CiAqIHdpbGwgY29tcGFyZSB0aGUgYWN0dWFsIHN0cmluZyBpbmZvLCBvdGhlcndpc2UgY29udGludWUgd2l0aCB0aGUgbmV4dCBrZXkuCiAqIFRvIGNhbGN1bGF0ZSB0aGUgaGFzaCBpbml0aWFsaXplIGEgRC1Xb3JkIHdpdGggMCBhbmQgYWRkIGFsbCBBU0NJSS12YWx1ZXMKICogb2YgdGhlIHN0cmluZyB3aGljaCBhcmUgc21hbGxlciB0aGFuIDB4ODAgKDEyOCkgdG8gdGhpcyBELVdvcmQuCiAqCiAqIElmIHlvdSB3YW50IHRvIG1vZGlmeSBrZXkgbmFtZXMsIGFsc28gbW9kaWZ5IHRoZSBoYXNoLXZhbHVlcywgc2luY2UgdGhleQogKiBjYW5ub3QgYmUgZm91bmQgYWdhaW4gKGFsdGhvdWdoIHRoZXkgd291bGQgYmUgZGlzcGxheWVkIGluIFJFR0VESVQpCiAqIEVuZCBvZiBsaXN0LXBvaW50ZXJzIGFyZSBmaWxsZWQgd2l0aCAweEZGRkZGRkZGCiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuck1TIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKgogKiBUaGUgbGFzdCBES0UgKHNlZSBmaWVsZCBsYXN0X2RrZSBpbiBfdzk1X3Jna24pIGhhcyBvbmx5IDMgRFdPUkRzIHdpdGgKICogMHg4MDAwMDAwMCAoRU9MIGluZGljYXRvciA/KSBhcyB4MSwgdGhlIGhhc2ggdmFsdWUgYW5kIDB4RkZGRkZGRkYgYXMgeDMuCiAqIFRoZSByZW1haW5pbmcgc3BhY2UgYmV0d2VlbiBsYXN0X2RrZSBhbmQgdGhlIG9mZnNldCBjYWxjdWxhdGVkIGZyb20KICogcmdrbi0+c2l6ZSBzZWVtcyB0byBiZSBmcmVlIGZvciB1c2UgZm9yIG1vcmUgZGtlOnMuCiAqIFNvIGl0IHNlZW1zIGlmIG1vcmUgZGtlOnMgYXJlIGFkZGVkLCB0aGV5IGFyZSBhZGRlZCB0byB0aGF0IHNwYWNlIGFuZAogKiBsYXN0X2RrZSBpcyBncm93biwgYW5kIGluIGNhc2UgdGhhdCAiZnJlZSIgc3BhY2UgaXMgb3V0LCB0aGUgc3BhY2UKICogZ2V0cyBncm93biBhbmQgcmdrbi0+c2l6ZSBnZXRzIGFkanVzdGVkLgogKgogKiB0aGVyZSBpcyBhIG9uZSB0byBvbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gZGtlIGFuZCBka2gKICovCiAvKiBrZXkgc3RydWN0LCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJeDE7CQkvKiBGcmVlIGVudHJ5IGluZGljYXRvcig/KSAqLwogICAgRFdPUkQJaGFzaDsJCS8qIHN1bSBvZiBieXRlcyBvZiBrZXluYW1lICovCiAgICBEV09SRAl4MzsJCS8qIFJvb3Qga2V5IGluZGljYXRvcj8gdXN1YWxseSAweEZGRkZGRkZGICovCiAgICBEV09SRAlwcmV2bHZsOwkvKiBvZmZzZXQgb2YgcHJldmlvdXMga2V5ICovCiAgICBEV09SRAluZXh0c3ViOwkvKiBvZmZzZXQgb2YgY2hpbGQga2V5ICovCiAgICBEV09SRAluZXh0OwkJLyogb2Zmc2V0IG9mIHNpYmxpbmcga2V5ICovCiAgICBXT1JECW5yTFM7CQkvKiBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KICAgIFdPUkQJbnJNUzsJCS8qIG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwp9IF93OTVka2U7CgovKiBTRUNUSU9OIDM6IGtleSBpbmZvcm1hdGlvbiwgdmFsdWVzIGFuZCBkYXRhCiAqCiAqIHN0cnVjdHVyZToKICogIHNlY3Rpb246CVtibG9ja3NdKgkJKHJlcGVhdCBjcmVnLT5yZ2RiX251bSB0aW1lcykKICogIGJsb2NrczoJW3JnZGJdIFtzdWJibG9ja3NdKiAJKHJlcGVhdCB0aWxsIGJsb2NrIHNpemUgcmVhY2hlZCApCiAqICBzdWJibG9ja3M6CVtka2hdIFtka3ZdKgkJKHJlcGVhdCBka2gtPnZhbHVlcyB0aW1lcyApCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgRFdPUkQgdmFsdWUKICogYXQgb2Zmc2V0IDB4MTAgZXF1YWxzIHRoZSBvbmUgYXQgb2Zmc2V0IDB4MDQgbWludXMgdGhlIG9uZSBhdCBvZmZzZXQgMHgwOC4KICogSSBoYXZlIG5vIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKi8KCi8qIGJsb2NrIGhlYWRlciwgb25jZSBwZXIgYmxvY2sgKi8KI2RlZmluZSBXOTVfUkVHX1JHREJfSUQJMHg0MjQ0NDc1MgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CS8qIDB4MDAgJ1JHREInID0gVzk1X1JFR19SR0RCX0lEICovCiAgICBEV09SRAlzaXplOwkvKiAweDA0ICovCiAgICBEV09SRAl1azE7CS8qIDB4MDggKi8KICAgIERXT1JECXVrMjsJLyogMHgwYyAqLwogICAgRFdPUkQJdWszOwkvKiAweDEwICovCiAgICBEV09SRAl1azQ7CS8qIDB4MTQgKi8KICAgIERXT1JECXVrNTsJLyogMHgxOCAqLwogICAgRFdPUkQJdWs2OwkvKiAweDFjICovCiAgICAvKiBka2ggKi8KfSBfdzk1cmdkYjsKCi8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCksIG9uY2UgcGVyIGtleSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAluZXh0a2V5b2ZmOyAJLyogMHgwMCBvZmZzZXQgdG8gbmV4dCBka2ggKi8KICAgIFdPUkQJbnJMUzsJCS8qIDB4MDQgaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCiAgICBXT1JECW5yTVM7CQkvKiAweDA2IG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwogICAgRFdPUkQJYnl0ZXN1c2VkOwkvKiAweDA4ICovCiAgICBXT1JECWtleW5hbWVsZW47CS8qIDB4MGMgbGVuIG9mIG5hbWUgKi8KICAgIFdPUkQJdmFsdWVzOwkJLyogMHgwZSBudW1iZXIgb2YgdmFsdWVzICovCiAgICBEV09SRAl4eDE7CQkvKiAweDEwICovCiAgICBjaGFyCW5hbWVbMV07CS8qIDB4MTQgKi8KICAgIC8qIGRrdiAqLwkJLyogMHgxNCArIGtleW5hbWVsZW4gKi8KfSBfdzk1ZGtoOwoKLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlLCBvbmNlIHBlciB2YWx1ZSAqLwp0eXBlZGVmCXN0cnVjdCB7CiAgICBEV09SRAl0eXBlOwkJLyogMHgwMCAqLwogICAgRFdPUkQJeDE7CQkvKiAweDA0ICovCiAgICBXT1JECXZhbG5hbWVsZW47CS8qIDB4MDggbGVuZ3RoIG9mIG5hbWUsIDAgaXMgZGVmYXVsdCBrZXkgKi8KICAgIFdPUkQJdmFsZGF0YWxlbjsJLyogMHgwQSBsZW5ndGggb2YgZGF0YSAqLwogICAgY2hhcgluYW1lWzFdOwkvKiAweDBjICovCiAgICAvKiByYXcgZGF0YSAqLwkJLyogMHgwYyArIHZhbG5hbWVsZW4gKi8KfSBfdzk1ZGt2OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvb2t1cF9ka2ggW0ludGVybmFsXQogKgogKiBzZWVrcyB0aGUgZGtoIGJlbG9uZ2luZyB0byBhIGRrZQogKi8Kc3RhdGljIF93OTVka2ggKl93OTVfbG9va3VwX2RraChfdzk1Y3JlZyAqY3JlZyxpbnQgbnJMUyxpbnQgbnJNUykKewogICAgX3c5NXJnZGIgKiByZ2RiOwogICAgX3c5NWRraCAqIGRraDsKICAgIGludCBpOwoKICAgIC8qIGdldCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZ2RiIGRhdGFzdG9yZSAqLwogICAgcmdkYiA9IChfdzk1cmdkYiopKChjaGFyKiljcmVnK2NyZWctPnJnZGJfb2ZmKTsKCiAgICAvKiBjaGVjazogcmVxdWVzdGVkIGJsb2NrIDwgbGFzdF9ibG9jaykgKi8KICAgIGlmIChjcmVnLT5yZ2RiX251bSA8PSBuck1TKSB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJlcXVlc3RlZCBibG9jayBuby4gYmV5b25kIGVuZC5cbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogZmluZCB0aGUgcmlnaHQgYmxvY2sgKi8KICAgIGZvcihpPTA7IGk8bnJNUyA7aSsrKSB7CiAgICAgICAgaWYocmdkYi0+aWQgIT0gVzk1X1JFR19SR0RCX0lEKSB7ICAvKiBjaGVjayB0aGUgbWFnaWMgKi8KICAgICAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGJhZCBtYWdpYyAweCUwOGx4XG4iLCByZ2RiLT5pZCk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIHJnZGIgPSAoX3c5NXJnZGIqKSAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSk7CQkvKiBmaW5kIG5leHQgYmxvY2sgKi8KICAgIH0KCiAgICBka2ggPSAoX3c5NWRraCopKHJnZGIgKyAxKTsJCQkJLyogZmlyc3Qgc3ViIGJsb2NrIHdpdGhpbiB0aGUgcmdkYiAqLwoKICAgIGRvIHsKICAgICAgICBpZihuckxTPT1ka2gtPm5yTFMgKSByZXR1cm4gZGtoOwogICAgICAgIGRraCA9IChfdzk1ZGtoKikoKGNoYXIqKWRraCArIGRraC0+bmV4dGtleW9mZik7CS8qIGZpbmQgbmV4dCBzdWJibG9jayAqLwogICAgfSB3aGlsZSAoKGNoYXIgKilka2ggPCAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSkpOwoKZXJyb3I6CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2R1bXBfZGt2IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9kdW1wX2Rrdihfdzk1ZGtoICpka2gsaW50IG5yTFMsaW50IG5yTVMsRklMRSAqZikKewogICAgX3c5NWRrdiAqIGRrdjsKICAgIGludCBpOwoKICAgIC8qIGZpcnN0IHZhbHVlIGJsb2NrICovCiAgICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka2grZGtoLT5rZXluYW1lbGVuKzB4MTQpOwoKICAgIC8qIGxvb3AgdGhyb3VnaCB0aGUgdmFsdWVzICovCiAgICBmb3IgKGk9MDsgaTwgZGtoLT52YWx1ZXM7IGkrKykgewogICAgICAgIHN0cnVjdCBrZXlfdmFsdWUgdmFsdWU7CiAgICAgICAgV0NIQVIgKnBkYXRhOwoKICAgICAgICB2YWx1ZS5uYW1lVyA9IF9zdHJkdXBuQXRvVyhka3YtPm5hbWUsZGt2LT52YWxuYW1lbGVuKTsKICAgICAgICB2YWx1ZS50eXBlID0gZGt2LT50eXBlOwogICAgICAgIHZhbHVlLmxlbiA9IGRrdi0+dmFsZGF0YWxlbjsKCiAgICAgICAgdmFsdWUuZGF0YSA9ICYoZGt2LT5uYW1lW2Rrdi0+dmFsbmFtZWxlbl0pOwogICAgICAgIHBkYXRhID0gTlVMTDsKICAgICAgICBpZiAoICh2YWx1ZS50eXBlPT1SRUdfU1opIHx8ICh2YWx1ZS50eXBlPT1SRUdfRVhQQU5EX1NaKSB8fCAodmFsdWUudHlwZT09UkVHX01VTFRJX1NaKSApIHsKICAgICAgICAgICAgcGRhdGEgPSBfc3RyZHVwbkF0b1codmFsdWUuZGF0YSx2YWx1ZS5sZW4pOwogICAgICAgICAgICB2YWx1ZS5sZW4gKj0gMjsKICAgICAgICB9CiAgICAgICAgaWYgKHBkYXRhICE9IE5VTEwpIHZhbHVlLmRhdGEgPSBwZGF0YTsKCiAgICAgICAgX2R1bXBfdmFsdWUoJnZhbHVlLGYpOwogICAgICAgIGZyZWUodmFsdWUubmFtZVcpOwogICAgICAgIGlmIChwZGF0YSAhPSBOVUxMKSBmcmVlKHBkYXRhKTsKCiAgICAgICAgLyogbmV4dCB2YWx1ZSAqLwogICAgICAgIGRrdiA9IChfdzk1ZGt2KikoKGNoYXIqKWRrditka3YtPnZhbG5hbWVsZW4rZGt2LT52YWxkYXRhbGVuKzB4MGMpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBpbnQgX3c5NV9kdW1wX29uZV9ka2UoTFBDU1RSIGtleV9uYW1lLF93OTVjcmVnICpjcmVnLF93OTVyZ2tuICpyZ2tuLF93OTVka2UgKmRrZSxGSUxFICpmLGludCBsZXZlbCk7CgpzdGF0aWMgaW50IF93OTVfZHVtcF9ka2UoTFBDU1RSIGtleV9uYW1lLF93OTVjcmVnICpjcmVnLF93OTVyZ2tuICpyZ2tuLF93OTVka2UgKmRrZSxGSUxFICpmLGludCBsZXZlbCkKewogICAgd2hpbGUgKDEpCiAgICB7CglpZiAoIV93OTVfZHVtcF9vbmVfZGtlKGtleV9uYW1lLCBjcmVnLCByZ2tuLCBka2UsIGYsIGxldmVsKSkKCSAgICByZXR1cm4gRkFMU0U7CglpZiAoZGtlLT5uZXh0ID09IDB4ZmZmZmZmZmYpCgkgICAgcmV0dXJuIFRSVUU7Cglka2UgPSAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dCk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9kdW1wX2RrZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfZHVtcF9vbmVfZGtlKExQQ1NUUiBrZXlfbmFtZSxfdzk1Y3JlZyAqY3JlZyxfdzk1cmdrbiAqcmdrbixfdzk1ZGtlICpka2UsRklMRSAqZixpbnQgbGV2ZWwpCnsKICAgIF93OTVka2ggKiBka2g7CiAgICBMUFNUUiBuZXdfa2V5X25hbWUgPSBOVUxMOwoKICAgIC8qIHNwZWNpYWwgcm9vdCBrZXkgKi8KICAgIGlmIChka2UtPm5yTFMgPT0gMHhmZmZmIHx8IGRrZS0+bnJNUz09MHhmZmZmKQkJLyogZWcuIHRoZSByb290IGtleSBoYXMgbm8gbmFtZSAqLwogICAgewogICAgICAgIC8qIHBhcnNlIHRoZSBvbmUgc3Via2V5ICovCiAgICAgICAgaWYgKGRrZS0+bmV4dHN1YiAhPSAweGZmZmZmZmZmKSByZXR1cm4gX3c5NV9kdW1wX2RrZShrZXlfbmFtZSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHRzdWIpLGYsbGV2ZWwpOwogICAgICAgIC8qIGhhcyBubyBzaWJsaW5nIGtleXMgKi8KICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgLyogc2VhcmNoIHN1YmJsb2NrICovCiAgICBpZiAoIShka2ggPSBfdzk1X2xvb2t1cF9ka2goY3JlZywgZGtlLT5uckxTLCBka2UtPm5yTVMpKSkgewogICAgICAgIEVSUigiZGtlIHBvaW50aW5nIHRvIG1pc3NpbmcgZGtoICFcbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAobGV2ZWwgPD0gMCkgewogICAgICAgIC8qIGNyZWF0ZSBuZXcgc3Via2V5IG5hbWUgKi8KICAgICAgICBzaXplX3QgbGVuID0gc3RybGVuKGtleV9uYW1lKTsKICAgICAgICBuZXdfa2V5X25hbWUgPSBfeG1hbGxvYyhsZW4rZGtoLT5rZXluYW1lbGVuKzIpOwogICAgICAgIG1lbWNweSggbmV3X2tleV9uYW1lLCBrZXlfbmFtZSwgbGVuICk7CiAgICAgICAgaWYgKGxlbikgbmV3X2tleV9uYW1lW2xlbisrXSA9ICdcXCc7CiAgICAgICAgbWVtY3B5KCBuZXdfa2V5X25hbWUgKyBsZW4sIGRraC0+bmFtZSwgZGtoLT5rZXluYW1lbGVuICk7CiAgICAgICAgbmV3X2tleV9uYW1lW2xlbiArIGRraC0+a2V5bmFtZWxlbl0gPSAwOwoKICAgICAgICAvKiB3cml0ZSB0aGUga2V5IHBhdGggKHNvbWV0aGluZyBsaWtlIFtTb2Z0d2FyZVxcTWljcm9zb2Z0XFwuLl0pIG9ubHkgaWY6CiAgICAgICAgICAgMSkga2V5IGhhcyBzb21lIHZhbHVlcwogICAgICAgICAgIDIpIGtleSBoYXMgbm8gdmFsdWVzIGFuZCBubyBzdWJrZXlzCiAgICAgICAgKi8KICAgICAgICBpZiAoZGtoLT52YWx1ZXMgPiAwKSB7CiAgICAgICAgICAgIC8qIHRoZXJlIGFyZSBzb21lIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgICAgICBpZiAoIV93OTVfZHVtcF9ka3YoZGtoLCBka2UtPm5yTFMsIGRrZS0+bnJNUyxmKSkgewogICAgICAgICAgICAgIGZyZWUobmV3X2tleV9uYW1lKTsKICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKChka2UtPm5leHRzdWIgPT0gMHhmZmZmZmZmZikgJiYgKGRraC0+dmFsdWVzID09IDApKSB7CiAgICAgICAgICAgIC8qIG5vIHN1YmtleXMgYW5kIG5vIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KICAgIH0gZWxzZSBuZXdfa2V5X25hbWUgPSBfeHN0cmR1cChrZXlfbmFtZSk7CgogICAgLyogbmV4dCBzdWIga2V5ICovCiAgICBpZiAoZGtlLT5uZXh0c3ViICE9IDB4ZmZmZmZmZmYpIHsKICAgICAgICBpZiAoIV93OTVfZHVtcF9ka2UobmV3X2tleV9uYW1lLCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dHN1YiksZixsZXZlbC0xKSkgewogICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICByZXR1cm4gVFJVRTsKfQovKiBlbmQgd2luZG93cyA5NSBsb2FkZXIgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dzIE5UIHJlZ2lzdHJ5IGxvYWRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBOVCBSRUdJU1RSWSBMT0FERVIgKi8KCiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKCiNpZm5kZWYgTUFQX0ZBSUxFRAojZGVmaW5lIE1BUF9GQUlMRUQgKChMUFZPSUQpLTEpCiNlbmRpZgoKI2RlZmluZSBOVF9SRUdfQkxPQ0tfU0laRSAgICAgICAgICAgIDB4MTAwMAoKI2RlZmluZSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEICAgICAgIDB4NjY2NzY1NzIJLyogcmVnZiAqLwojZGVmaW5lIE5UX1JFR19QT09MX0JMT0NLX0lEICAgICAgICAgMHg2RTY5NjI2OAkvKiBoYmluICovCiNkZWZpbmUgTlRfUkVHX0tFWV9CTE9DS19JRCAgICAgICAgICAweDZiNmUgLyogbmsgKi8KI2RlZmluZSBOVF9SRUdfVkFMVUVfQkxPQ0tfSUQgICAgICAgIDB4NmI3NiAvKiB2ayAqLwoKLyogc3ViYmxvY2tzIG9mIG5rICovCiNkZWZpbmUgTlRfUkVHX0hBU0hfQkxPQ0tfSUQgICAgICAgICAweDY2NmMgLyogbGYgKi8KI2RlZmluZSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEICAgICAgIDB4Njk2YyAvKiBsaSAqLwojZGVmaW5lIE5UX1JFR19SSV9CTE9DS19JRAkgICAgIDB4Njk3MiAvKiByaSAqLwoKI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX1RZUEUgICAgICAgIDB4MjAKI2RlZmluZSBOVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSAgIDB4MmMKCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JECWlkOwkJLyogMHg2NjY3NjU3MiAncmVnZicqLwogICAgRFdPUkQJdWsxOwkJLyogMHgwNCAqLwogICAgRFdPUkQJdWsyOwkJLyogMHgwOCAqLwogICAgRklMRVRJTUUJRGF0ZU1vZGlmaWVkOwkvKiAweDBjICovCiAgICBEV09SRAl1azM7CQkvKiAweDE0ICovCiAgICBEV09SRAl1azQ7CQkvKiAweDE4ICovCiAgICBEV09SRAl1azU7CQkvKiAweDFjICovCiAgICBEV09SRAl1azY7CQkvKiAweDIwICovCiAgICBEV09SRAlSb290S2V5QmxvY2s7CS8qIDB4MjQgKi8KICAgIERXT1JECUJsb2NrU2l6ZTsJLyogMHgyOCAqLwogICAgRFdPUkQgICB1azdbMTE2XTsKICAgIERXT1JECUNoZWNrc3VtOyAvKiBhdCBvZmZzZXQgMHgxRkMgKi8KfSBudF9yZWdmOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJYmxvY2tzaXplOwogICAgQllURQlkYXRhWzFdOwp9IG50X2hiaW5fc3ViOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJaWQ7CQkvKiAweDZFNjk2MjY4ICdoYmluJyAqLwogICAgRFdPUkQJb2ZmX3ByZXY7CiAgICBEV09SRAlvZmZfbmV4dDsKICAgIERXT1JECXVrMTsKICAgIERXT1JECXVrMjsJCS8qIDB4MTAgKi8KICAgIERXT1JECXVrMzsJCS8qIDB4MTQgKi8KICAgIERXT1JECXVrNDsJCS8qIDB4MTggKi8KICAgIERXT1JECXNpemU7CQkvKiAweDFDICovCiAgICBudF9oYmluX3N1YgloYmluX3N1YjsJLyogMHgyMCAqLwp9IG50X2hiaW47CgovKgogKiB0aGUgdmFsdWVfbGlzdCBjb25zaXN0cyBvZiBvZmZzZXRzIHRvIHRoZSB2YWx1ZXMgKHZrKQogKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlTdWJCbG9ja0lkOwkJLyogMHgwMCAweDZCNkUgKi8KICAgIFdPUkQJVHlwZTsJCQkvKiAweDAyIGZvciB0aGUgcm9vdC1rZXk6IDB4MkMsIG90aGVyd2lzZSAweDIwKi8KICAgIEZJTEVUSU1FCXdyaXRldGltZTsJLyogMHgwNCAqLwogICAgRFdPUkQJdWsxOwkJCS8qIDB4MEMgKi8KICAgIERXT1JECXBhcmVudF9vZmY7CQkvKiAweDEwIE9mZnNldCBvZiBPd25lci9QYXJlbnQga2V5ICovCiAgICBEV09SRAlucl9zdWJrZXlzOwkJLyogMHgxNCBudW1iZXIgb2Ygc3ViLUtleXMgKi8KICAgIERXT1JECXVrODsJCQkvKiAweDE4ICovCiAgICBEV09SRAlsZl9vZmY7CQkJLyogMHgxQyBPZmZzZXQgb2YgdGhlIHN1Yi1rZXkgbGYtUmVjb3JkcyAqLwogICAgRFdPUkQJdWsyOwkJCS8qIDB4MjAgKi8KICAgIERXT1JECW5yX3ZhbHVlczsJCS8qIDB4MjQgbnVtYmVyIG9mIHZhbHVlcyAqLwogICAgRFdPUkQJdmFsdWVsaXN0X29mZjsJCS8qIDB4MjggT2Zmc2V0IG9mIHRoZSBWYWx1ZS1MaXN0ICovCiAgICBEV09SRAlvZmZfc2s7CQkJLyogMHgyYyBPZmZzZXQgb2YgdGhlIHNrLVJlY29yZCAqLwogICAgRFdPUkQJb2ZmX2NsYXNzOwkJLyogMHgzMCBPZmZzZXQgb2YgdGhlIENsYXNzLU5hbWUgKi8KICAgIERXT1JECXVrMzsJCQkvKiAweDM0ICovCiAgICBEV09SRAl1azQ7CQkJLyogMHgzOCAqLwogICAgRFdPUkQJdWs1OwkJCS8qIDB4M2MgKi8KICAgIERXT1JECXVrNjsJCQkvKiAweDQwICovCiAgICBEV09SRAl1azc7CQkJLyogMHg0NCAqLwogICAgV09SRAluYW1lX2xlbjsJCS8qIDB4NDggbmFtZS1sZW5ndGggKi8KICAgIFdPUkQJY2xhc3NfbGVuOwkJLyogMHg0YSBjbGFzcy1uYW1lIGxlbmd0aCAqLwogICAgY2hhcgluYW1lWzFdOwkJLyogMHg0YyBrZXktbmFtZSAqLwp9IG50X25rOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQJb2ZmX25rOwkvKiAweDAwICovCiAgICBEV09SRAluYW1lOwkvKiAweDA0ICovCn0gaGFzaF9yZWM7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY2NmMgKi8KICAgIFdPUkQJbnJfa2V5czsJLyogMHgwNiAqLwogICAgaGFzaF9yZWMJaGFzaF9yZWNbMV07Cn0gbnRfbGY7CgovKgogbGlzdCBvZiBzdWJrZXlzIHdpdGhvdXQgaGFzaAoKIGxpIC0tKy0tPm5rCiAgICAgIHwKICAgICAgKy0tPm5rCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY5NmMgKi8KICAgIFdPUkQJbnJfa2V5czsKICAgIERXT1JECW9mZl9ua1sxXTsKfSBudF9saTsKCi8qCiB0aGlzIGlzIGEgaW50ZXJtZWRpYXRlIG5vZGUKCiByaSAtLSstLT5saS0tKy0tPm5rCiAgICAgIHwgICAgICAgKwogICAgICB8ICAgICAgICstLT5uawogICAgICB8CiAgICAgICstLT5saS0tKy0tPm5rCiAgICAgICAgICAgICAgKwoJICAgICAgKy0tPm5rCiAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBXT1JECWlkOwkJLyogMHgwMCAweDY5NzIgKi8KICAgIFdPUkQJbnJfbGk7CQkvKiAweDAyIG51bWJlciBvZmYgb2Zmc2V0cyAqLwogICAgRFdPUkQJb2ZmX2xpWzFdOwkvKiAweDA0IHBvaW50cyB0byBsaSAqLwp9IG50X3JpOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgV09SRAlpZDsJCS8qIDB4MDAgJ3ZrJyAqLwogICAgV09SRAluYW1fbGVuOwogICAgRFdPUkQJZGF0YV9sZW47CiAgICBEV09SRAlkYXRhX29mZjsKICAgIERXT1JECXR5cGU7CiAgICBXT1JECWZsYWc7CiAgICBXT1JECXVrMTsKICAgIGNoYXIJbmFtZVsxXTsKfSBudF92azsKCi8qCiAqIGdldHMgYSB2YWx1ZQogKgogKiB2ay0+ZmxhZzoKICogIDAgdmFsdWUgaXMgYSBkZWZhdWx0IHZhbHVlCiAqICAxIHRoZSB2YWx1ZSBoYXMgYSBuYW1lCiAqCiAqIHZrLT5kYXRhX2xlbgogKiAgbGVuIG9mIHRoZSB3aG9sZSBkYXRhIGJsb2NrCiAqICAtIHJlZ19zeiAodW5pY29kZSkKICogICAgYnl0ZXMgaW5jbHVkaW5nIHRoZSB0ZXJtaW5hdGluZyBcMCA9IDIqKG51bWJlcl9vZl9jaGFycysxKQogKiAgLSByZWdfZHdvcmQsIHJlZ19iaW5hcnk6CiAqICAgIGlmIGhpZ2hlc3QgYml0IG9mIGRhdGFfbGVuIGlzIHNldCBkYXRhX29mZiBjb250YWlucyB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQgX250X2R1bXBfdmsoTFBTVFIga2V5X25hbWUsIGNoYXIgKmJhc2UsIG50X3ZrICp2ayxGSUxFICpmKQp7CiAgICBCWVRFICpwZGF0YSA9IChCWVRFICopKGJhc2UrdmstPmRhdGFfb2ZmKzQpOyAvKiBzdGFydCBvZiBkYXRhICovCiAgICBzdHJ1Y3Qga2V5X3ZhbHVlIHZhbHVlOwoKICAgIGlmICh2ay0+aWQgIT0gTlRfUkVHX1ZBTFVFX0JMT0NLX0lEKSB7CiAgICAgICAgRVJSKCJ1bmtub3duIGJsb2NrIGZvdW5kICgweCUwNHgpLCBwbGVhc2UgcmVwb3J0IVxuIiwgdmstPmlkKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgdmFsdWUubmFtZVcgPSBfc3RyZHVwbkF0b1codmstPm5hbWUsdmstPm5hbV9sZW4pOwogICAgdmFsdWUudHlwZSA9IHZrLT50eXBlOwogICAgdmFsdWUubGVuID0gKHZrLT5kYXRhX2xlbiAmIDB4N2ZmZmZmZmYpOwogICAgdmFsdWUuZGF0YSA9ICh2ay0+ZGF0YV9sZW4gJiAweDgwMDAwMDAwKSA/IChMUEJZVEUpJih2ay0+ZGF0YV9vZmYpOiBwZGF0YTsKCiAgICBfZHVtcF92YWx1ZSgmdmFsdWUsZik7CiAgICBmcmVlKHZhbHVlLm5hbWVXKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyogaXQncyBjYWxsZWQgZnJvbSBfbnRfZHVtcF9sZigpICovCnN0YXRpYyBpbnQgX250X2R1bXBfbmsoTFBDU1RSIGtleV9uYW1lLGNoYXIgKmJhc2UsbnRfbmsgKm5rLEZJTEUgKmYsaW50IGxldmVsKTsKCi8qCiAqIGdldCB0aGUgc3Via2V5cwogKgogKiB0aGlzIHN0cnVjdHVyZSBjb250YWlucyB0aGUgaGFzaCBvZiBhIGtleW5hbWUgYW5kIHBvaW50cyB0byBhbGwKICogc3Via2V5cwogKgogKiBleGNlcHRpb246IGlmIHRoZSBpZCBpcyAnaWwnIHRoZXJlIGFyZSBubyBoYXNoIHZhbHVlcyBhbmQgZXZlcnkKICogZHdvcmQgaXMgYSBvZmZzZXQKICovCnN0YXRpYyBpbnQgX250X2R1bXBfbGYoTFBDU1RSIGtleV9uYW1lLCBjaGFyICpiYXNlLCBpbnQgc3Via2V5cywgbnRfbGYgKmxmLCBGSUxFICpmLCBpbnQgbGV2ZWwpCnsKICAgIGludCBpOwoKICAgIGlmIChsZi0+aWQgPT0gTlRfUkVHX0hBU0hfQkxPQ0tfSUQpIHsKICAgICAgICBpZiAoc3Via2V5cyAhPSBsZi0+bnJfa2V5cykgZ290byBlcnJvcjE7CgogICAgICAgIGZvciAoaT0wOyBpPGxmLT5ucl9rZXlzOyBpKyspCiAgICAgICAgICAgIGlmICghX250X2R1bXBfbmsoa2V5X25hbWUsIGJhc2UsIChudF9uayopKGJhc2UrbGYtPmhhc2hfcmVjW2ldLm9mZl9uays0KSwgZiwgbGV2ZWwpKSBnb3RvIGVycm9yOwogICAgfSBlbHNlIGlmIChsZi0+aWQgPT0gTlRfUkVHX05PSEFTSF9CTE9DS19JRCkgewogICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKWxmOwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCiAgICAgICAgZm9yIChpPTA7IGk8bGktPm5yX2tleXM7IGkrKykKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF9uayhrZXlfbmFtZSwgYmFzZSwgKG50X25rKikoYmFzZStsaS0+b2ZmX25rW2ldKzQpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfUklfQkxPQ0tfSUQpIHsgIC8qIHJpICovCiAgICAgICAgbnRfcmkgKiByaSA9IChudF9yaSopbGY7CiAgICAgICAgaW50IGxpX3N1YmtleXMgPSAwOwoKICAgICAgICAvKiBjb3VudCBhbGwgc3Via2V5cyAqLwogICAgICAgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKSB7CiAgICAgICAgICAgIG50X2xpICogbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmKGxpLT5pZCAhPSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKSBnb3RvIGVycm9yMjsKICAgICAgICAgICAgbGlfc3Via2V5cyArPSBsaS0+bnJfa2V5czsKICAgICAgICB9CgogICAgICAgIC8qIGNoZWNrIG51bWJlciAqLwogICAgICAgIGlmIChzdWJrZXlzICE9IGxpX3N1YmtleXMpIGdvdG8gZXJyb3IxOwoKICAgICAgICAvKiBsb29wIHRocm91Z2ggdGhlIGtleXMgKi8KICAgICAgICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykgewogICAgICAgICAgICBudF9saSAqbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CiAgICAgICAgICAgIGlmICghX250X2R1bXBfbGYoa2V5X25hbWUsIGJhc2UsIGxpLT5ucl9rZXlzLCAobnRfbGYqKWxpLCBmLCBsZXZlbCkpIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgfSBlbHNlIGdvdG8gZXJyb3IyOwoKICAgIHJldHVybiBUUlVFOwoKZXJyb3IyOgogICAgaWYgKGxmLT5pZCA9PSAweDY4NmMpCiAgICAgICAgRklYTUUoInVua25vd24gV2luIFhQIG5vZGUgaWQgMHg2ODZjOiBkbyB3ZSBuZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBpdCA/XG4iKTsKICAgIGVsc2UKICAgICAgICBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBsZi0+aWQpOwogICAgcmV0dXJuIFRSVUU7CgplcnJvcjE6CiAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgKGluY29uc2lzdGVudCBudW1iZXIgb2Ygc3Via2V5cylcbiIpOwogICAgcmV0dXJuIEZBTFNFOwoKZXJyb3I6CiAgICBFUlIoImVycm9yIHJlYWRpbmcgbGYgYmxvY2tcbiIpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKiBfbnRfZHVtcF9uayBbSW50ZXJuYWxdICovCnN0YXRpYyBpbnQgX250X2R1bXBfbmsoTFBDU1RSIGtleV9uYW1lLGNoYXIgKmJhc2UsbnRfbmsgKm5rLEZJTEUgKmYsaW50IGxldmVsKQp7CiAgICB1bnNpZ25lZCBpbnQgbjsKICAgIERXT1JEICp2bDsKICAgIExQU1RSIG5ld19rZXlfbmFtZSA9IE5VTEw7CgogICAgVFJBQ0UoIiVzXG4iLCBrZXlfbmFtZSk7CgogICAgaWYgKG5rLT5TdWJCbG9ja0lkICE9IE5UX1JFR19LRVlfQkxPQ0tfSUQpIHsKICAgICAgICBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBuay0+U3ViQmxvY2tJZCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICgobmstPlR5cGUhPU5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKSAmJiAoKChudF9uayopKGJhc2UrbmstPnBhcmVudF9vZmYrNCkpLT5TdWJCbG9ja0lkICE9IE5UX1JFR19LRVlfQkxPQ0tfSUQpKSB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhXG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgLyogY3JlYXRlIHRoZSBuZXcga2V5ICovCiAgICBpZiAobGV2ZWwgPD0gMCkgewogICAgICAgIC8qIGNyZWF0ZSBuZXcgc3Via2V5IG5hbWUgKi8KICAgICAgICBzaXplX3QgbGVuID0gc3RybGVuKGtleV9uYW1lKTsKICAgICAgICBuZXdfa2V5X25hbWUgPSBfeG1hbGxvYyggbGVuK25rLT5uYW1lX2xlbisyICk7CiAgICAgICAgbWVtY3B5KCBuZXdfa2V5X25hbWUsIGtleV9uYW1lLCBsZW4gKTsKICAgICAgICBpZiAobGVuKSBuZXdfa2V5X25hbWVbbGVuKytdID0gJ1xcJzsKICAgICAgICBtZW1jcHkoIG5ld19rZXlfbmFtZSArIGxlbiwgbmstPm5hbWUsIG5rLT5uYW1lX2xlbiApOwogICAgICAgIG5ld19rZXlfbmFtZVtsZW4gKyBuay0+bmFtZV9sZW5dID0gMDsKCiAgICAgICAgLyogd3JpdGUgdGhlIGtleSBwYXRoIChzb21ldGhpbmcgbGlrZSBbU29mdHdhcmVcXE1pY3Jvc29mdFxcLi5dKSBvbmx5IGlmOgogICAgICAgICAgIDEpIGtleSBoYXMgc29tZSB2YWx1ZXMKICAgICAgICAgICAyKSBrZXkgaGFzIG5vIHZhbHVlcyBhbmQgbm8gc3Via2V5cwogICAgICAgICovCiAgICAgICAgaWYgKG5rLT5ucl92YWx1ZXMgPiAwKSB7CiAgICAgICAgICAgIC8qIHRoZXJlIGFyZSBzb21lIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KICAgICAgICBpZiAoKG5rLT5ucl9zdWJrZXlzID09IDApICYmIChuay0+bnJfdmFsdWVzID09IDApKSB7CiAgICAgICAgICAgIC8qIG5vIHN1YmtleXMgYW5kIG5vIHZhbHVlcyAqLwogICAgICAgICAgICBmcHJpbnRmKGYsIlxuWyIpOwogICAgICAgICAgICBfZHVtcF9zdHJBdG9XKG5ld19rZXlfbmFtZSxzdHJsZW4obmV3X2tleV9uYW1lKSxmLCJbXSIpOwogICAgICAgICAgICBmcHJpbnRmKGYsIl1cbiIpOwogICAgICAgIH0KCiAgICAgICAgLyogbG9vcCB0cm91Z2ggdGhlIHZhbHVlIGxpc3QgKi8KICAgICAgICB2bCA9IChEV09SRCAqKShiYXNlK25rLT52YWx1ZWxpc3Rfb2ZmKzQpOwogICAgICAgIGZvciAobj0wOyBuPG5rLT5ucl92YWx1ZXM7IG4rKykgewogICAgICAgICAgICBudF92ayAqIHZrID0gKG50X3ZrKikoYmFzZSt2bFtuXSs0KTsKICAgICAgICAgICAgaWYgKCFfbnRfZHVtcF92ayhuZXdfa2V5X25hbWUsIGJhc2UsIHZrLCBmKSkgewogICAgICAgICAgICAgICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSBlbHNlIG5ld19rZXlfbmFtZSA9IF94c3RyZHVwKGtleV9uYW1lKTsKCiAgICAvKiBsb29wIHRocm91Z2ggdGhlIHN1YmtleXMgKi8KICAgIGlmIChuay0+bnJfc3Via2V5cykgewogICAgICAgIG50X2xmICpsZiA9IChudF9sZiopKGJhc2UrbmstPmxmX29mZis0KTsKICAgICAgICBpZiAoIV9udF9kdW1wX2xmKG5ld19rZXlfbmFtZSwgYmFzZSwgbmstPm5yX3N1YmtleXMsIGxmLCBmLCBsZXZlbC0xKSkgewogICAgICAgICAgICBmcmVlKG5ld19rZXlfbmFtZSk7CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgZnJlZShuZXdfa2V5X25hbWUpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qIGVuZCBudCBsb2FkZXIgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2FsbG9jYXRlX2RlZmF1bHRfa2V5cyBbSW50ZXJuYWxdCiAqIFJlZ2lzdHJ5IGluaXRpYWxpc2F0aW9uLCBhbGxvY2F0ZXMgc29tZSBkZWZhdWx0IGtleXMuCiAqLwpzdGF0aWMgdm9pZCBfYWxsb2NhdGVfZGVmYXVsdF9rZXlzKHZvaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBTdGF0RGF0YVdbXSA9IHsnRCcsJ3knLCduJywnRCcsJ2EnLCd0JywnYScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUCcsJ2UnLCdyJywnZicsJ1MnLCd0JywnYScsJ3QnLCdzJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywndCcsJ2EnLCd0JywnRCcsJ2EnLCd0JywnYScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgQ29uZmlnTWFuYWdlcldbXSA9IHsnRCcsJ3knLCduJywnRCcsJ2EnLCd0JywnYScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbycsJ24nLCdmJywnaScsJ2cnLCcgJywnTScsJ2EnLCduJywnYScsJ2cnLCdlJywncicsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRScsJ24nLCd1JywnbScsMH07CiAgICBIS0VZIGhrZXk7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CgogICAgVFJBQ0UoIih2b2lkKVxuIik7CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBTdGF0RGF0YVcgKTsKICAgIGlmICghTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkgTnRDbG9zZSggaGtleSApOwoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIENvbmZpZ01hbmFnZXJXICk7CiAgICBpZiAoIU50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpIE50Q2xvc2UoIGhrZXkgKTsKfQoKc3RhdGljIHZvaWQgZ2V0X3dpbmRvd3NfZGlyKFdDSEFSKiBidWZmZXIsIHVuc2lnbmVkIGxlbikKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHdpbmRvd3NfZGlyW10gPSB7J2MnLCc6JywnXFwnLCd3JywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywwfTsKICAgIE9CSkVDVF9BVFRSSUJVVEVTICAgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HICAgICAgbmFtZVcsIGtleVc7CiAgICBIS0VZICAgICAgICAgICAgICAgIGhrZXk7CgogICAgKmJ1ZmZlciA9IDA7CiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IDA7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwoKICAgIGlmIChSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCAiTWFjaGluZVxcU29mdHdhcmVcXFdpbmVcXFdpbmVcXENvbmZpZ1xcd2luZSIgKSkKICAgIHsKICAgICAgICBpZiAoIU50T3BlbktleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciApKQogICAgICAgIHsKICAgICAgICAgICAgY2hhciB0bXBbTUFYX1BBVEhOQU1FX0xFTipzaXplb2YoV0NIQVIpICsgc2l6ZW9mKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OKV07CiAgICAgICAgICAgIERXT1JEIGNvdW50OwoKICAgICAgICAgICAgUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZrZXlXLCAiV2luZG93cyIpOwogICAgICAgICAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleSwgJmtleVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICAgICAgICAgIG1lbWNweShidWZmZXIsIHN0ciwgbWluKCgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhTGVuZ3RoLCBsZW4pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJmtleVcgKTsKICAgICAgICB9CiAgICAgICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwogICAgfQogICAgaWYgKCEqYnVmZmVyKSBsc3RyY3B5blcoYnVmZmVyLCB3aW5kb3dzX2RpciwgbGVuKTsKfQoKCiNkZWZpbmUgUkVHX0RPTlRMT0FEIC0xCiNkZWZpbmUgUkVHX1dJTjMxICAgICAwCiNkZWZpbmUgUkVHX1dJTjk1ICAgICAxCiNkZWZpbmUgUkVHX1dJTk5UICAgICAyCgovKiByZXR1cm4gdGhlIHR5cGUgb2YgbmF0aXZlIHJlZ2lzdHJ5IFtJbnRlcm5hbF0gKi8Kc3RhdGljIGludCBfZ2V0X3JlZ190eXBlKGNvbnN0IFdDSEFSKiB3aW5kaXIpCnsKICAgIFdDSEFSIHRtcFtNQVhfUEFUSE5BTUVfTEVOXTsKICAgIGludCByZXQgPSBSRUdfV0lOMzE7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgbnRfcmVnX3BhdGhXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB3aW45eF9yZWdfcGF0aFdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCcuJywnZCcsJ2EnLCd0JywwfTsKCiAgICAvKiB0ZXN0ICV3aW5kaXIlL3N5c3RlbTMyL2NvbmZpZy9zeXN0ZW0gLS0+IHdpbm50ICovCiAgICBzdHJjcHlXKHRtcCwgd2luZGlyKTsKICAgIHN0cmNhdFcodG1wLCBudF9yZWdfcGF0aFcpOwogICAgaWYoR2V0RmlsZUF0dHJpYnV0ZXNXKHRtcCkgIT0gSU5WQUxJRF9GSUxFX0FUVFJJQlVURVMpCiAgICAgIHJldCA9IFJFR19XSU5OVDsKICAgIGVsc2UKICAgIHsKICAgICAgIC8qIHRlc3QgJXdpbmRpciUvc3lzdGVtLmRhdCAtLT4gd2luOTUgKi8KICAgICAgc3RyY3B5Vyh0bXAsIHdpbmRpcik7CiAgICAgIHN0cmNhdFcodG1wLCB3aW45eF9yZWdfcGF0aFcpOwogICAgICBpZihHZXRGaWxlQXR0cmlidXRlc1codG1wKSAhPSBJTlZBTElEX0ZJTEVfQVRUUklCVVRFUykKICAgICAgICByZXQgPSBSRUdfV0lOOTU7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKLyogbG9hZCB0aGUgcmVnaXN0cnkgZmlsZSBpbiB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyB2b2lkIGxvYWRfd2luZV9yZWdpc3RyeShIS0VZIGhrZXksTFBDU1RSIGZuKQp7CiAgICBXQ0hBUiAqYnVmZmVyOwogICAgSEFORExFIGZpbGU7CiAgICBEV09SRCBsZW47CiAgICBVTklDT0RFX1NUUklORyBuYW1lOwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIElPX1NUQVRVU19CTE9DSyBpbzsKCiAgICBsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9VTklYQ1AsIDAsIGZuLCAtMSwgTlVMTCwgMCApOwogICAgaWYgKCEoYnVmZmVyID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4gKiBzaXplb2YoV0NIQVIpICkpKSByZXR1cm47CiAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9VTklYQ1AsIDAsIGZuLCAtMSwgYnVmZmVyLCBsZW4gKTsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZSwgYnVmZmVyICk7CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwoKICAgIGlmICghTnRPcGVuRmlsZSggJmZpbGUsIEdFTkVSSUNfUkVBRCwgJmF0dHIsICZpbywgRklMRV9TSEFSRV9SRUFEIHwgRklMRV9TSEFSRV9XUklURSwKICAgICAgICAgICAgICAgICAgICAgRklMRV9OT05fRElSRUNUT1JZX0ZJTEUgfCBGSUxFX1NZTkNIUk9OT1VTX0lPX05PTkFMRVJUICkpCiAgICB7CiAgICAgICAgU0VSVkVSX1NUQVJUX1JFUSggbG9hZF9yZWdpc3RyeSApCiAgICAgICAgewogICAgICAgICAgICByZXEtPmhrZXkgICAgPSBoa2V5OwogICAgICAgICAgICByZXEtPmZpbGUgICAgPSBmaWxlOwogICAgICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgICAgICB9CiAgICAgICAgU0VSVkVSX0VORF9SRVE7CiAgICAgICAgQ2xvc2VIYW5kbGUoIGZpbGUgKTsKICAgIH0KICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBidWZmZXIgKTsKfQoKLyogZ2VuZXJhdGUgYW5kIHJldHVybiB0aGUgbmFtZSBvZiB0aGUgdG1wIGZpbGUgYW5kIGFzc29jaWF0ZWQgc3RyZWFtIFtJbnRlcm5hbF0gKi8Kc3RhdGljIExQU1RSIF9nZXRfdG1wX2ZuKEZJTEUgKipmKQp7CiAgICBMUFNUUiByZXQ7CiAgICBpbnQgdG1wX2ZkLGNvdW50OwoKICAgIHJldCA9IF94bWFsbG9jKDUwKTsKICAgIGZvciAoY291bnQgPSAwOzspIHsKICAgICAgICBzcHJpbnRmKHJldCwiL3RtcC9yZWclbHglMDR4LnRtcCIsKGxvbmcpZ2V0cGlkKCksY291bnQrKyk7CiAgICAgICAgaWYgKCh0bXBfZmQgPSBvcGVuKHJldCxPX0NSRUFUIHwgT19FWENMIHwgT19XUk9OTFksMDY2NikpICE9IC0xKSBicmVhazsKICAgICAgICBpZiAoZXJybm8gIT0gRUVYSVNUKSB7CiAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBlcnJvciB3aGlsZSBvcGVuKCkgY2FsbDogJXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICAgICAgZnJlZShyZXQpOwogICAgICAgICAgICAqZiA9IE5VTEw7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoKCpmID0gZmRvcGVuKHRtcF9mZCwidyIpKSA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJVbmV4cGVjdGVkIGVycm9yIHdoaWxlIGZkb3BlbigpIGNhbGw6ICVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgY2xvc2UodG1wX2ZkKTsKICAgICAgICBmcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCB3aW45NSBuYXRpdmUgcmVnaXN0cnkgZmlsZSB0byB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfY29udmVydF93aW45NV9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChMUENXU1RSIGZuLCBpbnQgbGV2ZWwpCnsKICAgIEhBTkRMRSBoRmlsZSwgaE1hcHBpbmc7CiAgICBGSUxFICpmOwogICAgdm9pZCAqYmFzZTsKICAgIExQU1RSIHJldCA9IE5VTEw7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgTEFSR0VfSU5URUdFUiBsZ19pbnQ7CiAgICBOVFNUQVRVUyBudHM7CiAgICBTSVpFX1QgbGVuOwoKICAgIF93OTVjcmVnICpjcmVnOwogICAgX3c5NXJna24gKnJna247CiAgICBfdzk1ZGtlICpka2UsICpyb290X2RrZTsKCiAgICBoRmlsZSA9IENyZWF0ZUZpbGVXKCBmbiwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIDAgKTsKICAgIGlmICggaEZpbGUgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUgKSByZXR1cm4gTlVMTDsKCiAgICBhdHRyLkxlbmd0aCAgICAgICAgICAgICAgICAgICA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSAgICAgICAgICAgID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSAgICAgICAgICAgICAgID0gTlVMTDsKICAgIGF0dHIuQXR0cmlidXRlcyAgICAgICAgICAgICAgID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yICAgICAgID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBsZ19pbnQuUXVhZFBhcnQgPSAwOwogICAgbnRzID0gTnRDcmVhdGVTZWN0aW9uKCAmaE1hcHBpbmcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBTVEFOREFSRF9SSUdIVFNfUkVRVUlSRUR8U0VDVElPTl9RVUVSWXxTRUNUSU9OX01BUF9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgICAmYXR0ciwgJmxnX2ludCwgUEFHRV9SRUFET05MWSwgU0VDX0NPTU1JVCwgaEZpbGUgKTsKICAgIGlmIChudHMgIT0gU1RBVFVTX1NVQ0NFU1MpIGdvdG8gZXJyb3IxOwoKICAgIGJhc2UgPSBOVUxMOyBsZW4gPSAwOwogICAgbnRzID0gTnRNYXBWaWV3T2ZTZWN0aW9uKCBoTWFwcGluZywgR2V0Q3VycmVudFByb2Nlc3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmJhc2UsIDAsIDAsICZsZ19pbnQsICZsZW4sIFZpZXdTaGFyZSwgMCwgCgkJCSAgICAgIFBBR0VfUkVBRE9OTFkpOwogICAgTnRDbG9zZSggaE1hcHBpbmcgKTsKICAgIGlmIChudHMgIT0gU1RBVFVTX1NVQ0NFU1MpIGdvdG8gZXJyb3IxOwoKICAgIC8qIGNvbnRyb2wgc2lnbmF0dXJlICovCiAgICBpZiAoKihMUERXT1JEKWJhc2UgIT0gVzk1X1JFR19DUkVHX0lEKSB7CiAgICAgICAgRVJSKCJ1bmFibGUgdG8gbG9hZCBuYXRpdmUgd2luOTUgcmVnaXN0cnkgZmlsZSAlczogdW5rbm93biBzaWduYXR1cmUuXG4iLAogICAgICAgICAgICBkZWJ1Z3N0cl93KGZuKSk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBjcmVnID0gYmFzZTsKICAgIC8qIGxvYWQgdGhlIGhlYWRlciAocmdrbikgKi8KICAgIHJna24gPSAoX3c5NXJna24qKShjcmVnICsgMSk7CiAgICBpZiAocmdrbi0+aWQgIT0gVzk1X1JFR19SR0tOX0lEKSB7CiAgICAgICAgRVJSKCJzZWNvbmQgSUZGIGhlYWRlciBub3QgUkdLTiwgYnV0ICVseFxuIiwgcmdrbi0+aWQpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAocmdrbi0+cm9vdF9vZmYgIT0gMHgyMCkgewogICAgICAgIEVSUigicmdrbi0+cm9vdF9vZmYgbm90IDB4MjAsIHBsZWFzZSByZXBvcnQgIVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5sYXN0X2RrZSA+IHJna24tPnNpemUpCiAgICB7CiAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISBsYXN0X2RrZSA+IHNpemUhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIC8qIHZlcmlmeSBsYXN0IGRrZSAqLwogICAgZGtlID0gKF93OTVka2UqKSgoY2hhciopcmdrbiArIHJna24tPmxhc3RfZGtlKTsKICAgIGlmIChka2UtPngxICE9IDB4ODAwMDAwMDApCiAgICB7IC8qIHdyb25nIG1hZ2ljICovCiAgICAgIEVSUigibGFzdCBka2UgaW52YWxpZCAhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChyZ2tuLT5zaXplID4gY3JlZy0+cmdkYl9vZmYpCiAgICB7CiAgICAgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISByZ2tuIHNpemUgPiByZ2RiX29mZiAhXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIHJvb3RfZGtlID0gKF93OTVka2UqKSgoY2hhciopcmdrbiArIHJna24tPnJvb3Rfb2ZmKTsKICAgIGlmICggKHJvb3RfZGtlLT5wcmV2bHZsICE9IDB4ZmZmZmZmZmYpIHx8IChyb290X2RrZS0+bmV4dCAhPSAweGZmZmZmZmZmKSApCiAgICB7CiAgICAgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGludmFsaWQgcm9vdCBka2UgIVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAoIChyZXQgPSBfZ2V0X3RtcF9mbigmZikpID09IE5VTEwpIGdvdG8gZXJyb3I7CiAgICBmcHJpbnRmKGYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAyIik7CiAgICBfdzk1X2R1bXBfZGtlKCIiLGNyZWcscmdrbixyb290X2RrZSxmLGxldmVsKTsKICAgIGZjbG9zZShmKTsKCmVycm9yOgogICAgaWYocmV0ID09IE5VTEwpIHsKICAgICAgICBFUlIoIlVuYWJsZSB0byBsb2FkIG5hdGl2ZSB3aW45NSByZWdpc3RyeSBmaWxlICVzLlxuIiwgZGVidWdzdHJfdyhmbikpOwogICAgICAgIEVSUigiUGxlYXNlIHJlcG9ydCB0aGlzLlxuIik7CiAgICAgICAgRVJSKCJNYWtlIGEgYmFja3VwIG9mIHRoZSBmaWxlLCBydW4gYSBnb29kIHJlZyBjbGVhbmVyIHByb2dyYW0gYW5kIHRyeSBhZ2FpbiFcbiIpOwogICAgfQoKICAgIE50VW5tYXBWaWV3T2ZTZWN0aW9uKCBHZXRDdXJyZW50UHJvY2VzcygpLCBiYXNlICk7CmVycm9yMToKICAgIE50Q2xvc2UoaEZpbGUpOwogICAgcmV0dXJuIHJldDsKfQoKLyogY29udmVydCB3aW5udCBuYXRpdmUgcmVnaXN0cnkgZmlsZSB0byB3aW5lIGZvcm1hdCBbSW50ZXJuYWxdICovCnN0YXRpYyBMUFNUUiBfY29udmVydF93aW5udF9yZWdpc3RyeV90b193aW5lX2Zvcm1hdChMUENXU1RSIGZuLCBpbnQgbGV2ZWwpCnsKICAgIEZJTEUgKmY7CiAgICB2b2lkICpiYXNlOwogICAgTFBTVFIgcmV0ID0gTlVMTDsKICAgIEhBTkRMRSBoRmlsZTsKICAgIEhBTkRMRSBoTWFwcGluZzsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBMQVJHRV9JTlRFR0VSIGxnX2ludDsKICAgIE5UU1RBVFVTIG50czsKICAgIFNJWkVfVCBsZW47CgogICAgbnRfcmVnZiAqcmVnZjsKICAgIG50X2hiaW4gKmhiaW47CiAgICBudF9oYmluX3N1YiAqaGJpbl9zdWI7CiAgICBudF9uayAqbms7CgogICAgVFJBQ0UoIiVzXG4iLCBkZWJ1Z3N0cl93KGZuKSk7CgogICAgaEZpbGUgPSBDcmVhdGVGaWxlVyggZm4sIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELCBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwICk7CiAgICBpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CiAgICBhdHRyLkxlbmd0aCAgICAgICAgICAgICAgICAgICA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSAgICAgICAgICAgID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSAgICAgICAgICAgICAgID0gTlVMTDsKICAgIGF0dHIuQXR0cmlidXRlcyAgICAgICAgICAgICAgID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yICAgICAgID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBsZ19pbnQuUXVhZFBhcnQgPSAwOwogICAgbnRzID0gTnRDcmVhdGVTZWN0aW9uKCAmaE1hcHBpbmcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBTVEFOREFSRF9SSUdIVFNfUkVRVUlSRUR8U0VDVElPTl9RVUVSWXxTRUNUSU9OX01BUF9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgICAmYXR0ciwgJmxnX2ludCwgUEFHRV9SRUFET05MWSwgU0VDX0NPTU1JVCwgaEZpbGUgKTsKICAgIGlmIChudHMgIT0gU1RBVFVTX1NVQ0NFU1MpIGdvdG8gZXJyb3IxOwoKICAgIGJhc2UgPSBOVUxMOyBsZW4gPSAwOwogICAgbnRzID0gTnRNYXBWaWV3T2ZTZWN0aW9uKCBoTWFwcGluZywgR2V0Q3VycmVudFByb2Nlc3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmJhc2UsIDAsIDAsICZsZ19pbnQsICZsZW4sIFZpZXdTaGFyZSwgMCwgCgkJCSAgICAgIFBBR0VfUkVBRE9OTFkpOwogICAgTnRDbG9zZSggaE1hcHBpbmcgKTsKICAgIGlmIChudHMgIT0gU1RBVFVTX1NVQ0NFU1MpIGdvdG8gZXJyb3IxOwoKICAgIC8qIGNvbnRyb2wgc2lnbmF0dXJlICovCiAgICBpZiAoKihMUERXT1JEKWJhc2UgIT0gTlRfUkVHX0hFQURFUl9CTE9DS19JRCkgewogICAgICAgIEVSUigidW5hYmxlIHRvIGxvYWQgbmF0aXZlIHdpbm50IHJlZ2lzdHJ5IGZpbGUgJXM6IHVua25vd24gc2lnbmF0dXJlLlxuIiwKICAgICAgICAgICAgZGVidWdzdHJfdyhmbikpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogc3RhcnQgYmxvY2sgKi8KICAgIHJlZ2YgPSBiYXNlOwoKICAgIC8qIGhiaW4gYmxvY2sgKi8KICAgIGhiaW4gPSAobnRfaGJpbiopKChjaGFyKikgYmFzZSArIDB4MTAwMCk7CiAgICBpZiAoaGJpbi0+aWQgIT0gTlRfUkVHX1BPT0xfQkxPQ0tfSUQpIHsKICAgICAgRVJSKCAiaGJpbiBibG9jayBpbnZhbGlkXG4iKTsKICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBoYmluX3N1YiBibG9jayAqLwogICAgaGJpbl9zdWIgPSAobnRfaGJpbl9zdWIqKSYoaGJpbi0+aGJpbl9zdWIpOwogICAgaWYgKChoYmluX3N1Yi0+ZGF0YVswXSAhPSAnbicpIHx8IChoYmluX3N1Yi0+ZGF0YVsxXSAhPSAnaycpKSB7CiAgICAgIEVSUiggImhiaW5fc3ViIGJsb2NrIGludmFsaWRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIG5rIGJsb2NrICovCiAgICBuayA9IChudF9uayopJihoYmluX3N1Yi0+ZGF0YVswXSk7CiAgICBpZiAobmstPlR5cGUgIT0gTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpIHsKICAgICAgRVJSKCAic3BlY2lhbCBuayBibG9jayBub3QgZm91bmRcbiIpOwogICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGlmICggKHJldCA9IF9nZXRfdG1wX2ZuKCZmKSkgPT0gTlVMTCkgZ290byBlcnJvcjsKICAgIGZwcmludGYoZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uIDIiKTsKICAgIF9udF9kdW1wX25rKCIiLChjaGFyKiliYXNlKzB4MTAwMCxuayxmLGxldmVsKTsKICAgIGZjbG9zZShmKTsKCmVycm9yOgogICAgTnRVbm1hcFZpZXdPZlNlY3Rpb24oIEdldEN1cnJlbnRQcm9jZXNzKCksIGJhc2UgKTsKZXJyb3IxOgogICAgTnRDbG9zZShoRmlsZSk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBjb252ZXJ0IG5hdGl2ZSByZWdpc3RyeSB0byB3aW5lIGZvcm1hdCBhbmQgbG9hZCBpdCB2aWEgc2VydmVyIGNhbGwgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkoTFBDV1NUUiBmbiwgSEtFWSBoa2V5LCBpbnQgcmVnX3R5cGUsIGludCBsZXZlbCkKewogICAgTFBTVFIgdG1wID0gTlVMTDsKCiAgICBzd2l0Y2ggKHJlZ190eXBlKSB7CiAgICAgICAgY2FzZSBSRUdfV0lOTlQ6CiAgICAgICAgICAgIC8qIEZJWE1FOiBmb2xsb3dpbmcgZnVuY3Rpb24gZG9lc24ndCByZWFsbHkgY29udmVydCB5ZXQgKi8KICAgICAgICAgICAgdG1wID0gX2NvbnZlcnRfd2lubnRfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoZm4sbGV2ZWwpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19XSU45NToKICAgICAgICAgICAgdG1wID0gX2NvbnZlcnRfd2luOTVfcmVnaXN0cnlfdG9fd2luZV9mb3JtYXQoZm4sbGV2ZWwpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19XSU4zMToKICAgICAgICAgICAgRVJSKCJEb24ndCBrbm93IGhvdyB0byBjb252ZXJ0IG5hdGl2ZSAzLjEgcmVnaXN0cnkgeWV0LlxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiVW5rbm93biByZWdpc3RyeSBmb3JtYXQgcGFyYW1ldGVyICglZClcbiIscmVnX3R5cGUpOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAodG1wICE9IE5VTEwpIHsKICAgICAgICBsb2FkX3dpbmVfcmVnaXN0cnkoaGtleSx0bXApOwogICAgICAgIFRSQUNFKCJGaWxlICVzIHN1Y2Nlc3NmdWxseSBjb252ZXJ0ZWQgdG8gJXMgYW5kIGxvYWRlZCB0byByZWdpc3RyeS5cbiIsCiAgICAgICAgICAgICAgZGVidWdzdHJfdyhmbiksIHRtcCk7CiAgICAgICAgdW5saW5rKHRtcCk7CiAgICB9CiAgICBlbHNlIFdBUk4oIlVuYWJsZSB0byBjb252ZXJ0ICVzIChkb2Vzbid0IGV4aXN0PylcbiIsIGRlYnVnc3RyX3coZm4pKTsKICAgIGZyZWUodG1wKTsKfQoKLyogbG9hZCBhbGwgbmF0aXZlIHdpbmRvd3MgcmVnaXN0cnkgZmlsZXMgW0ludGVybmFsXSAqLwpzdGF0aWMgdm9pZCBfbG9hZF93aW5kb3dzX3JlZ2lzdHJ5KCBIS0VZIGhrZXlfbG9jYWxfbWFjaGluZSwgSEtFWSBoa2V5X2N1cnJlbnRfdXNlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQgKQp7CiAgICBpbnQgcmVnX3R5cGU7CiAgICBXQ0hBUiB3aW5kaXJbTUFYX1BBVEhOQU1FX0xFTl07CiAgICBXQ0hBUiBwYXRoW01BWF9QQVRITkFNRV9MRU5dOwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgSEtFWSBoa2V5LCBwcm9maWxlX2tleTsKICAgIGNoYXIgdG1wWzEwMjRdOwogICAgRFdPUkQgZHVtbXk7CgogICAgc3RhdGljIGNvbnN0IFdDSEFSIFdpbmVXW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVycsJ2knLCduJywnZScsJ1xcJywnVycsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ1cnLCdpJywnbicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFByb2ZpbGVXW10gPSB7J1AnLCdyJywnbycsJ2YnLCdpJywnbCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFN5c3RlbVtdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLCdTJywneScsJ3MnLCd0JywnZScsJ20nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIFNvZnR3YXJlW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBDbG9uZVtdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1MnLCd5JywncycsJ3QnLCdlJywnbScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbCcsJ28nLCduJywnZScsMH07CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBXaW5lVyApOwogICAgaWYgKE50Q3JlYXRlS2V5KCAmcHJvZmlsZV9rZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgTlVMTCApKSBwcm9maWxlX2tleSA9IDA7CgogICAgZ2V0X3dpbmRvd3NfZGlyKHdpbmRpciwgc2l6ZW9mKHdpbmRpcikpOwoKICAgIHJlZ190eXBlID0gX2dldF9yZWdfdHlwZSh3aW5kaXIpOwogICAgc3dpdGNoIChyZWdfdHlwZSkgewogICAgICAgIGNhc2UgUkVHX1dJTk5UOiB7CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBudHVzZXJfZGF0V1tdID0geydcXCcsJ24nLCd0JywndScsJ3MnLCdlJywncicsJy4nLCdkJywnYScsJ3QnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgZGVmYXVsdFdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdkJywnZScsJ2YnLCdhJywndScsJ2wnLCd0JywwfTsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHN5c3RlbVdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc29mdHdhcmVXW10gPSB7J1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnMycsJzInLCdcXCcsJ2MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywncycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgc2FtV1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJzMnLCcyJywnXFwnLCdjJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsJ3MnLCdhJywnbScsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzZWN1cml0eVdbXSA9IHsnXFwnLCdzJywneScsJ3MnLCd0JywnZScsJ20nLCczJywnMicsJ1xcJywnYycsJ28nLCduJywnZicsJ2knLCdnJywnXFwnLCdzJywnZScsJ2MnLCd1JywncicsJ2knLCd0JywneScsMH07CgogICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIG50dXNlci5kYXQgKi8KICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgUHJvZmlsZVcgKTsKICAgICAgICAgICAgaWYgKHByb2ZpbGVfa2V5ICYmICFOdFF1ZXJ5VmFsdWVLZXkoIHByb2ZpbGVfa2V5LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wLCBzaXplb2YodG1wKSwgJmR1bW15ICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGEpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBudHVzZXJfZGF0Vyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2N1cnJlbnRfdXNlcixSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBNRVNTQUdFKCJXaGVuIHlvdSBhcmUgcnVubmluZyB3aXRoIGEgbmF0aXZlIE5UIGRpcmVjdG9yeSBzcGVjaWZ5XG4iKTsKICAgICAgICAgICAgICAgIE1FU1NBR0UoIidQcm9maWxlPTxwcm9maWxlZGlyZWN0b3J5Picgb3IgZGlzYWJsZSBsb2FkaW5nIG9mIFdpbmRvd3NcbiIpOwogICAgICAgICAgICAgICAgTUVTU0FHRSgicmVnaXN0cnkgKExvYWRXaW5kb3dzUmVnaXN0cnlGaWxlcz1OKVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogZGVmYXVsdCB1c2VyLmRhdCAqLwogICAgICAgICAgICBpZiAoaGtleV91c2Vyc19kZWZhdWx0KSB7CiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIGRlZmF1bHRXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfdXNlcnNfZGVmYXVsdCxSRUdfV0lOTlQsMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICogRklYTUUKICAgICAgICAgICAgKiAgbWFwIEhMTVxTeXN0ZW1cQ29udHJvbFNldDAwMSB0byBITE1cU3lzdGVtXEN1cnJlbnRDb250cm9sU2V0CiAgICAgICAgICAgICovCiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFN5c3RlbSApOwogICAgICAgICAgICBpZiAoIU50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgc3lzdGVtVyk7CiAgICAgICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5LFJFR19XSU5OVCwxKTsKICAgICAgICAgICAgICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBTb2Z0d2FyZSApOwogICAgICAgICAgICBpZiAoIU50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgc29mdHdhcmVXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXksUkVHX1dJTk5ULDEpOwogICAgICAgICAgICAgICAgTnRDbG9zZSggaGtleSApOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgc2FtVyk7CiAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfbG9jYWxfbWFjaGluZSxSRUdfV0lOTlQsMCk7CgogICAgICAgICAgICBzdHJjcHlXKHBhdGgsd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBzZWN1cml0eVcpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2xvY2FsX21hY2hpbmUsUkVHX1dJTk5ULDApOwoKICAgICAgICAgICAgLyogdGhpcyBrZXkgaXMgZ2VuZXJhdGVkIHdoZW4gdGhlIG50LWNvcmUgYm9vdGVkIHN1Y2Nlc3NmdWxseSAqLwogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBDbG9uZSApOwogICAgICAgICAgICBpZiAoIU50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIFJFR19XSU45NToKICAgICAgICB7CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzeXN0ZW1fMXN0V1tdID0geydjJywnOicsJ1xcJywncycsJ3knLCdzJywndCcsJ2UnLCdtJywnLicsJzEnLCdzJywndCcsMH07CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzeXN0ZW1fZGF0V1tdID0geydcXCcsJ3MnLCd5JywncycsJ3QnLCdlJywnbScsJy4nLCdkJywnYScsJ3QnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgY2xhc3Nlc19kYXRXW10gPSB7J1xcJywnYycsJ2wnLCdhJywncycsJ3MnLCdlJywncycsJy4nLCdkJywnYScsJ3QnLDB9OwogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgdXNlcl9kYXRXW10gPSB7J1xcJywndScsJ3MnLCdlJywncicsJy4nLCdkJywnYScsJ3QnLDB9OwoKICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHN5c3RlbV8xc3RXLGhrZXlfbG9jYWxfbWFjaGluZSxSRUdfV0lOOTUsMCk7CgogICAgICAgICAgICBzdHJjcHlXKHBhdGgsIHdpbmRpcik7CiAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgc3lzdGVtX2RhdFcpOwogICAgICAgICAgICBfY29udmVydF9hbmRfbG9hZF9uYXRpdmVfcmVnaXN0cnkocGF0aCxoa2V5X2xvY2FsX21hY2hpbmUsUkVHX1dJTjk1LDApOwoKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgQ2xhc3Nlc1Jvb3RXICk7CiAgICAgICAgICAgIGlmICghTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyY3B5VyhwYXRoLCB3aW5kaXIpOwogICAgICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCBjbGFzc2VzX2RhdFcpOwogICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleSxSRUdfV0lOOTUsMCk7CiAgICAgICAgICAgICAgICBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFByb2ZpbGVXICk7CiAgICAgICAgICAgIGlmIChwcm9maWxlX2tleSAmJiAhTnRRdWVyeVZhbHVlS2V5KCBwcm9maWxlX2tleSwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcCwgc2l6ZW9mKHRtcCksICZkdW1teSApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIHVzZXIuZGF0ICovCiAgICAgICAgICAgICAgICBzdHJjcHlXKHBhdGgsIChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgdXNlcl9kYXRXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfY3VycmVudF91c2VyLFJFR19XSU45NSwxKTsKCgkgICAgICAgIC8qIGRlZmF1bHQgdXNlci5kYXQgKi8KCSAgICAgICAgaWYgKGhrZXlfdXNlcnNfZGVmYXVsdCkgewogICAgICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgICAgICBzdHJjYXRXKHBhdGgsIHVzZXJfZGF0Vyk7CiAgICAgICAgICAgICAgICAgICAgX2NvbnZlcnRfYW5kX2xvYWRfbmF0aXZlX3JlZ2lzdHJ5KHBhdGgsaGtleV91c2Vyc19kZWZhdWx0LFJFR19XSU45NSwxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgICAgIHN0cmNhdFcocGF0aCwgdXNlcl9kYXRXKTsKICAgICAgICAgICAgICAgIF9jb252ZXJ0X2FuZF9sb2FkX25hdGl2ZV9yZWdpc3RyeShwYXRoLGhrZXlfY3VycmVudF91c2VyLFJFR19XSU45NSwxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgUkVHX1dJTjMxOgogICAgICAgIHsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHJlZ19kYXRXW10gPSB7J1xcJywncicsJ2UnLCdnJywnLicsJ2QnLCdhJywndCcsMH07CiAgICAgICAgICAgIC8qIEZJWE1FOiBoZXJlIHdlIHNob3VsZCBjb252ZXJ0IHRvICoucmVnIGZpbGUgc3VwcG9ydGVkIGJ5IHNlcnZlciBhbmQgY2FsbCBSRVFfTE9BRF9SRUdJU1RSWSwgc2VlIFJFR19XSU45NSBjYXNlICovCiAgICAgICAgICAgIHN0cmNweVcocGF0aCwgd2luZGlyKTsKICAgICAgICAgICAgc3RyY2F0VyhwYXRoLCByZWdfZGF0Vyk7CiAgICAgICAgICAgIF93MzFfbG9hZHJlZyggcGF0aCApOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgUkVHX0RPTlRMT0FEOgogICAgICAgICAgICBUUkFDRSgiUkVHX0RPTlRMT0FEXG4iKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigic3dpdGNoOiBubyBtYXRjaCAoJWQpXG4iLHJlZ190eXBlKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgfQogICAgaWYgKHByb2ZpbGVfa2V5KSBOdENsb3NlKCBwcm9maWxlX2tleSApOwp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWluaXRfY2Ryb21fcmVnaXN0cnkKICoKICogSW5pdGlhbGl6ZXMgcmVnaXN0cnkgdG8gY29udGFpbiBzY3NpIGluZm8gYWJvdXQgdGhlIGNkcm9tIGluIE5ULgogKiBBbGwgZGV2aWNlcyAoZXZlbiBub3QgcmVhbCBzY3NpIG9uZXMpIGhhdmUgdGhpcyBpbmZvIGluIE5ULgogKiBUT0RPOiBmb3Igbm93IGl0IG9ubHkgd29ya3MgZm9yIG5vbiBzY3NpIGRldmljZXMKICogTk9URTogcHJvZ3JhbXMgdXN1YWxseSByZWFkIHRoZXNlIHJlZ2lzdHJ5IGVudHJpZXMgYWZ0ZXIgc2VuZGluZyB0aGUKICogICAgICAgSU9DVExfU0NTSV9HRVRfQUREUkVTUyBpb2N0bCB0byB0aGUgY2Ryb20KICovCnN0YXRpYyB2b2lkIGluaXRfY2Ryb21fcmVnaXN0cnkoIEhBTkRMRSBoYW5kbGUgKQp7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBXQ0hBUiBkYXRhV1s1MF07CiAgICBEV09SRCBsZW5XOwogICAgY2hhciBidWZmZXJbNDBdOwogICAgRFdPUkQgdmFsdWU7CiAgICBjb25zdCBjaGFyICpkYXRhOwogICAgSEtFWSBzY3NpS2V5OwogICAgSEtFWSBwb3J0S2V5OwogICAgSEtFWSBidXNLZXk7CiAgICBIS0VZIHRhcmdldEtleTsKICAgIERXT1JEIGRpc3A7CiAgICBJT19TVEFUVVNfQkxPQ0sgaW87CiAgICBTQ1NJX0FERFJFU1Mgc2NzaV9hZGRyOwoKICAgIGlmIChOdERldmljZUlvQ29udHJvbEZpbGUoIGhhbmRsZSwgMCwgTlVMTCwgTlVMTCwgJmlvLCBJT0NUTF9TQ1NJX0dFVF9BRERSRVNTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgMCwgJnNjc2lfYWRkciwgc2l6ZW9mKHNjc2lfYWRkcikgKSkKICAgICAgICByZXR1cm47CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICAvKiBFbnN1cmUgdGhlcmUgaXMgU2NzaSBrZXkgKi8KICAgIGlmICghUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZuYW1lVywgIk1hY2hpbmVcXEhBUkRXQVJFXFxERVZJQ0VNQVBcXFNjc2kiICkgfHwKICAgICAgICBOdENyZWF0ZUtleSggJnNjc2lLZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwKICAgICAgICAgICAgICAgICAgICAgTlVMTCwgUkVHX09QVElPTl9WT0xBVElMRSwgJmRpc3AgKSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBjcmVhdGUgREVWSUNFTUFQXFxTY3NpIHJlZ2lzdHJ5IGtleVxuIiApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCAmbmFtZVcgKTsKCiAgICBzbnByaW50ZihidWZmZXIsc2l6ZW9mKGJ1ZmZlciksIlNjc2kgUG9ydCAlZCIsc2NzaV9hZGRyLlBvcnROdW1iZXIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gc2NzaUtleTsKICAgIGlmICghUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZuYW1lVywgYnVmZmVyICkgfHwKICAgICAgICBOdENyZWF0ZUtleSggJnBvcnRLZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwKICAgICAgICAgICAgICAgICAgICAgTlVMTCwgUkVHX09QVElPTl9WT0xBVElMRSwgJmRpc3AgKSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBjcmVhdGUgREVWSUNFTUFQXFxTY3NpIFBvcnQgcmVnaXN0cnkga2V5XG4iICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwoKICAgIFJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsICJEcml2ZXIiICk7CiAgICBkYXRhID0gImF0YXBpIjsKICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4oIGRhdGFXLCA1MCwgJmxlblcsIGRhdGEsIHN0cmxlbihkYXRhKSk7CiAgICBOdFNldFZhbHVlS2V5KCBwb3J0S2V5LCAmbmFtZVcsIDAsIFJFR19TWiwgKEJZVEUqKWRhdGFXLCBsZW5XICk7CiAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CiAgICB2YWx1ZSA9IDEwOwogICAgUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZuYW1lVywgIkZpcnN0QnVzVGltZVNjYW5Jbk1zIiApOwogICAgTnRTZXRWYWx1ZUtleSggcG9ydEtleSwmbmFtZVcsIDAsIFJFR19EV09SRCwgKEJZVEUgKikmdmFsdWUsIHNpemVvZihEV09SRCkpOwogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwogICAgdmFsdWUgPSAwOwojaWZkZWYgSERJT19HRVRfRE1BCiAgICB7CiAgICAgICAgaW50IGZkLCBkbWE7CiAgICAgICAgaWYgKCF3aW5lX3NlcnZlcl9oYW5kbGVfdG9fZmQoIGhhbmRsZSwgMCwgJmZkLCBOVUxMICkpCiAgICAgICAgewogICAgICAgICAgICBpZiAoaW9jdGwoZmQsSERJT19HRVRfRE1BLCAmZG1hKSAhPSAtMSkgdmFsdWUgPSBkbWE7CiAgICAgICAgICAgIHdpbmVfc2VydmVyX3JlbGVhc2VfZmQoIGhhbmRsZSwgZmQgKTsKICAgICAgICB9CiAgICB9CiNlbmRpZgogICAgUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZuYW1lVywgIkRNQUVuYWJsZWQiICk7CiAgICBOdFNldFZhbHVlS2V5KCBwb3J0S2V5LCZuYW1lVywgMCwgUkVHX0RXT1JELCAoQllURSAqKSZ2YWx1ZSwgc2l6ZW9mKERXT1JEKSk7CiAgICBSdGxGcmVlVW5pY29kZVN0cmluZyggJm5hbWVXICk7CgogICAgc25wcmludGYoYnVmZmVyLDQwLCJTY3NpIEJ1cyAlZCIsIHNjc2lfYWRkci5QYXRoSWQpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gcG9ydEtleTsKICAgIGlmICghUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZuYW1lVywgYnVmZmVyICkgfHwKICAgICAgICBOdENyZWF0ZUtleSggJmJ1c0tleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLAogICAgICAgICAgICAgICAgICAgICBOVUxMLCBSRUdfT1BUSU9OX1ZPTEFUSUxFLCAmZGlzcCApKQogICAgewogICAgICAgIEVSUigiQ2Fubm90IGNyZWF0ZSBERVZJQ0VNQVBcXFNjc2kgUG9ydFxcU2NzaSBCdXMgcmVnaXN0cnkga2V5XG4iICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwoKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IGJ1c0tleTsKICAgIGlmICghUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZuYW1lVywgIkluaXRpYXRvciBJZCAyNTUiICkgfHwKICAgICAgICBOdENyZWF0ZUtleSggJnRhcmdldEtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLAogICAgICAgICAgICAgICAgICAgICBOVUxMLCBSRUdfT1BUSU9OX1ZPTEFUSUxFLCAmZGlzcCApKQogICAgewogICAgICAgIEVSUigiQ2Fubm90IGNyZWF0ZSBERVZJQ0VNQVBcXFNjc2kgUG9ydFxcU2NzaSBCdXNcXEluaXRpYXRvciBJZCAyNTUgcmVnaXN0cnkga2V5XG4iICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwogICAgTnRDbG9zZSggdGFyZ2V0S2V5ICk7CgogICAgc25wcmludGYoYnVmZmVyLDQwLCJUYXJnZXQgSWQgJWQiLCBzY3NpX2FkZHIuVGFyZ2V0SWQpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gYnVzS2V5OwogICAgaWYgKCFSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeiggJm5hbWVXLCBidWZmZXIgKSB8fAogICAgICAgIE50Q3JlYXRlS2V5KCAmdGFyZ2V0S2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsCiAgICAgICAgICAgICAgICAgICAgIE5VTEwsIFJFR19PUFRJT05fVk9MQVRJTEUsICZkaXNwICkpCiAgICB7CiAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIERFVklDRU1BUFxcU2NzaSBQb3J0XFxTY3NpIEJ1cyAwXFxUYXJnZXQgSWQgcmVnaXN0cnkga2V5XG4iICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwoKICAgIFJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsICJUeXBlIiApOwogICAgZGF0YSA9ICJDZFJvbVBlcmlwaGVyYWwiOwogICAgUnRsTXVsdGlCeXRlVG9Vbmljb2RlTiggZGF0YVcsIDUwLCAmbGVuVywgZGF0YSwgc3RybGVuKGRhdGEpKTsKICAgIE50U2V0VmFsdWVLZXkoIHRhcmdldEtleSwgJm5hbWVXLCAwLCBSRUdfU1osIChCWVRFKilkYXRhVywgbGVuVyApOwogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwogICAgLyogRklYTUUgLSBtYXliZSByZWFkIHRoZSByZWFsIGlkZW50aWZpZXI/PyAqLwogICAgUnRsQ3JlYXRlVW5pY29kZVN0cmluZ0Zyb21Bc2NpaXooICZuYW1lVywgIklkZW50aWZpZXIiICk7CiAgICBkYXRhID0gIldpbmUgQ0RST00iOwogICAgUnRsTXVsdGlCeXRlVG9Vbmljb2RlTiggZGF0YVcsIDUwLCAmbGVuVywgZGF0YSwgc3RybGVuKGRhdGEpKTsKICAgIE50U2V0VmFsdWVLZXkoIHRhcmdldEtleSwgJm5hbWVXLCAwLCBSRUdfU1osIChCWVRFKilkYXRhVywgbGVuVyApOwogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwogICAgLyogRklYTUUgLSB3ZSBhbHdheXMgdXNlIENkcm9tMCAtIGRvIG5vdCBrbm93IGFib3V0IHRoZSBudCBiZWhhdmlvdXIgKi8KICAgIFJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCAmbmFtZVcsICJEZXZpY2VOYW1lIiApOwogICAgZGF0YSA9ICJDZHJvbTAiOwogICAgUnRsTXVsdGlCeXRlVG9Vbmljb2RlTiggZGF0YVcsIDUwLCAmbGVuVywgZGF0YSwgc3RybGVuKGRhdGEpKTsKICAgIE50U2V0VmFsdWVLZXkoIHRhcmdldEtleSwgJm5hbWVXLCAwLCBSRUdfU1osIChCWVRFKilkYXRhVywgbGVuVyApOwogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoICZuYW1lVyApOwoKICAgIE50Q2xvc2UoIHRhcmdldEtleSApOwogICAgTnRDbG9zZSggYnVzS2V5ICk7CiAgICBOdENsb3NlKCBwb3J0S2V5ICk7CiAgICBOdENsb3NlKCBzY3NpS2V5ICk7Cn0KCgovKiBjcmVhdGUgdGhlIGhhcmR3YXJlIHJlZ2lzdHJ5IGJyYW5jaCAqLwpzdGF0aWMgdm9pZCBjcmVhdGVfaGFyZHdhcmVfYnJhbmNoKHZvaWQpCnsKICAgIGludCBpOwogICAgSEFORExFIGhhbmRsZTsKICAgIGNoYXIgZHJpdmVbXSA9ICJcXFxcLlxcQToiOwoKICAgIC8qIGNyZWF0ZSBlbnRyaWVzIGZvciBjZHJvbXMgKi8KICAgIGZvciAoaSA9IDA7IGkgPCAyNjsgaSsrKQogICAgewogICAgICAgIGRyaXZlWzRdID0gJ0EnICsgaTsKICAgICAgICBoYW5kbGUgPSBDcmVhdGVGaWxlQSggZHJpdmUsIDAsIDAsIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIDAgKTsKICAgICAgICBpZiAoaGFuZGxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSBjb250aW51ZTsKICAgICAgICBpbml0X2Nkcm9tX3JlZ2lzdHJ5KCBoYW5kbGUgKTsKICAgICAgICBDbG9zZUhhbmRsZSggaGFuZGxlICk7CiAgICB9Cn0KCgovKiBjb252ZXJ0IHRoZSBkcml2ZSB0eXBlIGVudHJpZXMgZnJvbSB0aGUgb2xkIGZvcm1hdCB0byB0aGUgbmV3IG9uZSAqLwpzdGF0aWMgdm9pZCBjb252ZXJ0X2RyaXZlX3R5cGVzKHZvaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBUeXBlV1tdID0geydUJywneScsJ3AnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBkcml2ZV90eXBlc19rZXlXW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1cnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdEJywncicsJ2knLCd2JywnZScsJ3MnLDAgfTsKICAgIFdDSEFSIGRyaXZlV1tdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLCdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLCdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgJ0MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywnRCcsJ3InLCdpJywndicsJ2UnLCcgJywnQScsMH07CiAgICBjaGFyIHRtcFszMipzaXplb2YoV0NIQVIpICsgc2l6ZW9mKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OKV07CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBEV09SRCBkdW1teTsKICAgIFVMT05HIGRpc3A7CiAgICBIS0VZIGhrZXlfb2xkLCBoa2V5X25ldzsKICAgIGludCBpOwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBkcml2ZV90eXBlc19rZXlXICk7CgogICAgaWYgKE50Q3JlYXRlS2V5KCAmaGtleV9uZXcsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciwgMCwgTlVMTCwgMCwgJmRpc3AgKSkgcmV0dXJuOwogICAgaWYgKGRpc3AgIT0gUkVHX0NSRUFURURfTkVXX0tFWSkKICAgIHsKICAgICAgICBOdENsb3NlKCBoa2V5X25ldyApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDwgMjY7IGkrKykKICAgIHsKICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBkcml2ZVcgKTsKICAgICAgICBuYW1lVy5CdWZmZXJbKG5hbWVXLkxlbmd0aCAvIHNpemVvZihXQ0hBUikpIC0gMV0gPSAnQScgKyBpOwogICAgICAgIGlmIChOdE9wZW5LZXkoICZoa2V5X29sZCwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyICkgIT0gU1RBVFVTX1NVQ0NFU1MpIGNvbnRpbnVlOwogICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIFR5cGVXICk7CiAgICAgICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfb2xkLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmZHVtbXkgKSkKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIHZhbHVlV1tdID0geydBJywnOicsMH07CiAgICAgICAgICAgIFdDSEFSICp0eXBlID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CgogICAgICAgICAgICB2YWx1ZVdbMF0gPSAnQScgKyBpOwogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCB2YWx1ZVcgKTsKICAgICAgICAgICAgTnRTZXRWYWx1ZUtleSggaGtleV9uZXcsICZuYW1lVywgMCwgUkVHX1NaLCB0eXBlLCAoc3RybGVuVyh0eXBlKSArIDEpICogc2l6ZW9mKFdDSEFSKSApOwogICAgICAgICAgICBNRVNTQUdFKCAiQ29udmVydGVkIGRyaXZlIHR5cGUgdG8gbmV3IGVudHJ5IEhLTE1cXFNvZnR3YXJlXFxXaW5lXFxEcml2ZXMgXCIlYzpcIiA9ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAnQScgKyBpLCBkZWJ1Z3N0cl93KHR5cGUpICk7CiAgICAgICAgfQogICAgICAgIE50Q2xvc2UoIGhrZXlfb2xkICk7CiAgICB9CiAgICBOdENsb3NlKCBoa2V5X25ldyApOwp9CgoKLyogY29udmVydCB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGUgZW50cmllcyBmcm9tIHRoZSBvbGQgZm9ybWF0IHRvIHRoZSBuZXcgb25lICovCnN0YXRpYyB2b2lkIGNvbnZlcnRfZW52aXJvbm1lbnQoIEhLRVkgaGtleV9jdXJyZW50X3VzZXIgKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgd2luZVdbXSA9IHsnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLCdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0MnLCdvJywnbicsJ2YnLCdpJywnZycsJ1xcJywnVycsJ2knLCduJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgd2luZG93c1dbXSA9IHsndycsJ2knLCduJywnZCcsJ28nLCd3JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3lzdGVtV1tdID0geydzJywneScsJ3MnLCd0JywnZScsJ20nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHdpbmRpcldbXSA9IHsndycsJ2knLCduJywnZCcsJ2knLCdyJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzeXN0ZW1yb290V1tdID0geydTJywneScsJ3MnLCd0JywnZScsJ20nLCdyJywnbycsJ28nLCd0JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB3aW5zeXNkaXJXW10gPSB7J3cnLCdpJywnbicsJ3MnLCd5JywncycsJ2QnLCdpJywncicsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgZW52V1tdID0geydFJywnbicsJ3YnLCdpJywncicsJ28nLCduJywnbScsJ2UnLCduJywndCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgdGVtcFdbXSA9IHsnVCcsJ0UnLCdNJywnUCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgdG1wV1tdID0geydUJywnTScsJ1AnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHBhdGhXW10gPSB7J1AnLCdBJywnVCcsJ0gnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHByb2ZpbGVXW10gPSB7J3AnLCdyJywnbycsJ2YnLCdpJywnbCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHVzZXJwcm9maWxlV1tdID0geydVJywnUycsJ0UnLCdSJywnUCcsJ1InLCdPJywnRicsJ0knLCdMJywnRScsMH07CgogICAgY2hhciBidWZmZXJbMTAyNCpzaXplb2YoV0NIQVIpICsgc2l6ZW9mKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OKV07CiAgICBLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqaW5mbyA9IChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKWJ1ZmZlcjsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIERXT1JEIGR1bW15OwogICAgVUxPTkcgZGlzcDsKICAgIEhLRVkgaGtleV9vbGQsIGhrZXlfZW52OwoKICAgIGF0dHIuTGVuZ3RoID0gc2l6ZW9mKGF0dHIpOwogICAgYXR0ci5Sb290RGlyZWN0b3J5ID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSA9ICZuYW1lVzsKICAgIGF0dHIuQXR0cmlidXRlcyA9IDA7CiAgICBhdHRyLlNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CiAgICBhdHRyLlNlY3VyaXR5UXVhbGl0eU9mU2VydmljZSA9IE5VTEw7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCB3aW5lVyApOwoKICAgIGlmIChOdE9wZW5LZXkoICZoa2V5X29sZCwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyICkgIT0gU1RBVFVTX1NVQ0NFU1MpIHJldHVybjsKCiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5X2N1cnJlbnRfdXNlcjsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIGVudlcgKTsKICAgIGlmIChOdENyZWF0ZUtleSggJmhrZXlfZW52LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsICZkaXNwICkpCiAgICB7CiAgICAgICAgTnRDbG9zZSggaGtleV9vbGQgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLyogVGVzdCBmb3IgZXhpc3RlbmNlIG9mIFRFTVAgKi8KICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIHRlbXBXICk7CiAgICBpZiAoTnRRdWVyeVZhbHVlS2V5KGhrZXlfZW52LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCBidWZmZXIsIHNpemVvZihidWZmZXIpLCAmZHVtbXkgKSkKICAgIHsKICAgICAgICAvKiBjb252ZXJ0IFRFTVAgKi8KICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCB0ZW1wVyApOwogICAgICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X29sZCwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgJmR1bW15ICkpCiAgICAgICAgewogICAgICAgICAgICBOdFNldFZhbHVlS2V5KCBoa2V5X2VudiwgJm5hbWVXLCAwLCBpbmZvLT5UeXBlLCBpbmZvLT5EYXRhLCBpbmZvLT5EYXRhTGVuZ3RoICk7CiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIHRtcFcgKTsKICAgICAgICAgICAgTnRTZXRWYWx1ZUtleSggaGtleV9lbnYsICZuYW1lVywgMCwgaW5mby0+VHlwZSwgaW5mby0+RGF0YSwgaW5mby0+RGF0YUxlbmd0aCApOwogICAgICAgICAgICBNRVNTQUdFKCAiQ29udmVydGVkIHRlbXAgZGlyIHRvIG5ldyBlbnRyeSBIS0NVXFxFbnZpcm9ubWVudCBcIlRFTVBcIiA9ICVzXG4iLAogICAgICAgICAgICAgICAgICAgIGRlYnVnc3RyX3coIChXQ0hBUiopaW5mby0+RGF0YSApICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFRlc3QgZm9yIGV4aXN0ZW5jZSBvZiBQQVRIICovCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBwYXRoVyApOwogICAgaWYgKE50UXVlcnlWYWx1ZUtleShoa2V5X2VudiwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgJmR1bW15ICkpCiAgICB7CiAgICAgICAgLyogY29udmVydCBQQVRIICovCiAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgcGF0aFcgKTsKICAgICAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9vbGQsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksICZkdW1teSApKQogICAgICAgIHsKICAgICAgICAgICAgTnRTZXRWYWx1ZUtleSggaGtleV9lbnYsICZuYW1lVywgMCwgaW5mby0+VHlwZSwgaW5mby0+RGF0YSwgaW5mby0+RGF0YUxlbmd0aCApOwogICAgICAgICAgICBNRVNTQUdFKCAiQ29udmVydGVkIHBhdGggZGlyIHRvIG5ldyBlbnRyeSBIS0NVXFxFbnZpcm9ubWVudCBcIlBBVEhcIiA9ICVzXG4iLAogICAgICAgICAgICAgICAgICAgIGRlYnVnc3RyX3coIChXQ0hBUiopaW5mby0+RGF0YSApICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFRlc3QgZm9yIGV4aXN0ZW5jZSBvZiBVU0VSUFJPRklMRSAqLwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdXNlcnByb2ZpbGVXICk7CiAgICBpZiAoTnRRdWVyeVZhbHVlS2V5KGhrZXlfZW52LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCBidWZmZXIsIHNpemVvZihidWZmZXIpLCAmZHVtbXkgKSkKICAgIHsKICAgICAgICAvKiBjb252ZXJ0IFVTRVJQUk9GSUxFICovCiAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgcHJvZmlsZVcgKTsKICAgICAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9vbGQsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksICZkdW1teSApKQogICAgICAgIHsKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdXNlcnByb2ZpbGVXICk7CiAgICAgICAgICAgIE50U2V0VmFsdWVLZXkoIGhrZXlfZW52LCAmbmFtZVcsIDAsIGluZm8tPlR5cGUsIGluZm8tPkRhdGEsIGluZm8tPkRhdGFMZW5ndGggKTsKICAgICAgICAgICAgTUVTU0FHRSggIkNvbnZlcnRlZCBwcm9maWxlIGRpciB0byBuZXcgZW50cnkgSEtDVVxcRW52aXJvbm1lbnQgXCJVU0VSUFJPRklMRVwiID0gJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgZGVidWdzdHJfdyggKFdDSEFSKilpbmZvLT5EYXRhICkgKTsKICAgICAgICB9CiAgICB9CgogICAgLyogVGVzdCBmb3IgZXhpc3RlbmNlIG9mIHdpbmRpciAqLwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgd2luZGlyVyApOwogICAgaWYgKE50UXVlcnlWYWx1ZUtleShoa2V5X2VudiwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgJmR1bW15ICkpCiAgICB7CiAgICAgICAgLyogY29udmVydCB3aW5kaXIgKi8KICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCB3aW5kb3dzVyApOwogICAgICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X29sZCwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgJmR1bW15ICkpCiAgICAgICAgewogICAgICAgICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCB3aW5kaXJXICk7CiAgICAgICAgICAgIE50U2V0VmFsdWVLZXkoIGhrZXlfZW52LCAmbmFtZVcsIDAsIGluZm8tPlR5cGUsIGluZm8tPkRhdGEsIGluZm8tPkRhdGFMZW5ndGggKTsKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgc3lzdGVtcm9vdFcgKTsKICAgICAgICAgICAgTnRTZXRWYWx1ZUtleSggaGtleV9lbnYsICZuYW1lVywgMCwgaW5mby0+VHlwZSwgaW5mby0+RGF0YSwgaW5mby0+RGF0YUxlbmd0aCApOwogICAgICAgICAgICBNRVNTQUdFKCAiQ29udmVydGVkIHdpbmRvd3MgZGlyIHRvIG5ldyBlbnRyeSBIS0NVXFxFbnZpcm9ubWVudCBcIndpbmRpclwiID0gJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgZGVidWdzdHJfdyggKFdDSEFSKilpbmZvLT5EYXRhICkgKTsKICAgICAgICB9CiAgICB9CiAgICAgICAgCiAgICAvKiBUZXN0IGZvciBleGlzdGVuY2Ugb2Ygd2luc3lzZGlyICovCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCB3aW5zeXNkaXJXICk7CiAgICBpZiAoTnRRdWVyeVZhbHVlS2V5KGhrZXlfZW52LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCBidWZmZXIsIHNpemVvZihidWZmZXIpLCAmZHVtbXkgKSkKICAgIHsKICAgICAgICAvKiBjb252ZXJ0IHdpbnN5c2RpciAqLwogICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIHN5c3RlbVcgKTsKICAgICAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9vbGQsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksICZkdW1teSApKQogICAgICAgIHsKICAgICAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgd2luc3lzZGlyVyApOwogICAgICAgICAgICBOdFNldFZhbHVlS2V5KCBoa2V5X2VudiwgJm5hbWVXLCAwLCBpbmZvLT5UeXBlLCBpbmZvLT5EYXRhLCBpbmZvLT5EYXRhTGVuZ3RoICk7CiAgICAgICAgICAgIE1FU1NBR0UoICJDb252ZXJ0ZWQgc3lzdGVtIGRpciB0byBuZXcgZW50cnkgSEtDVVxcRW52aXJvbm1lbnQgXCJ3aW5zeXNkaXJcIiA9ICVzXG4iLAogICAgICAgICAgICAgICAgICAgIGRlYnVnc3RyX3coIChXQ0hBUiopaW5mby0+RGF0YSApICk7CiAgICAgICAgfQogICAgfQogICAgTnRDbG9zZSggaGtleV9vbGQgKTsKICAgIE50Q2xvc2UoIGhrZXlfZW52ICk7Cn0KCgovKiBsb2FkIGFsbCByZWdpc3RyeSAobmF0aXZlIGFuZCBnbG9iYWwgYW5kIGhvbWUpICovCnZvaWQgU0hFTExfTG9hZFJlZ2lzdHJ5KCB2b2lkICkKewogICAgSEtFWSBoa2V5X2xvY2FsX21hY2hpbmUsIGhrZXlfdXNlcnMsIGhrZXlfdXNlcnNfZGVmYXVsdCwgaGtleV9jdXJyZW50X3VzZXIsIGhrZXlfY29uZmlnOwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgRFdPUkQgY291bnQ7CiAgICBVTE9ORyBkaXNwb3M7CiAgICBCT09MIHJlczsKICAgIGludCBhbGwsIHBlcmlvZDsKICAgIGNoYXIgdG1wWzEwMjRdOwoKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBNYWNoaW5lV1tdID0geydNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBVc2VyV1tdID0geydVJywncycsJ2UnLCdyJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBEZWZhdWx0V1tdID0geycuJywnRCcsJ2UnLCdmJywnYScsJ3UnLCdsJywndCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgUmVnaXN0cnlXW10gPSB7J00nLCdhJywnYycsJ2gnLCdpJywnbicsJ2UnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdXJywnaScsJ24nLCdlJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywnbycsJ24nLCdmJywnaScsJ2cnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCd5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsb2FkX3dpbl9yZWdfZmlsZXNXW10gPSB7J0wnLCdvJywnYScsJ2QnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLCdGJywnaScsJ2wnLCdlJywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgbG9hZF9nbG9iYWxfcmVnX2ZpbGVzV1tdID0geydMJywnbycsJ2EnLCdkJywnRycsJ2wnLCdvJywnYicsJ2EnLCdsJywnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ3knLCdGJywnaScsJ2wnLCdlJywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgU2F2ZU9ubHlVcGRhdGVkS2V5c1dbXSA9IHsnUycsJ2EnLCd2JywnZScsJ08nLCduJywnbCcsJ3knLCdVJywncCcsJ2QnLCdhJywndCcsJ2UnLCdkJywnSycsJ2UnLCd5JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgUGVyaW9kaWNTYXZlV1tdID0geydQJywnZScsJ3InLCdpJywnbycsJ2QnLCdpJywnYycsJ1MnLCdhJywndicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIEdsb2JhbFJlZ2lzdHJ5RGlyV1tdID0geydHJywnbCcsJ28nLCdiJywnYScsJ2wnLCdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywneScsJ0QnLCdpJywncicsMH07CgogICAgVFJBQ0UoIih2b2lkKVxuIik7CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBVc2VyVyApOwogICAgTnRDcmVhdGVLZXkoICZoa2V5X3VzZXJzLCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsICZkaXNwb3MgKTsKICAgIGlmIChkaXNwb3MgPT0gUkVHX09QRU5FRF9FWElTVElOR19LRVkpCiAgICB7CiAgICAgICAgLyogc29tZW9uZSBlbHNlIGFscmVhZHkgbG9hZGVkIHRoZSByZWdpc3RyeSAqLwogICAgICAgIE50Q2xvc2UoIGhrZXlfdXNlcnMgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgTWFjaGluZVcgKTsKICAgIE50Q3JlYXRlS2V5KCAmaGtleV9sb2NhbF9tYWNoaW5lLCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKTsKCiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5X3VzZXJzOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgRGVmYXVsdFcgKTsKICAgIGlmIChOdENyZWF0ZUtleSggJmhrZXlfdXNlcnNfZGVmYXVsdCwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkpCiAgICB7CiAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIEhLRVlfVVNFUlMvLkRlZmF1bHRcbiIgKTsKICAgICAgICBFeGl0UHJvY2VzcygxKTsKICAgIH0KICAgIFJ0bE9wZW5DdXJyZW50VXNlciggS0VZX0FMTF9BQ0NFU1MsICZoa2V5X2N1cnJlbnRfdXNlciApOwoKICAgIF9hbGxvY2F0ZV9kZWZhdWx0X2tleXMoKTsKCiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSAwOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgUmVnaXN0cnlXICk7CiAgICBpZiAoTnRPcGVuS2V5KCAmaGtleV9jb25maWcsIEtFWV9BTExfQUNDRVNTLCAmYXR0ciApKSBoa2V5X2NvbmZpZyA9IDA7CgogICAgLyogbG9hZCB3aW5kb3dzIHJlZ2lzdHJ5IGlmIHJlcXVpcmVkICovCgogICAgcmVzID0gVFJVRTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IGhrZXlfY29uZmlnOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgbG9hZF93aW5fcmVnX2ZpbGVzVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgcmVzID0gIUlTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQogICAgaWYgKHJlcykgX2xvYWRfd2luZG93c19yZWdpc3RyeSggaGtleV9sb2NhbF9tYWNoaW5lLCBoa2V5X2N1cnJlbnRfdXNlciwgaGtleV91c2Vyc19kZWZhdWx0ICk7CgogICAgLyogbG9hZCBnbG9iYWwgcmVnaXN0cnkgaWYgcmVxdWlyZWQgKi8KCiAgICByZXMgPSBUUlVFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgbG9hZF9nbG9iYWxfcmVnX2ZpbGVzVyApOwogICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgIHsKICAgICAgICBXQ0hBUiAqc3RyID0gKFdDSEFSICopKChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKXRtcCktPkRhdGE7CiAgICAgICAgcmVzID0gIUlTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQogICAgaWYgKHJlcykKICAgIHsKICAgICAgICAvKiBsb2FkIGdsb2JhbCByZWdpc3RyeSBmaWxlcyAoc3RvcmVkIGluIC9ldGMvd2luZSkgKi8KICAgICAgICBjaGFyICpwLCBjb25maWdmaWxlW01BWF9QQVRITkFNRV9MRU5dOwoKICAgICAgICAvKiBPdmVycmlkZSBFVENESVI/ICovCiAgICAgICAgY29uZmlnZmlsZVswXSA9IDA7CiAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgR2xvYmFsUmVnaXN0cnlEaXJXICk7CiAgICAgICAgaWYgKCFOdFF1ZXJ5VmFsdWVLZXkoIGhrZXlfY29uZmlnLCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCB0bXAsIHNpemVvZih0bXApLCAmY291bnQgKSkKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICAgICAgUnRsVW5pY29kZVRvTXVsdGlCeXRlTiggY29uZmlnZmlsZSwgc2l6ZW9mKGNvbmZpZ2ZpbGUpLCBOVUxMLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyLCAoc3RybGVuVyhzdHIpICsgMSkgKiBzaXplb2YoV0NIQVIpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGNvbmZpZ2ZpbGVbMF0gIT0gJy8nKSBzdHJjcHkoY29uZmlnZmlsZSwgRVRDRElSKTsKCiAgICAgICAgVFJBQ0UoIkdsb2JhbFJlZ2lzdHJ5RGlyIGlzICclcycuXG4iLCBjb25maWdmaWxlKTsKCiAgICAgICAgLyogTG9hZCB0aGUgZ2xvYmFsIEhLVSBoaXZlIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpciAqLwogICAgICAgIHAgPSBjb25maWdmaWxlICsgc3RybGVuKGNvbmZpZ2ZpbGUpOwogICAgICAgIHN0cmNweShwLCBTQVZFX0dMT0JBTF9SRUdCUkFOQ0hfVVNFUl9ERUZBVUxUKTsKICAgICAgICBsb2FkX3dpbmVfcmVnaXN0cnkoIGhrZXlfdXNlcnMsIGNvbmZpZ2ZpbGUgKTsKCiAgICAgICAgLyogTG9hZCB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyICovCiAgICAgICAgc3RyY3B5KHAsIFNBVkVfR0xPQkFMX1JFR0JSQU5DSF9MT0NBTF9NQUNISU5FKTsKICAgICAgICBsb2FkX3dpbmVfcmVnaXN0cnkoIGhrZXlfbG9jYWxfbWFjaGluZSwgY29uZmlnZmlsZSApOwogICAgfQoKICAgIC8qIHNldHVwIHJlZ2lzdHJ5IHNhdmluZyAqLwoKICAgIGFsbCA9IEZBTFNFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgU2F2ZU9ubHlVcGRhdGVkS2V5c1cgKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KCBoa2V5X2NvbmZpZywgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgdG1wLCBzaXplb2YodG1wKSwgJmNvdW50ICkpCiAgICB7CiAgICAgICAgV0NIQVIgKnN0ciA9IChXQ0hBUiAqKSgoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKil0bXApLT5EYXRhOwogICAgICAgIGFsbCA9IElTX09QVElPTl9GQUxTRShzdHJbMF0pOwogICAgfQoKICAgIHBlcmlvZCA9IDA7CiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBQZXJpb2RpY1NhdmVXICk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleSggaGtleV9jb25maWcsICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIHRtcCwgc2l6ZW9mKHRtcCksICZjb3VudCApKQogICAgewogICAgICAgIFdDSEFSICpzdHIgPSAoV0NIQVIgKikoKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopdG1wKS0+RGF0YTsKICAgICAgICBwZXJpb2QgPSAoaW50KXN0cnRvbFcoc3RyLCBOVUxMLCAxMCk7CiAgICB9CgogICAgLyogbG9hZCBob21lIHJlZ2lzdHJ5IGFuZCBzZXQgc2F2aW5nIGxldmVsICgwIGZvciBzYXZpbmcgZXZlcnl0aGluZywKICAgICAqIDEgZm9yIHNhdmluZyBvbmx5IG1vZGlmaWVkIGtleXMpICovCgogICAgU0VSVkVSX1NUQVJUX1JFUSggbG9hZF91c2VyX3JlZ2lzdHJpZXMgKQogICAgewogICAgICAgIHJlcS0+aGtleSA9IGhrZXlfY3VycmVudF91c2VyOwogICAgICAgIHJlcS0+c2F2aW5nID0gIWFsbDsKICAgICAgICByZXEtPnBlcmlvZCA9IHBlcmlvZCAqIDEwMDA7CiAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICB9CiAgICBTRVJWRVJfRU5EX1JFUTsKCiAgICAvKiBjcmVhdGUgaGFyZHdhcmUgcmVnaXN0cnkgYnJhbmNoICovCgogICAgY3JlYXRlX2hhcmR3YXJlX2JyYW5jaCgpOwoKICAgIC8qIGNvbnZlcnQga2V5cyBmcm9tIGNvbmZpZyBmaWxlIHRvIG5ldyByZWdpc3RyeSBmb3JtYXQgKi8KCiAgICBjb252ZXJ0X2RyaXZlX3R5cGVzKCk7CiAgICBjb252ZXJ0X2Vudmlyb25tZW50KCBoa2V5X2N1cnJlbnRfdXNlciApOwoKICAgIE50Q2xvc2UoaGtleV91c2Vyc19kZWZhdWx0KTsKICAgIE50Q2xvc2UoaGtleV9jdXJyZW50X3VzZXIpOwogICAgTnRDbG9zZShoa2V5X3VzZXJzKTsKICAgIE50Q2xvc2UoaGtleV9sb2NhbF9tYWNoaW5lKTsKICAgIE50Q2xvc2UoaGtleV9jb25maWcpOwp9Cg==