LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGxpbWl0cy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpZmRlZiBIQVZFX1NZU19FUlJOT19ICiNpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDx0aW1lLmg+CiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5lL3dpbmVzdHJpbmcuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgInNlcnZlci5oIgojaW5jbHVkZSAic2VydmljZXMuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTChyZWcpOwoKc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCh2b2lkKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUICAgICAgICAgIEVUQ0RJUiIvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUICBFVENESVIiL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0NVUlJFTlRfVVNFUiAgICAgICAgICAgInVzZXIucmVnIgojZGVmaW5lIFNBVkVfREVGQVVMVF9VU0VSICAgICAgICAgICAidXNlcmRlZi5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUICAgICJ3aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FICAgICAgICAgICJzeXN0ZW0ucmVnIgoKLyogd2hhdCB2YWx1ZXR5cGVzIGRvIHdlIG5lZWQgdG8gY29udmVydD8gKi8KI2RlZmluZSBVTklDT05WTUFTSwkoKDE8PFJFR19TWil8KDE8PFJFR19NVUxUSV9TWil8KDE8PFJFR19FWFBBTkRfU1opKQoKCnN0YXRpYyB2b2lkICp4bWFsbG9jKCBzaXplX3Qgc2l6ZSApCnsKICAgIHZvaWQgKnJlczsKIAogICAgcmVzID0gbWFsbG9jIChzaXplID8gc2l6ZSA6IDEpOwogICAgaWYgKHJlcyA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiVmlydHVhbCBtZW1vcnkgZXhoYXVzdGVkLlxuIik7CiAgICAgICAgZXhpdCAoMSk7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgovKgogKiBRVUVTVElPTgogKiAgIEFyZSB0aGVzZSBkb2luZyB0aGUgc2FtZSBhcyBIRUFQX3N0cmR1cEF0b1cgYW5kIEhFQVBfc3RyZHVwV3RvQT8KICogICBJZiBzbywgY2FuIHdlIHJlbW92ZSB0aGVtPwogKiBBTlNXRVIKICogICBObywgdGhlIG1lbW9yeSBoYW5kbGluZyBmdW5jdGlvbnMgYXJlIGNhbGxlZCB2ZXJ5IG9mdGVuIGluIGhlcmUsIAogKiAgIGp1c3QgcmVwbGFjaW5nIHRoZW0gYnkgSGVhcEFsbG9jKFN5c3RlbUhlYXAsLi4uKSBtYWtlcyByZWdpc3RyeQogKiAgIGxvYWRpbmcgMTAwIHRpbWVzIHNsb3dlci4gLU1NCiAqLwpzdGF0aWMgTFBXU1RSIHN0cmR1cEEyVyhMUENTVFIgc3JjKQp7CiAgICBpZihzcmMpIHsKCUxQV1NUUiBkZXN0PXhtYWxsb2MoMipzdHJsZW4oc3JjKSsyKTsKCWxzdHJjcHlBdG9XKGRlc3Qsc3JjKTsKCXJldHVybiBkZXN0OwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCkxQV1NUUiBzdHJjdnRBMlcoTFBDU1RSIHNyYywgaW50IG5jaGFycykKCnsKICAgTFBXU1RSIGRlc3QgPSB4bWFsbG9jICgyICogbmNoYXJzICsgMik7CgogICBsc3RyY3B5bkF0b1coZGVzdCxzcmMsbmNoYXJzKzEpOwogICByZXR1cm4gZGVzdDsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJFR0lTVFJZX0luaXQgW0ludGVybmFsXQogKiBSZWdpc3RyeSBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIHNvbWUgZGVmYXVsdCBrZXlzLiAKICovCnN0YXRpYyB2b2lkIFJFR0lTVFJZX0luaXQodm9pZCkgewoJSEtFWQloa2V5OwoJY2hhcglidWZbMjAwXTsKCglUUkFDRSgiKHZvaWQpXG4iKTsKCglSZWdDcmVhdGVLZXlBKEhLRVlfRFlOX0RBVEEsIlBlcmZTdGF0c1xcU3RhdERhdGEiLCZoa2V5KTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKICAgICAgICAvKiBUaGlzIHdhcyBhbiBPcGVuLCBidXQgc2luY2UgaXQgaXMgY2FsbGVkIGJlZm9yZSB0aGUgcmVhbCByZWdpc3RyaWVzCiAgICAgICAgICAgYXJlIGxvYWRlZCwgaXQgd2FzIGNoYW5nZWQgdG8gYSBDcmVhdGUgLSBNVEIgOTgwNTA3Ki8KCVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCJIQVJEV0FSRVxcREVTQ1JJUFRJT05cXFN5c3RlbSIsJmhrZXkpOwoJUmVnU2V0VmFsdWVFeEEoaGtleSwiSWRlbnRpZmllciIsMCxSRUdfU1osIlN5c3RlbVR5cGUgV0lORSIsc3RybGVuKCJTeXN0ZW1UeXBlIFdJTkUiKSk7CglSZWdDbG9zZUtleShoa2V5KTsKCgkvKiBcXFNPRlRXQVJFXFxNaWNyb3NvZnRcXFdpbmRvd3MgTlRcXEN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRCdWlsZE51bWJlcgoJICoJCQkJCQlDdXJyZW50VHlwZQoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3duZXIKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE9yZ2FuaXphdGlvbgoJICoKCSAqLwoJLyogU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXFNOTVBcXFBhcmFtZXRlcnNcXFJGQzExNTZBZ2VudAoJICogCQkJCQlzdHJpbmcJU3lzQ29udGFjdAoJICogCQkJCQlzdHJpbmcJU3lzTG9jYXRpb24KCSAqIAkJCQkJCVN5c1NlcnZpY2VzCgkgKi8KCWlmICgtMSE9Z2V0aG9zdG5hbWUoYnVmLDIwMCkpIHsKCQlSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcQ29tcHV0ZXJOYW1lXFxDb21wdXRlck5hbWUiLCZoa2V5KTsKCQlSZWdTZXRWYWx1ZUV4QShoa2V5LCJDb21wdXRlck5hbWUiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSsxKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKiogTE9BRCBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF9rZXkgW0ludGVybmFsXQogKi8Kc3RhdGljIGlubGluZSBIS0VZIF9maW5kX29yX2FkZF9rZXkoIEhLRVkgaGtleSwgTFBXU1RSIGtleW5hbWUgKQp7CiAgICBIS0VZIHN1YmtleTsKICAgIGlmIChSZWdDcmVhdGVLZXlXKCBoa2V5LCBrZXluYW1lLCAmc3Via2V5ICkgIT0gRVJST1JfU1VDQ0VTUykgc3Via2V5ID0gMDsKICAgIGlmIChrZXluYW1lKSBmcmVlKCBrZXluYW1lICk7CiAgICByZXR1cm4gc3Via2V5Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF92YWx1ZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfZmluZF9vcl9hZGRfdmFsdWUoIEhLRVkgaGtleSwgTFBXU1RSIG5hbWUsIERXT1JEIHR5cGUsIExQQllURSBkYXRhLCBEV09SRCBsZW4gKQp7CiAgICBSZWdTZXRWYWx1ZUV4VyggaGtleSwgbmFtZSwgMCwgdHlwZSwgZGF0YSwgbGVuICk7CiAgICBpZiAobmFtZSkgZnJlZSggbmFtZSApOwogICAgaWYgKGRhdGEpIGZyZWUoIGRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9saW5lIFtJbnRlcm5hbF0KICoKICogcmVhZHMgYSBsaW5lIGluY2x1ZGluZyBkeW5hbWljYWxseSBlbmxhcmdpbmcgdGhlIHJlYWRidWZmZXIgYW5kIHRocm93aW5nCiAqIGF3YXkgY29tbWVudHMKICovCnN0YXRpYyBpbnQgX3dpbmVfcmVhZF9saW5lKCBGSUxFICpGLCBjaGFyICoqYnVmLCBpbnQgKmxlbiApCnsKCWNoYXIJKnMsKmN1cnJlYWQ7CglpbnQJbXlsZW4sY3Vyb2ZmOwoKCWN1cnJlYWQJPSAqYnVmOwoJbXlsZW4JPSAqbGVuOwoJKipidWYJPSAnXDAnOwoJd2hpbGUgKDEpIHsKCQl3aGlsZSAoMSkgewoJCQlzPWZnZXRzKGN1cnJlYWQsbXlsZW4sRik7CgkJCWlmIChzPT1OVUxMKQoJCQkJcmV0dXJuIDA7IC8qIEVPRiAqLwoJCQlpZiAoTlVMTD09KHM9c3RyY2hyKGN1cnJlYWQsJ1xuJykpKSB7CgkJCQkvKiBidWZmZXIgd2Fzbid0IGxhcmdlIGVub3VnaCAqLwoJCQkJY3Vyb2ZmCT0gc3RybGVuKCpidWYpOwoJCQkJY3VycmVhZAk9IHJlYWxsb2MoKmJ1ZiwqbGVuKjIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGN1cnJlYWQgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCJPdXQgb2YgbWVtb3J5Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqYnVmCT0gY3VycmVhZDsKCQkJCWN1cnJlYWQrPSBjdXJvZmY7CgkJCQlteWxlbgk9ICpsZW47CS8qIHdlIGZpbGxlZCB1cCB0aGUgYnVmZmVyIGFuZCAKCQkJCQkJICogZ290IG5ldyAnKmxlbicgYnl0ZXMgdG8gZmlsbAoJCQkJCQkgKi8KCQkJCSpsZW4JPSAqbGVuICogMjsKCQkJfSBlbHNlIHsKCQkJCSpzPSdcMCc7CgkJCQlicmVhazsKCQkJfQoJCX0KCQkvKiB0aHJvdyBhd2F5IGNvbW1lbnRzICovCgkJaWYgKCoqYnVmPT0nIycgfHwgKipidWY9PSc7JykgewoJCQljdXJyZWFkCT0gKmJ1ZjsKCQkJbXlsZW4JPSAqbGVuOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKHMpIAkvKiBnb3QgZW5kIG9mIGxpbmUgKi8KCQkJYnJlYWs7Cgl9CglyZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9VU1RSSU5HIFtJbnRlcm5hbF0KICoKICogY29udmVydHMgYSBjaGFyKiBpbnRvIGEgVU5JQ09ERSBzdHJpbmcgKHVwIHRvIGEgc3BlY2lhbCBjaGFyKQogKiBhbmQgcmV0dXJucyB0aGUgcG9zaXRpb24gZXhhY3RseSBhZnRlciB0aGF0IHN0cmluZwogKi8Kc3RhdGljIGNoYXIqIF93aW5lX3JlYWRfVVNUUklORyggY2hhciAqYnVmLCBMUFdTVFIgKnN0ciApCnsKCWNoYXIJKnM7CglMUFdTVFIJd3M7CgoJLyogcmVhZCB1cCB0byAiPSIgb3IgIlwwIiBvciAiXG4iICovCglzCT0gYnVmOwoJKnN0cgk9IChMUFdTVFIpeG1hbGxvYygyKnN0cmxlbihidWYpKzIpOwoJd3MJPSAqc3RyOwoJd2hpbGUgKCpzICYmICgqcyE9J1xuJykgJiYgKCpzIT0nPScpKSB7CgkJaWYgKCpzIT0nXFwnKQoJCQkqd3MrKz0qKCh1bnNpZ25lZCBjaGFyKilzKyspOwoJCWVsc2UgewoJCQlzKys7CgkJCWlmICghKnMpIHsKCQkJCS8qIERhbmdsaW5nIFwgLi4uIG1heSBvbmx5IGhhcHBlbiBpZiBhIHJlZ2lzdHJ5CgkJCQkgKiB3cml0ZSB3YXMgc2hvcnQuIEZJWE1FOiBXaGF0IHRvIGRvPwoJCQkJICovCgkJCQkgYnJlYWs7CgkJCX0KCQkJaWYgKCpzPT0nXFwnKSB7CgkJCQkqd3MrKz0nXFwnOwoJCQkJcysrOwoJCQkJY29udGludWU7CgkJCX0KCQkJaWYgKCpzIT0ndScpIHsKCQkJCVdBUk4oIk5vbiB1bmljb2RlIGVzY2FwZSBzZXF1ZW5jZSBcXCVjIGZvdW5kIGluIHwlc3xcbiIsKnMsYnVmKTsKCQkJCSp3cysrPSdcXCc7CgkJCQkqd3MrKz0qcysrOwoJCQl9IGVsc2UgewoJCQkJY2hhcgl4YnVmWzVdOwoJCQkJaW50CXdjOwoKCQkJCXMrKzsKCQkJCW1lbWNweSh4YnVmLHMsNCk7eGJ1Zls0XT0nXDAnOwoJCQkJaWYgKCFzc2NhbmYoeGJ1ZiwiJXgiLCZ3YykpCgkJCQkJV0FSTigiU3RyYW5nZSBlc2NhcGUgc2VxdWVuY2UgJXMgZm91bmQgaW4gfCVzfFxuIix4YnVmLGJ1Zik7CgkJCQlzKz00OwoJCQkJKndzKysJPSh1bnNpZ25lZCBzaG9ydCl3YzsKCQkJfQoJCX0KCX0KCSp3cwk9IDA7CglyZXR1cm4gczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHN1YmtleSBbSW50ZXJuYWxdCiAqCiAqIE5PVEVTCiAqICAgIEl0IHNlZW1zIGxpa2UgdGhpcyBpcyByZXR1cm5pbmcgYSBib29sZWFuLiAgU2hvdWxkIGl0PwogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IDEKICogICAgRmFpbHVyZTogMAogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3Via2V5KCBGSUxFICpGLCBIS0VZIGhrZXksIGludCBsZXZlbCwgY2hhciAqKmJ1ZiwgaW50ICpidWZsZW4gKQp7CiAgICAJSEtFWSBzdWJrZXk7CglpbnQJCWk7CgljaGFyCQkqczsKCUxQV1NUUgkJbmFtZTsKCiAgICBUUkFDRSgiKCVwLCV4LCVkLCVzLCVkKVxuIiwgRiwgaGtleSwgbGV2ZWwsIGRlYnVnc3RyX2EoKmJ1ZiksICpidWZsZW4pOwoKICAgIC8qIEdvb2QuICBXZSBhbHJlYWR5IGdvdCBhIGxpbmUgaGVyZSAuLi4gc28gcGFyc2UgaXQgKi8KICAgIHN1YmtleSA9IDA7CiAgICB3aGlsZSAoMSkgewogICAgICAgIGk9MDtzPSpidWY7CiAgICAgICAgd2hpbGUgKCpzPT0nXHQnKSB7CiAgICAgICAgICAgIHMrKzsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KICAgICAgICBpZiAoaT5sZXZlbCkgewogICAgICAgICAgICBpZiAoIXN1YmtleSkgewogICAgICAgICAgICAgICAgV0FSTigiR290IGEgc3ViaGllcmFyY2h5IHdpdGhvdXQgcmVzcC4ga2V5P1xuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoJICAgIGlmICghX3dpbmVfbG9hZHN1YmtleShGLHN1YmtleSxsZXZlbCsxLGJ1ZixidWZsZW4pKQoJICAgICAgIGlmICghX3dpbmVfcmVhZF9saW5lKEYsYnVmLGJ1ZmxlbikpCgkJICBnb3RvIGRvbmU7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCgkJLyogbGV0IHRoZSBjYWxsZXIgaGFuZGxlIHRoaXMgbGluZSAqLwoJCWlmIChpPGxldmVsIHx8ICoqYnVmPT0nXDAnKQoJCQlnb3RvIGRvbmU7CgoJCS8qIGl0IGNhbiBiZTogYSB2YWx1ZSBvciBhIGtleW5hbWUuIFBhcnNlIHRoZSBuYW1lIGZpcnN0ICovCgkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywmbmFtZSk7CgoJCS8qIHN3aXRjaCgpIGRlZmF1bHQ6IGhhY2sgdG8gYXZvaWQgZ290b3MgKi8KCQlzd2l0Y2ggKDApIHsKCQlkZWZhdWx0OgoJCQlpZiAoKnM9PSdcMCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3Via2V5KSBSZWdDbG9zZUtleSggc3Via2V5ICk7CgkJCQlzdWJrZXk9X2ZpbmRfb3JfYWRkX2tleShoa2V5LG5hbWUpOwoJCQl9IGVsc2UgewoJCQkJTFBCWVRFCQlkYXRhOwoJCQkJaW50CQlsZW4sbGFzdG1vZGlmaWVkLHR5cGU7CgoJCQkJaWYgKCpzIT0nPScpIHsKCQkJCQlXQVJOKCJVbmV4cGVjdGVkIGNoYXJhY3RlcjogJWNcbiIsKnMpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJcysrOwoJCQkJaWYgKDIhPXNzY2FuZihzLCIlZCwlZCwiLCZ0eXBlLCZsYXN0bW9kaWZpZWQpKSB7CgkJCQkJV0FSTigiSGF2ZW4ndCB1bmRlcnN0b29kIHBvc3NpYmxlIHZhbHVlIGluIHwlc3wsIHNraXBwaW5nLlxuIiwqYnVmKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCS8qIHNraXAgdGhlIDIgLCAqLwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCXM9c3RyY2hyKHMsJywnKTsKCQkJCWlmICghcysrKSB7CgkJCQkJV0FSTigiSGF2ZW4ndCB1bmRlcnN0b29kIHBvc3NpYmxlIHZhbHVlIGluIHwlc3wsIHNraXBwaW5nLlxuIiwqYnVmKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCWlmICh0eXBlID09IFJFR19TWiB8fCB0eXBlID09IFJFR19FWFBBTkRfU1opIHsKCQkJCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLChMUFdTVFIqKSZkYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbiA9IGxzdHJsZW5XKChMUFdTVFIpZGF0YSkqMisyOwoJCQkJfSBlbHNlIHsKCQkJCQlsZW49c3RybGVuKHMpLzI7CgkJCQkJZGF0YSA9IChMUEJZVEUpeG1hbGxvYyhsZW4rMSk7CgkJCQkJZm9yIChpPTA7aTxsZW47aSsrKSB7CgkJCQkJCWRhdGFbaV09MDsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV09KCpzLScwJyk8PDQ7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nYScrJ1x4YScpPDw0OwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ0EnKydceGEnKTw8NDsKCQkJCQkJcysrOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXXw9KnMtJzAnOwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ2EnKydceGEnOwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ0EnKydceGEnOwoJCQkJCQlzKys7CgkJCQkJfQoJCQkJfQoJCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKGhrZXksbmFtZSx0eXBlLGRhdGEsbGVuKTsKCQkJfQoJCX0KCQkvKiByZWFkIHRoZSBuZXh0IGxpbmUgKi8KCQlpZiAoIV93aW5lX3JlYWRfbGluZShGLGJ1ZixidWZsZW4pKQoJCQlnb3RvIGRvbmU7CiAgICB9CiBkb25lOgogICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwogICAgcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3VicmVnKCBGSUxFICpGLCBIS0VZIGhrZXksIGNvbnN0IGNoYXIgKmZuICkKewoJaW50CXZlcjsKCWNoYXIJKmJ1ZjsKCWludAlidWZsZW47CgoJYnVmPXhtYWxsb2MoMTApO2J1Zmxlbj0xMDsKCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghc3NjYW5mKGJ1ZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIiwmdmVyKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICh2ZXIhPTEpIHsKICAgICAgICAgICAgaWYgKHZlciA9PSAyKSAgLyogbmV3IHZlcnNpb24gKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSEFORExFIGZpbGU7CiAgICAgICAgICAgICAgICBpZiAoKGZpbGUgPSBGSUxFX0NyZWF0ZUZpbGUoIGZuLCBHRU5FUklDX1JFQUQsIDAsIE5VTEwsIE9QRU5fRVhJU1RJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRV9BVFRSSUJVVEVfTk9STUFMLCAtMSwgVFJVRSApKSAhPSBJTlZBTElEX0hBTkRMRV9WQUxVRSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgbG9hZF9yZWdpc3RyeV9yZXF1ZXN0ICpyZXEgPSBnZXRfcmVxX2J1ZmZlcigpOwogICAgICAgICAgICAgICAgICAgIHJlcS0+aGtleSAgICA9IGhrZXk7CiAgICAgICAgICAgICAgICAgICAgcmVxLT5maWxlICAgID0gZmlsZTsKICAgICAgICAgICAgICAgICAgICByZXEtPm5hbWVbMF0gPSAwOwogICAgICAgICAgICAgICAgICAgIHNlcnZlcl9jYWxsKCBSRVFfTE9BRF9SRUdJU1RSWSApOwogICAgICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBmaWxlICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmcmVlKCBidWYgKTsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewoJCVRSQUNFKCJPbGQgZm9ybWF0ICglZCkgcmVnaXN0cnkgZm91bmQsIGlnbm9yaW5nIGl0LiAoYnVmIHdhcyAlcykuXG4iLHZlcixidWYpOwoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKICAgICAgICAgICAgfQoJfQoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9sb2Fkc3Via2V5KEYsaGtleSwwLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglmcmVlKGJ1Zik7CglyZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93aW5lX2xvYWRyZWcoIEhLRVkgaGtleSwgY2hhciAqZm4gKQp7CiAgICBGSUxFICpGOwoKICAgIFRSQUNFKCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShmbikpOwoKICAgIEYgPSBmb3BlbihmbiwicmIiKTsKICAgIGlmIChGPT1OVUxMKSB7CiAgICAgICAgV0FSTigiQ291bGRuJ3Qgb3BlbiAlcyBmb3IgcmVhZGluZzogJXNcbiIsZm4sc3RyZXJyb3IoZXJybm8pICk7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgX3dpbmVfbG9hZHN1YnJlZyhGLGhrZXksZm4pOwogICAgZmNsb3NlKEYpOwogICAgcmV0dXJuIDA7Cn0KCi8qIE5UIFJFR0lTVFJZIExPQURFUiAqLwoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKI2lmbmRlZiBNQVBfRkFJTEVECiNkZWZpbmUgTUFQX0ZBSUxFRCAoKExQVk9JRCktMSkKI2VuZGlmCgojZGVmaW5lICBOVF9SRUdfQkxPQ0tfU0laRQkJMHgxMDAwCgojZGVmaW5lIE5UX1JFR19IRUFERVJfQkxPQ0tfSUQgICAgICAgMHg2NjY3NjU3MgkvKiByZWdmICovCiNkZWZpbmUgTlRfUkVHX1BPT0xfQkxPQ0tfSUQgICAgICAgICAweDZFNjk2MjY4CS8qIGhiaW4gKi8KI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX0lEICAgICAgICAgIDB4NmI2ZSAvKiBuayAqLwojZGVmaW5lIE5UX1JFR19WQUxVRV9CTE9DS19JRCAgICAgICAgMHg2Yjc2IC8qIHZrICovCgovKiBzdWJibG9ja3Mgb2YgbmsgKi8KI2RlZmluZSBOVF9SRUdfSEFTSF9CTE9DS19JRCAgICAgICAgIDB4NjY2YyAvKiBsZiAqLwojZGVmaW5lIE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQgICAgICAgMHg2OTZjIC8qIGxpICovCiNkZWZpbmUgTlRfUkVHX1JJX0JMT0NLX0lECSAgICAgMHg2OTcyIC8qIHJpICovCgojZGVmaW5lIE5UX1JFR19LRVlfQkxPQ0tfVFlQRSAgICAgICAgMHgyMAojZGVmaW5lIE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFICAgMHgyYwoKdHlwZWRlZiBzdHJ1Y3QgCnsKCURXT1JECWlkOwkJLyogMHg2NjY3NjU3MiAncmVnZicqLwoJRFdPUkQJdWsxOwkJLyogMHgwNCAqLwoJRFdPUkQJdWsyOwkJLyogMHgwOCAqLwoJRklMRVRJTUUJRGF0ZU1vZGlmaWVkOwkvKiAweDBjICovCglEV09SRAl1azM7CQkvKiAweDE0ICovCglEV09SRAl1azQ7CQkvKiAweDE4ICovCglEV09SRAl1azU7CQkvKiAweDFjICovCglEV09SRAl1azY7CQkvKiAweDIwICovCglEV09SRAlSb290S2V5QmxvY2s7CS8qIDB4MjQgKi8KCURXT1JECUJsb2NrU2l6ZTsJLyogMHgyOCAqLwoJRFdPUkQgICB1azdbMTE2XTsJCglEV09SRAlDaGVja3N1bTsgLyogYXQgb2Zmc2V0IDB4MUZDICovCn0gbnRfcmVnZjsKCnR5cGVkZWYgc3RydWN0CnsKCURXT1JECWJsb2Nrc2l6ZTsKCUJZVEUJZGF0YVsxXTsKfSBudF9oYmluX3N1YjsKCnR5cGVkZWYgc3RydWN0CnsKCURXT1JECWlkOwkJLyogMHg2RTY5NjI2OCAnaGJpbicgKi8KCURXT1JECW9mZl9wcmV2OwoJRFdPUkQJb2ZmX25leHQ7CglEV09SRAl1azE7CglEV09SRAl1azI7CQkvKiAweDEwICovCglEV09SRAl1azM7CQkvKiAweDE0ICovCglEV09SRAl1azQ7CQkvKiAweDE4ICovCglEV09SRAlzaXplOwkJLyogMHgxQyAqLwoJbnRfaGJpbl9zdWIJaGJpbl9zdWI7CS8qIDB4MjAgKi8KfSBudF9oYmluOwoKLyoKICogdGhlIHZhbHVlX2xpc3QgY29uc2lzdHMgb2Ygb2Zmc2V0cyB0byB0aGUgdmFsdWVzICh2aykKICovCnR5cGVkZWYgc3RydWN0CnsKCVdPUkQJU3ViQmxvY2tJZDsJCS8qIDB4MDAgMHg2QjZFICovCglXT1JECVR5cGU7CQkJLyogMHgwMiBmb3IgdGhlIHJvb3Qta2V5OiAweDJDLCBvdGhlcndpc2UgMHgyMCovCglGSUxFVElNRQl3cml0ZXRpbWU7CS8qIDB4MDQgKi8KCURXT1JECXVrMTsJCQkvKiAweDBDICovCglEV09SRAlwYXJlbnRfb2ZmOwkJLyogMHgxMCBPZmZzZXQgb2YgT3duZXIvUGFyZW50IGtleSAqLwoJRFdPUkQJbnJfc3Via2V5czsJCS8qIDB4MTQgbnVtYmVyIG9mIHN1Yi1LZXlzICovCglEV09SRAl1azg7CQkJLyogMHgxOCAqLwoJRFdPUkQJbGZfb2ZmOwkJCS8qIDB4MUMgT2Zmc2V0IG9mIHRoZSBzdWIta2V5IGxmLVJlY29yZHMgKi8KCURXT1JECXVrMjsJCQkvKiAweDIwICovCglEV09SRAlucl92YWx1ZXM7CQkvKiAweDI0IG51bWJlciBvZiB2YWx1ZXMgKi8KCURXT1JECXZhbHVlbGlzdF9vZmY7CQkvKiAweDI4IE9mZnNldCBvZiB0aGUgVmFsdWUtTGlzdCAqLwoJRFdPUkQJb2ZmX3NrOwkJCS8qIDB4MmMgT2Zmc2V0IG9mIHRoZSBzay1SZWNvcmQgKi8KCURXT1JECW9mZl9jbGFzczsJCS8qIDB4MzAgT2Zmc2V0IG9mIHRoZSBDbGFzcy1OYW1lICovCglEV09SRAl1azM7CQkJLyogMHgzNCAqLwoJRFdPUkQJdWs0OwkJCS8qIDB4MzggKi8KCURXT1JECXVrNTsJCQkvKiAweDNjICovCglEV09SRAl1azY7CQkJLyogMHg0MCAqLwoJRFdPUkQJdWs3OwkJCS8qIDB4NDQgKi8KCVdPUkQJbmFtZV9sZW47CQkvKiAweDQ4IG5hbWUtbGVuZ3RoICovCglXT1JECWNsYXNzX2xlbjsJCS8qIDB4NGEgY2xhc3MtbmFtZSBsZW5ndGggKi8KCWNoYXIJbmFtZVsxXTsJCS8qIDB4NGMga2V5LW5hbWUgKi8KfSBudF9uazsKCnR5cGVkZWYgc3RydWN0CnsKCURXT1JECW9mZl9uazsJLyogMHgwMCAqLwoJRFdPUkQJbmFtZTsJLyogMHgwNCAqLwp9IGhhc2hfcmVjOwoKdHlwZWRlZiBzdHJ1Y3QKewoJV09SRAlpZDsJCS8qIDB4MDAgMHg2NjZjICovCglXT1JECW5yX2tleXM7CS8qIDB4MDYgKi8KCWhhc2hfcmVjCWhhc2hfcmVjWzFdOwp9IG50X2xmOwoKLyoKIGxpc3Qgb2Ygc3Via2V5cyB3aXRob3V0IGhhc2gKCiBsaSAtLSstLT5uawogICAgICB8CiAgICAgICstLT5uawogKi8KdHlwZWRlZiBzdHJ1Y3QKewoJV09SRAlpZDsJCS8qIDB4MDAgMHg2OTZjICovCglXT1JECW5yX2tleXM7CglEV09SRAlvZmZfbmtbMV07Cn0gbnRfbGk7CgovKgogdGhpcyBpcyBhIGludGVybWVkaWF0ZSBub2RlCgogcmkgLS0rLS0+bGktLSstLT5uawogICAgICB8ICAgICAgICsKICAgICAgfCAgICAgICArLS0+bmsKICAgICAgfAogICAgICArLS0+bGktLSstLT5uawogICAgICAgICAgICAgICsKCSAgICAgICstLT5uawogKi8KdHlwZWRlZiBzdHJ1Y3QKewoJV09SRAlpZDsJCS8qIDB4MDAgMHg2OTcyICovCglXT1JECW5yX2xpOwkJLyogMHgwMiBudW1iZXIgb2ZmIG9mZnNldHMgKi8KCURXT1JECW9mZl9saVsxXTsJLyogMHgwNCBwb2ludHMgdG8gbGkgKi8KfSBudF9yaTsKCnR5cGVkZWYgc3RydWN0CnsKCVdPUkQJaWQ7CQkvKiAweDAwICd2aycgKi8KCVdPUkQJbmFtX2xlbjsKCURXT1JECWRhdGFfbGVuOwoJRFdPUkQJZGF0YV9vZmY7CglEV09SRAl0eXBlOwoJV09SRAlmbGFnOwoJV09SRAl1azE7CgljaGFyCW5hbWVbMV07Cn0gbnRfdms7CgpMUFNUUiBfc3RyZHVwbkEoIExQQ1NUUiBzdHIsIGludCBsZW4gKQp7CiAgICBMUFNUUiByZXQ7CgogICAgaWYgKCFzdHIpIHJldHVybiBOVUxMOwogICAgcmV0ID0gbWFsbG9jKCBsZW4gKyAxICk7CiAgICBsc3RyY3B5bkEoIHJldCwgc3RyLCBsZW4gKTsKICAgIHJldFtsZW5dID0gMHgwMDsKICAgIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgX250X3BhcnNlX25rKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIG50X25rICogbmssIGludCBsZXZlbCk7CnN0YXRpYyBpbnQgX250X3BhcnNlX3ZrKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIG50X3ZrICogdmspOwpzdGF0aWMgaW50IF9udF9wYXJzZV9sZihIS0VZIGhrZXksIGNoYXIgKiBiYXNlLCBpbnQgc3Via2V5cywgbnRfbGYgKiBsZiwgaW50IGxldmVsKTsKCgovKgogKiBnZXRzIGEgdmFsdWUKICoKICogdmstPmZsYWc6CiAqICAwIHZhbHVlIGlzIGEgZGVmYXVsdCB2YWx1ZQogKiAgMSB0aGUgdmFsdWUgaGFzIGEgbmFtZQogKgogKiB2ay0+ZGF0YV9sZW4KICogIGxlbiBvZiB0aGUgd2hvbGUgZGF0YSBibG9jawogKiAgLSByZWdfc3ogKHVuaWNvZGUpCiAqICAgIGJ5dGVzIGluY2x1ZGluZyB0aGUgdGVybWluYXRpbmcgXDAgPSAyKihudW1iZXJfb2ZfY2hhcnMrMSkKICogIC0gcmVnX2R3b3JkLCByZWdfYmluYXJ5OgogKiAgICBpZiBoaWdoZXN0IGJpdCBvZiBkYXRhX2xlbiBpcyBzZXQgZGF0YV9vZmYgY29udGFpbnMgdGhlIHZhbHVlCiAqLwpzdGF0aWMgaW50IF9udF9wYXJzZV92ayhIS0VZIGhrZXksIGNoYXIgKiBiYXNlLCBudF92ayAqIHZrKQp7CglXQ0hBUiBuYW1lIFsyNTZdOwoJRFdPUkQgcmV0OwoJQllURSAqIHBkYXRhID0gKEJZVEUgKikoYmFzZSt2ay0+ZGF0YV9vZmYrNCk7IC8qIHN0YXJ0IG9mIGRhdGEgKi8KCglpZih2ay0+aWQgIT0gTlRfUkVHX1ZBTFVFX0JMT0NLX0lEKSBnb3RvIGVycm9yOwoKCWxzdHJjcHluQXRvVyhuYW1lLCB2ay0+bmFtZSwgdmstPm5hbV9sZW4rMSk7CgoJcmV0ID0gUmVnU2V0VmFsdWVFeFcoIGhrZXksICh2ay0+ZmxhZyAmIDB4MDAwMDAwMDEpID8gbmFtZSA6IE5VTEwsIDAsIHZrLT50eXBlLAoJCQkodmstPmRhdGFfbGVuICYgMHg4MDAwMDAwMCkgPyAoTFBCWVRFKSYodmstPmRhdGFfb2ZmKTogcGRhdGEsCgkJCSh2ay0+ZGF0YV9sZW4gJiAweDdmZmZmZmZmKSApOwoJaWYgKHJldCkgRVJSKCJSZWdTZXRWYWx1ZUV4IGZhaWxlZCAoMHglMDhseClcbiIsIHJldCk7CglyZXR1cm4gVFJVRTsKZXJyb3I6CglFUlJfKHJlZykoInVua25vd24gYmxvY2sgZm91bmQgKDB4JTA0eCksIHBsZWFzZSByZXBvcnQhXG4iLCB2ay0+aWQpOwoJcmV0dXJuIEZBTFNFOwp9CgovKgogKiBnZXQgdGhlIHN1YmtleXMKICoKICogdGhpcyBzdHJ1Y3R1cmUgY29udGFpbnMgdGhlIGhhc2ggb2YgYSBrZXluYW1lIGFuZCBwb2ludHMgdG8gYWxsCiAqIHN1YmtleXMKICoKICogZXhjZXB0aW9uOiBpZiB0aGUgaWQgaXMgJ2lsJyB0aGVyZSBhcmUgbm8gaGFzaCB2YWx1ZXMgYW5kIGV2ZXJ5IAogKiBkd29yZCBpcyBhIG9mZnNldAogKi8Kc3RhdGljIGludCBfbnRfcGFyc2VfbGYoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgaW50IHN1YmtleXMsIG50X2xmICogbGYsIGludCBsZXZlbCkKewoJaW50IGk7CgoJaWYgKGxmLT5pZCA9PSBOVF9SRUdfSEFTSF9CTE9DS19JRCkKCXsKCSAgaWYgKHN1YmtleXMgIT0gbGYtPm5yX2tleXMpIGdvdG8gZXJyb3IxOwoKCSAgZm9yIChpPTA7IGk8bGYtPm5yX2tleXM7IGkrKykKCSAgewoJICAgIGlmICghX250X3BhcnNlX25rKGhrZXksIGJhc2UsIChudF9uayopKGJhc2UrbGYtPmhhc2hfcmVjW2ldLm9mZl9uays0KSwgbGV2ZWwpKSBnb3RvIGVycm9yOwoJICB9Cgl9CgllbHNlIGlmIChsZi0+aWQgPT0gTlRfUkVHX05PSEFTSF9CTE9DS19JRCkKCXsKCSAgbnRfbGkgKiBsaSA9IChudF9saSopbGY7CgkgIGlmIChzdWJrZXlzICE9IGxpLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCgkgIGZvciAoaT0wOyBpPGxpLT5ucl9rZXlzOyBpKyspCgkgIHsKCSAgICBpZiAoIV9udF9wYXJzZV9uayhoa2V5LCBiYXNlLCAobnRfbmsqKShiYXNlK2xpLT5vZmZfbmtbaV0rNCksIGxldmVsKSkgZ290byBlcnJvcjsKCSAgfQoJfQoJZWxzZSBpZiAobGYtPmlkID09IE5UX1JFR19SSV9CTE9DS19JRCkgLyogcmkgKi8KCXsKCSAgbnRfcmkgKiByaSA9IChudF9yaSopbGY7CgkgIGludCBsaV9zdWJrZXlzID0gMDsKCgkgIC8qIGNvdW50IGFsbCBzdWJrZXlzICovCgkgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKQoJICB7CgkgICAgbnRfbGkgKiBsaSA9IChudF9saSopKGJhc2UrcmktPm9mZl9saVtpXSs0KTsKCSAgICBpZihsaS0+aWQgIT0gTlRfUkVHX05PSEFTSF9CTE9DS19JRCkgZ290byBlcnJvcjI7CgkgICAgbGlfc3Via2V5cyArPSBsaS0+bnJfa2V5czsKCSAgfQoKCSAgLyogY2hlY2sgbnVtYmVyICovCgkgIGlmIChzdWJrZXlzICE9IGxpX3N1YmtleXMpIGdvdG8gZXJyb3IxOwoKCSAgLyogbG9vcCB0aHJvdWdoIHRoZSBrZXlzICovCgkgIGZvciAoaT0wOyBpPHJpLT5ucl9saTsgaSsrKQoJICB7CgkgICAgbnRfbGkgKiBsaSA9IChudF9saSopKGJhc2UrcmktPm9mZl9saVtpXSs0KTsKCSAgICBpZiAoIV9udF9wYXJzZV9sZihoa2V5LCBiYXNlLCBsaS0+bnJfa2V5cywgKG50X2xmKilsaSwgbGV2ZWwpKSBnb3RvIGVycm9yOwoJICB9Cgl9CgllbHNlIAoJewoJICBnb3RvIGVycm9yMjsKCX0KCXJldHVybiBUUlVFOwoKZXJyb3IyOiBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBsZi0+aWQpOwoJcmV0dXJuIFRSVUU7CgkKZXJyb3IxOglFUlJfKHJlZykoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgKGluY29uc2lzdGVudCBudW1iZXIgb2Ygc3Via2V5cylcbiIpOwoJcmV0dXJuIEZBTFNFOwoKZXJyb3I6CUVSUl8ocmVnKSgiZXJyb3IgcmVhZGluZyBsZiBibG9ja1xuIik7CglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBpbnQgX250X3BhcnNlX25rKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIG50X25rICogbmssIGludCBsZXZlbCkKewoJY2hhciAqIG5hbWU7CglpbnQgaTsKCURXT1JEICogdmw7CglIS0VZIHN1YmtleSA9IGhrZXk7CgoJaWYobmstPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkKCXsKCSAgRVJSKCJ1bmtub3duIG5vZGUgaWQgMHglMDR4LCBwbGVhc2UgcmVwb3J0IVxuIiwgbmstPlN1YkJsb2NrSWQpOwoJICBnb3RvIGVycm9yOwoJfQoKCWlmKChuay0+VHlwZSE9TlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpICYmCgkgICAoKChudF9uayopKGJhc2UrbmstPnBhcmVudF9vZmYrNCkpLT5TdWJCbG9ja0lkICE9IE5UX1JFR19LRVlfQkxPQ0tfSUQpKQoJewoJICBFUlJfKHJlZykoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCFcbiIpOwoJICBnb3RvIGVycm9yOwoJfQoKCS8qIGNyZWF0ZSB0aGUgbmV3IGtleSAqLwoJaWYobGV2ZWwgPD0gMCkKCXsKCSAgbmFtZSA9IF9zdHJkdXBuQSggbmstPm5hbWUsIG5rLT5uYW1lX2xlbisxKTsKCSAgaWYoUmVnQ3JlYXRlS2V5QSggaGtleSwgbmFtZSwgJnN1YmtleSApKSB7IGZyZWUobmFtZSk7IGdvdG8gZXJyb3I7IH0KCSAgZnJlZShuYW1lKTsKCX0KCgkvKiBsb29wIHRocm91Z2ggdGhlIHN1YmtleXMgKi8KCWlmIChuay0+bnJfc3Via2V5cykKCXsKCSAgbnRfbGYgKiBsZiA9IChudF9sZiopKGJhc2UrbmstPmxmX29mZis0KTsKCSAgaWYgKCFfbnRfcGFyc2VfbGYoc3Via2V5LCBiYXNlLCBuay0+bnJfc3Via2V5cywgbGYsIGxldmVsLTEpKSBnb3RvIGVycm9yMTsKCX0KCgkvKiBsb29wIHRyb3VnaCB0aGUgdmFsdWUgbGlzdCAqLwoJdmwgPSAoRFdPUkQgKikoYmFzZStuay0+dmFsdWVsaXN0X29mZis0KTsKCWZvciAoaT0wOyBpPG5rLT5ucl92YWx1ZXM7IGkrKykKCXsKCSAgbnRfdmsgKiB2ayA9IChudF92ayopKGJhc2UrdmxbaV0rNCk7CgkgIGlmICghX250X3BhcnNlX3ZrKHN1YmtleSwgYmFzZSwgdmspKSBnb3RvIGVycm9yMTsKCX0KCglSZWdDbG9zZUtleShzdWJrZXkpOwoJcmV0dXJuIFRSVUU7CgkKZXJyb3IxOglSZWdDbG9zZUtleShzdWJrZXkpOwplcnJvcjoJcmV0dXJuIEZBTFNFOwp9CgovKiBlbmQgbnQgbG9hZGVyICovCgovKiB3aW5kb3dzIDk1IHJlZ2lzdHJ5IGxvYWRlciAqLwoKLyogU0VDVElPTiAxOiBtYWluIGhlYWRlcgogKgogKiBvbmNlIGF0IG9mZnNldCAwCiAqLwojZGVmaW5lCVc5NV9SRUdfQ1JFR19JRAkweDQ3NDU1MjQzCgp0eXBlZGVmIHN0cnVjdCAKewoJRFdPUkQJaWQ7CQkvKiAiQ1JFRyIgPSBXOTVfUkVHX0NSRUdfSUQgKi8KCURXT1JECXZlcnNpb247CS8qID8/Pz8gMHgwMDAxMDAwMCAqLwoJRFdPUkQJcmdkYl9vZmY7CS8qIDB4MDggT2Zmc2V0IG9mIDFzdCBSR0RCLWJsb2NrICovCglEV09SRAl1azI7CQkvKiAweDBjICovCglXT1JECXJnZGJfbnVtOwkvKiAweDEwICMgb2YgUkdEQi1ibG9ja3MgKi8KCVdPUkQJdWszOwoJRFdPUkQJdWtbM107CgkvKiByZ2tuICovCn0gX3c5NWNyZWc7CgovKiBTRUNUSU9OIDI6IERpcmVjdG9yeSBpbmZvcm1hdGlvbiAodHJlZSBzdHJ1Y3R1cmUpCiAqCiAqIG9uY2Ugb24gb2Zmc2V0IDB4MjAKICoKICogc3RydWN0dXJlOiBbcmdrbl1bZGtlXSoJKHJlcGVhdCB0aWxsIHJna24tPnNpemUgaXMgcmVhY2hlZCkKICovCiNkZWZpbmUJVzk1X1JFR19SR0tOX0lECTB4NGU0YjQ3NTIKCnR5cGVkZWYgc3RydWN0CnsKCURXT1JECWlkOwkJLyoiUkdLTiIgPSBXOTVfUkVHX1JHS05fSUQgKi8KCURXT1JECXNpemU7CQkvKiBTaXplIG9mIHRoZSBSR0tOLWJsb2NrICovCglEV09SRAlyb290X29mZjsJLyogUmVsLiBPZmZzZXQgb2YgdGhlIHJvb3QtcmVjb3JkICovCglEV09SRAl1a1s1XTsKfSBfdzk1cmdrbjsKCi8qIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZQogKgogKiB0aGUgMXN0IGVudHJ5IGluIGEgInVzdWFsIiByZWdpc3RyeSBmaWxlIGlzIGEgbnVsLWVudHJ5IHdpdGggc3Via2V5czogdGhlCiAqIGhpdmUgaXRzZWxmLiBJdCBsb29rcyB0aGUgc2FtZSBsaWtlIG90aGVyIGtleXMuIEV2ZW4gdGhlIElELW51bWJlciBjYW4KICogYmUgYW55IHZhbHVlLgogKgogKiBUaGUgImhhc2giLXZhbHVlIGlzIGEgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBrZXkncyBuYW1lLiBXaW5kb3dzIHdpbGwgbm90CiAqIHNlYXJjaCBmb3IgdGhlIG5hbWUsIGJ1dCBmb3IgYSBtYXRjaGluZyBoYXNoLXZhbHVlLiBpZiBpdCBmaW5kcyBvbmUsIGl0CiAqIHdpbGwgY29tcGFyZSB0aGUgYWN0dWFsIHN0cmluZyBpbmZvLCBvdGhlcndpc2UgY29udGludWUgd2l0aCB0aGUgbmV4dCBrZXkuCiAqIFRvIGNhbGN1bGF0ZSB0aGUgaGFzaCBpbml0aWFsaXplIGEgRC1Xb3JkIHdpdGggMCBhbmQgYWRkIGFsbCBBU0NJSS12YWx1ZXMgCiAqIG9mIHRoZSBzdHJpbmcgd2hpY2ggYXJlIHNtYWxsZXIgdGhhbiAweDgwICgxMjgpIHRvIHRoaXMgRC1Xb3JkLiAgIAogKgogKiBJZiB5b3Ugd2FudCB0byBtb2RpZnkga2V5IG5hbWVzLCBhbHNvIG1vZGlmeSB0aGUgaGFzaC12YWx1ZXMsIHNpbmNlIHRoZXkKICogY2Fubm90IGJlIGZvdW5kIGFnYWluIChhbHRob3VnaCB0aGV5IHdvdWxkIGJlIGRpc3BsYXllZCBpbiBSRUdFRElUKQogKiBFbmQgb2YgbGlzdC1wb2ludGVycyBhcmUgZmlsbGVkIHdpdGggMHhGRkZGRkZGRgogKgogKiBEaXNrIGtleXMgYXJlIGxheWVkIG91dCBmbGF0IC4uLiBCdXQsIHNvbWV0aW1lcywgbnJMUyBhbmQgbnJIUyBhcmUgYm90aAogKiAweEZGRkYsIHdoaWNoIG1lYW5zIHNraXBwaW5nIG92ZXIgbmV4dGtleW9mZnNldCBieXRlcyAoaW5jbHVkaW5nIHRoaXMKICogc3RydWN0dXJlKSBhbmQgcmVhZGluZyBhbm90aGVyIFJHREJfc2VjdGlvbi4KICoKICogdGhlcmUgaXMgYSBvbmUgdG8gb25lIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGRrZSBhbmQgZGtoCiAqLwogLyoga2V5IHN0cnVjdCwgb25jZSBwZXIga2V5ICovCnR5cGVkZWYgc3RydWN0CnsKCURXT1JECXgxOwkJLyogRnJlZSBlbnRyeSBpbmRpY2F0b3IoPykgKi8KCURXT1JECWhhc2g7CQkvKiBzdW0gb2YgYnl0ZXMgb2Yga2V5bmFtZSAqLwoJRFdPUkQJeDM7CQkvKiBSb290IGtleSBpbmRpY2F0b3I/IHVzdWFsbHkgMHhGRkZGRkZGRiAqLwoJRFdPUkQJcHJldmx2bDsJLyogb2Zmc2V0IG9mIHByZXZpb3VzIGtleSAqLwoJRFdPUkQJbmV4dHN1YjsJLyogb2Zmc2V0IG9mIGNoaWxkIGtleSAqLwoJRFdPUkQJbmV4dDsJCS8qIG9mZnNldCBvZiBzaWJsaW5nIGtleSAqLwoJV09SRAluckxTOwkJLyogaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCglXT1JECW5yTVM7CQkvKiBudW1iZXIgb2YgdGhlIHJnZGIgYmxvY2sgKi8KfSBfdzk1ZGtlOwoKLyogU0VDVElPTiAzOiBrZXkgaW5mb3JtYXRpb24sIHZhbHVlcyBhbmQgZGF0YQogKgogKiBzdHJ1Y3R1cmU6CiAqICBzZWN0aW9uOglbYmxvY2tzXSoJCShyZXBlYXQgY3JlZy0+cmdkYl9udW0gdGltZXMpCiAqICBibG9ja3M6CVtyZ2RiXSBbc3ViYmxvY2tzXSogCShyZXBlYXQgdGlsbCBibG9jayBzaXplIHJlYWNoZWQgKQogKiAgc3ViYmxvY2tzOglbZGtoXSBbZGt2XSoJCShyZXBlYXQgZGtoLT52YWx1ZXMgdGltZXMgKQogKgogKiBBbiBpbnRlcmVzdGluZyByZWxhdGlvbnNoaXAgZXhpc3RzIGluIFJHREJfc2VjdGlvbi4gVGhlIHZhbHVlIGF0IG9mZnNldAogKiAxMCBlcXVhbHMgdGhlIHZhbHVlIGF0IG9mZnNldCA0IG1pbnVzIHRoZSB2YWx1ZSBhdCBvZmZzZXQgOC4gSSBoYXZlIG5vCiAqIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKi8KCi8qIGJsb2NrIGhlYWRlciwgb25jZSBwZXIgYmxvY2sgKi8KI2RlZmluZSBXOTVfUkVHX1JHREJfSUQJMHg0MjQ0NDc1MgoKdHlwZWRlZiBzdHJ1Y3QKewoJRFdPUkQJaWQ7CS8qIDB4MDAgJ3JnZGInID0gVzk1X1JFR19SR0RCX0lEICovCglEV09SRAlzaXplOwkvKiAweDA0ICovCglEV09SRAl1azE7CS8qIDB4MDggKi8KCURXT1JECXVrMjsJLyogMHgwYyAqLwoJRFdPUkQJdWszOwkvKiAweDEwICovCglEV09SRAl1azQ7CS8qIDB4MTQgKi8KCURXT1JECXVrNTsJLyogMHgxOCAqLwoJRFdPUkQJdWs2OwkvKiAweDFjICovCgkvKiBka2ggKi8KfSBfdzk1cmdkYjsKCi8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCksIG9uY2UgcGVyIGtleSAqLwp0eXBlZGVmCXN0cnVjdCAKewoJRFdPUkQJbmV4dGtleW9mZjsgCS8qIDB4MDAgb2Zmc2V0IHRvIG5leHQgZGtoKi8KCVdPUkQJbnJMUzsJCS8qIDB4MDQgaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCglXT1JECW5yTVM7CQkvKiAweDA2IG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwoJRFdPUkQJYnl0ZXN1c2VkOwkvKiAweDA4ICovCglXT1JECWtleW5hbWVsZW47CS8qIDB4MGMgbGVuIG9mIG5hbWUgKi8KCVdPUkQJdmFsdWVzOwkJLyogMHgwZSBudW1iZXIgb2YgdmFsdWVzICovCglEV09SRAl4eDE7CQkvKiAweDEwICovCgljaGFyCW5hbWVbMV07CS8qIDB4MTQgKi8KCS8qIGRrdiAqLwkJLyogMHgxNCArIGtleW5hbWVsZW4gKi8KfSBfdzk1ZGtoOwoKLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlLCBvbmNlIHBlciB2YWx1ZSAqLwp0eXBlZGVmCXN0cnVjdAp7CglEV09SRAl0eXBlOwkJLyogMHgwMCAqLwoJRFdPUkQJeDE7CQkvKiAweDA0ICovCglXT1JECXZhbG5hbWVsZW47CS8qIDB4MDggbGVuZ3RoIG9mIG5hbWUsIDAgaXMgZGVmYXVsdCBrZXkgKi8KCVdPUkQJdmFsZGF0YWxlbjsJLyogMHgwQSBsZW5ndGggb2YgZGF0YSAqLwoJY2hhcgluYW1lWzFdOwkvKiAweDBjICovCgkvKiByYXcgZGF0YSAqLwkJLyogMHgwYyArIHZhbG5hbWVsZW4gKi8KfSBfdzk1ZGt2OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvb2t1cF9ka2ggW0ludGVybmFsXQogKgogKiBzZWVrcyB0aGUgZGtoIGJlbG9uZ2luZyB0byBhIGRrZQogKi8Kc3RhdGljIF93OTVka2ggKiBfdzk1X2xvb2t1cF9ka2ggKF93OTVjcmVnICpjcmVnLCBpbnQgbnJMUywgaW50IG5yTVMpCnsKCV93OTVyZ2RiICogcmdkYjsKCV93OTVka2ggKiBka2g7CglpbnQgaTsKCQoJLyogZ2V0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHJnZGIgZGF0YXN0b3JlICovCglyZ2RiID0gKF93OTVyZ2RiKikoKGNoYXIqKWNyZWcrY3JlZy0+cmdkYl9vZmYpOwoKCS8qIGNoZWNrOiByZXF1ZXN0ZWQgYmxvY2sgPCBsYXN0X2Jsb2NrKSAqLwoJaWYgKGNyZWctPnJnZGJfbnVtIDw9IG5yTVMpCQkJCQoJewoJICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgcmVxdWVzdGVkIGJsb2NrIG5vLiBiZXlvbmQgZW5kLlxuIik7CgkgIGdvdG8gZXJyb3I7Cgl9CgkKCS8qIGZpbmQgdGhlIHJpZ2h0IGJsb2NrICovCglmb3IoaT0wOyBpPG5yTVMgO2krKykKCXsKCSAgaWYocmdkYi0+aWQgIT0gVzk1X1JFR19SR0RCX0lEKQkJCS8qIGNoZWNrIHRoZSBtYWdpYyAqLwoJICB7CgkgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGJhZCBtYWdpYyAweCUwOGx4XG4iLCByZ2RiLT5pZCk7CgkgICAgZ290byBlcnJvcjsKCSAgfQoJICByZ2RiID0gKF93OTVyZ2RiKikgKChjaGFyKilyZ2RiK3JnZGItPnNpemUpOwkJLyogZmluZCBuZXh0IGJsb2NrICovCgl9CgoJZGtoID0gKF93OTVka2gqKShyZ2RiICsgMSk7CQkJCS8qIGZpcnN0IHN1YiBibG9jayB3aXRoaW4gdGhlIHJnZGIgKi8KCglkbwoJewoJICBpZihuckxTPT1ka2gtPm5yTFMgKSByZXR1cm4gZGtoOwoJICBka2ggPSAoX3c5NWRraCopKChjaGFyKilka2ggKyBka2gtPm5leHRrZXlvZmYpOwkvKiBmaW5kIG5leHQgc3ViYmxvY2sgKi8KCX0gd2hpbGUgKChjaGFyICopZGtoIDwgKChjaGFyKilyZ2RiK3JnZGItPnNpemUpKTsKCmVycm9yOglyZXR1cm4gTlVMTDsKfQkKIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfcGFyc2VfZGt2IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9wYXJzZV9ka3YgKAoJSEtFWSBoa2V5LAoJX3c5NWRraCAqIGRraCwKCWludCBuckxTLAoJaW50IG5yTVMgKQp7Cglfdzk1ZGt2ICogZGt2OwoJaW50IGk7CglEV09SRCByZXQ7CgljaGFyICogbmFtZTsKCQkJCgkvKiBmaXJzdCB2YWx1ZSBibG9jayAqLwoJZGt2ID0gKF93OTVka3YqKSgoY2hhciopZGtoK2RraC0+a2V5bmFtZWxlbisweDE0KTsKCgkvKiBsb29wIHRyb3VnaHQgdGhlIHZhbHVlcyAqLwoJZm9yIChpPTA7IGk8IGRraC0+dmFsdWVzOyBpKyspCgl7CgkgIG5hbWUgPSBfc3RyZHVwbkEoZGt2LT5uYW1lLCBka3YtPnZhbG5hbWVsZW4rMSk7CgkgIHJldCA9IFJlZ1NldFZhbHVlRXhBKGhrZXksIG5hbWUsIDAsIGRrdi0+dHlwZSwgJihka3YtPm5hbWVbZGt2LT52YWxuYW1lbGVuXSksZGt2LT52YWxkYXRhbGVuKTsgCgkgIGlmIChyZXQpIEZJWE1FKCJSZWdTZXRWYWx1ZUV4IHJldHVybmVkOiAweCUwOGx4XG4iLCByZXQpOwoJICBmcmVlIChuYW1lKTsKCgkgIC8qIG5leHQgdmFsdWUgKi8KCSAgZGt2ID0gKF93OTVka3YqKSgoY2hhciopZGt2K2Rrdi0+dmFsbmFtZWxlbitka3YtPnZhbGRhdGFsZW4rMHgwYyk7Cgl9CglyZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X3BhcnNlX2RrZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfcGFyc2VfZGtlKCAKCUhLRVkgaGtleSwKCV93OTVjcmVnICogY3JlZywKCV93OTVyZ2tuICpyZ2tuLAoJX3c5NWRrZSAqIGRrZSwKCWludCBsZXZlbCApCnsKCV93OTVka2ggKiBka2g7CglIS0VZIGhzdWJrZXkgPSBoa2V5OwoJY2hhciAqIG5hbWU7CglpbnQgcmV0ID0gRkFMU0U7CgoJLyogZ2V0IHN0YXJ0IGFkZHJlc3Mgb2Ygcm9vdCBrZXkgYmxvY2sgKi8KCWlmICghZGtlKSBka2UgPSAoX3c5NWRrZSopKChjaGFyKilyZ2tuICsgcmdrbi0+cm9vdF9vZmYpOwoJCgkvKiBzcGVjaWFsIHJvb3Qga2V5ICovCglpZiAoZGtlLT5uckxTID09IDB4ZmZmZiB8fCBka2UtPm5yTVM9PTB4ZmZmZikJCS8qIGVnLiB0aGUgcm9vdCBrZXkgaGFzIG5vIG5hbWUgKi8KCXsKCSAgLyogcGFyc2UgdGhlIG9uZSBzdWJrZXkqLwoJICBpZiAoZGtlLT5uZXh0c3ViICE9IDB4ZmZmZmZmZmYpIAoJICB7CiAgICAJICAgIHJldHVybiBfdzk1X3BhcnNlX2RrZShoc3Via2V5LCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dHN1YiksIGxldmVsKTsKCSAgfQoJICAvKiBoYXMgbm8gc2libGluZyBrZXlzICovCgkgIGdvdG8gZXJyb3I7Cgl9CgoJLyogc2VhcmNoIHN1YmJsb2NrICovCglpZiAoIShka2ggPSBfdzk1X2xvb2t1cF9ka2goY3JlZywgZGtlLT5uckxTLCBka2UtPm5yTVMpKSkKCXsKCSAgZnByaW50ZihzdGRlcnIsICJka2UgcG9pbnRpbmcgdG8gbWlzc2luZyBka2ggIVxuIik7CgkgIGdvdG8gZXJyb3I7Cgl9CgoJaWYgKCBsZXZlbCA8PSAwICkKCXsKCSAgLyogd2FsayBzaWJsaW5nIGtleXMgKi8KCSAgaWYgKGRrZS0+bmV4dCAhPSAweGZmZmZmZmZmICkKCSAgewogICAgCSAgICBpZiAoIV93OTVfcGFyc2VfZGtlKGhrZXksIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0KSwgbGV2ZWwpKSBnb3RvIGVycm9yOwoJICB9CgoJICAvKiBjcmVhdGUgc3Via2V5IGFuZCBpbnNlcnQgdmFsdWVzICovCgkgIG5hbWUgPSBfc3RyZHVwbkEoIGRraC0+bmFtZSwgZGtoLT5rZXluYW1lbGVuKzEpOwoJICBpZiAoUmVnQ3JlYXRlS2V5QShoa2V5LCBuYW1lLCAmaHN1YmtleSkpIHsgZnJlZShuYW1lKTsgZ290byBlcnJvcjsgfQoJICBmcmVlKG5hbWUpOwoJICBpZiAoIV93OTVfcGFyc2VfZGt2KGhzdWJrZXksIGRraCwgZGtlLT5uckxTLCBka2UtPm5yTVMpKSBnb3RvIGVycm9yMTsKCX0gIAoJCiAJLyogbmV4dCBzdWIga2V5ICovCglpZiAoZGtlLT5uZXh0c3ViICE9IDB4ZmZmZmZmZmYpIAoJewogICAgCSAgaWYgKCFfdzk1X3BhcnNlX2RrZShoc3Via2V5LCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dHN1YiksIGxldmVsLTEpKSBnb3RvIGVycm9yMTsKCX0KCglyZXQgPSBUUlVFOwplcnJvcjE6CWlmIChoc3Via2V5ICE9IGhrZXkpIFJlZ0Nsb3NlS2V5KGhzdWJrZXkpOwplcnJvcjoJcmV0dXJuIHJldDsKfQovKiBlbmQgd2luZG93cyA5NSBsb2FkZXIgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJTmF0aXZlUmVnTG9hZEtleSBbSW50ZXJuYWxdCiAqCiAqIExvYWRzIGEgbmF0aXZlIHJlZ2lzdHJ5IGZpbGUgKHdpbjk1L250KQogKiAJaGtleQlyb290IGtleQogKglmbglmaWxlbmFtZQogKglsZXZlbAludW1iZXIgb2YgbGV2ZWxzIHRvIGN1dCBhd2F5IChlZy4gIi5EZWZhdWx0IiBpbiB1c2VyLmRhdCkKICoKICogdGhpcyBmdW5jdGlvbiBpbnRlbnRpb25hbGx5IHVzZXMgdW5peCBmaWxlIGZ1bmN0aW9ucyB0byBtYWtlIGl0IHBvc3NpYmxlCiAqIHRvIG1vdmUgaXQgdG8gYSBzZXBlcmF0ZSByZWdpc3RyeSBoZWxwZXIgcHJvZ3JhbW0KICovCnN0YXRpYyBpbnQgTmF0aXZlUmVnTG9hZEtleSggSEtFWSBoa2V5LCBjaGFyKiBmbiwgaW50IGxldmVsICkKewoJaW50IGZkID0gMDsKCXN0cnVjdCBzdGF0IHN0OwogICAgICAgIERPU19GVUxMX05BTUUgZnVsbF9uYW1lOwoJaW50IHJldCA9IEZBTFNFOwoJdm9pZCAqIGJhc2U7CgkJCQogICAgICAgIGlmICghRE9TRlNfR2V0RnVsbE5hbWUoIGZuLCAwLCAmZnVsbF9uYW1lICkpIHJldHVybiBGQUxTRTsKCQoJLyogbWFwIHRoZSByZWdpc3RyeSBpbnRvIHRoZSBtZW1vcnkgKi8KCWlmICgoZmQgPSBvcGVuKGZ1bGxfbmFtZS5sb25nX25hbWUsIE9fUkRPTkxZIHwgT19OT05CTE9DSykpID09IC0xKSByZXR1cm4gRkFMU0U7CglpZiAoKGZzdGF0KGZkLCAmc3QpID09IC0xKSkgZ290byBlcnJvcjsKCWlmICghc3Quc3Rfc2l6ZSkgZ290byBlcnJvcjsKCWlmICgoYmFzZSA9IG1tYXAoTlVMTCwgc3Quc3Rfc2l6ZSwgUFJPVF9SRUFELCBNQVBfUFJJVkFURSwgZmQsIDApKSA9PSBNQVBfRkFJTEVEKSBnb3RvIGVycm9yOwoKCXN3aXRjaCAoKihMUERXT1JEKWJhc2UpCgl7CgkgIC8qIHdpbmRvd3MgOTUgJ2NyZWcnICovCgkgIGNhc2UgVzk1X1JFR19DUkVHX0lEOgoJICAgIHsKCSAgICAgIF93OTVjcmVnICogY3JlZzsKCSAgICAgIF93OTVyZ2tuICogcmdrbjsKCSAgICAgIGNyZWcgPSBiYXNlOwoJICAgICAgVFJBQ0VfKHJlZykoIkxvYWRpbmcgd2luOTUgcmVnaXN0cnkgJyVzJyAnJXMnXG4iLGZuLCBmdWxsX25hbWUubG9uZ19uYW1lKTsKCgkgICAgICAvKiBsb2FkIHRoZSBoZWFkZXIgKHJna24pICovCgkgICAgICByZ2tuID0gKF93OTVyZ2tuKikoY3JlZyArIDEpOwoJICAgICAgaWYgKHJna24tPmlkICE9IFc5NV9SRUdfUkdLTl9JRCkgCgkgICAgICB7CgkJRVJSKCJzZWNvbmQgSUZGIGhlYWRlciBub3QgUkdLTiwgYnV0ICVseFxuIiwgcmdrbi0+aWQpOwoJCWdvdG8gZXJyb3IxOwoJICAgICAgfQoKCSAgICAgIHJldCA9IF93OTVfcGFyc2VfZGtlKGhrZXksIGNyZWcsIHJna24sIE5VTEwsIGxldmVsKTsKCSAgICB9CgkgICAgYnJlYWs7CgkgIC8qIG50ICdyZWdmJyovCgkgIGNhc2UgTlRfUkVHX0hFQURFUl9CTE9DS19JRDoKCSAgICB7CgkgICAgICBudF9yZWdmICogcmVnZjsKCSAgICAgIG50X2hiaW4gKiBoYmluOwoJICAgICAgbnRfaGJpbl9zdWIgKiBoYmluX3N1YjsKCSAgICAgIG50X25rKiBuazsKCgkgICAgICBUUkFDRV8ocmVnKSgiTG9hZGluZyBudCByZWdpc3RyeSAnJXMnICclcydcbiIsZm4sIGZ1bGxfbmFtZS5sb25nX25hbWUpOwoKCSAgICAgIC8qIHN0YXJ0IGJsb2NrICovCgkgICAgICByZWdmID0gYmFzZTsKCgkgICAgICAvKiBoYmluIGJsb2NrICovCgkgICAgICBoYmluID0gKG50X2hiaW4qKSgoY2hhciopIGJhc2UgKyAweDEwMDApOwoJICAgICAgaWYgKGhiaW4tPmlkICE9IE5UX1JFR19QT09MX0JMT0NLX0lEKQoJICAgICAgewoJICAgICAgICBFUlJfKHJlZykoICIlcyBoYmluIGJsb2NrIGludmFsaWRcbiIsIGZuKTsKCSAgICAgICAgZ290byBlcnJvcjE7CgkgICAgICB9CgoJICAgICAgLyogaGJpbl9zdWIgYmxvY2sgKi8KCSAgICAgIGhiaW5fc3ViID0gKG50X2hiaW5fc3ViKikmKGhiaW4tPmhiaW5fc3ViKTsKCSAgICAgIGlmICgoaGJpbl9zdWItPmRhdGFbMF0gIT0gJ24nKSB8fCAoaGJpbl9zdWItPmRhdGFbMV0gIT0gJ2snKSkKCSAgICAgIHsKCSAgICAgICAgRVJSXyhyZWcpKCAiJXMgaGJpbl9zdWIgYmxvY2sgaW52YWxpZFxuIiwgZm4pOwoJICAgICAgICBnb3RvIGVycm9yMTsKCSAgICAgIH0KCgkgICAgICAvKiBuayBibG9jayAqLwoJICAgICAgbmsgPSAobnRfbmsqKSYoaGJpbl9zdWItPmRhdGFbMF0pOwoJICAgICAgaWYgKG5rLT5UeXBlICE9IE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKQoJICAgICAgewoJICAgICAgICBFUlJfKHJlZykoICIlcyBzcGVjaWFsIG5rIGJsb2NrIG5vdCBmb3VuZFxuIiwgZm4pOwoJICAgICAgICBnb3RvIGVycm9yMTsKCSAgICAgIH0KCgkgICAgICByZXQgPSBfbnRfcGFyc2VfbmsgKGhrZXksIChjaGFyICopIGJhc2UgKyAweDEwMDAsIG5rLCBsZXZlbCk7CgkgICAgfQoJICAgIGJyZWFrOwoJICBkZWZhdWx0OgoJICAgIHsKCSAgICAgIEVSUigidW5rbm93biBzaWduYXR1cmUgaW4gcmVnaXN0cnkgZmlsZSAlcy5cbiIsZm4pOwoJICAgICAgZ290byBlcnJvcjE7CgkgICAgfQoJfQoJaWYoIXJldCkgRVJSKCJlcnJvciBsb2FkaW5nIHJlZ2lzdHJ5IGZpbGUgJXNcbiIsIGZuKTsKZXJyb3IxOgltdW5tYXAoYmFzZSwgc3Quc3Rfc2l6ZSk7CmVycm9yOgljbG9zZShmZCk7CglyZXR1cm4gcmV0OwkKfQoKLyogV0lORE9XUyAzMSBSRUdJU1RSWSBMT0FERVIsIHN1cHBsaWVkIGJ5IFRvciBTavh3YWxsLCB0b3JAc24ubm8gKi8KLyoKICAgIHJlZ2hhY2sgLSB3aW5kb3dzIDMuMTEgcmVnaXN0cnkgZGF0YSBmb3JtYXQgZGVtbyBwcm9ncmFtLgoKICAgIFRoZSByZWcuZGF0IGZpbGUgaGFzIDMgcGFydHMsIGEgaGVhZGVyLCBhIHRhYmxlIG9mIDgtYnl0ZSBlbnRyaWVzIHRoYXQgaXMKICAgIGEgY29tYmluZWQgaGFzaCB0YWJsZSBhbmQgdHJlZSBkZXNjcmlwdGlvbiwgYW5kIGZpbmFsbHkgYSB0ZXh0IHRhYmxlLgoKICAgIFRoZSBoZWFkZXIgaXMgb2J2aW91cyBmcm9tIHRoZSBzdHJ1Y3QgaGVhZGVyLiBUaGUgdGFib2ZmMSBhbmQgdGFib2ZmMgogICAgZmllbGRzIGFyZSBhbHdheXMgMHgyMCwgYW5kIHRoZWlyIHVzYWdlIGlzIHVua25vd24uCgogICAgVGhlIDgtYnl0ZSBlbnRyeSB0YWJsZSBoYXMgdmFyaW91cyBlbnRyeSB0eXBlcy4KCiAgICB0YWJlbnRbMF0gaXMgYSByb290IGluZGV4LiBUaGUgc2Vjb25kIHdvcmQgaGFzIHRoZSBpbmRleCBvZiB0aGUgcm9vdCBvZgogICAgICAgICAgICB0aGUgZGlyZWN0b3J5LgogICAgdGFiZW50WzEuLmhhc2hzaXplXSBpcyBhIGhhc2ggdGFibGUuIFRoZSBmaXJzdCB3b3JkIGluIHRoZSBoYXNoIGVudHJ5IGlzCiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUga2V5L3ZhbHVlIHRoYXQgaGFzIHRoYXQgaGFzaC4gRGF0YSB3aXRoIHRoZSBzYW1lCiAgICAgICAgICAgIGhhc2ggdmFsdWUgYXJlIG9uIGEgY2lyY3VsYXIgbGlzdC4gVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZQogICAgICAgICAgICBoYXNoIGVudHJ5IGFyZSBhbHdheXMgemVyby4KICAgIHRhYmVudFtoYXNoc2l6ZS4udGFiY250XSBpcyB0aGUgdHJlZSBzdHJ1Y3R1cmUuIFRoZXJlIGFyZSB0d28ga2luZHMgb2YKICAgICAgICAgICAgZW50cnk6IGRpcmVudCBhbmQga2V5ZW50L3ZhbGVudC4gVGhleSBhcmUgaWRlbnRpZmllZCBieSBjb250ZXh0LgogICAgdGFiZW50W2ZyZWVpZHhdIGlzIHRoZSBmaXJzdCBmcmVlIGVudHJ5LiBUaGUgZmlyc3Qgd29yZCBpbiBhIGZyZWUgZW50cnkKICAgICAgICAgICAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGZyZWUgZW50cnkuIFRoZSBsYXN0IGhhcyAwIGFzIGEgbGluay4KICAgICAgICAgICAgVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZSBmcmVlIGxpc3QgYXJlIHByb2JhYmx5IGlycmVsZXZhbnQuCgogICAgRW50cmllcyBpbiB0ZXh0IHRhYmxlIGFyZSBwcmVjZWVkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewoJY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCgl1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7Cgl1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7Cgl1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCgl1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgKi8Kdm9pZApfX3czMV9kdW1wdHJlZSgJdW5zaWduZWQgc2hvcnQgaWR4LAoJCXVuc2lnbmVkIGNoYXIgKnR4dCwKCQlzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYiwKCQlzdHJ1Y3QgX3czMV9oZWFkZXIgKmhlYWQsCgkJSEtFWSBoa2V5LAoJCXRpbWVfdAkJbGFzdG1vZGlmaWVkLAoJCWludAkJbGV2ZWwKKSB7CglzdHJ1Y3QgX3czMV9kaXJlbnQJKmRpcjsKCXN0cnVjdCBfdzMxX2tleWVudAkqa2V5OwoJc3RydWN0IF93MzFfdmFsZW50CSp2YWw7CiAgICAgICAgSEtFWSBzdWJrZXkgPSAwOwoJc3RhdGljIGNoYXIJCXRhaWxbNDAwXTsKCgl3aGlsZSAoaWR4IT0wKSB7CgkJZGlyPShzdHJ1Y3QgX3czMV9kaXJlbnQqKSZ0YWJbaWR4XTsKCgkJaWYgKGRpci0+a2V5X2lkeCkgewoJCQlrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgoJCQltZW1jcHkodGFpbCwmdHh0W2tleS0+c3RyaW5nX29mZl0sa2V5LT5sZW5ndGgpOwoJCQl0YWlsW2tleS0+bGVuZ3RoXT0nXDAnOwoJCQkvKiBhbGwgdG9wbGV2ZWwgZW50cmllcyBBTkQgdGhlIGVudHJpZXMgaW4gdGhlIAoJCQkgKiB0b3BsZXZlbCBzdWJkaXJlY3RvcnkgYmVsb25nIHRvIFxTT0ZUV0FSRVxDbGFzc2VzCgkJCSAqLwoJCQlpZiAoIWxldmVsICYmICFsc3RyY21wQSh0YWlsLCIuY2xhc3NlcyIpKSB7CgkJCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsaGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJCQlpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKCQkJCWNvbnRpbnVlOwoJCQl9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFJlZ0NyZWF0ZUtleUEoIGhrZXksIHRhaWwsICZzdWJrZXkgKSAhPSBFUlJPUl9TVUNDRVNTKSBzdWJrZXkgPSAwOwoJCQkvKiBvbmx5IGFkZCBpZiBsZWFmIG5vZGUgb3IgdmFsdWVkIG5vZGUgKi8KCQkJaWYgKGRpci0+dmFsdWVfaWR4IT0wfHxkaXItPmNoaWxkX2lkeD09MCkgewoJCQkJaWYgKGRpci0+dmFsdWVfaWR4KSB7CgkJCQkJdmFsPShzdHJ1Y3QgX3czMV92YWxlbnQqKSZ0YWJbZGlyLT52YWx1ZV9pZHhdOwoJCQkJCW1lbWNweSh0YWlsLCZ0eHRbdmFsLT5zdHJpbmdfb2ZmXSx2YWwtPmxlbmd0aCk7CgkJCQkJdGFpbFt2YWwtPmxlbmd0aF09J1wwJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1NldFZhbHVlQSggc3Via2V5LCBOVUxMLCBSRUdfU1osIHRhaWwsIDAgKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCVRSQUNFKCJzdHJhbmdlOiBubyBkaXJlY3Rvcnkga2V5IG5hbWUsIGlkeD0lMDR4XG4iLCBpZHgpOwoJCX0KCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsc3Via2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQlpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKCX0KICAgICAgICBpZiAoc3Via2V5KSBSZWdDbG9zZUtleSggc3Via2V5ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93MzFfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwp2b2lkIF93MzFfbG9hZHJlZyh2b2lkKSB7CglIRklMRQkJCWhmOwoJc3RydWN0IF93MzFfaGVhZGVyCWhlYWQ7CglzdHJ1Y3QgX3czMV90YWJlbnQJKnRhYjsKCXVuc2lnbmVkIGNoYXIJCSp0eHQ7CglpbnQJCQlsZW47CglPRlNUUlVDVAkJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZpbmZvOwoJdGltZV90CQkJbGFzdG1vZGlmaWVkOwoKCVRSQUNFKCIodm9pZClcbiIpOwoKCWhmID0gT3BlbkZpbGUoInJlZy5kYXQiLCZvZnMsT0ZfUkVBRCk7CglpZiAoaGY9PUhGSUxFX0VSUk9SKQoJCXJldHVybjsKCgkvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KCWlmIChzaXplb2YoaGVhZCkhPV9scmVhZChoZiwmaGVhZCxzaXplb2YoaGVhZCkpKSB7CgkJRVJSKCJyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpIT0wKSB7CgkJRVJSKCJyZWcuZGF0IGhhcyBiYWQgc2lnbmF0dXJlLlxuIik7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCWxlbiA9IGhlYWQudGFiY250ICogc2l6ZW9mKHN0cnVjdCBfdzMxX3RhYmVudCk7CgkvKiByZWFkIGFuZCBkdW1wIGluZGV4IHRhYmxlICovCgl0YWIgPSB4bWFsbG9jKGxlbik7CglpZiAobGVuIT1fbHJlYWQoaGYsdGFiLGxlbikpIHsKCQlFUlIoImNvdWxkbid0IHJlYWQgJWQgYnl0ZXMuXG4iLGxlbik7IAoJCWZyZWUodGFiKTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJLyogcmVhZCB0ZXh0ICovCgl0eHQgPSB4bWFsbG9jKGhlYWQudGV4dHNpemUpOwoJaWYgKC0xPT1fbGxzZWVrKGhmLGhlYWQudGV4dG9mZixTRUVLX1NFVCkpIHsKCQlFUlIoImNvdWxkbid0IHNlZWsgdG8gdGV4dGJsb2NrLlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoJaWYgKGhlYWQudGV4dHNpemUhPV9scmVhZChoZix0eHQsaGVhZC50ZXh0c2l6ZSkpIHsKCQlFUlIoInRleHRibG9jayB0b28gc2hvcnQgKCVkIGluc3RlYWQgb2YgJWxkKS5cbiIsbGVuLGhlYWQudGV4dHNpemUpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCglpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmLCZoZmluZm8pKSB7CgkJRVJSKCJHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoJbGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoJX193MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQsSEtFWV9DTEFTU0VTX1JPT1QsbGFzdG1vZGlmaWVkLDApOwoJZnJlZSh0YWIpOwoJZnJlZSh0eHQpOwoJX2xjbG9zZShoZik7CglyZXR1cm47Cn0KCgovKiBjb25maWd1cmUgc2F2ZSBmaWxlcyBhbmQgc3RhcnQgdGhlIHBlcmlvZGljIHNhdmluZyB0aW1lciAqLwpzdGF0aWMgdm9pZCBTSEVMTF9Jbml0UmVnaXN0cnlTYXZpbmcoIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0ICkKewogICAgc3RydWN0IHNldF9yZWdpc3RyeV9sZXZlbHNfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKCiAgICBpbnQgYWxsID0gUFJPRklMRV9HZXRXaW5lSW5pQm9vbCggInJlZ2lzdHJ5IiwgIlNhdmVPbmx5VXBkYXRlZEtleXMiLCAxICk7CiAgICBpbnQgcGVyaW9kID0gUFJPRklMRV9HZXRXaW5lSW5pSW50KCAicmVnaXN0cnkiLCAiUGVyaW9kaWNTYXZlIiwgMCApOwoKICAgIC8qIHNldCBzYXZpbmcgbGV2ZWwgKDAgZm9yIHNhdmluZyBldmVyeXRoaW5nLCAxIGZvciBzYXZpbmcgb25seSBtb2RpZmllZCBrZXlzKSAqLwogICAgcmVxLT5jdXJyZW50ID0gMTsKICAgIHJlcS0+c2F2aW5nICA9ICFhbGw7CiAgICByZXEtPnBlcmlvZCAgPSBwZXJpb2QgKiAxMDAwOwogICAgc2VydmVyX2NhbGwoIFJFUV9TRVRfUkVHSVNUUllfTEVWRUxTICk7CgogICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woInJlZ2lzdHJ5IiwiV3JpdGV0b0hvbWVSZWdpc3RyaWVzIiwxKSkKICAgIHsKICAgICAgICBzdHJ1Y3Qgc2F2ZV9yZWdpc3RyeV9hdGV4aXRfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKICAgICAgICBjb25zdCBjaGFyICpjb25mZGlyID0gZ2V0X2NvbmZpZ19kaXIoKTsKICAgICAgICBjaGFyICpzdHIgPSByZXEtPmZpbGUgKyBzdHJsZW4oY29uZmRpcik7CgogICAgICAgIGlmIChzdHIgKyAyMCA+IHJlcS0+ZmlsZSArIHNlcnZlcl9yZW1haW5pbmcocmVxLT5maWxlKSkKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiY29uZmlnIGRpciAnJXMnIHRvbyBsb25nXG4iLCBjb25mZGlyICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHN0cmNweSggcmVxLT5maWxlLCBjb25mZGlyICk7CiAgICAgICAgc3RyY3B5KCBzdHIsICIvIiBTQVZFX0NVUlJFTlRfVVNFUiApOwogICAgICAgIHJlcS0+aGtleSA9IEhLRVlfQ1VSUkVOVF9VU0VSOwogICAgICAgIHNlcnZlcl9jYWxsKCBSRVFfU0FWRV9SRUdJU1RSWV9BVEVYSVQgKTsKCiAgICAgICAgc3RyY3B5KCByZXEtPmZpbGUsIGNvbmZkaXIgKTsKICAgICAgICBzdHJjcHkoIHN0ciwgIi8iIFNBVkVfTE9DQUxfTUFDSElORSApOwogICAgICAgIHJlcS0+aGtleSA9IEhLRVlfTE9DQUxfTUFDSElORTsKICAgICAgICBzZXJ2ZXJfY2FsbCggUkVRX1NBVkVfUkVHSVNUUllfQVRFWElUICk7CgogICAgICAgIHN0cmNweSggcmVxLT5maWxlLCBjb25mZGlyICk7CiAgICAgICAgc3RyY3B5KCBzdHIsICIvIiBTQVZFX0RFRkFVTFRfVVNFUiApOwogICAgICAgIHJlcS0+aGtleSA9IGhrZXlfdXNlcnNfZGVmYXVsdDsKICAgICAgICBzZXJ2ZXJfY2FsbCggUkVRX1NBVkVfUkVHSVNUUllfQVRFWElUICk7CgogICAgICAgIHN0cmNweSggcmVxLT5maWxlLCBjb25mZGlyICk7CiAgICAgICAgc3RyY3B5KCBzdHIsICIvIiBTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQgKTsKICAgICAgICByZXEtPmhrZXkgPSBIS0VZX1VTRVJTOwogICAgICAgIHNlcnZlcl9jYWxsKCBSRVFfU0FWRV9SRUdJU1RSWV9BVEVYSVQgKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNldExvYWRMZXZlbCBbSW50ZXJuYWxdCiAqCiAqIHNldCBsZXZlbCB0byAwIGZvciBsb2FkaW5nIHN5c3RlbSBmaWxlcwogKiBzZXQgbGV2ZWwgdG8gMSBmb3IgbG9hZGluZyB1c2VyIGZpbGVzCiAqLwpzdGF0aWMgdm9pZCBTZXRMb2FkTGV2ZWwoaW50IGxldmVsKQp7CglzdHJ1Y3Qgc2V0X3JlZ2lzdHJ5X2xldmVsc19yZXF1ZXN0ICpyZXEgPSBnZXRfcmVxX2J1ZmZlcigpOwoKCXJlcS0+Y3VycmVudCA9IGxldmVsOwoJcmVxLT5zYXZpbmcgID0gMDsKICAgICAgICByZXEtPnBlcmlvZCAgPSAwOwoJc2VydmVyX2NhbGwoIFJFUV9TRVRfUkVHSVNUUllfTEVWRUxTICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX0xvYWRSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwojZGVmaW5lIFJFR19ET05UTE9BRCAtMQojZGVmaW5lIFJFR19XSU4zMSAgMAojZGVmaW5lIFJFR19XSU45NSAgMQojZGVmaW5lIFJFR19XSU5OVCAgMgoKdm9pZCBTSEVMTF9Mb2FkUmVnaXN0cnkoIHZvaWQgKQp7CiAgSEtFWQloa2V5OwogIGNoYXIgd2luZGlyW01BWF9QQVRITkFNRV9MRU5dOwogIGNoYXIgcGF0aFtNQVhfUEFUSE5BTUVfTEVOXTsKICBpbnQgIHN5c3RlbXR5cGUgPSBSRUdfV0lOMzE7CiAgSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQ7CgogIFRSQUNFKCIodm9pZClcbiIpOwoKICBpZiAoIUNMSUVOVF9Jc0Jvb3RUaHJlYWQoKSkgcmV0dXJuOyAgLyogYWxyZWFkeSBsb2FkZWQgKi8KCiAgUkVHSVNUUllfSW5pdCgpOwogIFNldExvYWRMZXZlbCgwKTsKCiAgaWYgKFJlZ0NyZWF0ZUtleUEoSEtFWV9VU0VSUywgIi5EZWZhdWx0IiwgJmhrZXlfdXNlcnNfZGVmYXVsdCkpCgkgIGhrZXlfdXNlcnNfZGVmYXVsdCA9IDA7CgogIEdldFdpbmRvd3NEaXJlY3RvcnlBKCB3aW5kaXIsIE1BWF9QQVRITkFNRV9MRU4gKTsKCiAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woICJSZWdpc3RyeSIsICJMb2FkV2luZG93c1JlZ2lzdHJ5RmlsZXMiLCAxKSkKICB7CiAgICAvKiB0ZXN0ICV3aW5kaXIlL3N5c3RlbTMyL2NvbmZpZy9zeXN0ZW0gLS0+IHdpbm50ICovCiAgICBzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgIHN0cm5jYXQocGF0aCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc3lzdGVtIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgaWYoR2V0RmlsZUF0dHJpYnV0ZXNBKHBhdGgpICE9IC0xKSAKICAgIHsKICAgICAgc3lzdGVtdHlwZSA9IFJFR19XSU5OVDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgIC8qIHRlc3QgJXdpbmRpciUvc3lzdGVtLmRhdCAtLT4gd2luOTUgKi8KICAgICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgIHN0cm5jYXQocGF0aCwgIlxcc3lzdGVtLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgaWYoR2V0RmlsZUF0dHJpYnV0ZXNBKHBhdGgpICE9IC0xKQogICAgICB7CiAgICAgICAgc3lzdGVtdHlwZSA9IFJFR19XSU45NTsKICAgICAgfQogICAgfQoKICAgIGlmICgoc3lzdGVtdHlwZT09UkVHX1dJTk5UKQogICAgICAmJiAoISBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJXaW5lIiwgIlByb2ZpbGUiLCAiIiwgcGF0aCwgTUFYX1BBVEhOQU1FX0xFTikpKQogICAgewogICAgICAgTUVTU0FHRSgiV2hlbiB5b3UgYXJlIHJ1bm5pbmcgd2l0aCBhIG5hdGl2ZSBOVCBkaXJlY3Rvcnkgc3BlY2lmeVxuIik7CiAgICAgICBNRVNTQUdFKCInUHJvZmlsZT08cHJvZmlsZWRpcmVjdG9yeT4nIG9yIGRpc2FibGUgbG9hZGluZyBvZiBXaW5kb3dzXG4iKTsKICAgICAgIE1FU1NBR0UoInJlZ2lzdHJ5IChMb2FkV2luZG93c1JlZ2lzdHJ5RmlsZXM9TilcbiIpOwogICAgICAgc3lzdGVtdHlwZSA9IFJFR19ET05UTE9BRDsKICAgIH0KICB9CiAgZWxzZQogIHsKICAgIC8qIG9ubHkgd2luZSByZWdpc3RyeSAqLwogICAgc3lzdGVtdHlwZSA9IFJFR19ET05UTE9BRDsKICB9ICAKCiAgc3dpdGNoIChzeXN0ZW10eXBlKQogIHsKICAgIGNhc2UgUkVHX1dJTjMxOgogICAgICBfdzMxX2xvYWRyZWcoKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBSRUdfV0lOOTU6ICAKICAgICAgLyogTG9hZCB3aW5kb3dzIDk1IGVudHJpZXMgKi8KICAgICAgTmF0aXZlUmVnTG9hZEtleShIS0VZX0xPQ0FMX01BQ0hJTkUsICJDOlxcc3lzdGVtLjFzdCIsIDApOwoKICAgICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgIHN0cm5jYXQocGF0aCwgIlxcc3lzdGVtLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgTmF0aXZlUmVnTG9hZEtleShIS0VZX0xPQ0FMX01BQ0hJTkUsIHBhdGgsIDApOwoKICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggIldpbmUiLCAiUHJvZmlsZSIsICIiLCBwYXRoLCBNQVhfUEFUSE5BTUVfTEVOKSkKICAgICAgewoJLyogdXNlciBzcGVjaWZpYyB1c2VyLmRhdCAqLwoJc3RybmNhdChwYXRoLCAiXFx1c2VyLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgICBpZiAoIU5hdGl2ZVJlZ0xvYWRLZXkoIEhLRVlfQ1VSUkVOVF9VU0VSLCBwYXRoLCAxICkpCgl7CgkgIE1FU1NBR0UoImNhbid0IGxvYWQgd2luOTUgdXNlci1yZWdpc3RyeSAlc1xuIiwgcGF0aCk7CgkgIE1FU1NBR0UoImNoZWNrIHdpbmUuY29uZiwgc2VjdGlvbiBbV2luZV0sIHZhbHVlICdQcm9maWxlJ1xuIik7Cgl9CgkvKiBkZWZhdWx0IHVzZXIuZGF0ICovCglpZiAoaGtleV91c2Vyc19kZWZhdWx0KQoJewogICAgICAgICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgICAgICBzdHJuY2F0KHBhdGgsICJcXHVzZXIuZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICAgICAgTmF0aXZlUmVnTG9hZEtleShoa2V5X3VzZXJzX2RlZmF1bHQsIHBhdGgsIDEpOwoJfQogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgIC8qIGdsb2JhbCB1c2VyLmRhdCAqLwoJc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgICAgc3RybmNhdChwYXRoLCAiXFx1c2VyLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgICBOYXRpdmVSZWdMb2FkS2V5KEhLRVlfQ1VSUkVOVF9VU0VSLCBwYXRoLCAxKTsKICAgICAgfQogICAgICBicmVhazsKCiAgICBjYXNlIFJFR19XSU5OVDogIAogICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCiAgICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJXaW5lIiwgIlByb2ZpbGUiLCAiIiwgcGF0aCwgTUFYX1BBVEhOQU1FX0xFTikpCiAgICAgIHsKICAgICAgICBzdHJuY2F0KHBhdGgsICJcXG50dXNlci5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgICAgaWYoIU5hdGl2ZVJlZ0xvYWRLZXkoIEhLRVlfQ1VSUkVOVF9VU0VSLCBwYXRoLCAxICkpCiAgICAgICAgewogICAgICAgICAgIE1FU1NBR0UoImNhbid0IGxvYWQgTlQgdXNlci1yZWdpc3RyeSAlc1xuIiwgcGF0aCk7CgkgICBNRVNTQUdFKCJjaGVjayB3aW5lLmNvbmYsIHNlY3Rpb24gW1dpbmVdLCB2YWx1ZSAnUHJvZmlsZSdcbiIpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLyogZGVmYXVsdCB1c2VyLmRhdCAqLwogICAgICBpZiAoaGtleV91c2Vyc19kZWZhdWx0KQogICAgICB7CiAgICAgICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgICAgc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0zMlxcY29uZmlnXFxkZWZhdWx0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoaGtleV91c2Vyc19kZWZhdWx0LCBwYXRoLCAxKTsKICAgICAgfQoKICAgICAgLyoKICAgICAgKiBGSVhNRQogICAgICAqICBtYXAgSExNXFN5c3RlbVxDb250cm9sU2V0MDAxIHRvIEhMTVxTeXN0ZW1cQ3VycmVudENvbnRyb2xTZXQKICAgICAgKi8KCiAgICAgIGlmICghUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsICJTWVNURU0iLCAmaGtleSkpCiAgICAgIHsKCXN0cmNweShwYXRoLCB3aW5kaXIpOwoJc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0zMlxcY29uZmlnXFxzeXN0ZW0iLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CglOYXRpdmVSZWdMb2FkS2V5KGhrZXksIHBhdGgsIDEpOwogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICB9CgogICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCAiU09GVFdBUkUiLCAmaGtleSkpCiAgICAgIHsKCXN0cmNweShwYXRoLCB3aW5kaXIpOwoJc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0zMlxcY29uZmlnXFxzb2Z0d2FyZSIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKCU5hdGl2ZVJlZ0xvYWRLZXkoaGtleSwgcGF0aCwgMSk7CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgIH0KCiAgICAgIHN0cmNweShwYXRoLCB3aW5kaXIpOwogICAgICBzdHJuY2F0KHBhdGgsICJcXHN5c3RlbTMyXFxjb25maWdcXHNhbSIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgTmF0aXZlUmVnTG9hZEtleShIS0VZX0xPQ0FMX01BQ0hJTkUsIHBhdGgsIDApOwoKICAgICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgIHN0cm5jYXQocGF0aCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc2VjdXJpdHkiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoSEtFWV9MT0NBTF9NQUNISU5FLCBwYXRoLCAwKTsKCiAgICAgIC8qIHRoaXMga2V5IGlzIGdlbmVyYXRlZCB3aGVuIHRoZSBudC1jb3JlIGJvb3RlZCBzdWNjZXNzZnVsbHkgKi8KICAgICAgaWYgKCFSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDbG9uZSIsJmhrZXkpKQogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICBicmVhazsKICB9IC8qIHN3aXRjaCAqLwogIAogIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sICgicmVnaXN0cnkiLCJMb2FkR2xvYmFsUmVnaXN0cnlGaWxlcyIsIDEpKQogIHsKICAgICAgLyogCiAgICAgICAqIExvYWQgdGhlIGdsb2JhbCBIS1UgaGl2ZSBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIKICAgICAgICovIAogICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX1VTRVJTLCBTQVZFX1VTRVJTX0RFRkFVTFQgKTsKCiAgICAgIC8qIAogICAgICAgKiBMb2FkIHRoZSBnbG9iYWwgbWFjaGluZSBkZWZhdWx0cyBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIKICAgICAgICovCiAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfTE9DQUxfTUFDSElORSwgU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQgKTsKICB9CgogIFNldExvYWRMZXZlbCgxKTsKCiAgLyoKICAgKiBMb2FkIHRoZSB1c2VyIHNhdmVkIHJlZ2lzdHJpZXMgCiAgICovCiAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woInJlZ2lzdHJ5IiwgIkxvYWRIb21lUmVnaXN0cnlGaWxlcyIsIDEpKQogIHsKICAgICAgY29uc3QgY2hhciAqY29uZmRpciA9IGdldF9jb25maWdfZGlyKCk7CiAgICAgIGludCBsZW4gPSBzdHJsZW4oY29uZmRpcikgKyAyMDsKICAgICAgY2hhciAqZm4gPSBwYXRoOwoKICAgICAgaWYgKGxlbiA+IHNpemVvZihwYXRoKSkgZm4gPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbiApOwogICAgICAvKiAKICAgICAgICogTG9hZCB1c2VyJ3MgcGVyc29uYWwgdmVyc2lvbnMgb2YgZ2xvYmFsIEhLVS8uRGVmYXVsdCBrZXlzCiAgICAgICAqLwogICAgICBpZiAoZm4pCiAgICAgIHsKICAgICAgICAgIGNoYXIgKnN0cjsKICAgICAgICAgIHN0cmNweSggZm4sIGNvbmZkaXIgKTsKICAgICAgICAgIHN0ciA9IGZuICsgc3RybGVuKGZuKTsKICAgICAgICAgICpzdHIrKyA9ICcvJzsKCiAgICAgICAgICAvKiB0cnkgdG8gbG9hZCBIS1VcLkRlZmF1bHQga2V5IG9ubHkgKi8KICAgICAgICAgIHN0cmNweSggc3RyLCBTQVZFX0RFRkFVTFRfVVNFUiApOwogICAgICAgICAgaWYgKF93aW5lX2xvYWRyZWcoIGhrZXlfdXNlcnNfZGVmYXVsdCwgZm4gKSkKICAgICAgICAgIHsKICAgICAgICAgICAgICAvKiBpZiBub3QgZm91bmQgbG9hZCBvbGQgZmlsZSBjb250YWluaW5nIGJvdGggSEtVXC5EZWZhdWx0IGFuZCBIS1VcdXNlciAqLwogICAgICAgICAgICAgIHN0cmNweSggc3RyLCBTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQgKTsKICAgICAgICAgICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX1VTRVJTLCBmbiApOyAKICAgICAgICAgIH0KCiAgICAgICAgICBzdHJjcHkoIHN0ciwgU0FWRV9DVVJSRU5UX1VTRVIgKTsKICAgICAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfQ1VSUkVOVF9VU0VSLCBmbiApOwoKICAgICAgICAgIHN0cmNweSggc3RyLCBTQVZFX0xPQ0FMX01BQ0hJTkUgKTsKICAgICAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfTE9DQUxfTUFDSElORSwgZm4gKTsKCiAgICAgICAgICBpZiAoZm4gIT0gcGF0aCkgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGZuICk7CiAgICAgIH0KICB9CiAgU0hFTExfSW5pdFJlZ2lzdHJ5U2F2aW5nKCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKICBSZWdDbG9zZUtleSggaGtleV91c2Vyc19kZWZhdWx0ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKiogQVBJIEZVTkNUSU9OUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0ZsdXNoS2V5IFtLRVJORUwuMjI3XSBbQURWQVBJMzIuMTQzXQogKiBJbW1lZGlhdGVseSB3cml0ZXMga2V5IHRvIHJlZ2lzdHJ5LgogKiBPbmx5IHJldHVybnMgYWZ0ZXIgZGF0YSBoYXMgYmVlbiB3cml0dGVuIHRvIGRpc2suCiAqCiAqIEZJWE1FOiBkb2VzIGl0IHJlYWxseSB3YWl0IHVudGlsIGRhdGEgaXMgd3JpdHRlbiA/CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdyaXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkoIEhLRVkgaGtleSApCnsKICAgIEZJWE1FKCAiKCV4KTogc3R1YlxuIiwgaGtleSApOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ29ubmVjdFJlZ2lzdHJ5VyBbQURWQVBJMzIuMTI4XQogKgogKiBQQVJBTVMKICogICAgbHBNYWNoaW5lTmFtZSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHJlbW90ZSBjb21wdXRlcgogKiAgICBoSGV5ICAgICAgICAgIFtJXSBQcmVkZWZpbmVkIHJlZ2lzdHJ5IGhhbmRsZQogKiAgICBwaGtSZXN1bHQgICAgIFtJXSBBZGRyZXNzIG9mIGJ1ZmZlciBmb3IgcmVtb3RlIHJlZ2lzdHJ5IGhhbmRsZQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5VyggTFBDV1NUUiBscE1hY2hpbmVOYW1lLCBIS0VZIGhLZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSBwaGtSZXN1bHQgKQp7CiAgICBUUkFDRSgiKCVzLCV4LCVwKTogc3R1YlxuIixkZWJ1Z3N0cl93KGxwTWFjaGluZU5hbWUpLGhLZXkscGhrUmVzdWx0KTsKCiAgICBpZiAoIWxwTWFjaGluZU5hbWUgfHwgISpscE1hY2hpbmVOYW1lKSB7CiAgICAgICAgLyogVXNlIHRoZSBsb2NhbCBtYWNoaW5lIG5hbWUgKi8KICAgICAgICByZXR1cm4gUmVnT3BlbktleTE2KCBoS2V5LCAiIiwgcGhrUmVzdWx0ICk7CiAgICB9CgogICAgRklYTUUoIkNhbm5vdCBjb25uZWN0IHRvICVzXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSkpOwogICAgcmV0dXJuIEVSUk9SX0JBRF9ORVRQQVRIOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnlBIFtBRFZBUEkzMi4xMjddCiAqLwpMT05HIFdJTkFQSSBSZWdDb25uZWN0UmVnaXN0cnlBKCBMUENTVFIgbWFjaGluZSwgSEtFWSBoa2V5LCBMUEhLRVkgcmVza2V5ICkKewogICAgRFdPUkQgcmV0OwogICAgTFBXU1RSIG1hY2hpbmVXID0gc3RyZHVwQTJXKG1hY2hpbmUpOwogICAgcmV0ID0gUmVnQ29ubmVjdFJlZ2lzdHJ5VyggbWFjaGluZVcsIGhrZXksIHJlc2tleSApOwogICAgZnJlZShtYWNoaW5lVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdHZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTQ0XQogKiBSZXRyaWV2ZXMgYSBjb3B5IG9mIHNlY3VyaXR5IGRlc2NyaXB0b3IgcHJvdGVjdGluZyB0aGUgcmVnaXN0cnkga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgICAgICAgIFtJXSAgIE9wZW4gaGFuZGxlIG9mIGtleSB0byBzZXQKICogICAgU2VjdXJpdHlJbmZvcm1hdGlvbiAgICBbSV0gICBEZXNjcmlwdG9yIGNvbnRlbnRzCiAqICAgIHBTZWN1cml0eURlc2NyaXB0b3IgICAgW09dICAgQWRkcmVzcyBvZiBkZXNjcmlwdG9yIGZvciBrZXkKICogICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciBbSS9PXSBBZGRyZXNzIG9mIHNpemUgb2YgYnVmZmVyIGFuZCBkZXNjcmlwdGlvbgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KTE9ORyBXSU5BUEkgUmVnR2V0S2V5U2VjdXJpdHkoIEhLRVkgaGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRUNVUklUWV9JTkZPUk1BVElPTiBTZWN1cml0eUluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciApCnsKICAgIFRSQUNFKCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxTZWN1cml0eUluZm9ybWF0aW9uLHBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yPypscGNiU2VjdXJpdHlEZXNjcmlwdG9yOjApOwoKICAgIC8qIEZJWE1FOiBDaGVjayBmb3IgdmFsaWQgU2VjdXJpdHlJbmZvcm1hdGlvbiB2YWx1ZXMgKi8KCiAgICBpZiAoKmxwY2JTZWN1cml0eURlc2NyaXB0b3IgPCBzaXplb2YoU0VDVVJJVFlfREVTQ1JJUFRPUikpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVI7CgogICAgRklYTUUoIigleCwlbGQsJXAsJWxkKTogc3R1YlxuIixoa2V5LFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICBwU2VjdXJpdHlEZXNjcmlwdG9yLGxwY2JTZWN1cml0eURlc2NyaXB0b3I/KmxwY2JTZWN1cml0eURlc2NyaXB0b3I6MCk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlIFtBRFZBUEkzMi4/Pz9dCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgW0ldIEhhbmRsZSBvZiBrZXkgdG8gd2F0Y2gKICogICAgZldhdGNoU3ViVHJlZSAgIFtJXSBGbGFnIGZvciBzdWJrZXkgbm90aWZpY2F0aW9uCiAqICAgIGZkd05vdGlmeUZpbHRlciBbSV0gQ2hhbmdlcyB0byBiZSByZXBvcnRlZAogKiAgICBoRXZlbnQgICAgICAgICAgW0ldIEhhbmRsZSBvZiBzaWduYWxlZCBldmVudAogKiAgICBmQXN5bmMgICAgICAgICAgW0ldIEZsYWcgZm9yIGFzeW5jaHJvbm91cyByZXBvcnRpbmcKICovCkxPTkcgV0lOQVBJIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlKCBIS0VZIGhrZXksIEJPT0wgZldhdGNoU3ViVHJlZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBmZHdOb3RpZnlGaWx0ZXIsIEhBTkRMRSBoRXZlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIGZBc3luYyApCnsKICAgIEZJWE1FKCIoJXgsJWksJWxkLCV4LCVpKTogc3R1YlxuIixoa2V5LGZXYXRjaFN1YlRyZWUsZmR3Tm90aWZ5RmlsdGVyLAogICAgICAgICAgaEV2ZW50LGZBc3luYyk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnVW5Mb2FkS2V5VyBbQURWQVBJMzIuMTczXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscFN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleSB0byB1bmxvYWQKICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSApCnsKICAgIEZJWE1FKCIoJXgsJXMpOiBzdHViXG4iLGhrZXksIGRlYnVnc3RyX3cobHBTdWJLZXkpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXlBIFtBRFZBUEkzMi4xNzJdCiAqLwpMT05HIFdJTkFQSSBSZWdVbkxvYWRLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwU3ViS2V5VyA9IHN0cmR1cEEyVyhscFN1YktleSk7CiAgICByZXQgPSBSZWdVbkxvYWRLZXlXKCBoa2V5LCBscFN1YktleVcgKTsKICAgIGlmKGxwU3ViS2V5VykgZnJlZShscFN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0S2V5U2VjdXJpdHkgW0FEVkFQSTMyLjE2N10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldIE9wZW4gaGFuZGxlIG9mIGtleSB0byBzZXQKICogICAgU2VjdXJpdHlJbmZvICBbSV0gRGVzY3JpcHRvciBjb250ZW50cwogKiAgICBwU2VjdXJpdHlEZXNjIFtJXSBBZGRyZXNzIG9mIGRlc2NyaXB0b3IgZm9yIGtleQogKi8KTE9ORyBXSU5BUEkgUmVnU2V0S2V5U2VjdXJpdHkoIEhLRVkgaGtleSwgU0VDVVJJVFlfSU5GT1JNQVRJT04gU2VjdXJpdHlJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzYyApCnsKICAgIFRSQUNFKCIoJXgsJWxkLCVwKVxuIixoa2V5LFNlY3VyaXR5SW5mbyxwU2VjdXJpdHlEZXNjKTsKCiAgICAvKiBJdCBzZWVtcyB0byBwZXJmb3JtIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoKFNlY3VyaXR5SW5mbyAmIE9XTkVSX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBHUk9VUF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgREFDTF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgU0FDTF9TRUNVUklUWV9JTkZPUk1BVElPTikpIHsKICAgICAgICAvKiBQYXJhbSBPSyAqLwogICAgfSBlbHNlCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGlmICghcFNlY3VyaXR5RGVzYykKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgRklYTUUoIjooJXgsJWxkLCVwKTogc3R1YlxuIixoa2V5LFNlY3VyaXR5SW5mbyxwU2VjdXJpdHlEZXNjKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleVcgW0FEVkFQSTMyLjE2NF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgcmVzdG9yZSBiZWdpbnMKICogICAgbHBGaWxlICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBjb250YWluaW5nIHNhdmVkIHRyZWUKICogICAgZHdGbGFncyBbSV0gT3B0aW9uYWwgZmxhZ3MKICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgVFJBQ0UoIigleCwlcywlbGQpXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIEl0IHNlZW1zIHRvIGRvIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoIWxwRmlsZSB8fCAhKmxwRmlsZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgRklYTUUoIigleCwlcywlbGQpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIENoZWNrIGZvciBmaWxlIGV4aXN0ZW5jZSAqLwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5QSBbQURWQVBJMzIuMTYzXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVzdG9yZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwRmlsZVcgPSBzdHJkdXBBMlcobHBGaWxlKTsKICAgIHJldCA9IFJlZ1Jlc3RvcmVLZXlXKCBoa2V5LCBscEZpbGVXLCBkd0ZsYWdzICk7CiAgICBpZihscEZpbGVXKSBmcmVlKGxwRmlsZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleVcgW0FEVkFQSTMyLjE2Ml0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwU3ViS2V5ICBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleQogKiAgICBscE5ld0ZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIGZpbGUgd2l0aCBuZXcgZGF0YQogKiAgICBscE9sZEZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIGJhY2t1cCBmaWxlCiAqLwpMT05HIFdJTkFQSSBSZWdSZXBsYWNlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwU3ViS2V5LCBMUENXU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBscE9sZEZpbGUgKQp7CiAgICBGSVhNRSgiKCV4LCVzLCVzLCVzKTogc3R1YlxuIiwgaGtleSwgZGVidWdzdHJfdyhscFN1YktleSksIAogICAgICAgICAgZGVidWdzdHJfdyhscE5ld0ZpbGUpLGRlYnVnc3RyX3cobHBPbGRGaWxlKSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleUEgW0FEVkFQSTMyLjE2MV0KICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSwgTFBDU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwT2xkRmlsZSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwU3ViS2V5VyA9IHN0cmR1cEEyVyhscFN1YktleSk7CiAgICBMUFdTVFIgbHBOZXdGaWxlVyA9IHN0cmR1cEEyVyhscE5ld0ZpbGUpOwogICAgTFBXU1RSIGxwT2xkRmlsZVcgPSBzdHJkdXBBMlcobHBPbGRGaWxlKTsKICAgIHJldCA9IFJlZ1JlcGxhY2VLZXlXKCBoa2V5LCBscFN1YktleVcsIGxwTmV3RmlsZVcsIGxwT2xkRmlsZVcgKTsKICAgIGZyZWUobHBPbGRGaWxlVyk7CiAgICBmcmVlKGxwTmV3RmlsZVcpOwogICAgZnJlZShscFN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCgoKCgovKiAxNi1iaXQgZnVuY3Rpb25zICovCgovKiAwIGFuZCAxIGFyZSB2YWxpZCByb290a2V5cyBpbiB3aW4xNiBzaGVsbC5kbGwgYW5kIGFyZSB1c2VkIGJ5CiAqIHNvbWUgcHJvZ3JhbXMuIERvIG5vdCByZW1vdmUgdGhvc2UgY2FzZXMuIC1NTQogKi8Kc3RhdGljIGlubGluZSB2b2lkIGZpeF93aW4xNl9oa2V5KCBIS0VZICpoa2V5ICkKewogICAgaWYgKCpoa2V5ID09IDAgfHwgKmhrZXkgPT0gMSkgKmhrZXkgPSBIS0VZX0NMQVNTRVNfUk9PVDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRW51bUtleTE2ICAgW0tFUk5FTC4yMTZdIFtTSEVMTC43XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXkxNiggSEtFWSBoa2V5LCBEV09SRCBpbmRleCwgTFBTVFIgbmFtZSwgRFdPUkQgbmFtZV9sZW4gKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdFbnVtS2V5QSggaGtleSwgaW5kZXgsIG5hbWUsIG5hbWVfbGVuICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ09wZW5LZXkxNiAgIFtLRVJORUwuMjE3XSBbU0hFTEwuMV0KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQSEtFWSByZXRrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdPcGVuS2V5QSggaGtleSwgbmFtZSwgcmV0a2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0NyZWF0ZUtleTE2ICAgW0tFUk5FTC4yMThdIFtTSEVMTC4yXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUEhLRVkgcmV0a2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5QSggaGtleSwgbmFtZSwgcmV0a2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0RlbGV0ZUtleTE2ICAgW0tFUk5FTC4yMTldIFtTSEVMTC40XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRGVsZXRlS2V5QSggaGtleSwgbmFtZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdDbG9zZUtleTE2ICAgW0tFUk5FTC4yMjBdIFtTSEVMTC4zXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0Nsb3NlS2V5MTYoIEhLRVkgaGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0Nsb3NlS2V5KCBoa2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1NldFZhbHVlMTYgICBbS0VSTkVMLjIyMV0gW1NIRUxMLjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgRFdPUkQgdHlwZSwgTFBDU1RSIGRhdGEsIERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVBKCBoa2V5LCBuYW1lLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdEZWxldGVWYWx1ZTE2ICBbS0VSTkVMLjIyMl0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTE2KCBIS0VZIGhrZXksIExQU1RSIG5hbWUgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdEZWxldGVWYWx1ZUEoIGhrZXksIG5hbWUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRW51bVZhbHVlMTYgICBbS0VSTkVMLjIyM10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUxNiggSEtFWSBoa2V5LCBEV09SRCBpbmRleCwgTFBTVFIgdmFsdWUsIExQRFdPUkQgdmFsX2NvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgcmVzZXJ2ZWQsIExQRFdPUkQgdHlwZSwgTFBCWVRFIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdFbnVtVmFsdWVBKCBoa2V5LCBpbmRleCwgdmFsdWUsIHZhbF9jb3VudCwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUxNiAgIFtLRVJORUwuMjI0XSBbU0hFTEwuNl0KICoKICogTk9URVMKICogICAgSXMgdGhpcyBIQUNLIHN0aWxsIGFwcGxpY2FibGU/CiAqCiAqIEhBQ0sKICogICAgVGhlIDE2Yml0IFJlZ1F1ZXJ5VmFsdWUgZG9lc24ndCBoYW5kbGUgc2VsZWN0b3JibG9ja3MgYW55d2F5LCBzbyB3ZSBqdXN0CiAqICAgIG1hc2sgb3V0IHRoZSBoaWdoIDE2IGJpdC4gIFRoaXMgKG5vdCBzbyBtdWNoIGluY2lkZW50bHkpIGhvcGVmdWxseSBmaXhlcwogKiAgICBBbGR1cyBGSDQpCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUFNUUiBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICBpZiAoY291bnQpICpjb3VudCAmPSAweGZmZmY7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUEoIGhrZXksIG5hbWUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWVFeDE2ICAgW0tFUk5FTC4yMjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQRFdPUkQgcmVzZXJ2ZWQsIExQRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeEEoIGhrZXksIG5hbWUsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdTZXRWYWx1ZUV4MTYgICBbS0VSTkVMLjIyNl0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIERXT1JEIHJlc2VydmVkLCBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05TVCBCWVRFICpkYXRhLCBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlRXhBKCBoa2V5LCBuYW1lLCByZXNlcnZlZCwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQo=