LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGxpbWl0cy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpZmRlZiBIQVZFX1NZU19FUlJOT19ICiNpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDx0aW1lLmg+CiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5lL3dpbmVzdHJpbmcuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgInNlcnZlci5oIgojaW5jbHVkZSAic2VydmljZXMuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTChyZWcpOwoKc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCh2b2lkKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUICAgICAgICAgIEVUQ0RJUiIvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUICBFVENESVIiL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0NVUlJFTlRfVVNFUiAgICAgICAgICAgInVzZXIucmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCAgICAid2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORSAgICAgICAgICAic3lzdGVtLnJlZyIKCi8qIHdoYXQgdmFsdWV0eXBlcyBkbyB3ZSBuZWVkIHRvIGNvbnZlcnQ/ICovCiNkZWZpbmUgVU5JQ09OVk1BU0sJKCgxPDxSRUdfU1opfCgxPDxSRUdfTVVMVElfU1opfCgxPDxSRUdfRVhQQU5EX1NaKSkKCgpzdGF0aWMgdm9pZCAqeG1hbGxvYyggc2l6ZV90IHNpemUgKQp7CiAgICB2b2lkICpyZXM7CiAKICAgIHJlcyA9IG1hbGxvYyAoc2l6ZSA/IHNpemUgOiAxKTsKICAgIGlmIChyZXMgPT0gTlVMTCkgewogICAgICAgIFdBUk4oIlZpcnR1YWwgbWVtb3J5IGV4aGF1c3RlZC5cbiIpOwogICAgICAgIGV4aXQgKDEpOwogICAgfQogICAgcmV0dXJuIHJlczsKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoKLyoKICogUVVFU1RJT04KICogICBBcmUgdGhlc2UgZG9pbmcgdGhlIHNhbWUgYXMgSEVBUF9zdHJkdXBBdG9XIGFuZCBIRUFQX3N0cmR1cFd0b0E/CiAqICAgSWYgc28sIGNhbiB3ZSByZW1vdmUgdGhlbT8KICogQU5TV0VSCiAqICAgTm8sIHRoZSBtZW1vcnkgaGFuZGxpbmcgZnVuY3Rpb25zIGFyZSBjYWxsZWQgdmVyeSBvZnRlbiBpbiBoZXJlLCAKICogICBqdXN0IHJlcGxhY2luZyB0aGVtIGJ5IEhlYXBBbGxvYyhTeXN0ZW1IZWFwLC4uLikgbWFrZXMgcmVnaXN0cnkKICogICBsb2FkaW5nIDEwMCB0aW1lcyBzbG93ZXIuIC1NTQogKi8Kc3RhdGljIExQV1NUUiBzdHJkdXBBMlcoTFBDU1RSIHNyYykKewogICAgaWYoc3JjKSB7CglMUFdTVFIgZGVzdD14bWFsbG9jKDIqc3RybGVuKHNyYykrMik7Cglsc3RyY3B5QXRvVyhkZXN0LHNyYyk7CglyZXR1cm4gZGVzdDsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgpMUFdTVFIgc3RyY3Z0QTJXKExQQ1NUUiBzcmMsIGludCBuY2hhcnMpCgp7CiAgIExQV1NUUiBkZXN0ID0geG1hbGxvYyAoMiAqIG5jaGFycyArIDIpOwoKICAgbHN0cmNweW5BdG9XKGRlc3Qsc3JjLG5jaGFycysxKTsKICAgcmV0dXJuIGRlc3Q7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSRUdJU1RSWV9Jbml0IFtJbnRlcm5hbF0KICogUmVnaXN0cnkgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBzb21lIGRlZmF1bHQga2V5cy4gCiAqLwpzdGF0aWMgdm9pZCBSRUdJU1RSWV9Jbml0KHZvaWQpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJVFJBQ0UoIih2b2lkKVxuIik7CgoJUmVnQ3JlYXRlS2V5QShIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXhBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3cgTlRcXEN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRCdWlsZE51bWJlcgoJICoJCQkJCQlDdXJyZW50VHlwZQoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3duZXIKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE9yZ2FuaXphdGlvbgoJICoKCSAqLwoJLyogU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXFNOTVBcXFBhcmFtZXRlcnNcXFJGQzExNTZBZ2VudAoJICogCQkJCQlzdHJpbmcJU3lzQ29udGFjdAoJICogCQkJCQlzdHJpbmcJU3lzTG9jYXRpb24KCSAqIAkJCQkJCVN5c1NlcnZpY2VzCgkgKi8KCWlmICgtMSE9Z2V0aG9zdG5hbWUoYnVmLDIwMCkpIHsKCQlSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcQ29tcHV0ZXJOYW1lXFxDb21wdXRlck5hbWUiLCZoa2V5KTsKCQlSZWdTZXRWYWx1ZUV4QShoa2V5LCJDb21wdXRlck5hbWUiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSsxKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKiogTE9BRCBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF9rZXkgW0ludGVybmFsXQogKi8Kc3RhdGljIGlubGluZSBIS0VZIF9maW5kX29yX2FkZF9rZXkoIEhLRVkgaGtleSwgTFBXU1RSIGtleW5hbWUgKQp7CiAgICBIS0VZIHN1YmtleTsKICAgIGlmIChSZWdDcmVhdGVLZXlXKCBoa2V5LCBrZXluYW1lLCAmc3Via2V5ICkgIT0gRVJST1JfU1VDQ0VTUykgc3Via2V5ID0gMDsKICAgIGlmIChrZXluYW1lKSBmcmVlKCBrZXluYW1lICk7CiAgICByZXR1cm4gc3Via2V5Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF92YWx1ZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfZmluZF9vcl9hZGRfdmFsdWUoIEhLRVkgaGtleSwgTFBXU1RSIG5hbWUsIERXT1JEIHR5cGUsIExQQllURSBkYXRhLCBEV09SRCBsZW4gKQp7CiAgICBSZWdTZXRWYWx1ZUV4VyggaGtleSwgbmFtZSwgMCwgdHlwZSwgZGF0YSwgbGVuICk7CiAgICBpZiAobmFtZSkgZnJlZSggbmFtZSApOwogICAgaWYgKGRhdGEpIGZyZWUoIGRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9saW5lIFtJbnRlcm5hbF0KICoKICogcmVhZHMgYSBsaW5lIGluY2x1ZGluZyBkeW5hbWljYWxseSBlbmxhcmdpbmcgdGhlIHJlYWRidWZmZXIgYW5kIHRocm93aW5nCiAqIGF3YXkgY29tbWVudHMKICovCnN0YXRpYyBpbnQgX3dpbmVfcmVhZF9saW5lKCBGSUxFICpGLCBjaGFyICoqYnVmLCBpbnQgKmxlbiApCnsKCWNoYXIJKnMsKmN1cnJlYWQ7CglpbnQJbXlsZW4sY3Vyb2ZmOwoKCWN1cnJlYWQJPSAqYnVmOwoJbXlsZW4JPSAqbGVuOwoJKipidWYJPSAnXDAnOwoJd2hpbGUgKDEpIHsKCQl3aGlsZSAoMSkgewoJCQlzPWZnZXRzKGN1cnJlYWQsbXlsZW4sRik7CgkJCWlmIChzPT1OVUxMKQoJCQkJcmV0dXJuIDA7IC8qIEVPRiAqLwoJCQlpZiAoTlVMTD09KHM9c3RyY2hyKGN1cnJlYWQsJ1xuJykpKSB7CgkJCQkvKiBidWZmZXIgd2Fzbid0IGxhcmdlIGVub3VnaCAqLwoJCQkJY3Vyb2ZmCT0gc3RybGVuKCpidWYpOwoJCQkJY3VycmVhZAk9IHJlYWxsb2MoKmJ1ZiwqbGVuKjIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGN1cnJlYWQgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCJPdXQgb2YgbWVtb3J5Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqYnVmCT0gY3VycmVhZDsKCQkJCWN1cnJlYWQrPSBjdXJvZmY7CgkJCQlteWxlbgk9ICpsZW47CS8qIHdlIGZpbGxlZCB1cCB0aGUgYnVmZmVyIGFuZCAKCQkJCQkJICogZ290IG5ldyAnKmxlbicgYnl0ZXMgdG8gZmlsbAoJCQkJCQkgKi8KCQkJCSpsZW4JPSAqbGVuICogMjsKCQkJfSBlbHNlIHsKCQkJCSpzPSdcMCc7CgkJCQlicmVhazsKCQkJfQoJCX0KCQkvKiB0aHJvdyBhd2F5IGNvbW1lbnRzICovCgkJaWYgKCoqYnVmPT0nIycgfHwgKipidWY9PSc7JykgewoJCQljdXJyZWFkCT0gKmJ1ZjsKCQkJbXlsZW4JPSAqbGVuOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKHMpIAkvKiBnb3QgZW5kIG9mIGxpbmUgKi8KCQkJYnJlYWs7Cgl9CglyZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9VU1RSSU5HIFtJbnRlcm5hbF0KICoKICogY29udmVydHMgYSBjaGFyKiBpbnRvIGEgVU5JQ09ERSBzdHJpbmcgKHVwIHRvIGEgc3BlY2lhbCBjaGFyKQogKiBhbmQgcmV0dXJucyB0aGUgcG9zaXRpb24gZXhhY3RseSBhZnRlciB0aGF0IHN0cmluZwogKi8Kc3RhdGljIGNoYXIqIF93aW5lX3JlYWRfVVNUUklORyggY2hhciAqYnVmLCBMUFdTVFIgKnN0ciApCnsKCWNoYXIJKnM7CglMUFdTVFIJd3M7CgoJLyogcmVhZCB1cCB0byAiPSIgb3IgIlwwIiBvciAiXG4iICovCglzCT0gYnVmOwoJKnN0cgk9IChMUFdTVFIpeG1hbGxvYygyKnN0cmxlbihidWYpKzIpOwoJd3MJPSAqc3RyOwoJd2hpbGUgKCpzICYmICgqcyE9J1xuJykgJiYgKCpzIT0nPScpKSB7CgkJaWYgKCpzIT0nXFwnKQoJCQkqd3MrKz0qKCh1bnNpZ25lZCBjaGFyKilzKyspOwoJCWVsc2UgewoJCQlzKys7CgkJCWlmICghKnMpIHsKCQkJCS8qIERhbmdsaW5nIFwgLi4uIG1heSBvbmx5IGhhcHBlbiBpZiBhIHJlZ2lzdHJ5CgkJCQkgKiB3cml0ZSB3YXMgc2hvcnQuIEZJWE1FOiBXaGF0IGRvIHRvPwoJCQkJICovCgkJCQkgYnJlYWs7CgkJCX0KCQkJaWYgKCpzPT0nXFwnKSB7CgkJCQkqd3MrKz0nXFwnOwoJCQkJcysrOwoJCQkJY29udGludWU7CgkJCX0KCQkJaWYgKCpzIT0ndScpIHsKCQkJCVdBUk4oIk5vbiB1bmljb2RlIGVzY2FwZSBzZXF1ZW5jZSBcXCVjIGZvdW5kIGluIHwlc3xcbiIsKnMsYnVmKTsKCQkJCSp3cysrPSdcXCc7CgkJCQkqd3MrKz0qcysrOwoJCQl9IGVsc2UgewoJCQkJY2hhcgl4YnVmWzVdOwoJCQkJaW50CXdjOwoKCQkJCXMrKzsKCQkJCW1lbWNweSh4YnVmLHMsNCk7eGJ1Zls0XT0nXDAnOwoJCQkJaWYgKCFzc2NhbmYoeGJ1ZiwiJXgiLCZ3YykpCgkJCQkJV0FSTigiU3RyYW5nZSBlc2NhcGUgc2VxdWVuY2UgJXMgZm91bmQgaW4gfCVzfFxuIix4YnVmLGJ1Zik7CgkJCQlzKz00OwoJCQkJKndzKysJPSh1bnNpZ25lZCBzaG9ydCl3YzsKCQkJfQoJCX0KCX0KCSp3cwk9IDA7CglyZXR1cm4gczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHN1YmtleSBbSW50ZXJuYWxdCiAqCiAqIE5PVEVTCiAqICAgIEl0IHNlZW1zIGxpa2UgdGhpcyBpcyByZXR1cm5pbmcgYSBib29sZWFuLiAgU2hvdWxkIGl0PwogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IDEKICogICAgRmFpbHVyZTogMAogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3Via2V5KCBGSUxFICpGLCBIS0VZIGhrZXksIGludCBsZXZlbCwgY2hhciAqKmJ1ZiwgaW50ICpidWZsZW4gKQp7CiAgICAJSEtFWSBzdWJrZXk7CglpbnQJCWk7CgljaGFyCQkqczsKCUxQV1NUUgkJbmFtZTsKCiAgICBUUkFDRSgiKCVwLCV4LCVkLCVzLCVkKVxuIiwgRiwgaGtleSwgbGV2ZWwsIGRlYnVnc3RyX2EoKmJ1ZiksICpidWZsZW4pOwoKICAgIC8qIEdvb2QuICBXZSBhbHJlYWR5IGdvdCBhIGxpbmUgaGVyZSAuLi4gc28gcGFyc2UgaXQgKi8KICAgIHN1YmtleSA9IDA7CiAgICB3aGlsZSAoMSkgewogICAgICAgIGk9MDtzPSpidWY7CiAgICAgICAgd2hpbGUgKCpzPT0nXHQnKSB7CiAgICAgICAgICAgIHMrKzsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KICAgICAgICBpZiAoaT5sZXZlbCkgewogICAgICAgICAgICBpZiAoIXN1YmtleSkgewogICAgICAgICAgICAgICAgV0FSTigiR290IGEgc3ViaGllcmFyY2h5IHdpdGhvdXQgcmVzcC4ga2V5P1xuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoJICAgIGlmICghX3dpbmVfbG9hZHN1YmtleShGLHN1YmtleSxsZXZlbCsxLGJ1ZixidWZsZW4pKQoJICAgICAgIGlmICghX3dpbmVfcmVhZF9saW5lKEYsYnVmLGJ1ZmxlbikpCgkJICBnb3RvIGRvbmU7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCgkJLyogbGV0IHRoZSBjYWxsZXIgaGFuZGxlIHRoaXMgbGluZSAqLwoJCWlmIChpPGxldmVsIHx8ICoqYnVmPT0nXDAnKQoJCQlnb3RvIGRvbmU7CgoJCS8qIGl0IGNhbiBiZTogYSB2YWx1ZSBvciBhIGtleW5hbWUuIFBhcnNlIHRoZSBuYW1lIGZpcnN0ICovCgkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywmbmFtZSk7CgoJCS8qIHN3aXRjaCgpIGRlZmF1bHQ6IGhhY2sgdG8gYXZvaWQgZ290b3MgKi8KCQlzd2l0Y2ggKDApIHsKCQlkZWZhdWx0OgoJCQlpZiAoKnM9PSdcMCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3Via2V5KSBSZWdDbG9zZUtleSggc3Via2V5ICk7CgkJCQlzdWJrZXk9X2ZpbmRfb3JfYWRkX2tleShoa2V5LG5hbWUpOwoJCQl9IGVsc2UgewoJCQkJTFBCWVRFCQlkYXRhOwoJCQkJaW50CQlsZW4sbGFzdG1vZGlmaWVkLHR5cGU7CgoJCQkJaWYgKCpzIT0nPScpIHsKCQkJCQlXQVJOKCJVbmV4cGVjdGVkIGNoYXJhY3RlcjogJWNcbiIsKnMpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJcysrOwoJCQkJaWYgKDIhPXNzY2FuZihzLCIlZCwlZCwiLCZ0eXBlLCZsYXN0bW9kaWZpZWQpKSB7CgkJCQkJV0FSTigiSGF2ZW4ndCB1bmRlcnN0b29kIHBvc3NpYmxlIHZhbHVlIGluIHwlc3wsIHNraXBwaW5nLlxuIiwqYnVmKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCS8qIHNraXAgdGhlIDIgLCAqLwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCXM9c3RyY2hyKHMsJywnKTsKCQkJCWlmICghcysrKSB7CgkJCQkJV0FSTigiSGF2ZW4ndCB1bmRlcnN0b29kIHBvc3NpYmxlIHZhbHVlIGluIHwlc3wsIHNraXBwaW5nLlxuIiwqYnVmKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCWlmICh0eXBlID09IFJFR19TWiB8fCB0eXBlID09IFJFR19FWFBBTkRfU1opIHsKCQkJCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLChMUFdTVFIqKSZkYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbiA9IGxzdHJsZW5XKChMUFdTVFIpZGF0YSkqMisyOwoJCQkJfSBlbHNlIHsKCQkJCQlsZW49c3RybGVuKHMpLzI7CgkJCQkJZGF0YSA9IChMUEJZVEUpeG1hbGxvYyhsZW4rMSk7CgkJCQkJZm9yIChpPTA7aTxsZW47aSsrKSB7CgkJCQkJCWRhdGFbaV09MDsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV09KCpzLScwJyk8PDQ7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nYScrJ1x4YScpPDw0OwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ0EnKydceGEnKTw8NDsKCQkJCQkJcysrOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXXw9KnMtJzAnOwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ2EnKydceGEnOwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ0EnKydceGEnOwoJCQkJCQlzKys7CgkJCQkJfQoJCQkJfQoJCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKGhrZXksbmFtZSx0eXBlLGRhdGEsbGVuKTsKCQkJfQoJCX0KCQkvKiByZWFkIHRoZSBuZXh0IGxpbmUgKi8KCQlpZiAoIV93aW5lX3JlYWRfbGluZShGLGJ1ZixidWZsZW4pKQoJCQlnb3RvIGRvbmU7CiAgICB9CiBkb25lOgogICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwogICAgcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3VicmVnKCBGSUxFICpGLCBIS0VZIGhrZXksIGNvbnN0IGNoYXIgKmZuICkKewoJaW50CXZlcjsKCWNoYXIJKmJ1ZjsKCWludAlidWZsZW47CgoJYnVmPXhtYWxsb2MoMTApO2J1Zmxlbj0xMDsKCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghc3NjYW5mKGJ1ZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIiwmdmVyKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICh2ZXIhPTEpIHsKICAgICAgICAgICAgaWYgKHZlciA9PSAyKSAgLyogbmV3IHZlcnNpb24gKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSEFORExFIGZpbGU7CiAgICAgICAgICAgICAgICBpZiAoKGZpbGUgPSBGSUxFX0NyZWF0ZUZpbGUoIGZuLCBHRU5FUklDX1JFQUQsIDAsIE5VTEwsIE9QRU5fRVhJU1RJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRV9BVFRSSUJVVEVfTk9STUFMLCAtMSwgVFJVRSApKSAhPSBJTlZBTElEX0hBTkRMRV9WQUxVRSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgbG9hZF9yZWdpc3RyeV9yZXF1ZXN0ICpyZXEgPSBnZXRfcmVxX2J1ZmZlcigpOwogICAgICAgICAgICAgICAgICAgIHJlcS0+aGtleSAgICA9IGhrZXk7CiAgICAgICAgICAgICAgICAgICAgcmVxLT5maWxlICAgID0gZmlsZTsKICAgICAgICAgICAgICAgICAgICByZXEtPm5hbWVbMF0gPSAwOwogICAgICAgICAgICAgICAgICAgIHNlcnZlcl9jYWxsKCBSRVFfTE9BRF9SRUdJU1RSWSApOwogICAgICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBmaWxlICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmcmVlKCBidWYgKTsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewoJCVRSQUNFKCJPbGQgZm9ybWF0ICglZCkgcmVnaXN0cnkgZm91bmQsIGlnbm9yaW5nIGl0LiAoYnVmIHdhcyAlcykuXG4iLHZlcixidWYpOwoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKICAgICAgICAgICAgfQoJfQoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9sb2Fkc3Via2V5KEYsaGtleSwwLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglmcmVlKGJ1Zik7CglyZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfd2luZV9sb2FkcmVnKCBIS0VZIGhrZXksIGNoYXIgKmZuICkKewogICAgRklMRSAqRjsKCiAgICBUUkFDRSgiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EoZm4pKTsKCiAgICBGID0gZm9wZW4oZm4sInJiIik7CiAgICBpZiAoRj09TlVMTCkgewogICAgICAgIFdBUk4oIkNvdWxkbid0IG9wZW4gJXMgZm9yIHJlYWRpbmc6ICVzXG4iLGZuLHN0cmVycm9yKGVycm5vKSApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIF93aW5lX2xvYWRzdWJyZWcoRixoa2V5LGZuKTsKICAgIGZjbG9zZShGKTsKfQoKLyogTlQgUkVHSVNUUlkgTE9BREVSICovCgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgojaWZuZGVmIE1BUF9GQUlMRUQKI2RlZmluZSBNQVBfRkFJTEVEICgoTFBWT0lEKS0xKQojZW5kaWYKCiNkZWZpbmUgIE5UX1JFR19CTE9DS19TSVpFCQkweDEwMDAKCiNkZWZpbmUgTlRfUkVHX0hFQURFUl9CTE9DS19JRCAgICAgICAweDY2Njc2NTcyCS8qIHJlZ2YgKi8KI2RlZmluZSBOVF9SRUdfUE9PTF9CTE9DS19JRCAgICAgICAgIDB4NkU2OTYyNjgJLyogaGJpbiAqLwojZGVmaW5lIE5UX1JFR19LRVlfQkxPQ0tfSUQgICAgICAgICAgMHg2YjZlIC8qIG5rICovCiNkZWZpbmUgTlRfUkVHX1ZBTFVFX0JMT0NLX0lEICAgICAgICAweDZiNzYgLyogdmsgKi8KCi8qIHN1YmJsb2NrcyBvZiBuayAqLwojZGVmaW5lIE5UX1JFR19IQVNIX0JMT0NLX0lEICAgICAgICAgMHg2NjZjIC8qIGxmICovCiNkZWZpbmUgTlRfUkVHX05PSEFTSF9CTE9DS19JRCAgICAgICAweDY5NmMgLyogbGkgKi8KI2RlZmluZSBOVF9SRUdfUklfQkxPQ0tfSUQJICAgICAweDY5NzIgLyogcmkgKi8KCiNkZWZpbmUgTlRfUkVHX0tFWV9CTE9DS19UWVBFICAgICAgICAweDIwCiNkZWZpbmUgTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUgICAweDJjCgp0eXBlZGVmIHN0cnVjdCAKewoJRFdPUkQJaWQ7CQkvKiAweDY2Njc2NTcyICdyZWdmJyovCglEV09SRAl1azE7CQkvKiAweDA0ICovCglEV09SRAl1azI7CQkvKiAweDA4ICovCglGSUxFVElNRQlEYXRlTW9kaWZpZWQ7CS8qIDB4MGMgKi8KCURXT1JECXVrMzsJCS8qIDB4MTQgKi8KCURXT1JECXVrNDsJCS8qIDB4MTggKi8KCURXT1JECXVrNTsJCS8qIDB4MWMgKi8KCURXT1JECXVrNjsJCS8qIDB4MjAgKi8KCURXT1JECVJvb3RLZXlCbG9jazsJLyogMHgyNCAqLwoJRFdPUkQJQmxvY2tTaXplOwkvKiAweDI4ICovCglEV09SRCAgIHVrN1sxMTZdOwkKCURXT1JECUNoZWNrc3VtOyAvKiBhdCBvZmZzZXQgMHgxRkMgKi8KfSBudF9yZWdmOwoKdHlwZWRlZiBzdHJ1Y3QKewoJRFdPUkQJYmxvY2tzaXplOwoJQllURQlkYXRhWzFdOwp9IG50X2hiaW5fc3ViOwoKdHlwZWRlZiBzdHJ1Y3QKewoJRFdPUkQJaWQ7CQkvKiAweDZFNjk2MjY4ICdoYmluJyAqLwoJRFdPUkQJb2ZmX3ByZXY7CglEV09SRAlvZmZfbmV4dDsKCURXT1JECXVrMTsKCURXT1JECXVrMjsJCS8qIDB4MTAgKi8KCURXT1JECXVrMzsJCS8qIDB4MTQgKi8KCURXT1JECXVrNDsJCS8qIDB4MTggKi8KCURXT1JECXNpemU7CQkvKiAweDFDICovCgludF9oYmluX3N1YgloYmluX3N1YjsJLyogMHgyMCAqLwp9IG50X2hiaW47CgovKgogKiB0aGUgdmFsdWVfbGlzdCBjb25zaXN0cyBvZiBvZmZzZXRzIHRvIHRoZSB2YWx1ZXMgKHZrKQogKi8KdHlwZWRlZiBzdHJ1Y3QKewoJV09SRAlTdWJCbG9ja0lkOwkJLyogMHgwMCAweDZCNkUgKi8KCVdPUkQJVHlwZTsJCQkvKiAweDAyIGZvciB0aGUgcm9vdC1rZXk6IDB4MkMsIG90aGVyd2lzZSAweDIwKi8KCUZJTEVUSU1FCXdyaXRldGltZTsJLyogMHgwNCAqLwoJRFdPUkQJdWsxOwkJCS8qIDB4MEMgKi8KCURXT1JECXBhcmVudF9vZmY7CQkvKiAweDEwIE9mZnNldCBvZiBPd25lci9QYXJlbnQga2V5ICovCglEV09SRAlucl9zdWJrZXlzOwkJLyogMHgxNCBudW1iZXIgb2Ygc3ViLUtleXMgKi8KCURXT1JECXVrODsJCQkvKiAweDE4ICovCglEV09SRAlsZl9vZmY7CQkJLyogMHgxQyBPZmZzZXQgb2YgdGhlIHN1Yi1rZXkgbGYtUmVjb3JkcyAqLwoJRFdPUkQJdWsyOwkJCS8qIDB4MjAgKi8KCURXT1JECW5yX3ZhbHVlczsJCS8qIDB4MjQgbnVtYmVyIG9mIHZhbHVlcyAqLwoJRFdPUkQJdmFsdWVsaXN0X29mZjsJCS8qIDB4MjggT2Zmc2V0IG9mIHRoZSBWYWx1ZS1MaXN0ICovCglEV09SRAlvZmZfc2s7CQkJLyogMHgyYyBPZmZzZXQgb2YgdGhlIHNrLVJlY29yZCAqLwoJRFdPUkQJb2ZmX2NsYXNzOwkJLyogMHgzMCBPZmZzZXQgb2YgdGhlIENsYXNzLU5hbWUgKi8KCURXT1JECXVrMzsJCQkvKiAweDM0ICovCglEV09SRAl1azQ7CQkJLyogMHgzOCAqLwoJRFdPUkQJdWs1OwkJCS8qIDB4M2MgKi8KCURXT1JECXVrNjsJCQkvKiAweDQwICovCglEV09SRAl1azc7CQkJLyogMHg0NCAqLwoJV09SRAluYW1lX2xlbjsJCS8qIDB4NDggbmFtZS1sZW5ndGggKi8KCVdPUkQJY2xhc3NfbGVuOwkJLyogMHg0YSBjbGFzcy1uYW1lIGxlbmd0aCAqLwoJY2hhcgluYW1lWzFdOwkJLyogMHg0YyBrZXktbmFtZSAqLwp9IG50X25rOwoKdHlwZWRlZiBzdHJ1Y3QKewoJRFdPUkQJb2ZmX25rOwkvKiAweDAwICovCglEV09SRAluYW1lOwkvKiAweDA0ICovCn0gaGFzaF9yZWM7Cgp0eXBlZGVmIHN0cnVjdAp7CglXT1JECWlkOwkJLyogMHgwMCAweDY2NmMgKi8KCVdPUkQJbnJfa2V5czsJLyogMHgwNiAqLwoJaGFzaF9yZWMJaGFzaF9yZWNbMV07Cn0gbnRfbGY7CgovKgogbGlzdCBvZiBzdWJrZXlzIHdpdGhvdXQgaGFzaAoKIGxpIC0tKy0tPm5rCiAgICAgIHwKICAgICAgKy0tPm5rCiAqLwp0eXBlZGVmIHN0cnVjdAp7CglXT1JECWlkOwkJLyogMHgwMCAweDY5NmMgKi8KCVdPUkQJbnJfa2V5czsKCURXT1JECW9mZl9ua1sxXTsKfSBudF9saTsKCi8qCiB0aGlzIGlzIGEgaW50ZXJtZWRpYXRlIG5vZGUKCiByaSAtLSstLT5saS0tKy0tPm5rCiAgICAgIHwgICAgICAgKwogICAgICB8ICAgICAgICstLT5uawogICAgICB8CiAgICAgICstLT5saS0tKy0tPm5rCiAgICAgICAgICAgICAgKwoJICAgICAgKy0tPm5rCiAqLwp0eXBlZGVmIHN0cnVjdAp7CglXT1JECWlkOwkJLyogMHgwMCAweDY5NzIgKi8KCVdPUkQJbnJfbGk7CQkvKiAweDAyIG51bWJlciBvZmYgb2Zmc2V0cyAqLwoJRFdPUkQJb2ZmX2xpWzFdOwkvKiAweDA0IHBvaW50cyB0byBsaSAqLwp9IG50X3JpOwoKdHlwZWRlZiBzdHJ1Y3QKewoJV09SRAlpZDsJCS8qIDB4MDAgJ3ZrJyAqLwoJV09SRAluYW1fbGVuOwoJRFdPUkQJZGF0YV9sZW47CglEV09SRAlkYXRhX29mZjsKCURXT1JECXR5cGU7CglXT1JECWZsYWc7CglXT1JECXVrMTsKCWNoYXIJbmFtZVsxXTsKfSBudF92azsKCkxQU1RSIF9zdHJkdXBuQSggTFBDU1RSIHN0ciwgaW50IGxlbiApCnsKICAgIExQU1RSIHJldDsKCiAgICBpZiAoIXN0cikgcmV0dXJuIE5VTEw7CiAgICByZXQgPSBtYWxsb2MoIGxlbiArIDEgKTsKICAgIGxzdHJjcHluQSggcmV0LCBzdHIsIGxlbiApOwogICAgcmV0W2xlbl0gPSAweDAwOwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBfbnRfcGFyc2VfbmsoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgbnRfbmsgKiBuaywgaW50IGxldmVsKTsKc3RhdGljIGludCBfbnRfcGFyc2VfdmsoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgbnRfdmsgKiB2ayk7CnN0YXRpYyBpbnQgX250X3BhcnNlX2xmKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIGludCBzdWJrZXlzLCBudF9sZiAqIGxmLCBpbnQgbGV2ZWwpOwoKCi8qCiAqIGdldHMgYSB2YWx1ZQogKgogKiB2ay0+ZmxhZzoKICogIDAgdmFsdWUgaXMgYSBkZWZhdWx0IHZhbHVlCiAqICAxIHRoZSB2YWx1ZSBoYXMgYSBuYW1lCiAqCiAqIHZrLT5kYXRhX2xlbgogKiAgbGVuIG9mIHRoZSB3aG9sZSBkYXRhIGJsb2NrCiAqICAtIHJlZ19zeiAodW5pY29kZSkKICogICAgYnl0ZXMgaW5jbHVkaW5nIHRoZSB0ZXJtaW5hdGluZyBcMCA9IDIqKG51bWJlcl9vZl9jaGFycysxKQogKiAgLSByZWdfZHdvcmQsIHJlZ19iaW5hcnk6CiAqICAgIGlmIGhpZ2hlc3QgYml0IG9mIGRhdGFfbGVuIGlzIHNldCBkYXRhX29mZiBjb250YWlucyB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQgX250X3BhcnNlX3ZrKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIG50X3ZrICogdmspCnsKCVdDSEFSIG5hbWUgWzI1Nl07CglEV09SRCByZXQ7CglCWVRFICogcGRhdGEgPSAoQllURSAqKShiYXNlK3ZrLT5kYXRhX29mZis0KTsgLyogc3RhcnQgb2YgZGF0YSAqLwoKCWlmKHZrLT5pZCAhPSBOVF9SRUdfVkFMVUVfQkxPQ0tfSUQpIGdvdG8gZXJyb3I7CgoJbHN0cmNweW5BdG9XKG5hbWUsIHZrLT5uYW1lLCB2ay0+bmFtX2xlbisxKTsKCglyZXQgPSBSZWdTZXRWYWx1ZUV4VyggaGtleSwgKHZrLT5mbGFnICYgMHgwMDAwMDAwMSkgPyBuYW1lIDogTlVMTCwgMCwgdmstPnR5cGUsCgkJCSh2ay0+ZGF0YV9sZW4gJiAweDgwMDAwMDAwKSA/IChMUEJZVEUpJih2ay0+ZGF0YV9vZmYpOiBwZGF0YSwKCQkJKHZrLT5kYXRhX2xlbiAmIDB4N2ZmZmZmZmYpICk7CglpZiAocmV0KSBFUlIoIlJlZ1NldFZhbHVlRXggZmFpbGVkICgweCUwOGx4KVxuIiwgcmV0KTsKCXJldHVybiBUUlVFOwplcnJvcjoKCUVSUl8ocmVnKSgidW5rbm93biBibG9jayBmb3VuZCAoMHglMDR4KSwgcGxlYXNlIHJlcG9ydCFcbiIsIHZrLT5pZCk7CglyZXR1cm4gRkFMU0U7Cn0KCi8qCiAqIGdldCB0aGUgc3Via2V5cwogKgogKiB0aGlzIHN0cnVjdHVyZSBjb250YWlucyB0aGUgaGFzaCBvZiBhIGtleW5hbWUgYW5kIHBvaW50cyB0byBhbGwKICogc3Via2V5cwogKgogKiBleGNlcHRpb246IGlmIHRoZSBpZCBpcyAnaWwnIHRoZXJlIGFyZSBubyBoYXNoIHZhbHVlcyBhbmQgZXZlcnkgCiAqIGR3b3JkIGlzIGEgb2Zmc2V0CiAqLwpzdGF0aWMgaW50IF9udF9wYXJzZV9sZihIS0VZIGhrZXksIGNoYXIgKiBiYXNlLCBpbnQgc3Via2V5cywgbnRfbGYgKiBsZiwgaW50IGxldmVsKQp7CglpbnQgaTsKCglpZiAobGYtPmlkID09IE5UX1JFR19IQVNIX0JMT0NLX0lEKQoJewoJICBpZiAoc3Via2V5cyAhPSBsZi0+bnJfa2V5cykgZ290byBlcnJvcjE7CgoJICBmb3IgKGk9MDsgaTxsZi0+bnJfa2V5czsgaSsrKQoJICB7CgkgICAgaWYgKCFfbnRfcGFyc2VfbmsoaGtleSwgYmFzZSwgKG50X25rKikoYmFzZStsZi0+aGFzaF9yZWNbaV0ub2ZmX25rKzQpLCBsZXZlbCkpIGdvdG8gZXJyb3I7CgkgIH0KCX0KCWVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKQoJewoJICBudF9saSAqIGxpID0gKG50X2xpKilsZjsKCSAgaWYgKHN1YmtleXMgIT0gbGktPm5yX2tleXMpIGdvdG8gZXJyb3IxOwoKCSAgZm9yIChpPTA7IGk8bGktPm5yX2tleXM7IGkrKykKCSAgewoJICAgIGlmICghX250X3BhcnNlX25rKGhrZXksIGJhc2UsIChudF9uayopKGJhc2UrbGktPm9mZl9ua1tpXSs0KSwgbGV2ZWwpKSBnb3RvIGVycm9yOwoJICB9Cgl9CgllbHNlIGlmIChsZi0+aWQgPT0gTlRfUkVHX1JJX0JMT0NLX0lEKSAvKiByaSAqLwoJewoJICBudF9yaSAqIHJpID0gKG50X3JpKilsZjsKCSAgaW50IGxpX3N1YmtleXMgPSAwOwoKCSAgLyogY291bnQgYWxsIHN1YmtleXMgKi8KCSAgZm9yIChpPTA7IGk8cmktPm5yX2xpOyBpKyspCgkgIHsKCSAgICBudF9saSAqIGxpID0gKG50X2xpKikoYmFzZStyaS0+b2ZmX2xpW2ldKzQpOwoJICAgIGlmKGxpLT5pZCAhPSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEKSBnb3RvIGVycm9yMjsKCSAgICBsaV9zdWJrZXlzICs9IGxpLT5ucl9rZXlzOwoJICB9CgoJICAvKiBjaGVjayBudW1iZXIgKi8KCSAgaWYgKHN1YmtleXMgIT0gbGlfc3Via2V5cykgZ290byBlcnJvcjE7CgoJICAvKiBsb29wIHRocm91Z2ggdGhlIGtleXMgKi8KCSAgZm9yIChpPTA7IGk8cmktPm5yX2xpOyBpKyspCgkgIHsKCSAgICBudF9saSAqIGxpID0gKG50X2xpKikoYmFzZStyaS0+b2ZmX2xpW2ldKzQpOwoJICAgIGlmICghX250X3BhcnNlX2xmKGhrZXksIGJhc2UsIGxpLT5ucl9rZXlzLCAobnRfbGYqKWxpLCBsZXZlbCkpIGdvdG8gZXJyb3I7CgkgIH0KCX0KCWVsc2UgCgl7CgkgIGdvdG8gZXJyb3IyOwoJfQoJcmV0dXJuIFRSVUU7CgplcnJvcjI6IEVSUigidW5rbm93biBub2RlIGlkIDB4JTA0eCwgcGxlYXNlIHJlcG9ydCFcbiIsIGxmLT5pZCk7CglyZXR1cm4gVFJVRTsKCQplcnJvcjE6CUVSUl8ocmVnKSgicmVnaXN0cnkgZmlsZSBjb3JydXB0ISAoaW5jb25zaXN0ZW50IG51bWJlciBvZiBzdWJrZXlzKVxuIik7CglyZXR1cm4gRkFMU0U7CgplcnJvcjoJRVJSXyhyZWcpKCJlcnJvciByZWFkaW5nIGxmIGJsb2NrXG4iKTsKCXJldHVybiBGQUxTRTsKfQoKc3RhdGljIGludCBfbnRfcGFyc2VfbmsoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgbnRfbmsgKiBuaywgaW50IGxldmVsKQp7CgljaGFyICogbmFtZTsKCWludCBpOwoJRFdPUkQgKiB2bDsKCUhLRVkgc3Via2V5ID0gaGtleTsKCglpZihuay0+U3ViQmxvY2tJZCAhPSBOVF9SRUdfS0VZX0JMT0NLX0lEKQoJewoJICBFUlIoInVua25vd24gbm9kZSBpZCAweCUwNHgsIHBsZWFzZSByZXBvcnQhXG4iLCBuay0+U3ViQmxvY2tJZCk7CgkgIGdvdG8gZXJyb3I7Cgl9CgoJaWYoKG5rLT5UeXBlIT1OVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSkgJiYKCSAgICgoKG50X25rKikoYmFzZStuay0+cGFyZW50X29mZis0KSktPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkpCgl7CgkgIEVSUl8ocmVnKSgicmVnaXN0cnkgZmlsZSBjb3JydXB0IVxuIik7CgkgIGdvdG8gZXJyb3I7Cgl9CgoJLyogY3JlYXRlIHRoZSBuZXcga2V5ICovCglpZihsZXZlbCA8PSAwKQoJewoJICBuYW1lID0gX3N0cmR1cG5BKCBuay0+bmFtZSwgbmstPm5hbWVfbGVuKzEpOwoJICBpZihSZWdDcmVhdGVLZXlBKCBoa2V5LCBuYW1lLCAmc3Via2V5ICkpIHsgZnJlZShuYW1lKTsgZ290byBlcnJvcjsgfQoJICBmcmVlKG5hbWUpOwoJfQoKCS8qIGxvb3AgdGhyb3VnaCB0aGUgc3Via2V5cyAqLwoJaWYgKG5rLT5ucl9zdWJrZXlzKQoJewoJICBudF9sZiAqIGxmID0gKG50X2xmKikoYmFzZStuay0+bGZfb2ZmKzQpOwoJICBpZiAoIV9udF9wYXJzZV9sZihzdWJrZXksIGJhc2UsIG5rLT5ucl9zdWJrZXlzLCBsZiwgbGV2ZWwtMSkpIGdvdG8gZXJyb3IxOwoJfQoKCS8qIGxvb3AgdHJvdWdoIHRoZSB2YWx1ZSBsaXN0ICovCgl2bCA9IChEV09SRCAqKShiYXNlK25rLT52YWx1ZWxpc3Rfb2ZmKzQpOwoJZm9yIChpPTA7IGk8bmstPm5yX3ZhbHVlczsgaSsrKQoJewoJICBudF92ayAqIHZrID0gKG50X3ZrKikoYmFzZSt2bFtpXSs0KTsKCSAgaWYgKCFfbnRfcGFyc2Vfdmsoc3Via2V5LCBiYXNlLCB2aykpIGdvdG8gZXJyb3IxOwoJfQoKCVJlZ0Nsb3NlS2V5KHN1YmtleSk7CglyZXR1cm4gVFJVRTsKCQplcnJvcjE6CVJlZ0Nsb3NlS2V5KHN1YmtleSk7CmVycm9yOglyZXR1cm4gRkFMU0U7Cn0KCi8qIGVuZCBudCBsb2FkZXIgKi8KCi8qIHdpbmRvd3MgOTUgcmVnaXN0cnkgbG9hZGVyICovCgovKiBTRUNUSU9OIDE6IG1haW4gaGVhZGVyCiAqCiAqIG9uY2UgYXQgb2Zmc2V0IDAKICovCiNkZWZpbmUJVzk1X1JFR19DUkVHX0lECTB4NDc0NTUyNDMKCnR5cGVkZWYgc3RydWN0IAp7CglEV09SRAlpZDsJCS8qICJDUkVHIiA9IFc5NV9SRUdfQ1JFR19JRCAqLwoJRFdPUkQJdmVyc2lvbjsJLyogPz8/PyAweDAwMDEwMDAwICovCglEV09SRAlyZ2RiX29mZjsJLyogMHgwOCBPZmZzZXQgb2YgMXN0IFJHREItYmxvY2sgKi8KCURXT1JECXVrMjsJCS8qIDB4MGMgKi8KCVdPUkQJcmdkYl9udW07CS8qIDB4MTAgIyBvZiBSR0RCLWJsb2NrcyAqLwoJV09SRAl1azM7CglEV09SRAl1a1szXTsKCS8qIHJna24gKi8KfSBfdzk1Y3JlZzsKCi8qIFNFQ1RJT04gMjogRGlyZWN0b3J5IGluZm9ybWF0aW9uICh0cmVlIHN0cnVjdHVyZSkKICoKICogb25jZSBvbiBvZmZzZXQgMHgyMAogKgogKiBzdHJ1Y3R1cmU6IFtyZ2tuXVtka2VdKgkocmVwZWF0IHRpbGwgcmdrbi0+c2l6ZSBpcyByZWFjaGVkKQogKi8KI2RlZmluZQlXOTVfUkVHX1JHS05fSUQJMHg0ZTRiNDc1MgoKdHlwZWRlZiBzdHJ1Y3QKewoJRFdPUkQJaWQ7CQkvKiJSR0tOIiA9IFc5NV9SRUdfUkdLTl9JRCAqLwoJRFdPUkQJc2l6ZTsJCS8qIFNpemUgb2YgdGhlIFJHS04tYmxvY2sgKi8KCURXT1JECXJvb3Rfb2ZmOwkvKiBSZWwuIE9mZnNldCBvZiB0aGUgcm9vdC1yZWNvcmQgKi8KCURXT1JECXVrWzVdOwp9IF93OTVyZ2tuOwoKLyogRGlzayBLZXkgRW50cnkgU3RydWN0dXJlCiAqCiAqIHRoZSAxc3QgZW50cnkgaW4gYSAidXN1YWwiIHJlZ2lzdHJ5IGZpbGUgaXMgYSBudWwtZW50cnkgd2l0aCBzdWJrZXlzOiB0aGUKICogaGl2ZSBpdHNlbGYuIEl0IGxvb2tzIHRoZSBzYW1lIGxpa2Ugb3RoZXIga2V5cy4gRXZlbiB0aGUgSUQtbnVtYmVyIGNhbgogKiBiZSBhbnkgdmFsdWUuCiAqCiAqIFRoZSAiaGFzaCItdmFsdWUgaXMgYSB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIGtleSdzIG5hbWUuIFdpbmRvd3Mgd2lsbCBub3QKICogc2VhcmNoIGZvciB0aGUgbmFtZSwgYnV0IGZvciBhIG1hdGNoaW5nIGhhc2gtdmFsdWUuIGlmIGl0IGZpbmRzIG9uZSwgaXQKICogd2lsbCBjb21wYXJlIHRoZSBhY3R1YWwgc3RyaW5nIGluZm8sIG90aGVyd2lzZSBjb250aW51ZSB3aXRoIHRoZSBuZXh0IGtleS4KICogVG8gY2FsY3VsYXRlIHRoZSBoYXNoIGluaXRpYWxpemUgYSBELVdvcmQgd2l0aCAwIGFuZCBhZGQgYWxsIEFTQ0lJLXZhbHVlcyAKICogb2YgdGhlIHN0cmluZyB3aGljaCBhcmUgc21hbGxlciB0aGFuIDB4ODAgKDEyOCkgdG8gdGhpcyBELVdvcmQuICAgCiAqCiAqIElmIHlvdSB3YW50IHRvIG1vZGlmeSBrZXkgbmFtZXMsIGFsc28gbW9kaWZ5IHRoZSBoYXNoLXZhbHVlcywgc2luY2UgdGhleQogKiBjYW5ub3QgYmUgZm91bmQgYWdhaW4gKGFsdGhvdWdoIHRoZXkgd291bGQgYmUgZGlzcGxheWVkIGluIFJFR0VESVQpCiAqIEVuZCBvZiBsaXN0LXBvaW50ZXJzIGFyZSBmaWxsZWQgd2l0aCAweEZGRkZGRkZGCiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuckhTIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKgogKiB0aGVyZSBpcyBhIG9uZSB0byBvbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gZGtlIGFuZCBka2gKICovCiAvKiBrZXkgc3RydWN0LCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QKewoJRFdPUkQJeDE7CQkvKiBGcmVlIGVudHJ5IGluZGljYXRvcig/KSAqLwoJRFdPUkQJaGFzaDsJCS8qIHN1bSBvZiBieXRlcyBvZiBrZXluYW1lICovCglEV09SRAl4MzsJCS8qIFJvb3Qga2V5IGluZGljYXRvcj8gdXN1YWxseSAweEZGRkZGRkZGICovCglEV09SRAlwcmV2bHZsOwkvKiBvZmZzZXQgb2YgcHJldmlvdXMga2V5ICovCglEV09SRAluZXh0c3ViOwkvKiBvZmZzZXQgb2YgY2hpbGQga2V5ICovCglEV09SRAluZXh0OwkJLyogb2Zmc2V0IG9mIHNpYmxpbmcga2V5ICovCglXT1JECW5yTFM7CQkvKiBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KCVdPUkQJbnJNUzsJCS8qIG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwp9IF93OTVka2U7CgovKiBTRUNUSU9OIDM6IGtleSBpbmZvcm1hdGlvbiwgdmFsdWVzIGFuZCBkYXRhCiAqCiAqIHN0cnVjdHVyZToKICogIHNlY3Rpb246CVtibG9ja3NdKgkJKHJlcGVhdCBjcmVnLT5yZ2RiX251bSB0aW1lcykKICogIGJsb2NrczoJW3JnZGJdIFtzdWJibG9ja3NdKiAJKHJlcGVhdCB0aWxsIGJsb2NrIHNpemUgcmVhY2hlZCApCiAqICBzdWJibG9ja3M6CVtka2hdIFtka3ZdKgkJKHJlcGVhdCBka2gtPnZhbHVlcyB0aW1lcyApCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgdmFsdWUgYXQgb2Zmc2V0CiAqIDEwIGVxdWFscyB0aGUgdmFsdWUgYXQgb2Zmc2V0IDQgbWludXMgdGhlIHZhbHVlIGF0IG9mZnNldCA4LiBJIGhhdmUgbm8KICogaWRlYSBhdCB0aGUgbW9tZW50IHdoYXQgdGhpcyBtZWFucy4gIChLZXZpbiBDb3plbnMpCiAqLwoKLyogYmxvY2sgaGVhZGVyLCBvbmNlIHBlciBibG9jayAqLwojZGVmaW5lIFc5NV9SRUdfUkdEQl9JRAkweDQyNDQ0NzUyCgp0eXBlZGVmIHN0cnVjdAp7CglEV09SRAlpZDsJLyogMHgwMCAncmdkYicgPSBXOTVfUkVHX1JHREJfSUQgKi8KCURXT1JECXNpemU7CS8qIDB4MDQgKi8KCURXT1JECXVrMTsJLyogMHgwOCAqLwoJRFdPUkQJdWsyOwkvKiAweDBjICovCglEV09SRAl1azM7CS8qIDB4MTAgKi8KCURXT1JECXVrNDsJLyogMHgxNCAqLwoJRFdPUkQJdWs1OwkvKiAweDE4ICovCglEV09SRAl1azY7CS8qIDB4MWMgKi8KCS8qIGRraCAqLwp9IF93OTVyZ2RiOwoKLyogRGlzayBLZXkgSGVhZGVyIHN0cnVjdHVyZSAoUkdEQiBwYXJ0KSwgb25jZSBwZXIga2V5ICovCnR5cGVkZWYJc3RydWN0IAp7CglEV09SRAluZXh0a2V5b2ZmOyAJLyogMHgwMCBvZmZzZXQgdG8gbmV4dCBka2gqLwoJV09SRAluckxTOwkJLyogMHgwNCBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KCVdPUkQJbnJNUzsJCS8qIDB4MDYgbnVtYmVyIG9mIHRoZSByZ2RiIGJsb2NrICovCglEV09SRAlieXRlc3VzZWQ7CS8qIDB4MDggKi8KCVdPUkQJa2V5bmFtZWxlbjsJLyogMHgwYyBsZW4gb2YgbmFtZSAqLwoJV09SRAl2YWx1ZXM7CQkvKiAweDBlIG51bWJlciBvZiB2YWx1ZXMgKi8KCURXT1JECXh4MTsJCS8qIDB4MTAgKi8KCWNoYXIJbmFtZVsxXTsJLyogMHgxNCAqLwoJLyogZGt2ICovCQkvKiAweDE0ICsga2V5bmFtZWxlbiAqLwp9IF93OTVka2g7CgovKiBEaXNrIEtleSBWYWx1ZSBzdHJ1Y3R1cmUsIG9uY2UgcGVyIHZhbHVlICovCnR5cGVkZWYJc3RydWN0CnsKCURXT1JECXR5cGU7CQkvKiAweDAwICovCglEV09SRAl4MTsJCS8qIDB4MDQgKi8KCVdPUkQJdmFsbmFtZWxlbjsJLyogMHgwOCBsZW5ndGggb2YgbmFtZSwgMCBpcyBkZWZhdWx0IGtleSAqLwoJV09SRAl2YWxkYXRhbGVuOwkvKiAweDBBIGxlbmd0aCBvZiBkYXRhICovCgljaGFyCW5hbWVbMV07CS8qIDB4MGMgKi8KCS8qIHJhdyBkYXRhICovCQkvKiAweDBjICsgdmFsbmFtZWxlbiAqLwp9IF93OTVka3Y7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfbG9va3VwX2RraCBbSW50ZXJuYWxdCiAqCiAqIHNlZWtzIHRoZSBka2ggYmVsb25naW5nIHRvIGEgZGtlCiAqLwpzdGF0aWMgX3c5NWRraCAqIF93OTVfbG9va3VwX2RraCAoX3c5NWNyZWcgKmNyZWcsIGludCBuckxTLCBpbnQgbnJNUykKewoJX3c5NXJnZGIgKiByZ2RiOwoJX3c5NWRraCAqIGRraDsKCWludCBpOwoJCgkvKiBnZXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgcmdkYiBkYXRhc3RvcmUgKi8KCXJnZGIgPSAoX3c5NXJnZGIqKSgoY2hhciopY3JlZytjcmVnLT5yZ2RiX29mZik7CgoJLyogY2hlY2s6IHJlcXVlc3RlZCBibG9jayA8IGxhc3RfYmxvY2spICovCglpZiAoY3JlZy0+cmdkYl9udW0gPD0gbnJNUykJCQkJCgl7CgkgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISByZXF1ZXN0ZWQgYmxvY2sgbm8uIGJleW9uZCBlbmQuXG4iKTsKCSAgZ290byBlcnJvcjsKCX0KCQoJLyogZmluZCB0aGUgcmlnaHQgYmxvY2sgKi8KCWZvcihpPTA7IGk8bnJNUyA7aSsrKQoJewoJICBpZihyZ2RiLT5pZCAhPSBXOTVfUkVHX1JHREJfSUQpCQkJLyogY2hlY2sgdGhlIG1hZ2ljICovCgkgIHsKCSAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgYmFkIG1hZ2ljIDB4JTA4bHhcbiIsIHJnZGItPmlkKTsKCSAgICBnb3RvIGVycm9yOwoJICB9CgkgIHJnZGIgPSAoX3c5NXJnZGIqKSAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSk7CQkvKiBmaW5kIG5leHQgYmxvY2sgKi8KCX0KCglka2ggPSAoX3c5NWRraCopKHJnZGIgKyAxKTsJCQkJLyogZmlyc3Qgc3ViIGJsb2NrIHdpdGhpbiB0aGUgcmdkYiAqLwoKCWRvCgl7CgkgIGlmKG5yTFM9PWRraC0+bnJMUyApIHJldHVybiBka2g7CgkgIGRraCA9IChfdzk1ZGtoKikoKGNoYXIqKWRraCArIGRraC0+bmV4dGtleW9mZik7CS8qIGZpbmQgbmV4dCBzdWJibG9jayAqLwoJfSB3aGlsZSAoKGNoYXIgKilka2ggPCAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSkpOwoKZXJyb3I6CXJldHVybiBOVUxMOwp9CQogCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9wYXJzZV9ka3YgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfdzk1X3BhcnNlX2RrdiAoCglIS0VZIGhrZXksCglfdzk1ZGtoICogZGtoLAoJaW50IG5yTFMsCglpbnQgbnJNUyApCnsKCV93OTVka3YgKiBka3Y7CglpbnQgaTsKCURXT1JEIHJldDsKCWNoYXIgKiBuYW1lOwoJCQkKCS8qIGZpcnN0IHZhbHVlIGJsb2NrICovCglka3YgPSAoX3c5NWRrdiopKChjaGFyKilka2grZGtoLT5rZXluYW1lbGVuKzB4MTQpOwoKCS8qIGxvb3AgdHJvdWdodCB0aGUgdmFsdWVzICovCglmb3IgKGk9MDsgaTwgZGtoLT52YWx1ZXM7IGkrKykKCXsKCSAgbmFtZSA9IF9zdHJkdXBuQShka3YtPm5hbWUsIGRrdi0+dmFsbmFtZWxlbisxKTsKCSAgcmV0ID0gUmVnU2V0VmFsdWVFeEEoaGtleSwgbmFtZSwgMCwgZGt2LT50eXBlLCAmKGRrdi0+bmFtZVtka3YtPnZhbG5hbWVsZW5dKSxka3YtPnZhbGRhdGFsZW4pOyAKCSAgaWYgKHJldCkgRklYTUUoIlJlZ1NldFZhbHVlRXggcmV0dXJuZWQ6IDB4JTA4bHhcbiIsIHJldCk7CgkgIGZyZWUgKG5hbWUpOwoKCSAgLyogbmV4dCB2YWx1ZSAqLwoJICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka3YrZGt2LT52YWxuYW1lbGVuK2Rrdi0+dmFsZGF0YWxlbisweDBjKTsKCX0KCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfcGFyc2VfZGtlIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9wYXJzZV9ka2UoIAoJSEtFWSBoa2V5LAoJX3c5NWNyZWcgKiBjcmVnLAoJX3c5NXJna24gKnJna24sCglfdzk1ZGtlICogZGtlLAoJaW50IGxldmVsICkKewoJX3c5NWRraCAqIGRraDsKCUhLRVkgaHN1YmtleSA9IGhrZXk7CgljaGFyICogbmFtZTsKCWludCByZXQgPSBGQUxTRTsKCgkvKiBnZXQgc3RhcnQgYWRkcmVzcyBvZiByb290IGtleSBibG9jayAqLwoJaWYgKCFka2UpIGRrZSA9IChfdzk1ZGtlKikoKGNoYXIqKXJna24gKyByZ2tuLT5yb290X29mZik7CgkKCS8qIHNwZWNpYWwgcm9vdCBrZXkgKi8KCWlmIChka2UtPm5yTFMgPT0gMHhmZmZmIHx8IGRrZS0+bnJNUz09MHhmZmZmKQkJLyogZWcuIHRoZSByb290IGtleSBoYXMgbm8gbmFtZSAqLwoJewoJICAvKiBwYXJzZSB0aGUgb25lIHN1YmtleSovCgkgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgCgkgIHsKICAgIAkgICAgcmV0dXJuIF93OTVfcGFyc2VfZGtlKGhzdWJrZXksIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSwgbGV2ZWwpOwoJICB9CgkgIC8qIGhhcyBubyBzaWJsaW5nIGtleXMgKi8KCSAgZ290byBlcnJvcjsKCX0KCgkvKiBzZWFyY2ggc3ViYmxvY2sgKi8KCWlmICghKGRraCA9IF93OTVfbG9va3VwX2RraChjcmVnLCBka2UtPm5yTFMsIGRrZS0+bnJNUykpKQoJewoJICBmcHJpbnRmKHN0ZGVyciwgImRrZSBwb2ludGluZyB0byBtaXNzaW5nIGRraCAhXG4iKTsKCSAgZ290byBlcnJvcjsKCX0KCglpZiAoIGxldmVsIDw9IDAgKQoJewoJICAvKiB3YWxrIHNpYmxpbmcga2V5cyAqLwoJICBpZiAoZGtlLT5uZXh0ICE9IDB4ZmZmZmZmZmYgKQoJICB7CiAgICAJICAgIGlmICghX3c5NV9wYXJzZV9ka2UoaGtleSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHQpLCBsZXZlbCkpIGdvdG8gZXJyb3I7CgkgIH0KCgkgIC8qIGNyZWF0ZSBzdWJrZXkgYW5kIGluc2VydCB2YWx1ZXMgKi8KCSAgbmFtZSA9IF9zdHJkdXBuQSggZGtoLT5uYW1lLCBka2gtPmtleW5hbWVsZW4rMSk7CgkgIGlmIChSZWdDcmVhdGVLZXlBKGhrZXksIG5hbWUsICZoc3Via2V5KSkgeyBmcmVlKG5hbWUpOyBnb3RvIGVycm9yOyB9CgkgIGZyZWUobmFtZSk7CgkgIGlmICghX3c5NV9wYXJzZV9ka3YoaHN1YmtleSwgZGtoLCBka2UtPm5yTFMsIGRrZS0+bnJNUykpIGdvdG8gZXJyb3IxOwoJfSAgCgkKIAkvKiBuZXh0IHN1YiBrZXkgKi8KCWlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgCgl7CiAgICAJICBpZiAoIV93OTVfcGFyc2VfZGtlKGhzdWJrZXksIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSwgbGV2ZWwtMSkpIGdvdG8gZXJyb3IxOwoJfQoKCXJldCA9IFRSVUU7CmVycm9yMToJaWYgKGhzdWJrZXkgIT0gaGtleSkgUmVnQ2xvc2VLZXkoaHN1YmtleSk7CmVycm9yOglyZXR1cm4gcmV0Owp9Ci8qIGVuZCB3aW5kb3dzIDk1IGxvYWRlciAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglOYXRpdmVSZWdMb2FkS2V5IFtJbnRlcm5hbF0KICoKICogTG9hZHMgYSBuYXRpdmUgcmVnaXN0cnkgZmlsZSAod2luOTUvbnQpCiAqIAloa2V5CXJvb3Qga2V5CiAqCWZuCWZpbGVuYW1lCiAqCWxldmVsCW51bWJlciBvZiBsZXZlbHMgdG8gY3V0IGF3YXkgKGVnLiAiLkRlZmF1bHQiIGluIHVzZXIuZGF0KQogKgogKiB0aGlzIGZ1bmN0aW9uIGludGVudGlvbmFsbHkgdXNlcyB1bml4IGZpbGUgZnVuY3Rpb25zIHRvIG1ha2UgaXQgcG9zc2libGUKICogdG8gbW92ZSBpdCB0byBhIHNlcGVyYXRlIHJlZ2lzdHJ5IGhlbHBlciBwcm9ncmFtbQogKi8Kc3RhdGljIGludCBOYXRpdmVSZWdMb2FkS2V5KCBIS0VZIGhrZXksIGNoYXIqIGZuLCBpbnQgbGV2ZWwgKQp7CglpbnQgZmQgPSAwOwoJc3RydWN0IHN0YXQgc3Q7CiAgICAgICAgRE9TX0ZVTExfTkFNRSBmdWxsX25hbWU7CglpbnQgcmV0ID0gRkFMU0U7Cgl2b2lkICogYmFzZTsKCQkJCiAgICAgICAgaWYgKCFET1NGU19HZXRGdWxsTmFtZSggZm4sIDAsICZmdWxsX25hbWUgKSkgcmV0dXJuIEZBTFNFOwoJCgkvKiBtYXAgdGhlIHJlZ2lzdHJ5IGludG8gdGhlIG1lbW9yeSAqLwoJaWYgKChmZCA9IG9wZW4oZnVsbF9uYW1lLmxvbmdfbmFtZSwgT19SRE9OTFkgfCBPX05PTkJMT0NLKSkgPT0gLTEpIHJldHVybiBGQUxTRTsKCWlmICgoZnN0YXQoZmQsICZzdCkgPT0gLTEpKSBnb3RvIGVycm9yOwoJaWYgKCFzdC5zdF9zaXplKSBnb3RvIGVycm9yOwoJaWYgKChiYXNlID0gbW1hcChOVUxMLCBzdC5zdF9zaXplLCBQUk9UX1JFQUQsIE1BUF9QUklWQVRFLCBmZCwgMCkpID09IE1BUF9GQUlMRUQpIGdvdG8gZXJyb3I7CgoJc3dpdGNoICgqKExQRFdPUkQpYmFzZSkKCXsKCSAgLyogd2luZG93cyA5NSAnY3JlZycgKi8KCSAgY2FzZSBXOTVfUkVHX0NSRUdfSUQ6CgkgICAgewoJICAgICAgX3c5NWNyZWcgKiBjcmVnOwoJICAgICAgX3c5NXJna24gKiByZ2tuOwoJICAgICAgY3JlZyA9IGJhc2U7CgkgICAgICBUUkFDRV8ocmVnKSgiTG9hZGluZyB3aW45NSByZWdpc3RyeSAnJXMnICclcydcbiIsZm4sIGZ1bGxfbmFtZS5sb25nX25hbWUpOwoKCSAgICAgIC8qIGxvYWQgdGhlIGhlYWRlciAocmdrbikgKi8KCSAgICAgIHJna24gPSAoX3c5NXJna24qKShjcmVnICsgMSk7CgkgICAgICBpZiAocmdrbi0+aWQgIT0gVzk1X1JFR19SR0tOX0lEKSAKCSAgICAgIHsKCQlFUlIoInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJWx4XG4iLCByZ2tuLT5pZCk7CgkJZ290byBlcnJvcjE7CgkgICAgICB9CgoJICAgICAgcmV0ID0gX3c5NV9wYXJzZV9ka2UoaGtleSwgY3JlZywgcmdrbiwgTlVMTCwgbGV2ZWwpOwoJICAgIH0KCSAgICBicmVhazsKCSAgLyogbnQgJ3JlZ2YnKi8KCSAgY2FzZSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEOgoJICAgIHsKCSAgICAgIG50X3JlZ2YgKiByZWdmOwoJICAgICAgbnRfaGJpbiAqIGhiaW47CgkgICAgICBudF9oYmluX3N1YiAqIGhiaW5fc3ViOwoJICAgICAgbnRfbmsqIG5rOwoKCSAgICAgIFRSQUNFXyhyZWcpKCJMb2FkaW5nIG50IHJlZ2lzdHJ5ICclcycgJyVzJ1xuIixmbiwgZnVsbF9uYW1lLmxvbmdfbmFtZSk7CgoJICAgICAgLyogc3RhcnQgYmxvY2sgKi8KCSAgICAgIHJlZ2YgPSBiYXNlOwoKCSAgICAgIC8qIGhiaW4gYmxvY2sgKi8KCSAgICAgIGhiaW4gPSAobnRfaGJpbiopKChjaGFyKikgYmFzZSArIDB4MTAwMCk7CgkgICAgICBpZiAoaGJpbi0+aWQgIT0gTlRfUkVHX1BPT0xfQkxPQ0tfSUQpCgkgICAgICB7CgkgICAgICAgIEVSUl8ocmVnKSggIiVzIGhiaW4gYmxvY2sgaW52YWxpZFxuIiwgZm4pOwoJICAgICAgICBnb3RvIGVycm9yMTsKCSAgICAgIH0KCgkgICAgICAvKiBoYmluX3N1YiBibG9jayAqLwoJICAgICAgaGJpbl9zdWIgPSAobnRfaGJpbl9zdWIqKSYoaGJpbi0+aGJpbl9zdWIpOwoJICAgICAgaWYgKChoYmluX3N1Yi0+ZGF0YVswXSAhPSAnbicpIHx8IChoYmluX3N1Yi0+ZGF0YVsxXSAhPSAnaycpKQoJICAgICAgewoJICAgICAgICBFUlJfKHJlZykoICIlcyBoYmluX3N1YiBibG9jayBpbnZhbGlkXG4iLCBmbik7CgkgICAgICAgIGdvdG8gZXJyb3IxOwoJICAgICAgfQoKCSAgICAgIC8qIG5rIGJsb2NrICovCgkgICAgICBuayA9IChudF9uayopJihoYmluX3N1Yi0+ZGF0YVswXSk7CgkgICAgICBpZiAobmstPlR5cGUgIT0gTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpCgkgICAgICB7CgkgICAgICAgIEVSUl8ocmVnKSggIiVzIHNwZWNpYWwgbmsgYmxvY2sgbm90IGZvdW5kXG4iLCBmbik7CgkgICAgICAgIGdvdG8gZXJyb3IxOwoJICAgICAgfQoKCSAgICAgIHJldCA9IF9udF9wYXJzZV9uayAoaGtleSwgKGNoYXIgKikgYmFzZSArIDB4MTAwMCwgbmssIGxldmVsKTsKCSAgICB9CgkgICAgYnJlYWs7CgkgIGRlZmF1bHQ6CgkgICAgewoJICAgICAgRVJSKCJ1bmtub3duIHNpZ25hdHVyZSBpbiByZWdpc3RyeSBmaWxlICVzLlxuIixmbik7CgkgICAgICBnb3RvIGVycm9yMTsKCSAgICB9Cgl9CglpZighcmV0KSBFUlIoImVycm9yIGxvYWRpbmcgcmVnaXN0cnkgZmlsZSAlc1xuIiwgZm4pOwplcnJvcjE6CW11bm1hcChiYXNlLCBzdC5zdF9zaXplKTsKZXJyb3I6CWNsb3NlKGZkKTsKCXJldHVybiByZXQ7CQp9CgovKiBXSU5ET1dTIDMxIFJFR0lTVFJZIExPQURFUiwgc3VwcGxpZWQgYnkgVG9yIFNq+HdhbGwsIHRvckBzbi5ubyAqLwovKgogICAgcmVnaGFjayAtIHdpbmRvd3MgMy4xMSByZWdpc3RyeSBkYXRhIGZvcm1hdCBkZW1vIHByb2dyYW0uCgogICAgVGhlIHJlZy5kYXQgZmlsZSBoYXMgMyBwYXJ0cywgYSBoZWFkZXIsIGEgdGFibGUgb2YgOC1ieXRlIGVudHJpZXMgdGhhdCBpcwogICAgYSBjb21iaW5lZCBoYXNoIHRhYmxlIGFuZCB0cmVlIGRlc2NyaXB0aW9uLCBhbmQgZmluYWxseSBhIHRleHQgdGFibGUuCgogICAgVGhlIGhlYWRlciBpcyBvYnZpb3VzIGZyb20gdGhlIHN0cnVjdCBoZWFkZXIuIFRoZSB0YWJvZmYxIGFuZCB0YWJvZmYyCiAgICBmaWVsZHMgYXJlIGFsd2F5cyAweDIwLCBhbmQgdGhlaXIgdXNhZ2UgaXMgdW5rbm93bi4KCiAgICBUaGUgOC1ieXRlIGVudHJ5IHRhYmxlIGhhcyB2YXJpb3VzIGVudHJ5IHR5cGVzLgoKICAgIHRhYmVudFswXSBpcyBhIHJvb3QgaW5kZXguIFRoZSBzZWNvbmQgd29yZCBoYXMgdGhlIGluZGV4IG9mIHRoZSByb290IG9mCiAgICAgICAgICAgIHRoZSBkaXJlY3RvcnkuCiAgICB0YWJlbnRbMS4uaGFzaHNpemVdIGlzIGEgaGFzaCB0YWJsZS4gVGhlIGZpcnN0IHdvcmQgaW4gdGhlIGhhc2ggZW50cnkgaXMKICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBrZXkvdmFsdWUgdGhhdCBoYXMgdGhhdCBoYXNoLiBEYXRhIHdpdGggdGhlIHNhbWUKICAgICAgICAgICAgaGFzaCB2YWx1ZSBhcmUgb24gYSBjaXJjdWxhciBsaXN0LiBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlCiAgICAgICAgICAgIGhhc2ggZW50cnkgYXJlIGFsd2F5cyB6ZXJvLgogICAgdGFiZW50W2hhc2hzaXplLi50YWJjbnRdIGlzIHRoZSB0cmVlIHN0cnVjdHVyZS4gVGhlcmUgYXJlIHR3byBraW5kcyBvZgogICAgICAgICAgICBlbnRyeTogZGlyZW50IGFuZCBrZXllbnQvdmFsZW50LiBUaGV5IGFyZSBpZGVudGlmaWVkIGJ5IGNvbnRleHQuCiAgICB0YWJlbnRbZnJlZWlkeF0gaXMgdGhlIGZpcnN0IGZyZWUgZW50cnkuIFRoZSBmaXJzdCB3b3JkIGluIGEgZnJlZSBlbnRyeQogICAgICAgICAgICBpcyB0aGUgaW5kZXggb2YgdGhlIG5leHQgZnJlZSBlbnRyeS4gVGhlIGxhc3QgaGFzIDAgYXMgYSBsaW5rLgogICAgICAgICAgICBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlIGZyZWUgbGlzdCBhcmUgcHJvYmFibHkgaXJyZWxldmFudC4KCiAgICBFbnRyaWVzIGluIHRleHQgdGFibGUgYXJlIHByZWNlZWRlZCBieSBhIHdvcmQgYXQgb2Zmc2V0LTIuIFRoaXMgd29yZAogICAgaGFzIHRoZSB2YWx1ZSAoMippbmRleCkrMSwgd2hlcmUgaW5kZXggaXMgdGhlIHJlZmVycmluZyBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBpbiB0aGUgdGFibGUuIEkgaGF2ZSBubyBzdWdnZXN0aW9uIGZvciB0aGUgMiogYW5kIHRoZSArMS4KICAgIEZvbGxvd2luZyB0aGUgd29yZCwgdGhlcmUgYXJlIE4gYnl0ZXMgb2YgZGF0YSwgYXMgcGVyIHRoZSBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBsZW5ndGguIFRoZSBvZmZzZXQgb2YgdGhlIGtleWVudC92YWxlbnQgZW50cnkgaXMgZnJvbSB0aGUgc3RhcnQKICAgIG9mIHRoZSB0ZXh0IHRhYmxlIHRvIHRoZSBmaXJzdCBkYXRhIGJ5dGUuCgogICAgVGhpcyBpbmZvcm1hdGlvbiBpcyBub3QgYXZhaWxhYmxlIGZyb20gTWljcm9zb2Z0LiBUaGUgZGF0YSBmb3JtYXQgaXMKICAgIGRlZHVjZWQgZnJvbSB0aGUgcmVnLmRhdCBmaWxlIGJ5IG1lLiBNaXN0YWtlcyBtYXkKICAgIGhhdmUgYmVlbiBtYWRlLiBJIGNsYWltIG5vIHJpZ2h0cyBhbmQgZ2l2ZSBubyBndWFyYW50ZWVzIGZvciB0aGlzIHByb2dyYW0uCgogICAgVG9yIFNq+HdhbGwsIHRvckBzbi5ubwoqLwoKLyogcmVnLmRhdCBoZWFkZXIgZm9ybWF0ICovCnN0cnVjdCBfdzMxX2hlYWRlciB7CgljaGFyCQljb29raWVbOF07CS8qICdTSENDMy4xMCcgKi8KCXVuc2lnbmVkIGxvbmcJdGFib2ZmMTsJLyogb2Zmc2V0IG9mIGhhc2ggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFib2ZmMjsJLyogb2Zmc2V0IG9mIGluZGV4IHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYmNudDsJCS8qIG51bWJlciBvZiBlbnRyaWVzIGluIGluZGV4IHRhYmxlICovCgl1bnNpZ25lZCBsb25nCXRleHRvZmY7CS8qIG9mZnNldCBvZiB0ZXh0IHBhcnQgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dHNpemU7CS8qIGJ5dGUgc2l6ZSBvZiB0ZXh0IHBhcnQgKi8KCXVuc2lnbmVkIHNob3J0CWhhc2hzaXplOwkvKiBoYXNoIHNpemUgKi8KCXVuc2lnbmVkIHNob3J0CWZyZWVpZHg7CS8qIGZyZWUgaW5kZXggKi8KfTsKCi8qIGdlbmVyaWMgZm9ybWF0IG9mIHRhYmxlIGVudHJpZXMgKi8Kc3RydWN0IF93MzFfdGFiZW50IHsKCXVuc2lnbmVkIHNob3J0IHcwLCB3MSwgdzIsIHczOwp9OwoKLyogZGlyZWN0b3J5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfZGlyZW50IHsKCXVuc2lnbmVkIHNob3J0CXNpYmxpbmdfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBzaWJsaW5nIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJY2hpbGRfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBjaGlsZCBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWtleV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGtleSBrZXllbnQgKi8KCXVuc2lnbmVkIHNob3J0CXZhbHVlX2lkeDsJLyogdGFibGUgaW5kZXggb2YgdmFsdWUgdmFsZW50ICovCn07CgovKiBrZXkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9rZXllbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHZhbHVlIHRhYmVudDogKi8Kc3RydWN0IF93MzFfdmFsZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiByZWN1cnNpdmUgaGVscGVyIGZ1bmN0aW9uIHRvIGRpc3BsYXkgYSBkaXJlY3RvcnkgdHJlZSAqLwp2b2lkCl9fdzMxX2R1bXB0cmVlKAl1bnNpZ25lZCBzaG9ydCBpZHgsCgkJdW5zaWduZWQgY2hhciAqdHh0LAoJCXN0cnVjdCBfdzMxX3RhYmVudCAqdGFiLAoJCXN0cnVjdCBfdzMxX2hlYWRlciAqaGVhZCwKCQlIS0VZIGhrZXksCgkJdGltZV90CQlsYXN0bW9kaWZpZWQsCgkJaW50CQlsZXZlbAopIHsKCXN0cnVjdCBfdzMxX2RpcmVudAkqZGlyOwoJc3RydWN0IF93MzFfa2V5ZW50CSprZXk7CglzdHJ1Y3QgX3czMV92YWxlbnQJKnZhbDsKICAgICAgICBIS0VZIHN1YmtleSA9IDA7CglzdGF0aWMgY2hhcgkJdGFpbFs0MDBdOwoKCXdoaWxlIChpZHghPTApIHsKCQlkaXI9KHN0cnVjdCBfdzMxX2RpcmVudCopJnRhYltpZHhdOwoKCQlpZiAoZGlyLT5rZXlfaWR4KSB7CgkJCWtleSA9IChzdHJ1Y3QgX3czMV9rZXllbnQqKSZ0YWJbZGlyLT5rZXlfaWR4XTsKCgkJCW1lbWNweSh0YWlsLCZ0eHRba2V5LT5zdHJpbmdfb2ZmXSxrZXktPmxlbmd0aCk7CgkJCXRhaWxba2V5LT5sZW5ndGhdPSdcMCc7CgkJCS8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUgCgkJCSAqIHRvcGxldmVsIHN1YmRpcmVjdG9yeSBiZWxvbmcgdG8gXFNPRlRXQVJFXENsYXNzZXMKCQkJICovCgkJCWlmICghbGV2ZWwgJiYgIWxzdHJjbXBBKHRhaWwsIi5jbGFzc2VzIikpIHsKCQkJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxoa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQkJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJCQkJY29udGludWU7CgkJCX0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoUmVnQ3JlYXRlS2V5QSggaGtleSwgdGFpbCwgJnN1YmtleSApICE9IEVSUk9SX1NVQ0NFU1MpIHN1YmtleSA9IDA7CgkJCS8qIG9ubHkgYWRkIGlmIGxlYWYgbm9kZSBvciB2YWx1ZWQgbm9kZSAqLwoJCQlpZiAoZGlyLT52YWx1ZV9pZHghPTB8fGRpci0+Y2hpbGRfaWR4PT0wKSB7CgkJCQlpZiAoZGlyLT52YWx1ZV9pZHgpIHsKCQkJCQl2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CgkJCQkJbWVtY3B5KHRhaWwsJnR4dFt2YWwtPnN0cmluZ19vZmZdLHZhbC0+bGVuZ3RoKTsKCQkJCQl0YWlsW3ZhbC0+bGVuZ3RoXT0nXDAnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnU2V0VmFsdWVBKCBzdWJrZXksIE5VTEwsIFJFR19TWiwgdGFpbCwgMCApOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJVFJBQ0UoInN0cmFuZ2U6IG5vIGRpcmVjdG9yeSBrZXkgbmFtZSwgaWR4PSUwNHhcbiIsIGlkeCk7CgkJfQoJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxzdWJrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJfQogICAgICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3czMV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnZvaWQgX3czMV9sb2FkcmVnKHZvaWQpIHsKCUhGSUxFCQkJaGY7CglzdHJ1Y3QgX3czMV9oZWFkZXIJaGVhZDsKCXN0cnVjdCBfdzMxX3RhYmVudAkqdGFiOwoJdW5zaWduZWQgY2hhcgkJKnR4dDsKCWludAkJCWxlbjsKCU9GU1RSVUNUCQlvZnM7CglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmluZm87Cgl0aW1lX3QJCQlsYXN0bW9kaWZpZWQ7CgoJVFJBQ0UoIih2b2lkKVxuIik7CgoJaGYgPSBPcGVuRmlsZSgicmVnLmRhdCIsJm9mcyxPRl9SRUFEKTsKCWlmIChoZj09SEZJTEVfRVJST1IpCgkJcmV0dXJuOwoKCS8qIHJlYWQgJiBkdW1wIGhlYWRlciAqLwoJaWYgKHNpemVvZihoZWFkKSE9X2xyZWFkKGhmLCZoZWFkLHNpemVvZihoZWFkKSkpIHsKCQlFUlIoInJlZy5kYXQgaXMgdG9vIHNob3J0LlxuIik7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoJaWYgKG1lbWNtcChoZWFkLmNvb2tpZSwgIlNIQ0MzLjEwIiwgc2l6ZW9mKGhlYWQuY29va2llKSkhPTApIHsKCQlFUlIoInJlZy5kYXQgaGFzIGJhZCBzaWduYXR1cmUuXG4iKTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJbGVuID0gaGVhZC50YWJjbnQgKiBzaXplb2Yoc3RydWN0IF93MzFfdGFiZW50KTsKCS8qIHJlYWQgYW5kIGR1bXAgaW5kZXggdGFibGUgKi8KCXRhYiA9IHhtYWxsb2MobGVuKTsKCWlmIChsZW4hPV9scmVhZChoZix0YWIsbGVuKSkgewoJCUVSUigiY291bGRuJ3QgcmVhZCAlZCBieXRlcy5cbiIsbGVuKTsgCgkJZnJlZSh0YWIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCgkvKiByZWFkIHRleHQgKi8KCXR4dCA9IHhtYWxsb2MoaGVhZC50ZXh0c2l6ZSk7CglpZiAoLTE9PV9sbHNlZWsoaGYsaGVhZC50ZXh0b2ZmLFNFRUtfU0VUKSkgewoJCUVSUigiY291bGRuJ3Qgc2VlayB0byB0ZXh0YmxvY2suXG4iKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAoaGVhZC50ZXh0c2l6ZSE9X2xyZWFkKGhmLHR4dCxoZWFkLnRleHRzaXplKSkgewoJCUVSUigidGV4dGJsb2NrIHRvbyBzaG9ydCAoJWQgaW5zdGVhZCBvZiAlbGQpLlxuIixsZW4saGVhZC50ZXh0c2l6ZSk7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGYsJmhmaW5mbykpIHsKCQlFUlIoIkdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlIGZhaWxlZD8uXG4iKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CglsYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CglfX3czMV9kdW1wdHJlZSh0YWJbMF0udzEsdHh0LHRhYiwmaGVhZCxIS0VZX0NMQVNTRVNfUk9PVCxsYXN0bW9kaWZpZWQsMCk7CglmcmVlKHRhYik7CglmcmVlKHR4dCk7CglfbGNsb3NlKGhmKTsKCXJldHVybjsKfQoKCi8qIGNvbmZpZ3VyZSBzYXZlIGZpbGVzIGFuZCBzdGFydCB0aGUgcGVyaW9kaWMgc2F2aW5nIHRpbWVyICovCnN0YXRpYyB2b2lkIFNIRUxMX0luaXRSZWdpc3RyeVNhdmluZyh2b2lkKQp7CiAgICBzdHJ1Y3Qgc2V0X3JlZ2lzdHJ5X2xldmVsc19yZXF1ZXN0ICpyZXEgPSBnZXRfcmVxX2J1ZmZlcigpOwoKICAgIGludCBhbGwgPSBQUk9GSUxFX0dldFdpbmVJbmlCb29sKCAicmVnaXN0cnkiLCAiU2F2ZU9ubHlVcGRhdGVkS2V5cyIsIDEgKTsKICAgIGludCB2ZXJzaW9uID0gUFJPRklMRV9HZXRXaW5lSW5pQm9vbCggInJlZ2lzdHJ5IiwgIlVzZU5ld0Zvcm1hdCIsIDEgKSA/IDIgOiAxOwogICAgaW50IHBlcmlvZCA9IFBST0ZJTEVfR2V0V2luZUluaUludCggInJlZ2lzdHJ5IiwgIlBlcmlvZGljU2F2ZSIsIDAgKTsKCiAgICAvKiBzZXQgc2F2aW5nIGxldmVsICgwIGZvciBzYXZpbmcgZXZlcnl0aGluZywgMSBmb3Igc2F2aW5nIG9ubHkgbW9kaWZpZWQga2V5cykgKi8KICAgIHJlcS0+Y3VycmVudCA9IDE7CiAgICByZXEtPnNhdmluZyAgPSAhYWxsOwogICAgcmVxLT52ZXJzaW9uID0gdmVyc2lvbjsKICAgIHJlcS0+cGVyaW9kICA9IHBlcmlvZCAqIDEwMDA7CiAgICBzZXJ2ZXJfY2FsbCggUkVRX1NFVF9SRUdJU1RSWV9MRVZFTFMgKTsKCiAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgicmVnaXN0cnkiLCJXcml0ZXRvSG9tZVJlZ2lzdHJpZXMiLDEpKQogICAgewogICAgICAgIHN0cnVjdCBzYXZlX3JlZ2lzdHJ5X2F0ZXhpdF9yZXF1ZXN0ICpyZXEgPSBnZXRfcmVxX2J1ZmZlcigpOwogICAgICAgIGNvbnN0IGNoYXIgKmNvbmZkaXIgPSBnZXRfY29uZmlnX2RpcigpOwogICAgICAgIGNoYXIgKnN0ciA9IHJlcS0+ZmlsZSArIHN0cmxlbihjb25mZGlyKTsKCiAgICAgICAgaWYgKHN0ciArIDIwID4gcmVxLT5maWxlICsgc2VydmVyX3JlbWFpbmluZyhyZXEtPmZpbGUpKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJjb25maWcgZGlyICclcycgdG9vIGxvbmdcbiIsIGNvbmZkaXIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgc3RyY3B5KCByZXEtPmZpbGUsIGNvbmZkaXIgKTsKICAgICAgICBzdHJjcHkoIHN0ciwgIi8iIFNBVkVfQ1VSUkVOVF9VU0VSICk7CiAgICAgICAgcmVxLT5oa2V5ID0gSEtFWV9DVVJSRU5UX1VTRVI7CiAgICAgICAgc2VydmVyX2NhbGwoIFJFUV9TQVZFX1JFR0lTVFJZX0FURVhJVCApOwoKICAgICAgICBzdHJjcHkoIHJlcS0+ZmlsZSwgY29uZmRpciApOwogICAgICAgIHN0cmNweSggc3RyLCAiLyIgU0FWRV9MT0NBTF9NQUNISU5FICk7CiAgICAgICAgcmVxLT5oa2V5ID0gSEtFWV9MT0NBTF9NQUNISU5FOwogICAgICAgIHNlcnZlcl9jYWxsKCBSRVFfU0FWRV9SRUdJU1RSWV9BVEVYSVQgKTsKCiAgICAgICAgc3RyY3B5KCByZXEtPmZpbGUsIGNvbmZkaXIgKTsKICAgICAgICBzdHJjcHkoIHN0ciwgIi8iIFNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCApOwogICAgICAgIHJlcS0+aGtleSA9IEhLRVlfVVNFUlM7CiAgICAgICAgc2VydmVyX2NhbGwoIFJFUV9TQVZFX1JFR0lTVFJZX0FURVhJVCApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2V0TG9hZExldmVsIFtJbnRlcm5hbF0KICoKICogc2V0IGxldmVsIHRvIDAgZm9yIGxvYWRpbmcgc3lzdGVtIGZpbGVzCiAqIHNldCBsZXZlbCB0byAxIGZvciBsb2FkaW5nIHVzZXIgZmlsZXMKICovCnN0YXRpYyB2b2lkIFNldExvYWRMZXZlbChpbnQgbGV2ZWwpCnsKCXN0cnVjdCBzZXRfcmVnaXN0cnlfbGV2ZWxzX3JlcXVlc3QgKnJlcSA9IGdldF9yZXFfYnVmZmVyKCk7CgoJcmVxLT5jdXJyZW50ID0gbGV2ZWw7CglyZXEtPnNhdmluZyAgPSAwOwoJcmVxLT52ZXJzaW9uID0gMTsKICAgICAgICByZXEtPnBlcmlvZCAgPSAwOwoJc2VydmVyX2NhbGwoIFJFUV9TRVRfUkVHSVNUUllfTEVWRUxTICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX0xvYWRSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwojZGVmaW5lIFJFR19ET05UTE9BRCAtMQojZGVmaW5lIFJFR19XSU4zMSAgMAojZGVmaW5lIFJFR19XSU45NSAgMQojZGVmaW5lIFJFR19XSU5OVCAgMgoKdm9pZCBTSEVMTF9Mb2FkUmVnaXN0cnkoIHZvaWQgKQp7CiAgSEtFWQloa2V5OwogIGNoYXIgd2luZGlyW01BWF9QQVRITkFNRV9MRU5dOwogIGNoYXIgcGF0aFtNQVhfUEFUSE5BTUVfTEVOXTsKICBpbnQgIHN5c3RlbXR5cGUgPSBSRUdfV0lOMzE7CgogIFRSQUNFKCIodm9pZClcbiIpOwoKICBpZiAoIUNMSUVOVF9Jc0Jvb3RUaHJlYWQoKSkgcmV0dXJuOyAgLyogYWxyZWFkeSBsb2FkZWQgKi8KCiAgUkVHSVNUUllfSW5pdCgpOwogIFNldExvYWRMZXZlbCgwKTsKCiAgR2V0V2luZG93c0RpcmVjdG9yeUEoIHdpbmRpciwgTUFYX1BBVEhOQU1FX0xFTiApOwoKICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCggIlJlZ2lzdHJ5IiwgIkxvYWRXaW5kb3dzUmVnaXN0cnlGaWxlcyIsIDEpKQogIHsKICAgIC8qIHRlc3QgJXdpbmRpciUvc3lzdGVtMzIvY29uZmlnL3N5c3RlbSAtLT4gd2lubnQgKi8KICAgIHN0cmNweShwYXRoLCB3aW5kaXIpOwogICAgc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0zMlxcY29uZmlnXFxzeXN0ZW0iLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICBpZihHZXRGaWxlQXR0cmlidXRlc0EocGF0aCkgIT0gLTEpIAogICAgewogICAgICBzeXN0ZW10eXBlID0gUkVHX1dJTk5UOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0uZGF0IC0tPiB3aW45NSAqLwogICAgICBzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgICAgc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0uZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICBpZihHZXRGaWxlQXR0cmlidXRlc0EocGF0aCkgIT0gLTEpCiAgICAgIHsKICAgICAgICBzeXN0ZW10eXBlID0gUkVHX1dJTjk1OwogICAgICB9CiAgICB9CgogICAgaWYgKChzeXN0ZW10eXBlPT1SRUdfV0lOTlQpCiAgICAgICYmICghIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggIldpbmUiLCAiUHJvZmlsZSIsICIiLCBwYXRoLCBNQVhfUEFUSE5BTUVfTEVOKSkpCiAgICB7CiAgICAgICBNRVNTQUdFKCJXaGVuIHlvdSBhcmUgcnVubmluZyB3aXRoIGEgbmF0aXZlIE5UIGRpcmVjdG9yeSBzcGVjaWZ5XG4iKTsKICAgICAgIE1FU1NBR0UoIidQcm9maWxlPTxwcm9maWxlZGlyZWN0b3J5Picgb3IgZGlzYWJsZSBsb2FkaW5nIG9mIFdpbmRvd3NcbiIpOwogICAgICAgTUVTU0FHRSgicmVnaXN0cnkgKExvYWRXaW5kb3dzUmVnaXN0cnlGaWxlcz1OKVxuIik7CiAgICAgICBzeXN0ZW10eXBlID0gUkVHX0RPTlRMT0FEOwogICAgfQogIH0KICBlbHNlCiAgewogICAgLyogb25seSB3aW5lIHJlZ2lzdHJ5ICovCiAgICBzeXN0ZW10eXBlID0gUkVHX0RPTlRMT0FEOwogIH0gIAoKICBzd2l0Y2ggKHN5c3RlbXR5cGUpCiAgewogICAgY2FzZSBSRUdfV0lOMzE6CiAgICAgIF93MzFfbG9hZHJlZygpOwogICAgICBicmVhazsKCiAgICBjYXNlIFJFR19XSU45NTogIAogICAgICAvKiBMb2FkIHdpbmRvd3MgOTUgZW50cmllcyAqLwogICAgICBOYXRpdmVSZWdMb2FkS2V5KEhLRVlfTE9DQUxfTUFDSElORSwgIkM6XFxzeXN0ZW0uMXN0IiwgMCk7CgogICAgICBzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgICAgc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0uZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICBOYXRpdmVSZWdMb2FkS2V5KEhLRVlfTE9DQUxfTUFDSElORSwgcGF0aCwgMCk7CgogICAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiV2luZSIsICJQcm9maWxlIiwgIiIsIHBhdGgsIE1BWF9QQVRITkFNRV9MRU4pKQogICAgICB7CgkvKiB1c2VyIHNwZWNpZmljIHVzZXIuZGF0ICovCglzdHJuY2F0KHBhdGgsICJcXHVzZXIuZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICAgIGlmICghTmF0aXZlUmVnTG9hZEtleSggSEtFWV9DVVJSRU5UX1VTRVIsIHBhdGgsIDEgKSkKCXsKCSAgTUVTU0FHRSgiY2FuJ3QgbG9hZCB3aW45NSB1c2VyLXJlZ2lzdHJ5ICVzXG4iLCBwYXRoKTsKCSAgTUVTU0FHRSgiY2hlY2sgd2luZS5jb25mLCBzZWN0aW9uIFtXaW5lXSwgdmFsdWUgJ1Byb2ZpbGUnXG4iKTsKCX0KCS8qIGRlZmF1bHQgdXNlci5kYXQgKi8KCWlmICghUmVnQ3JlYXRlS2V5QShIS0VZX1VTRVJTLCAiLkRlZmF1bHQiLCAmaGtleSkpCgl7CiAgICAgICAgICBzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgICAgICAgIHN0cm5jYXQocGF0aCwgIlxcdXNlci5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgICAgICBOYXRpdmVSZWdMb2FkS2V5KGhrZXksIHBhdGgsIDEpOwoJICBSZWdDbG9zZUtleShoa2V5KTsKCX0KICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICAvKiBnbG9iYWwgdXNlci5kYXQgKi8KCXN0cmNweShwYXRoLCB3aW5kaXIpOwogICAgICAgIHN0cm5jYXQocGF0aCwgIlxcdXNlci5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgICAgTmF0aXZlUmVnTG9hZEtleShIS0VZX0NVUlJFTlRfVVNFUiwgcGF0aCwgMSk7CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgY2FzZSBSRUdfV0lOTlQ6ICAKICAgICAgLyogZGVmYXVsdCB1c2VyLmRhdCAqLwogICAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiV2luZSIsICJQcm9maWxlIiwgIiIsIHBhdGgsIE1BWF9QQVRITkFNRV9MRU4pKQogICAgICB7CiAgICAgICAgc3RybmNhdChwYXRoLCAiXFxudHVzZXIuZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICAgIGlmKCFOYXRpdmVSZWdMb2FkS2V5KCBIS0VZX0NVUlJFTlRfVVNFUiwgcGF0aCwgMSApKQogICAgICAgIHsKICAgICAgICAgICBNRVNTQUdFKCJjYW4ndCBsb2FkIE5UIHVzZXItcmVnaXN0cnkgJXNcbiIsIHBhdGgpOwoJICAgTUVTU0FHRSgiY2hlY2sgd2luZS5jb25mLCBzZWN0aW9uIFtXaW5lXSwgdmFsdWUgJ1Byb2ZpbGUnXG4iKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8qIGRlZmF1bHQgdXNlci5kYXQgKi8KICAgICAgaWYgKCFSZWdDcmVhdGVLZXlBKEhLRVlfVVNFUlMsICIuRGVmYXVsdCIsICZoa2V5KSkKICAgICAgewogICAgICAgIHN0cmNweShwYXRoLCB3aW5kaXIpOwogICAgICAgIHN0cm5jYXQocGF0aCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcZGVmYXVsdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgICBOYXRpdmVSZWdMb2FkS2V5KGhrZXksIHBhdGgsIDEpOwogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICB9CgogICAgICAvKgogICAgICAqIEZJWE1FCiAgICAgICogIG1hcCBITE1cU3lzdGVtXENvbnRyb2xTZXQwMDEgdG8gSExNXFN5c3RlbVxDdXJyZW50Q29udHJvbFNldAogICAgICAqLwoKICAgICAgaWYgKCFSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwgIlNZU1RFTSIsICZoa2V5KSkKICAgICAgewoJc3RyY3B5KHBhdGgsIHdpbmRpcik7CglzdHJuY2F0KHBhdGgsICJcXHN5c3RlbTMyXFxjb25maWdcXHN5c3RlbSIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKCU5hdGl2ZVJlZ0xvYWRLZXkoaGtleSwgcGF0aCwgMSk7CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgIH0KCiAgICAgIGlmICghUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsICJTT0ZUV0FSRSIsICZoa2V5KSkKICAgICAgewoJc3RyY3B5KHBhdGgsIHdpbmRpcik7CglzdHJuY2F0KHBhdGgsICJcXHN5c3RlbTMyXFxjb25maWdcXHNvZnR3YXJlIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwoJTmF0aXZlUmVnTG9hZEtleShoa2V5LCBwYXRoLCAxKTsKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgfQoKICAgICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgIHN0cm5jYXQocGF0aCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc2FtIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICBOYXRpdmVSZWdMb2FkS2V5KEhLRVlfTE9DQUxfTUFDSElORSwgcGF0aCwgMCk7CgogICAgICBzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgICAgc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0zMlxcY29uZmlnXFxzZWN1cml0eSIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgTmF0aXZlUmVnTG9hZEtleShIS0VZX0xPQ0FMX01BQ0hJTkUsIHBhdGgsIDApOwoKICAgICAgLyogdGhpcyBrZXkgaXMgZ2VuZXJhdGVkIHdoZW4gdGhlIG50LWNvcmUgYm9vdGVkIHN1Y2Nlc3NmdWxseSAqLwogICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXENsb25lIiwmaGtleSkpCiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgIGJyZWFrOwogIH0gLyogc3dpdGNoICovCiAgCiAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2wgKCJyZWdpc3RyeSIsIkxvYWRHbG9iYWxSZWdpc3RyeUZpbGVzIiwgMSkpCiAgewogICAgICAvKiAKICAgICAgICogTG9hZCB0aGUgZ2xvYmFsIEhLVSBoaXZlIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpcgogICAgICAgKi8gCiAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfVVNFUlMsIFNBVkVfVVNFUlNfREVGQVVMVCApOwoKICAgICAgLyogCiAgICAgICAqIExvYWQgdGhlIGdsb2JhbCBtYWNoaW5lIGRlZmF1bHRzIGRpcmVjdGx5IGZvcm0gc3lzY29uZmRpcgogICAgICAgKi8KICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9MT0NBTF9NQUNISU5FLCBTQVZFX0xPQ0FMX01BQ0hJTkVfREVGQVVMVCApOwogIH0KCiAgU2V0TG9hZExldmVsKDEpOwoKICAvKgogICAqIExvYWQgdGhlIHVzZXIgc2F2ZWQgcmVnaXN0cmllcyAKICAgKi8KICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgicmVnaXN0cnkiLCAiTG9hZEhvbWVSZWdpc3RyeUZpbGVzIiwgMSkpCiAgewogICAgICBjb25zdCBjaGFyICpjb25mZGlyID0gZ2V0X2NvbmZpZ19kaXIoKTsKICAgICAgaW50IGxlbiA9IHN0cmxlbihjb25mZGlyKSArIDIwOwogICAgICBjaGFyICpmbiA9IHBhdGg7CgogICAgICBpZiAobGVuID4gc2l6ZW9mKHBhdGgpKSBmbiA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICk7CiAgICAgIC8qIAogICAgICAgKiBMb2FkIHVzZXIncyBwZXJzb25hbCB2ZXJzaW9ucyBvZiBnbG9iYWwgSEtVLy5EZWZhdWx0IGtleXMKICAgICAgICovCiAgICAgIGlmIChmbikKICAgICAgewogICAgICAgICAgY2hhciAqc3RyOwogICAgICAgICAgc3RyY3B5KCBmbiwgY29uZmRpciApOwogICAgICAgICAgc3RyID0gZm4gKyBzdHJsZW4oZm4pOwogICAgICAgICAgKnN0cisrID0gJy8nOwoKICAgICAgICAgIHN0cmNweSggc3RyLCBTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQgKTsKICAgICAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfVVNFUlMsIGZuICk7IAoKICAgICAgICAgIHN0cmNweSggc3RyLCBTQVZFX0NVUlJFTlRfVVNFUiApOwogICAgICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9DVVJSRU5UX1VTRVIsIGZuICk7CgogICAgICAgICAgc3RyY3B5KCBzdHIsIFNBVkVfTE9DQUxfTUFDSElORSApOwogICAgICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9MT0NBTF9NQUNISU5FLCBmbiApOwoKICAgICAgICAgIGlmIChmbiAhPSBwYXRoKSBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZm4gKTsKICAgICAgfQogIH0KCiAgU0hFTExfSW5pdFJlZ2lzdHJ5U2F2aW5nKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKiogQVBJIEZVTkNUSU9OUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0ZsdXNoS2V5IFtLRVJORUwuMjI3XSBbQURWQVBJMzIuMTQzXQogKiBJbW1lZGlhdGVseSB3cml0ZXMga2V5IHRvIHJlZ2lzdHJ5LgogKiBPbmx5IHJldHVybnMgYWZ0ZXIgZGF0YSBoYXMgYmVlbiB3cml0dGVuIHRvIGRpc2suCiAqCiAqIEZJWE1FOiBkb2VzIGl0IHJlYWxseSB3YWl0IHVudGlsIGRhdGEgaXMgd3JpdHRlbiA/CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdyaXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkoIEhLRVkgaGtleSApCnsKICAgIEZJWE1FKCAiKCV4KTogc3R1YlxuIiwgaGtleSApOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ29ubmVjdFJlZ2lzdHJ5VyBbQURWQVBJMzIuMTI4XQogKgogKiBQQVJBTVMKICogICAgbHBNYWNoaW5lTmFtZSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHJlbW90ZSBjb21wdXRlcgogKiAgICBoSGV5ICAgICAgICAgIFtJXSBQcmVkZWZpbmVkIHJlZ2lzdHJ5IGhhbmRsZQogKiAgICBwaGtSZXN1bHQgICAgIFtJXSBBZGRyZXNzIG9mIGJ1ZmZlciBmb3IgcmVtb3RlIHJlZ2lzdHJ5IGhhbmRsZQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5VyggTFBDV1NUUiBscE1hY2hpbmVOYW1lLCBIS0VZIGhLZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSBwaGtSZXN1bHQgKQp7CiAgICBUUkFDRSgiKCVzLCV4LCVwKTogc3R1YlxuIixkZWJ1Z3N0cl93KGxwTWFjaGluZU5hbWUpLGhLZXkscGhrUmVzdWx0KTsKCiAgICBpZiAoIWxwTWFjaGluZU5hbWUgfHwgISpscE1hY2hpbmVOYW1lKSB7CiAgICAgICAgLyogVXNlIHRoZSBsb2NhbCBtYWNoaW5lIG5hbWUgKi8KICAgICAgICByZXR1cm4gUmVnT3BlbktleTE2KCBoS2V5LCAiIiwgcGhrUmVzdWx0ICk7CiAgICB9CgogICAgRklYTUUoIkNhbm5vdCBjb25uZWN0IHRvICVzXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSkpOwogICAgcmV0dXJuIEVSUk9SX0JBRF9ORVRQQVRIOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnlBIFtBRFZBUEkzMi4xMjddCiAqLwpMT05HIFdJTkFQSSBSZWdDb25uZWN0UmVnaXN0cnlBKCBMUENTVFIgbWFjaGluZSwgSEtFWSBoa2V5LCBMUEhLRVkgcmVza2V5ICkKewogICAgRFdPUkQgcmV0OwogICAgTFBXU1RSIG1hY2hpbmVXID0gc3RyZHVwQTJXKG1hY2hpbmUpOwogICAgcmV0ID0gUmVnQ29ubmVjdFJlZ2lzdHJ5VyggbWFjaGluZVcsIGhrZXksIHJlc2tleSApOwogICAgZnJlZShtYWNoaW5lVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdHZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTQ0XQogKiBSZXRyaWV2ZXMgYSBjb3B5IG9mIHNlY3VyaXR5IGRlc2NyaXB0b3IgcHJvdGVjdGluZyB0aGUgcmVnaXN0cnkga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgICAgICAgIFtJXSAgIE9wZW4gaGFuZGxlIG9mIGtleSB0byBzZXQKICogICAgU2VjdXJpdHlJbmZvcm1hdGlvbiAgICBbSV0gICBEZXNjcmlwdG9yIGNvbnRlbnRzCiAqICAgIHBTZWN1cml0eURlc2NyaXB0b3IgICAgW09dICAgQWRkcmVzcyBvZiBkZXNjcmlwdG9yIGZvciBrZXkKICogICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciBbSS9PXSBBZGRyZXNzIG9mIHNpemUgb2YgYnVmZmVyIGFuZCBkZXNjcmlwdGlvbgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KTE9ORyBXSU5BUEkgUmVnR2V0S2V5U2VjdXJpdHkoIEhLRVkgaGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRUNVUklUWV9JTkZPUk1BVElPTiBTZWN1cml0eUluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciApCnsKICAgIFRSQUNFKCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxTZWN1cml0eUluZm9ybWF0aW9uLHBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yPypscGNiU2VjdXJpdHlEZXNjcmlwdG9yOjApOwoKICAgIC8qIEZJWE1FOiBDaGVjayBmb3IgdmFsaWQgU2VjdXJpdHlJbmZvcm1hdGlvbiB2YWx1ZXMgKi8KCiAgICBpZiAoKmxwY2JTZWN1cml0eURlc2NyaXB0b3IgPCBzaXplb2YoU0VDVVJJVFlfREVTQ1JJUFRPUikpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVI7CgogICAgRklYTUUoIigleCwlbGQsJXAsJWxkKTogc3R1YlxuIixoa2V5LFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICBwU2VjdXJpdHlEZXNjcmlwdG9yLGxwY2JTZWN1cml0eURlc2NyaXB0b3I/KmxwY2JTZWN1cml0eURlc2NyaXB0b3I6MCk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlIFtBRFZBUEkzMi4/Pz9dCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgW0ldIEhhbmRsZSBvZiBrZXkgdG8gd2F0Y2gKICogICAgZldhdGNoU3ViVHJlZSAgIFtJXSBGbGFnIGZvciBzdWJrZXkgbm90aWZpY2F0aW9uCiAqICAgIGZkd05vdGlmeUZpbHRlciBbSV0gQ2hhbmdlcyB0byBiZSByZXBvcnRlZAogKiAgICBoRXZlbnQgICAgICAgICAgW0ldIEhhbmRsZSBvZiBzaWduYWxlZCBldmVudAogKiAgICBmQXN5bmMgICAgICAgICAgW0ldIEZsYWcgZm9yIGFzeW5jaHJvbm91cyByZXBvcnRpbmcKICovCkxPTkcgV0lOQVBJIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlKCBIS0VZIGhrZXksIEJPT0wgZldhdGNoU3ViVHJlZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBmZHdOb3RpZnlGaWx0ZXIsIEhBTkRMRSBoRXZlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIGZBc3luYyApCnsKICAgIEZJWE1FKCIoJXgsJWksJWxkLCV4LCVpKTogc3R1YlxuIixoa2V5LGZXYXRjaFN1YlRyZWUsZmR3Tm90aWZ5RmlsdGVyLAogICAgICAgICAgaEV2ZW50LGZBc3luYyk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnVW5Mb2FkS2V5VyBbQURWQVBJMzIuMTczXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscFN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleSB0byB1bmxvYWQKICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSApCnsKICAgIEZJWE1FKCIoJXgsJXMpOiBzdHViXG4iLGhrZXksIGRlYnVnc3RyX3cobHBTdWJLZXkpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXlBIFtBRFZBUEkzMi4xNzJdCiAqLwpMT05HIFdJTkFQSSBSZWdVbkxvYWRLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwU3ViS2V5VyA9IHN0cmR1cEEyVyhscFN1YktleSk7CiAgICByZXQgPSBSZWdVbkxvYWRLZXlXKCBoa2V5LCBscFN1YktleVcgKTsKICAgIGlmKGxwU3ViS2V5VykgZnJlZShscFN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0S2V5U2VjdXJpdHkgW0FEVkFQSTMyLjE2N10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldIE9wZW4gaGFuZGxlIG9mIGtleSB0byBzZXQKICogICAgU2VjdXJpdHlJbmZvICBbSV0gRGVzY3JpcHRvciBjb250ZW50cwogKiAgICBwU2VjdXJpdHlEZXNjIFtJXSBBZGRyZXNzIG9mIGRlc2NyaXB0b3IgZm9yIGtleQogKi8KTE9ORyBXSU5BUEkgUmVnU2V0S2V5U2VjdXJpdHkoIEhLRVkgaGtleSwgU0VDVVJJVFlfSU5GT1JNQVRJT04gU2VjdXJpdHlJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzYyApCnsKICAgIFRSQUNFKCIoJXgsJWxkLCVwKVxuIixoa2V5LFNlY3VyaXR5SW5mbyxwU2VjdXJpdHlEZXNjKTsKCiAgICAvKiBJdCBzZWVtcyB0byBwZXJmb3JtIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoKFNlY3VyaXR5SW5mbyAmIE9XTkVSX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBHUk9VUF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgREFDTF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgU0FDTF9TRUNVUklUWV9JTkZPUk1BVElPTikpIHsKICAgICAgICAvKiBQYXJhbSBPSyAqLwogICAgfSBlbHNlCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGlmICghcFNlY3VyaXR5RGVzYykKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgRklYTUUoIjooJXgsJWxkLCVwKTogc3R1YlxuIixoa2V5LFNlY3VyaXR5SW5mbyxwU2VjdXJpdHlEZXNjKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleVcgW0FEVkFQSTMyLjE2NF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgcmVzdG9yZSBiZWdpbnMKICogICAgbHBGaWxlICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBjb250YWluaW5nIHNhdmVkIHRyZWUKICogICAgZHdGbGFncyBbSV0gT3B0aW9uYWwgZmxhZ3MKICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgVFJBQ0UoIigleCwlcywlbGQpXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIEl0IHNlZW1zIHRvIGRvIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoIWxwRmlsZSB8fCAhKmxwRmlsZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgRklYTUUoIigleCwlcywlbGQpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIENoZWNrIGZvciBmaWxlIGV4aXN0ZW5jZSAqLwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5QSBbQURWQVBJMzIuMTYzXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVzdG9yZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwRmlsZVcgPSBzdHJkdXBBMlcobHBGaWxlKTsKICAgIHJldCA9IFJlZ1Jlc3RvcmVLZXlXKCBoa2V5LCBscEZpbGVXLCBkd0ZsYWdzICk7CiAgICBpZihscEZpbGVXKSBmcmVlKGxwRmlsZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleVcgW0FEVkFQSTMyLjE2Ml0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwU3ViS2V5ICBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleQogKiAgICBscE5ld0ZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIGZpbGUgd2l0aCBuZXcgZGF0YQogKiAgICBscE9sZEZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIGJhY2t1cCBmaWxlCiAqLwpMT05HIFdJTkFQSSBSZWdSZXBsYWNlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwU3ViS2V5LCBMUENXU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBscE9sZEZpbGUgKQp7CiAgICBGSVhNRSgiKCV4LCVzLCVzLCVzKTogc3R1YlxuIiwgaGtleSwgZGVidWdzdHJfdyhscFN1YktleSksIAogICAgICAgICAgZGVidWdzdHJfdyhscE5ld0ZpbGUpLGRlYnVnc3RyX3cobHBPbGRGaWxlKSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleUEgW0FEVkFQSTMyLjE2MV0KICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSwgTFBDU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwT2xkRmlsZSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwU3ViS2V5VyA9IHN0cmR1cEEyVyhscFN1YktleSk7CiAgICBMUFdTVFIgbHBOZXdGaWxlVyA9IHN0cmR1cEEyVyhscE5ld0ZpbGUpOwogICAgTFBXU1RSIGxwT2xkRmlsZVcgPSBzdHJkdXBBMlcobHBPbGRGaWxlKTsKICAgIHJldCA9IFJlZ1JlcGxhY2VLZXlXKCBoa2V5LCBscFN1YktleVcsIGxwTmV3RmlsZVcsIGxwT2xkRmlsZVcgKTsKICAgIGZyZWUobHBPbGRGaWxlVyk7CiAgICBmcmVlKGxwTmV3RmlsZVcpOwogICAgZnJlZShscFN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCgoKCgovKiAxNi1iaXQgZnVuY3Rpb25zICovCgovKiAwIGFuZCAxIGFyZSB2YWxpZCByb290a2V5cyBpbiB3aW4xNiBzaGVsbC5kbGwgYW5kIGFyZSB1c2VkIGJ5CiAqIHNvbWUgcHJvZ3JhbXMuIERvIG5vdCByZW1vdmUgdGhvc2UgY2FzZXMuIC1NTQogKi8Kc3RhdGljIGlubGluZSB2b2lkIGZpeF93aW4xNl9oa2V5KCBIS0VZICpoa2V5ICkKewogICAgaWYgKCpoa2V5ID09IDAgfHwgKmhrZXkgPT0gMSkgKmhrZXkgPSBIS0VZX0NMQVNTRVNfUk9PVDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRW51bUtleTE2ICAgW0tFUk5FTC4yMTZdIFtTSEVMTC43XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXkxNiggSEtFWSBoa2V5LCBEV09SRCBpbmRleCwgTFBTVFIgbmFtZSwgRFdPUkQgbmFtZV9sZW4gKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdFbnVtS2V5QSggaGtleSwgaW5kZXgsIG5hbWUsIG5hbWVfbGVuICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ09wZW5LZXkxNiAgIFtLRVJORUwuMjE3XSBbU0hFTEwuMV0KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQSEtFWSByZXRrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdPcGVuS2V5QSggaGtleSwgbmFtZSwgcmV0a2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0NyZWF0ZUtleTE2ICAgW0tFUk5FTC4yMThdIFtTSEVMTC4yXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUEhLRVkgcmV0a2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5QSggaGtleSwgbmFtZSwgcmV0a2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0RlbGV0ZUtleTE2ICAgW0tFUk5FTC4yMTldIFtTSEVMTC40XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRGVsZXRlS2V5QSggaGtleSwgbmFtZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdDbG9zZUtleTE2ICAgW0tFUk5FTC4yMjBdIFtTSEVMTC4zXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0Nsb3NlS2V5MTYoIEhLRVkgaGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0Nsb3NlS2V5KCBoa2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1NldFZhbHVlMTYgICBbS0VSTkVMLjIyMV0gW1NIRUxMLjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgRFdPUkQgdHlwZSwgTFBDU1RSIGRhdGEsIERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVBKCBoa2V5LCBuYW1lLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdEZWxldGVWYWx1ZTE2ICBbS0VSTkVMLjIyMl0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTE2KCBIS0VZIGhrZXksIExQU1RSIG5hbWUgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdEZWxldGVWYWx1ZUEoIGhrZXksIG5hbWUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRW51bVZhbHVlMTYgICBbS0VSTkVMLjIyM10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUxNiggSEtFWSBoa2V5LCBEV09SRCBpbmRleCwgTFBTVFIgdmFsdWUsIExQRFdPUkQgdmFsX2NvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgcmVzZXJ2ZWQsIExQRFdPUkQgdHlwZSwgTFBCWVRFIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdFbnVtVmFsdWVBKCBoa2V5LCBpbmRleCwgdmFsdWUsIHZhbF9jb3VudCwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUxNiAgIFtLRVJORUwuMjI0XSBbU0hFTEwuNl0KICoKICogTk9URVMKICogICAgSXMgdGhpcyBIQUNLIHN0aWxsIGFwcGxpY2FibGU/CiAqCiAqIEhBQ0sKICogICAgVGhlIDE2Yml0IFJlZ1F1ZXJ5VmFsdWUgZG9lc24ndCBoYW5kbGUgc2VsZWN0b3JibG9ja3MgYW55d2F5LCBzbyB3ZSBqdXN0CiAqICAgIG1hc2sgb3V0IHRoZSBoaWdoIDE2IGJpdC4gIFRoaXMgKG5vdCBzbyBtdWNoIGluY2lkZW50bHkpIGhvcGVmdWxseSBmaXhlcwogKiAgICBBbGR1cyBGSDQpCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUFNUUiBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICBpZiAoY291bnQpICpjb3VudCAmPSAweGZmZmY7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUEoIGhrZXksIG5hbWUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWVFeDE2ICAgW0tFUk5FTC4yMjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQRFdPUkQgcmVzZXJ2ZWQsIExQRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeEEoIGhrZXksIG5hbWUsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdTZXRWYWx1ZUV4MTYgICBbS0VSTkVMLjIyNl0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIERXT1JEIHJlc2VydmVkLCBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05TVCBCWVRFICpkYXRhLCBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlRXhBKCBoa2V5LCBuYW1lLCByZXNlcnZlZCwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQo=