LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGxpbWl0cy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpZmRlZiBIQVZFX1NZU19FUlJOT19ICiNpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDx0aW1lLmg+CiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgInNlcnZlci5oIgojaW5jbHVkZSAic2VydmljZXMuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTChyZWcpOwoKc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCh2b2lkKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUICAgICAgICAgIEVUQ0RJUiIvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUICBFVENESVIiL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0NVUlJFTlRfVVNFUiAgICAgICAgICAgInVzZXIucmVnIgojZGVmaW5lIFNBVkVfREVGQVVMVF9VU0VSICAgICAgICAgICAidXNlcmRlZi5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUICAgICJ3aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FICAgICAgICAgICJzeXN0ZW0ucmVnIgoKCnN0YXRpYyB2b2lkICp4bWFsbG9jKCBzaXplX3Qgc2l6ZSApCnsKICAgIHZvaWQgKnJlczsKIAogICAgcmVzID0gbWFsbG9jIChzaXplID8gc2l6ZSA6IDEpOwogICAgaWYgKHJlcyA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiVmlydHVhbCBtZW1vcnkgZXhoYXVzdGVkLlxuIik7CiAgICAgICAgZXhpdCAoMSk7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSRUdJU1RSWV9Jbml0IFtJbnRlcm5hbF0KICogUmVnaXN0cnkgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBzb21lIGRlZmF1bHQga2V5cy4gCiAqLwpzdGF0aWMgdm9pZCBSRUdJU1RSWV9Jbml0KHZvaWQpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJVFJBQ0UoIih2b2lkKVxuIik7CgoJUmVnQ3JlYXRlS2V5QShIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXhBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3dzIE5UXFxDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50QnVpbGROdW1iZXIKCSAqCQkJCQkJQ3VycmVudFR5cGUKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE93bmVyCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPcmdhbml6YXRpb24KCSAqCgkgKi8KCS8qIFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTTk1QXFxQYXJhbWV0ZXJzXFxSRkMxMTU2QWdlbnQKCSAqIAkJCQkJc3RyaW5nCVN5c0NvbnRhY3QKCSAqIAkJCQkJc3RyaW5nCVN5c0xvY2F0aW9uCgkgKiAJCQkJCQlTeXNTZXJ2aWNlcwoJICovCglpZiAoLTEhPWdldGhvc3RuYW1lKGJ1ZiwyMDApKSB7CgkJUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXENvbnRyb2xcXENvbXB1dGVyTmFtZVxcQ29tcHV0ZXJOYW1lIiwmaGtleSk7CgkJUmVnU2V0VmFsdWVFeEEoaGtleSwiQ29tcHV0ZXJOYW1lIiwwLFJFR19TWixidWYsc3RybGVuKGJ1ZikrMSk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqIExPQUQgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmluZF9vcl9hZGRfa2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbmxpbmUgSEtFWSBfZmluZF9vcl9hZGRfa2V5KCBIS0VZIGhrZXksIExQV1NUUiBrZXluYW1lICkKewogICAgSEtFWSBzdWJrZXk7CiAgICBpZiAoUmVnQ3JlYXRlS2V5VyggaGtleSwga2V5bmFtZSwgJnN1YmtleSApICE9IEVSUk9SX1NVQ0NFU1MpIHN1YmtleSA9IDA7CiAgICBpZiAoa2V5bmFtZSkgZnJlZSgga2V5bmFtZSApOwogICAgcmV0dXJuIHN1YmtleTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmluZF9vcl9hZGRfdmFsdWUgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX2ZpbmRfb3JfYWRkX3ZhbHVlKCBIS0VZIGhrZXksIExQV1NUUiBuYW1lLCBEV09SRCB0eXBlLCBMUEJZVEUgZGF0YSwgRFdPUkQgbGVuICkKewogICAgUmVnU2V0VmFsdWVFeFcoIGhrZXksIG5hbWUsIDAsIHR5cGUsIGRhdGEsIGxlbiApOwogICAgaWYgKG5hbWUpIGZyZWUoIG5hbWUgKTsKICAgIGlmIChkYXRhKSBmcmVlKCBkYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfbGluZSBbSW50ZXJuYWxdCiAqCiAqIHJlYWRzIGEgbGluZSBpbmNsdWRpbmcgZHluYW1pY2FsbHkgZW5sYXJnaW5nIHRoZSByZWFkYnVmZmVyIGFuZCB0aHJvd2luZwogKiBhd2F5IGNvbW1lbnRzCiAqLwpzdGF0aWMgaW50IF93aW5lX3JlYWRfbGluZSggRklMRSAqRiwgY2hhciAqKmJ1ZiwgaW50ICpsZW4gKQp7CgljaGFyCSpzLCpjdXJyZWFkOwoJaW50CW15bGVuLGN1cm9mZjsKCgljdXJyZWFkCT0gKmJ1ZjsKCW15bGVuCT0gKmxlbjsKCSoqYnVmCT0gJ1wwJzsKCXdoaWxlICgxKSB7CgkJd2hpbGUgKDEpIHsKCQkJcz1mZ2V0cyhjdXJyZWFkLG15bGVuLEYpOwoJCQlpZiAocz09TlVMTCkKCQkJCXJldHVybiAwOyAvKiBFT0YgKi8KCQkJaWYgKE5VTEw9PShzPXN0cmNocihjdXJyZWFkLCdcbicpKSkgewoJCQkJLyogYnVmZmVyIHdhc24ndCBsYXJnZSBlbm91Z2ggKi8KCQkJCWN1cm9mZgk9IHN0cmxlbigqYnVmKTsKCQkJCWN1cnJlYWQJPSByZWFsbG9jKCpidWYsKmxlbioyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihjdXJyZWFkID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiT3V0IG9mIG1lbW9yeSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKmJ1Zgk9IGN1cnJlYWQ7CgkJCQljdXJyZWFkKz0gY3Vyb2ZmOwoJCQkJbXlsZW4JPSAqbGVuOwkvKiB3ZSBmaWxsZWQgdXAgdGhlIGJ1ZmZlciBhbmQgCgkJCQkJCSAqIGdvdCBuZXcgJypsZW4nIGJ5dGVzIHRvIGZpbGwKCQkJCQkJICovCgkJCQkqbGVuCT0gKmxlbiAqIDI7CgkJCX0gZWxzZSB7CgkJCQkqcz0nXDAnOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLyogdGhyb3cgYXdheSBjb21tZW50cyAqLwoJCWlmICgqKmJ1Zj09JyMnIHx8ICoqYnVmPT0nOycpIHsKCQkJY3VycmVhZAk9ICpidWY7CgkJCW15bGVuCT0gKmxlbjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzKSAJLyogZ290IGVuZCBvZiBsaW5lICovCgkJCWJyZWFrOwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfVVNUUklORyBbSW50ZXJuYWxdCiAqCiAqIGNvbnZlcnRzIGEgY2hhciogaW50byBhIFVOSUNPREUgc3RyaW5nICh1cCB0byBhIHNwZWNpYWwgY2hhcikKICogYW5kIHJldHVybnMgdGhlIHBvc2l0aW9uIGV4YWN0bHkgYWZ0ZXIgdGhhdCBzdHJpbmcKICovCnN0YXRpYyBjaGFyKiBfd2luZV9yZWFkX1VTVFJJTkcoIGNoYXIgKmJ1ZiwgTFBXU1RSICpzdHIgKQp7CgljaGFyCSpzOwoJTFBXU1RSCXdzOwoKCS8qIHJlYWQgdXAgdG8gIj0iIG9yICJcMCIgb3IgIlxuIiAqLwoJcwk9IGJ1ZjsKCSpzdHIJPSAoTFBXU1RSKXhtYWxsb2MoMipzdHJsZW4oYnVmKSsyKTsKCXdzCT0gKnN0cjsKCXdoaWxlICgqcyAmJiAoKnMhPSdcbicpICYmICgqcyE9Jz0nKSkgewoJCWlmICgqcyE9J1xcJykKCQkJKndzKys9KigodW5zaWduZWQgY2hhciopcysrKTsKCQllbHNlIHsKCQkJcysrOwoJCQlpZiAoISpzKSB7CgkJCQkvKiBEYW5nbGluZyBcIC4uLiBtYXkgb25seSBoYXBwZW4gaWYgYSByZWdpc3RyeQoJCQkJICogd3JpdGUgd2FzIHNob3J0LiBGSVhNRTogV2hhdCB0byBkbz8KCQkJCSAqLwoJCQkJIGJyZWFrOwoJCQl9CgkJCWlmICgqcz09J1xcJykgewoJCQkJKndzKys9J1xcJzsKCQkJCXMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWlmICgqcyE9J3UnKSB7CgkJCQlXQVJOKCJOb24gdW5pY29kZSBlc2NhcGUgc2VxdWVuY2UgXFwlYyBmb3VuZCBpbiB8JXN8XG4iLCpzLGJ1Zik7CgkJCQkqd3MrKz0nXFwnOwoJCQkJKndzKys9KnMrKzsKCQkJfSBlbHNlIHsKCQkJCWNoYXIJeGJ1Zls1XTsKCQkJCWludAl3YzsKCgkJCQlzKys7CgkJCQltZW1jcHkoeGJ1ZixzLDQpO3hidWZbNF09J1wwJzsKCQkJCWlmICghc3NjYW5mKHhidWYsIiV4Iiwmd2MpKQoJCQkJCVdBUk4oIlN0cmFuZ2UgZXNjYXBlIHNlcXVlbmNlICVzIGZvdW5kIGluIHwlc3xcbiIseGJ1ZixidWYpOwoJCQkJcys9NDsKCQkJCSp3cysrCT0odW5zaWduZWQgc2hvcnQpd2M7CgkJCX0KCQl9Cgl9Cgkqd3MJPSAwOwoJcmV0dXJuIHM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJrZXkgW0ludGVybmFsXQogKgogKiBOT1RFUwogKiAgICBJdCBzZWVtcyBsaWtlIHRoaXMgaXMgcmV0dXJuaW5nIGEgYm9vbGVhbi4gIFNob3VsZCBpdD8KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiAxCiAqICAgIEZhaWx1cmU6IDAKICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YmtleSggRklMRSAqRiwgSEtFWSBoa2V5LCBpbnQgbGV2ZWwsIGNoYXIgKipidWYsIGludCAqYnVmbGVuICkKewogICAgCUhLRVkgc3Via2V5OwoJaW50CQlpOwoJY2hhcgkJKnM7CglMUFdTVFIJCW5hbWU7CgogICAgVFJBQ0UoIiglcCwleCwlZCwlcywlZClcbiIsIEYsIGhrZXksIGxldmVsLCBkZWJ1Z3N0cl9hKCpidWYpLCAqYnVmbGVuKTsKCiAgICAvKiBHb29kLiAgV2UgYWxyZWFkeSBnb3QgYSBsaW5lIGhlcmUgLi4uIHNvIHBhcnNlIGl0ICovCiAgICBzdWJrZXkgPSAwOwogICAgd2hpbGUgKDEpIHsKICAgICAgICBpPTA7cz0qYnVmOwogICAgICAgIHdoaWxlICgqcz09J1x0JykgewogICAgICAgICAgICBzKys7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9CiAgICAgICAgaWYgKGk+bGV2ZWwpIHsKICAgICAgICAgICAgaWYgKCFzdWJrZXkpIHsKICAgICAgICAgICAgICAgIFdBUk4oIkdvdCBhIHN1YmhpZXJhcmNoeSB3aXRob3V0IHJlc3AuIGtleT9cbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCSAgICBpZiAoIV93aW5lX2xvYWRzdWJrZXkoRixzdWJrZXksbGV2ZWwrMSxidWYsYnVmbGVuKSkKCSAgICAgICBpZiAoIV93aW5lX3JlYWRfbGluZShGLGJ1ZixidWZsZW4pKQoJCSAgZ290byBkb25lOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoJCS8qIGxldCB0aGUgY2FsbGVyIGhhbmRsZSB0aGlzIGxpbmUgKi8KCQlpZiAoaTxsZXZlbCB8fCAqKmJ1Zj09J1wwJykKCQkJZ290byBkb25lOwoKCQkvKiBpdCBjYW4gYmU6IGEgdmFsdWUgb3IgYSBrZXluYW1lLiBQYXJzZSB0aGUgbmFtZSBmaXJzdCAqLwoJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsJm5hbWUpOwoKCQkvKiBzd2l0Y2goKSBkZWZhdWx0OiBoYWNrIHRvIGF2b2lkIGdvdG9zICovCgkJc3dpdGNoICgwKSB7CgkJZGVmYXVsdDoKCQkJaWYgKCpzPT0nXDAnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwoJCQkJc3Via2V5PV9maW5kX29yX2FkZF9rZXkoaGtleSxuYW1lKTsKCQkJfSBlbHNlIHsKCQkJCUxQQllURQkJZGF0YTsKCQkJCWludAkJbGVuLGxhc3Rtb2RpZmllZCx0eXBlOwoKCQkJCWlmICgqcyE9Jz0nKSB7CgkJCQkJV0FSTigiVW5leHBlY3RlZCBjaGFyYWN0ZXI6ICVjXG4iLCpzKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCXMrKzsKCQkJCWlmICgyIT1zc2NhbmYocywiJWQsJWQsIiwmdHlwZSwmbGFzdG1vZGlmaWVkKSkgewoJCQkJCVdBUk4oIkhhdmVuJ3QgdW5kZXJzdG9vZCBwb3NzaWJsZSB2YWx1ZSBpbiB8JXN8LCBza2lwcGluZy5cbiIsKmJ1Zik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQkvKiBza2lwIHRoZSAyICwgKi8KCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlzPXN0cmNocihzLCcsJyk7CgkJCQlpZiAoIXMrKykgewoJCQkJCVdBUk4oIkhhdmVuJ3QgdW5kZXJzdG9vZCBwb3NzaWJsZSB2YWx1ZSBpbiB8JXN8LCBza2lwcGluZy5cbiIsKmJ1Zik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlpZiAodHlwZSA9PSBSRUdfU1ogfHwgdHlwZSA9PSBSRUdfRVhQQU5EX1NaKSB7CgkJCQkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywoTFBXU1RSKikmZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4gPSBsc3RybGVuVygoTFBXU1RSKWRhdGEpKjIrMjsKCQkJCX0gZWxzZSB7CgkJCQkJbGVuPXN0cmxlbihzKS8yOwoJCQkJCWRhdGEgPSAoTFBCWVRFKXhtYWxsb2MobGVuKzEpOwoJCQkJCWZvciAoaT0wO2k8bGVuO2krKykgewoJCQkJCQlkYXRhW2ldPTA7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldPSgqcy0nMCcpPDw0OwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ2EnKydceGEnKTw8NDsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV09KCpzLSdBJysnXHhhJyk8PDQ7CgkJCQkJCXMrKzsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV18PSpzLScwJzsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV18PSpzLSdhJysnXHhhJzsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV18PSpzLSdBJysnXHhhJzsKCQkJCQkJcysrOwoJCQkJCX0KCQkJCX0KCQkJCV9maW5kX29yX2FkZF92YWx1ZShoa2V5LG5hbWUsdHlwZSxkYXRhLGxlbik7CgkJCX0KCQl9CgkJLyogcmVhZCB0aGUgbmV4dCBsaW5lICovCgkJaWYgKCFfd2luZV9yZWFkX2xpbmUoRixidWYsYnVmbGVuKSkKCQkJZ290byBkb25lOwogICAgfQogZG9uZToKICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKICAgIHJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2Fkc3VicmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YnJlZyggRklMRSAqRiwgSEtFWSBoa2V5LCBjb25zdCBjaGFyICpmbiApCnsKCWludAl2ZXI7CgljaGFyCSpidWY7CglpbnQJYnVmbGVuOwoKCWJ1Zj14bWFsbG9jKDEwKTtidWZsZW49MTA7CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXNzY2FuZihidWYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAodmVyIT0xKSB7CiAgICAgICAgICAgIGlmICh2ZXIgPT0gMikgIC8qIG5ldyB2ZXJzaW9uICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEhBTkRMRSBmaWxlOwogICAgICAgICAgICAgICAgaWYgKChmaWxlID0gRklMRV9DcmVhdGVGaWxlKCBmbiwgR0VORVJJQ19SRUFELCAwLCBOVUxMLCBPUEVOX0VYSVNUSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfQVRUUklCVVRFX05PUk1BTCwgLTEsIFRSVUUgKSkgIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgU0VSVkVSX1NUQVJUX1JFUQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGxvYWRfcmVnaXN0cnlfcmVxdWVzdCAqcmVxID0gc2VydmVyX2FsbG9jX3JlcSggc2l6ZW9mKCpyZXEpLCAwICk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcS0+aGtleSAgICA9IGhrZXk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcS0+ZmlsZSAgICA9IGZpbGU7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlcl9jYWxsKCBSRVFfTE9BRF9SRUdJU1RSWSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBTRVJWRVJfRU5EX1JFUTsKICAgICAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggZmlsZSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZnJlZSggYnVmICk7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKCQlUUkFDRSgiT2xkIGZvcm1hdCAoJWQpIHJlZ2lzdHJ5IGZvdW5kLCBpZ25vcmluZyBpdC4gKGJ1ZiB3YXMgJXMpLlxuIix2ZXIsYnVmKTsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCX0KCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfbG9hZHN1YmtleShGLGhrZXksMCwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJZnJlZShidWYpOwoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfd2luZV9sb2FkcmVnKCBIS0VZIGhrZXksIGNoYXIgKmZuICkKewogICAgRklMRSAqRjsKCiAgICBUUkFDRSgiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EoZm4pKTsKCiAgICBGID0gZm9wZW4oZm4sInJiIik7CiAgICBpZiAoRj09TlVMTCkgewogICAgICAgIFdBUk4oIkNvdWxkbid0IG9wZW4gJXMgZm9yIHJlYWRpbmc6ICVzXG4iLGZuLHN0cmVycm9yKGVycm5vKSApOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIF93aW5lX2xvYWRzdWJyZWcoRixoa2V5LGZuKTsKICAgIGZjbG9zZShGKTsKICAgIHJldHVybiAwOwp9CgovKiBOVCBSRUdJU1RSWSBMT0FERVIgKi8KCiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKCiNpZm5kZWYgTUFQX0ZBSUxFRAojZGVmaW5lIE1BUF9GQUlMRUQgKChMUFZPSUQpLTEpCiNlbmRpZgoKI2RlZmluZSAgTlRfUkVHX0JMT0NLX1NJWkUJCTB4MTAwMAoKI2RlZmluZSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEICAgICAgIDB4NjY2NzY1NzIJLyogcmVnZiAqLwojZGVmaW5lIE5UX1JFR19QT09MX0JMT0NLX0lEICAgICAgICAgMHg2RTY5NjI2OAkvKiBoYmluICovCiNkZWZpbmUgTlRfUkVHX0tFWV9CTE9DS19JRCAgICAgICAgICAweDZiNmUgLyogbmsgKi8KI2RlZmluZSBOVF9SRUdfVkFMVUVfQkxPQ0tfSUQgICAgICAgIDB4NmI3NiAvKiB2ayAqLwoKLyogc3ViYmxvY2tzIG9mIG5rICovCiNkZWZpbmUgTlRfUkVHX0hBU0hfQkxPQ0tfSUQgICAgICAgICAweDY2NmMgLyogbGYgKi8KI2RlZmluZSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEICAgICAgIDB4Njk2YyAvKiBsaSAqLwojZGVmaW5lIE5UX1JFR19SSV9CTE9DS19JRAkgICAgIDB4Njk3MiAvKiByaSAqLwoKI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX1RZUEUgICAgICAgIDB4MjAKI2RlZmluZSBOVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSAgIDB4MmMKCnR5cGVkZWYgc3RydWN0IAp7CglEV09SRAlpZDsJCS8qIDB4NjY2NzY1NzIgJ3JlZ2YnKi8KCURXT1JECXVrMTsJCS8qIDB4MDQgKi8KCURXT1JECXVrMjsJCS8qIDB4MDggKi8KCUZJTEVUSU1FCURhdGVNb2RpZmllZDsJLyogMHgwYyAqLwoJRFdPUkQJdWszOwkJLyogMHgxNCAqLwoJRFdPUkQJdWs0OwkJLyogMHgxOCAqLwoJRFdPUkQJdWs1OwkJLyogMHgxYyAqLwoJRFdPUkQJdWs2OwkJLyogMHgyMCAqLwoJRFdPUkQJUm9vdEtleUJsb2NrOwkvKiAweDI0ICovCglEV09SRAlCbG9ja1NpemU7CS8qIDB4MjggKi8KCURXT1JEICAgdWs3WzExNl07CQoJRFdPUkQJQ2hlY2tzdW07IC8qIGF0IG9mZnNldCAweDFGQyAqLwp9IG50X3JlZ2Y7Cgp0eXBlZGVmIHN0cnVjdAp7CglEV09SRAlibG9ja3NpemU7CglCWVRFCWRhdGFbMV07Cn0gbnRfaGJpbl9zdWI7Cgp0eXBlZGVmIHN0cnVjdAp7CglEV09SRAlpZDsJCS8qIDB4NkU2OTYyNjggJ2hiaW4nICovCglEV09SRAlvZmZfcHJldjsKCURXT1JECW9mZl9uZXh0OwoJRFdPUkQJdWsxOwoJRFdPUkQJdWsyOwkJLyogMHgxMCAqLwoJRFdPUkQJdWszOwkJLyogMHgxNCAqLwoJRFdPUkQJdWs0OwkJLyogMHgxOCAqLwoJRFdPUkQJc2l6ZTsJCS8qIDB4MUMgKi8KCW50X2hiaW5fc3ViCWhiaW5fc3ViOwkvKiAweDIwICovCn0gbnRfaGJpbjsKCi8qCiAqIHRoZSB2YWx1ZV9saXN0IGNvbnNpc3RzIG9mIG9mZnNldHMgdG8gdGhlIHZhbHVlcyAodmspCiAqLwp0eXBlZGVmIHN0cnVjdAp7CglXT1JECVN1YkJsb2NrSWQ7CQkvKiAweDAwIDB4NkI2RSAqLwoJV09SRAlUeXBlOwkJCS8qIDB4MDIgZm9yIHRoZSByb290LWtleTogMHgyQywgb3RoZXJ3aXNlIDB4MjAqLwoJRklMRVRJTUUJd3JpdGV0aW1lOwkvKiAweDA0ICovCglEV09SRAl1azE7CQkJLyogMHgwQyAqLwoJRFdPUkQJcGFyZW50X29mZjsJCS8qIDB4MTAgT2Zmc2V0IG9mIE93bmVyL1BhcmVudCBrZXkgKi8KCURXT1JECW5yX3N1YmtleXM7CQkvKiAweDE0IG51bWJlciBvZiBzdWItS2V5cyAqLwoJRFdPUkQJdWs4OwkJCS8qIDB4MTggKi8KCURXT1JECWxmX29mZjsJCQkvKiAweDFDIE9mZnNldCBvZiB0aGUgc3ViLWtleSBsZi1SZWNvcmRzICovCglEV09SRAl1azI7CQkJLyogMHgyMCAqLwoJRFdPUkQJbnJfdmFsdWVzOwkJLyogMHgyNCBudW1iZXIgb2YgdmFsdWVzICovCglEV09SRAl2YWx1ZWxpc3Rfb2ZmOwkJLyogMHgyOCBPZmZzZXQgb2YgdGhlIFZhbHVlLUxpc3QgKi8KCURXT1JECW9mZl9zazsJCQkvKiAweDJjIE9mZnNldCBvZiB0aGUgc2stUmVjb3JkICovCglEV09SRAlvZmZfY2xhc3M7CQkvKiAweDMwIE9mZnNldCBvZiB0aGUgQ2xhc3MtTmFtZSAqLwoJRFdPUkQJdWszOwkJCS8qIDB4MzQgKi8KCURXT1JECXVrNDsJCQkvKiAweDM4ICovCglEV09SRAl1azU7CQkJLyogMHgzYyAqLwoJRFdPUkQJdWs2OwkJCS8qIDB4NDAgKi8KCURXT1JECXVrNzsJCQkvKiAweDQ0ICovCglXT1JECW5hbWVfbGVuOwkJLyogMHg0OCBuYW1lLWxlbmd0aCAqLwoJV09SRAljbGFzc19sZW47CQkvKiAweDRhIGNsYXNzLW5hbWUgbGVuZ3RoICovCgljaGFyCW5hbWVbMV07CQkvKiAweDRjIGtleS1uYW1lICovCn0gbnRfbms7Cgp0eXBlZGVmIHN0cnVjdAp7CglEV09SRAlvZmZfbms7CS8qIDB4MDAgKi8KCURXT1JECW5hbWU7CS8qIDB4MDQgKi8KfSBoYXNoX3JlYzsKCnR5cGVkZWYgc3RydWN0CnsKCVdPUkQJaWQ7CQkvKiAweDAwIDB4NjY2YyAqLwoJV09SRAlucl9rZXlzOwkvKiAweDA2ICovCgloYXNoX3JlYwloYXNoX3JlY1sxXTsKfSBudF9sZjsKCi8qCiBsaXN0IG9mIHN1YmtleXMgd2l0aG91dCBoYXNoCgogbGkgLS0rLS0+bmsKICAgICAgfAogICAgICArLS0+bmsKICovCnR5cGVkZWYgc3RydWN0CnsKCVdPUkQJaWQ7CQkvKiAweDAwIDB4Njk2YyAqLwoJV09SRAlucl9rZXlzOwoJRFdPUkQJb2ZmX25rWzFdOwp9IG50X2xpOwoKLyoKIHRoaXMgaXMgYSBpbnRlcm1lZGlhdGUgbm9kZQoKIHJpIC0tKy0tPmxpLS0rLS0+bmsKICAgICAgfCAgICAgICArCiAgICAgIHwgICAgICAgKy0tPm5rCiAgICAgIHwKICAgICAgKy0tPmxpLS0rLS0+bmsKICAgICAgICAgICAgICArCgkgICAgICArLS0+bmsKICovCnR5cGVkZWYgc3RydWN0CnsKCVdPUkQJaWQ7CQkvKiAweDAwIDB4Njk3MiAqLwoJV09SRAlucl9saTsJCS8qIDB4MDIgbnVtYmVyIG9mZiBvZmZzZXRzICovCglEV09SRAlvZmZfbGlbMV07CS8qIDB4MDQgcG9pbnRzIHRvIGxpICovCn0gbnRfcmk7Cgp0eXBlZGVmIHN0cnVjdAp7CglXT1JECWlkOwkJLyogMHgwMCAndmsnICovCglXT1JECW5hbV9sZW47CglEV09SRAlkYXRhX2xlbjsKCURXT1JECWRhdGFfb2ZmOwoJRFdPUkQJdHlwZTsKCVdPUkQJZmxhZzsKCVdPUkQJdWsxOwoJY2hhcgluYW1lWzFdOwp9IG50X3ZrOwoKTFBTVFIgX3N0cmR1cG5BKCBMUENTVFIgc3RyLCBpbnQgbGVuICkKewogICAgTFBTVFIgcmV0OwoKICAgIGlmICghc3RyKSByZXR1cm4gTlVMTDsKICAgIHJldCA9IHhtYWxsb2MoIGxlbiArIDEgKTsKICAgIG1lbWNweSggcmV0LCBzdHIsIGxlbiApOwogICAgcmV0W2xlbl0gPSAweDAwOwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBfbnRfcGFyc2VfbmsoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgbnRfbmsgKiBuaywgaW50IGxldmVsKTsKc3RhdGljIGludCBfbnRfcGFyc2VfdmsoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgbnRfdmsgKiB2ayk7CnN0YXRpYyBpbnQgX250X3BhcnNlX2xmKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIGludCBzdWJrZXlzLCBudF9sZiAqIGxmLCBpbnQgbGV2ZWwpOwoKCi8qCiAqIGdldHMgYSB2YWx1ZQogKgogKiB2ay0+ZmxhZzoKICogIDAgdmFsdWUgaXMgYSBkZWZhdWx0IHZhbHVlCiAqICAxIHRoZSB2YWx1ZSBoYXMgYSBuYW1lCiAqCiAqIHZrLT5kYXRhX2xlbgogKiAgbGVuIG9mIHRoZSB3aG9sZSBkYXRhIGJsb2NrCiAqICAtIHJlZ19zeiAodW5pY29kZSkKICogICAgYnl0ZXMgaW5jbHVkaW5nIHRoZSB0ZXJtaW5hdGluZyBcMCA9IDIqKG51bWJlcl9vZl9jaGFycysxKQogKiAgLSByZWdfZHdvcmQsIHJlZ19iaW5hcnk6CiAqICAgIGlmIGhpZ2hlc3QgYml0IG9mIGRhdGFfbGVuIGlzIHNldCBkYXRhX29mZiBjb250YWlucyB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQgX250X3BhcnNlX3ZrKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIG50X3ZrICogdmspCnsKCVdDSEFSIG5hbWUgWzI1Nl07CglEV09SRCBsZW4sIHJldDsKCUJZVEUgKiBwZGF0YSA9IChCWVRFICopKGJhc2UrdmstPmRhdGFfb2ZmKzQpOyAvKiBzdGFydCBvZiBkYXRhICovCgoJaWYodmstPmlkICE9IE5UX1JFR19WQUxVRV9CTE9DS19JRCkgZ290byBlcnJvcjsKCiAgICAgICAgaWYgKCEobGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfQUNQLCAwLCB2ay0+bmFtZSwgdmstPm5hbV9sZW4sIG5hbWUsIDI1NiApKSAmJiB2ay0+bmFtX2xlbikKICAgICAgICB7CiAgICAgICAgICAgIEVSUigibmFtZSB0b28gbGFyZ2UgJyUuKnMnICglZClcbiIsIHZrLT5uYW1fbGVuLCB2ay0+bmFtZSwgdmstPm5hbV9sZW4gKTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgICAgICBuYW1lW2xlbl0gPSAwOwoKCXJldCA9IFJlZ1NldFZhbHVlRXhXKCBoa2V5LCAodmstPmZsYWcgJiAweDAwMDAwMDAxKSA/IG5hbWUgOiBOVUxMLCAwLCB2ay0+dHlwZSwKCQkJKHZrLT5kYXRhX2xlbiAmIDB4ODAwMDAwMDApID8gKExQQllURSkmKHZrLT5kYXRhX29mZik6IHBkYXRhLAoJCQkodmstPmRhdGFfbGVuICYgMHg3ZmZmZmZmZikgKTsKCWlmIChyZXQpIEVSUigiUmVnU2V0VmFsdWVFeCBmYWlsZWQgKDB4JTA4bHgpXG4iLCByZXQpOwoJcmV0dXJuIFRSVUU7CmVycm9yOgoJRVJSKCJ1bmtub3duIGJsb2NrIGZvdW5kICgweCUwNHgpLCBwbGVhc2UgcmVwb3J0IVxuIiwgdmstPmlkKTsKCXJldHVybiBGQUxTRTsKfQoKLyoKICogZ2V0IHRoZSBzdWJrZXlzCiAqCiAqIHRoaXMgc3RydWN0dXJlIGNvbnRhaW5zIHRoZSBoYXNoIG9mIGEga2V5bmFtZSBhbmQgcG9pbnRzIHRvIGFsbAogKiBzdWJrZXlzCiAqCiAqIGV4Y2VwdGlvbjogaWYgdGhlIGlkIGlzICdpbCcgdGhlcmUgYXJlIG5vIGhhc2ggdmFsdWVzIGFuZCBldmVyeSAKICogZHdvcmQgaXMgYSBvZmZzZXQKICovCnN0YXRpYyBpbnQgX250X3BhcnNlX2xmKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIGludCBzdWJrZXlzLCBudF9sZiAqIGxmLCBpbnQgbGV2ZWwpCnsKCWludCBpOwoKCWlmIChsZi0+aWQgPT0gTlRfUkVHX0hBU0hfQkxPQ0tfSUQpCgl7CgkgIGlmIChzdWJrZXlzICE9IGxmLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCgkgIGZvciAoaT0wOyBpPGxmLT5ucl9rZXlzOyBpKyspCgkgIHsKCSAgICBpZiAoIV9udF9wYXJzZV9uayhoa2V5LCBiYXNlLCAobnRfbmsqKShiYXNlK2xmLT5oYXNoX3JlY1tpXS5vZmZfbmsrNCksIGxldmVsKSkgZ290byBlcnJvcjsKCSAgfQoJfQoJZWxzZSBpZiAobGYtPmlkID09IE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQpCgl7CgkgIG50X2xpICogbGkgPSAobnRfbGkqKWxmOwoJICBpZiAoc3Via2V5cyAhPSBsaS0+bnJfa2V5cykgZ290byBlcnJvcjE7CgoJICBmb3IgKGk9MDsgaTxsaS0+bnJfa2V5czsgaSsrKQoJICB7CgkgICAgaWYgKCFfbnRfcGFyc2VfbmsoaGtleSwgYmFzZSwgKG50X25rKikoYmFzZStsaS0+b2ZmX25rW2ldKzQpLCBsZXZlbCkpIGdvdG8gZXJyb3I7CgkgIH0KCX0KCWVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfUklfQkxPQ0tfSUQpIC8qIHJpICovCgl7CgkgIG50X3JpICogcmkgPSAobnRfcmkqKWxmOwoJICBpbnQgbGlfc3Via2V5cyA9IDA7CgoJICAvKiBjb3VudCBhbGwgc3Via2V5cyAqLwoJICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykKCSAgewoJICAgIG50X2xpICogbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CgkgICAgaWYobGktPmlkICE9IE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQpIGdvdG8gZXJyb3IyOwoJICAgIGxpX3N1YmtleXMgKz0gbGktPm5yX2tleXM7CgkgIH0KCgkgIC8qIGNoZWNrIG51bWJlciAqLwoJICBpZiAoc3Via2V5cyAhPSBsaV9zdWJrZXlzKSBnb3RvIGVycm9yMTsKCgkgIC8qIGxvb3AgdGhyb3VnaCB0aGUga2V5cyAqLwoJICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykKCSAgewoJICAgIG50X2xpICogbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CgkgICAgaWYgKCFfbnRfcGFyc2VfbGYoaGtleSwgYmFzZSwgbGktPm5yX2tleXMsIChudF9sZiopbGksIGxldmVsKSkgZ290byBlcnJvcjsKCSAgfQoJfQoJZWxzZSAKCXsKCSAgZ290byBlcnJvcjI7Cgl9CglyZXR1cm4gVFJVRTsKCmVycm9yMjogRVJSKCJ1bmtub3duIG5vZGUgaWQgMHglMDR4LCBwbGVhc2UgcmVwb3J0IVxuIiwgbGYtPmlkKTsKCXJldHVybiBUUlVFOwoJCmVycm9yMToJRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIChpbmNvbnNpc3RlbnQgbnVtYmVyIG9mIHN1YmtleXMpXG4iKTsKCXJldHVybiBGQUxTRTsKCmVycm9yOglFUlIoImVycm9yIHJlYWRpbmcgbGYgYmxvY2tcbiIpOwoJcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgaW50IF9udF9wYXJzZV9uayhIS0VZIGhrZXksIGNoYXIgKiBiYXNlLCBudF9uayAqIG5rLCBpbnQgbGV2ZWwpCnsKCWNoYXIgKiBuYW1lOwoJdW5zaWduZWQgaW50IG47CglEV09SRCAqIHZsOwoJSEtFWSBzdWJrZXkgPSBoa2V5OwoKCWlmKG5rLT5TdWJCbG9ja0lkICE9IE5UX1JFR19LRVlfQkxPQ0tfSUQpCgl7CgkgIEVSUigidW5rbm93biBub2RlIGlkIDB4JTA0eCwgcGxlYXNlIHJlcG9ydCFcbiIsIG5rLT5TdWJCbG9ja0lkKTsKCSAgZ290byBlcnJvcjsKCX0KCglpZigobmstPlR5cGUhPU5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKSAmJgoJICAgKCgobnRfbmsqKShiYXNlK25rLT5wYXJlbnRfb2ZmKzQpKS0+U3ViQmxvY2tJZCAhPSBOVF9SRUdfS0VZX0JMT0NLX0lEKSkKCXsKCSAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhXG4iKTsKCSAgZ290byBlcnJvcjsKCX0KCgkvKiBjcmVhdGUgdGhlIG5ldyBrZXkgKi8KCWlmKGxldmVsIDw9IDApCgl7CgkgIG5hbWUgPSBfc3RyZHVwbkEoIG5rLT5uYW1lLCBuay0+bmFtZV9sZW4pOwoJICBpZihSZWdDcmVhdGVLZXlBKCBoa2V5LCBuYW1lLCAmc3Via2V5ICkpIHsgZnJlZShuYW1lKTsgZ290byBlcnJvcjsgfQoJICBmcmVlKG5hbWUpOwoJfQoKCS8qIGxvb3AgdGhyb3VnaCB0aGUgc3Via2V5cyAqLwoJaWYgKG5rLT5ucl9zdWJrZXlzKQoJewoJICBudF9sZiAqIGxmID0gKG50X2xmKikoYmFzZStuay0+bGZfb2ZmKzQpOwoJICBpZiAoIV9udF9wYXJzZV9sZihzdWJrZXksIGJhc2UsIG5rLT5ucl9zdWJrZXlzLCBsZiwgbGV2ZWwtMSkpIGdvdG8gZXJyb3IxOwoJfQoKCS8qIGxvb3AgdHJvdWdoIHRoZSB2YWx1ZSBsaXN0ICovCgl2bCA9IChEV09SRCAqKShiYXNlK25rLT52YWx1ZWxpc3Rfb2ZmKzQpOwoJZm9yIChuPTA7IG48bmstPm5yX3ZhbHVlczsgbisrKQoJewoJICBudF92ayAqIHZrID0gKG50X3ZrKikoYmFzZSt2bFtuXSs0KTsKCSAgaWYgKCFfbnRfcGFyc2Vfdmsoc3Via2V5LCBiYXNlLCB2aykpIGdvdG8gZXJyb3IxOwoJfQoKCS8qIERvbid0IGNsb3NlIHRoZSBzdWJrZXkgaWYgaXQgaXMgdGhlIGhrZXkgdGhhdCB3YXMgcGFzc2VkCgkgKiAoaS5lLiBMZXZlbCB3YXMgPD0gMCkKCSAqLwoJaWYoIHN1YmtleSE9aGtleSApIFJlZ0Nsb3NlS2V5KHN1YmtleSk7CglyZXR1cm4gVFJVRTsKCQplcnJvcjE6CVJlZ0Nsb3NlS2V5KHN1YmtleSk7CmVycm9yOglyZXR1cm4gRkFMU0U7Cn0KCi8qIGVuZCBudCBsb2FkZXIgKi8KCi8qIHdpbmRvd3MgOTUgcmVnaXN0cnkgbG9hZGVyICovCgovKiBTRUNUSU9OIDE6IG1haW4gaGVhZGVyCiAqCiAqIG9uY2UgYXQgb2Zmc2V0IDAKICovCiNkZWZpbmUJVzk1X1JFR19DUkVHX0lECTB4NDc0NTUyNDMKCnR5cGVkZWYgc3RydWN0IAp7CglEV09SRAlpZDsJCS8qICJDUkVHIiA9IFc5NV9SRUdfQ1JFR19JRCAqLwoJRFdPUkQJdmVyc2lvbjsJLyogPz8/PyAweDAwMDEwMDAwICovCglEV09SRAlyZ2RiX29mZjsJLyogMHgwOCBPZmZzZXQgb2YgMXN0IFJHREItYmxvY2sgKi8KCURXT1JECXVrMjsJCS8qIDB4MGMgKi8KCVdPUkQJcmdkYl9udW07CS8qIDB4MTAgIyBvZiBSR0RCLWJsb2NrcyAqLwoJV09SRAl1azM7CglEV09SRAl1a1szXTsKCS8qIHJna24gKi8KfSBfdzk1Y3JlZzsKCi8qIFNFQ1RJT04gMjogRGlyZWN0b3J5IGluZm9ybWF0aW9uICh0cmVlIHN0cnVjdHVyZSkKICoKICogb25jZSBvbiBvZmZzZXQgMHgyMAogKgogKiBzdHJ1Y3R1cmU6IFtyZ2tuXVtka2VdKgkocmVwZWF0IHRpbGwgbGFzdF9ka2UgaXMgcmVhY2hlZCkKICovCiNkZWZpbmUJVzk1X1JFR19SR0tOX0lECTB4NGU0YjQ3NTIKCnR5cGVkZWYgc3RydWN0CnsKCURXT1JECWlkOwkJLyoiUkdLTiIgPSBXOTVfUkVHX1JHS05fSUQgKi8KCURXT1JECXNpemU7CQkvKiBTaXplIG9mIHRoZSBSR0tOLWJsb2NrICovCglEV09SRAlyb290X29mZjsJLyogUmVsLiBPZmZzZXQgb2YgdGhlIHJvb3QtcmVjb3JkICovCglEV09SRCAgIGxhc3RfZGtlOyAgICAgICAvKiBPZmZzZXQgdG8gbGFzdCBES0UgPyAqLwoJRFdPUkQJdWtbNF07Cn0gX3c5NXJna247CgovKiBEaXNrIEtleSBFbnRyeSBTdHJ1Y3R1cmUKICoKICogdGhlIDFzdCBlbnRyeSBpbiBhICJ1c3VhbCIgcmVnaXN0cnkgZmlsZSBpcyBhIG51bC1lbnRyeSB3aXRoIHN1YmtleXM6IHRoZQogKiBoaXZlIGl0c2VsZi4gSXQgbG9va3MgdGhlIHNhbWUgbGlrZSBvdGhlciBrZXlzLiBFdmVuIHRoZSBJRC1udW1iZXIgY2FuCiAqIGJlIGFueSB2YWx1ZS4KICoKICogVGhlICJoYXNoIi12YWx1ZSBpcyBhIHZhbHVlIHJlcHJlc2VudGluZyB0aGUga2V5J3MgbmFtZS4gV2luZG93cyB3aWxsIG5vdAogKiBzZWFyY2ggZm9yIHRoZSBuYW1lLCBidXQgZm9yIGEgbWF0Y2hpbmcgaGFzaC12YWx1ZS4gaWYgaXQgZmluZHMgb25lLCBpdAogKiB3aWxsIGNvbXBhcmUgdGhlIGFjdHVhbCBzdHJpbmcgaW5mbywgb3RoZXJ3aXNlIGNvbnRpbnVlIHdpdGggdGhlIG5leHQga2V5LgogKiBUbyBjYWxjdWxhdGUgdGhlIGhhc2ggaW5pdGlhbGl6ZSBhIEQtV29yZCB3aXRoIDAgYW5kIGFkZCBhbGwgQVNDSUktdmFsdWVzIAogKiBvZiB0aGUgc3RyaW5nIHdoaWNoIGFyZSBzbWFsbGVyIHRoYW4gMHg4MCAoMTI4KSB0byB0aGlzIEQtV29yZC4gICAKICoKICogSWYgeW91IHdhbnQgdG8gbW9kaWZ5IGtleSBuYW1lcywgYWxzbyBtb2RpZnkgdGhlIGhhc2gtdmFsdWVzLCBzaW5jZSB0aGV5CiAqIGNhbm5vdCBiZSBmb3VuZCBhZ2FpbiAoYWx0aG91Z2ggdGhleSB3b3VsZCBiZSBkaXNwbGF5ZWQgaW4gUkVHRURJVCkKICogRW5kIG9mIGxpc3QtcG9pbnRlcnMgYXJlIGZpbGxlZCB3aXRoIDB4RkZGRkZGRkYKICoKICogRGlzayBrZXlzIGFyZSBsYXllZCBvdXQgZmxhdCAuLi4gQnV0LCBzb21ldGltZXMsIG5yTFMgYW5kIG5yTVMgYXJlIGJvdGgKICogMHhGRkZGLCB3aGljaCBtZWFucyBza2lwcGluZyBvdmVyIG5leHRrZXlvZmZzZXQgYnl0ZXMgKGluY2x1ZGluZyB0aGlzCiAqIHN0cnVjdHVyZSkgYW5kIHJlYWRpbmcgYW5vdGhlciBSR0RCX3NlY3Rpb24uCiAqCiAqIFRoZSBsYXN0IERLRSAoc2VlIGZpZWxkIGxhc3RfZGtlIGluIF93OTVfcmdrbikgaGFzIG9ubHkgMyBEV09SRHMgd2l0aAogKiAweDgwMDAwMDAwIChFT0wgaW5kaWNhdG9yID8pIGFzIHgxLCB0aGUgaGFzaCB2YWx1ZSBhbmQgMHhGRkZGRkZGRiBhcyB4My4KICogVGhlIHJlbWFpbmluZyBzcGFjZSBiZXR3ZWVuIGxhc3RfZGtlIGFuZCB0aGUgb2Zmc2V0IGNhbGN1bGF0ZWQgZnJvbQogKiByZ2tuLT5zaXplIHNlZW1zIHRvIGJlIGZyZWUgZm9yIHVzZSBmb3IgbW9yZSBka2U6cy4KICogU28gaXQgc2VlbXMgaWYgbW9yZSBka2U6cyBhcmUgYWRkZWQsIHRoZXkgYXJlIGFkZGVkIHRvIHRoYXQgc3BhY2UgYW5kCiAqIGxhc3RfZGtlIGlzIGdyb3duLCBhbmQgaW4gY2FzZSB0aGF0ICJmcmVlIiBzcGFjZSBpcyBvdXQsIHRoZSBzcGFjZQogKiBnZXRzIGdyb3duIGFuZCByZ2tuLT5zaXplIGdldHMgYWRqdXN0ZWQuCiAqCiAqIHRoZXJlIGlzIGEgb25lIHRvIG9uZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBka2UgYW5kIGRraAogKi8KIC8qIGtleSBzdHJ1Y3QsIG9uY2UgcGVyIGtleSAqLwp0eXBlZGVmIHN0cnVjdAp7CglEV09SRAl4MTsJCS8qIEZyZWUgZW50cnkgaW5kaWNhdG9yKD8pICovCglEV09SRAloYXNoOwkJLyogc3VtIG9mIGJ5dGVzIG9mIGtleW5hbWUgKi8KCURXT1JECXgzOwkJLyogUm9vdCBrZXkgaW5kaWNhdG9yPyB1c3VhbGx5IDB4RkZGRkZGRkYgKi8KCURXT1JECXByZXZsdmw7CS8qIG9mZnNldCBvZiBwcmV2aW91cyBrZXkgKi8KCURXT1JECW5leHRzdWI7CS8qIG9mZnNldCBvZiBjaGlsZCBrZXkgKi8KCURXT1JECW5leHQ7CQkvKiBvZmZzZXQgb2Ygc2libGluZyBrZXkgKi8KCVdPUkQJbnJMUzsJCS8qIGlkIGluc2lkZSB0aGUgcmdkYiBibG9jayAqLwoJV09SRAluck1TOwkJLyogbnVtYmVyIG9mIHRoZSByZ2RiIGJsb2NrICovCn0gX3c5NWRrZTsKCi8qIFNFQ1RJT04gMzoga2V5IGluZm9ybWF0aW9uLCB2YWx1ZXMgYW5kIGRhdGEKICoKICogc3RydWN0dXJlOgogKiAgc2VjdGlvbjoJW2Jsb2Nrc10qCQkocmVwZWF0IGNyZWctPnJnZGJfbnVtIHRpbWVzKQogKiAgYmxvY2tzOglbcmdkYl0gW3N1YmJsb2Nrc10qIAkocmVwZWF0IHRpbGwgYmxvY2sgc2l6ZSByZWFjaGVkICkKICogIHN1YmJsb2NrczoJW2RraF0gW2Rrdl0qCQkocmVwZWF0IGRraC0+dmFsdWVzIHRpbWVzICkKICoKICogQW4gaW50ZXJlc3RpbmcgcmVsYXRpb25zaGlwIGV4aXN0cyBpbiBSR0RCX3NlY3Rpb24uIFRoZSBEV09SRCB2YWx1ZQogKiBhdCBvZmZzZXQgMHgxMCBlcXVhbHMgdGhlIG9uZSBhdCBvZmZzZXQgMHgwNCBtaW51cyB0aGUgb25lIGF0IG9mZnNldCAweDA4LgogKiBJIGhhdmUgbm8gaWRlYSBhdCB0aGUgbW9tZW50IHdoYXQgdGhpcyBtZWFucy4gIChLZXZpbiBDb3plbnMpCiAqLwoKLyogYmxvY2sgaGVhZGVyLCBvbmNlIHBlciBibG9jayAqLwojZGVmaW5lIFc5NV9SRUdfUkdEQl9JRAkweDQyNDQ0NzUyCgp0eXBlZGVmIHN0cnVjdAp7CglEV09SRAlpZDsJLyogMHgwMCAnUkdEQicgPSBXOTVfUkVHX1JHREJfSUQgKi8KCURXT1JECXNpemU7CS8qIDB4MDQgKi8KCURXT1JECXVrMTsJLyogMHgwOCAqLwoJRFdPUkQJdWsyOwkvKiAweDBjICovCglEV09SRAl1azM7CS8qIDB4MTAgKi8KCURXT1JECXVrNDsJLyogMHgxNCAqLwoJRFdPUkQJdWs1OwkvKiAweDE4ICovCglEV09SRAl1azY7CS8qIDB4MWMgKi8KCS8qIGRraCAqLwp9IF93OTVyZ2RiOwoKLyogRGlzayBLZXkgSGVhZGVyIHN0cnVjdHVyZSAoUkdEQiBwYXJ0KSwgb25jZSBwZXIga2V5ICovCnR5cGVkZWYJc3RydWN0IAp7CglEV09SRAluZXh0a2V5b2ZmOyAJLyogMHgwMCBvZmZzZXQgdG8gbmV4dCBka2ggKi8KCVdPUkQJbnJMUzsJCS8qIDB4MDQgaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCglXT1JECW5yTVM7CQkvKiAweDA2IG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwoJRFdPUkQJYnl0ZXN1c2VkOwkvKiAweDA4ICovCglXT1JECWtleW5hbWVsZW47CS8qIDB4MGMgbGVuIG9mIG5hbWUgKi8KCVdPUkQJdmFsdWVzOwkJLyogMHgwZSBudW1iZXIgb2YgdmFsdWVzICovCglEV09SRAl4eDE7CQkvKiAweDEwICovCgljaGFyCW5hbWVbMV07CS8qIDB4MTQgKi8KCS8qIGRrdiAqLwkJLyogMHgxNCArIGtleW5hbWVsZW4gKi8KfSBfdzk1ZGtoOwoKLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlLCBvbmNlIHBlciB2YWx1ZSAqLwp0eXBlZGVmCXN0cnVjdAp7CglEV09SRAl0eXBlOwkJLyogMHgwMCAqLwoJRFdPUkQJeDE7CQkvKiAweDA0ICovCglXT1JECXZhbG5hbWVsZW47CS8qIDB4MDggbGVuZ3RoIG9mIG5hbWUsIDAgaXMgZGVmYXVsdCBrZXkgKi8KCVdPUkQJdmFsZGF0YWxlbjsJLyogMHgwQSBsZW5ndGggb2YgZGF0YSAqLwoJY2hhcgluYW1lWzFdOwkvKiAweDBjICovCgkvKiByYXcgZGF0YSAqLwkJLyogMHgwYyArIHZhbG5hbWVsZW4gKi8KfSBfdzk1ZGt2OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvb2t1cF9ka2ggW0ludGVybmFsXQogKgogKiBzZWVrcyB0aGUgZGtoIGJlbG9uZ2luZyB0byBhIGRrZQogKi8Kc3RhdGljIF93OTVka2ggKiBfdzk1X2xvb2t1cF9ka2ggKF93OTVjcmVnICpjcmVnLCBpbnQgbnJMUywgaW50IG5yTVMpCnsKCV93OTVyZ2RiICogcmdkYjsKCV93OTVka2ggKiBka2g7CglpbnQgaTsKCQoJLyogZ2V0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHJnZGIgZGF0YXN0b3JlICovCglyZ2RiID0gKF93OTVyZ2RiKikoKGNoYXIqKWNyZWcrY3JlZy0+cmdkYl9vZmYpOwoKCS8qIGNoZWNrOiByZXF1ZXN0ZWQgYmxvY2sgPCBsYXN0X2Jsb2NrKSAqLwoJaWYgKGNyZWctPnJnZGJfbnVtIDw9IG5yTVMpCQkJCQoJewoJICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgcmVxdWVzdGVkIGJsb2NrIG5vLiBiZXlvbmQgZW5kLlxuIik7CgkgIGdvdG8gZXJyb3I7Cgl9CgkKCS8qIGZpbmQgdGhlIHJpZ2h0IGJsb2NrICovCglmb3IoaT0wOyBpPG5yTVMgO2krKykKCXsKCSAgaWYocmdkYi0+aWQgIT0gVzk1X1JFR19SR0RCX0lEKQkJCS8qIGNoZWNrIHRoZSBtYWdpYyAqLwoJICB7CgkgICAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIGJhZCBtYWdpYyAweCUwOGx4XG4iLCByZ2RiLT5pZCk7CgkgICAgZ290byBlcnJvcjsKCSAgfQoJICByZ2RiID0gKF93OTVyZ2RiKikgKChjaGFyKilyZ2RiK3JnZGItPnNpemUpOwkJLyogZmluZCBuZXh0IGJsb2NrICovCgl9CgoJZGtoID0gKF93OTVka2gqKShyZ2RiICsgMSk7CQkJCS8qIGZpcnN0IHN1YiBibG9jayB3aXRoaW4gdGhlIHJnZGIgKi8KCglkbwoJewoJICBpZihuckxTPT1ka2gtPm5yTFMgKSByZXR1cm4gZGtoOwoJICBka2ggPSAoX3c5NWRraCopKChjaGFyKilka2ggKyBka2gtPm5leHRrZXlvZmYpOwkvKiBmaW5kIG5leHQgc3ViYmxvY2sgKi8KCX0gd2hpbGUgKChjaGFyICopZGtoIDwgKChjaGFyKilyZ2RiK3JnZGItPnNpemUpKTsKCmVycm9yOglyZXR1cm4gTlVMTDsKfQkKIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfcGFyc2VfZGt2IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9wYXJzZV9ka3YgKAoJSEtFWSBoa2V5LAoJX3c5NWRraCAqIGRraCwKCWludCBuckxTLAoJaW50IG5yTVMgKQp7Cglfdzk1ZGt2ICogZGt2OwoJaW50IGk7CglEV09SRCByZXQ7CgljaGFyICogbmFtZTsKCQkJCgkvKiBmaXJzdCB2YWx1ZSBibG9jayAqLwoJZGt2ID0gKF93OTVka3YqKSgoY2hhciopZGtoK2RraC0+a2V5bmFtZWxlbisweDE0KTsKCgkvKiBsb29wIHRyb3VnaHQgdGhlIHZhbHVlcyAqLwoJZm9yIChpPTA7IGk8IGRraC0+dmFsdWVzOyBpKyspCgl7CgkgIG5hbWUgPSBfc3RyZHVwbkEoZGt2LT5uYW1lLCBka3YtPnZhbG5hbWVsZW4pOwoJICByZXQgPSBSZWdTZXRWYWx1ZUV4QShoa2V5LCBuYW1lLCAwLCBka3YtPnR5cGUsICYoZGt2LT5uYW1lW2Rrdi0+dmFsbmFtZWxlbl0pLGRrdi0+dmFsZGF0YWxlbik7IAoJICBpZiAocmV0KSBGSVhNRSgiUmVnU2V0VmFsdWVFeCByZXR1cm5lZDogMHglMDhseFxuIiwgcmV0KTsKCSAgZnJlZSAobmFtZSk7CgoJICAvKiBuZXh0IHZhbHVlICovCgkgIGRrdiA9IChfdzk1ZGt2KikoKGNoYXIqKWRrditka3YtPnZhbG5hbWVsZW4rZGt2LT52YWxkYXRhbGVuKzB4MGMpOwoJfQoJcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9wYXJzZV9ka2UgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfdzk1X3BhcnNlX2RrZSggCglIS0VZIGhrZXksCglfdzk1Y3JlZyAqIGNyZWcsCglfdzk1cmdrbiAqcmdrbiwKCV93OTVka2UgKiBka2UsCglpbnQgbGV2ZWwgKQp7Cglfdzk1ZGtoICogZGtoOwoJSEtFWSBoc3Via2V5ID0gaGtleTsKCWNoYXIgKiBuYW1lOwoJaW50IHJldCA9IEZBTFNFOwoKCS8qIHNwZWNpYWwgcm9vdCBrZXkgKi8KCWlmIChka2UtPm5yTFMgPT0gMHhmZmZmIHx8IGRrZS0+bnJNUz09MHhmZmZmKQkJLyogZWcuIHRoZSByb290IGtleSBoYXMgbm8gbmFtZSAqLwoJewoJICAvKiBwYXJzZSB0aGUgb25lIHN1YmtleSAqLwoJICBpZiAoZGtlLT5uZXh0c3ViICE9IDB4ZmZmZmZmZmYpIAoJICB7CiAgICAJICAgIHJldHVybiBfdzk1X3BhcnNlX2RrZShoc3Via2V5LCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dHN1YiksIGxldmVsKTsKCSAgfQoJICAvKiBoYXMgbm8gc2libGluZyBrZXlzICovCgkgIGdvdG8gZXJyb3I7Cgl9CgoJLyogc2VhcmNoIHN1YmJsb2NrICovCglpZiAoIShka2ggPSBfdzk1X2xvb2t1cF9ka2goY3JlZywgZGtlLT5uckxTLCBka2UtPm5yTVMpKSkKCXsKCSAgZnByaW50ZihzdGRlcnIsICJka2UgcG9pbnRpbmcgdG8gbWlzc2luZyBka2ggIVxuIik7CgkgIGdvdG8gZXJyb3I7Cgl9CgoJaWYgKCBsZXZlbCA8PSAwICkKCXsKCSAgLyogd2FsayBzaWJsaW5nIGtleXMgKi8KCSAgaWYgKGRrZS0+bmV4dCAhPSAweGZmZmZmZmZmICkKCSAgewogICAgCSAgICBpZiAoIV93OTVfcGFyc2VfZGtlKGhrZXksIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0KSwgbGV2ZWwpKSBnb3RvIGVycm9yOwoJICB9CgoJICAvKiBjcmVhdGUgc3Via2V5IGFuZCBpbnNlcnQgdmFsdWVzICovCgkgIG5hbWUgPSBfc3RyZHVwbkEoIGRraC0+bmFtZSwgZGtoLT5rZXluYW1lbGVuKTsKCSAgaWYgKFJlZ0NyZWF0ZUtleUEoaGtleSwgbmFtZSwgJmhzdWJrZXkpKSB7IGZyZWUobmFtZSk7IGdvdG8gZXJyb3I7IH0KCSAgZnJlZShuYW1lKTsKCSAgaWYgKCFfdzk1X3BhcnNlX2Rrdihoc3Via2V5LCBka2gsIGRrZS0+bnJMUywgZGtlLT5uck1TKSkgZ290byBlcnJvcjE7Cgl9ICAKCQogCS8qIG5leHQgc3ViIGtleSAqLwoJaWYgKGRrZS0+bmV4dHN1YiAhPSAweGZmZmZmZmZmKSAKCXsKICAgIAkgIGlmICghX3c5NV9wYXJzZV9ka2UoaHN1YmtleSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHRzdWIpLCBsZXZlbC0xKSkgZ290byBlcnJvcjE7Cgl9CgoJcmV0ID0gVFJVRTsKZXJyb3IxOglpZiAoaHN1YmtleSAhPSBoa2V5KSBSZWdDbG9zZUtleShoc3Via2V5KTsKZXJyb3I6CXJldHVybiByZXQ7Cn0KLyogZW5kIHdpbmRvd3MgOTUgbG9hZGVyICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCU5hdGl2ZVJlZ0xvYWRLZXkgW0ludGVybmFsXQogKgogKiBMb2FkcyBhIG5hdGl2ZSByZWdpc3RyeSBmaWxlICh3aW45NS9udCkKICogCWhrZXkJcm9vdCBrZXkKICoJZm4JZmlsZW5hbWUKICoJbGV2ZWwJbnVtYmVyIG9mIGxldmVscyB0byBjdXQgYXdheSAoZWcuICIuRGVmYXVsdCIgaW4gdXNlci5kYXQpCiAqCiAqIHRoaXMgZnVuY3Rpb24gaW50ZW50aW9uYWxseSB1c2VzIHVuaXggZmlsZSBmdW5jdGlvbnMgdG8gbWFrZSBpdCBwb3NzaWJsZQogKiB0byBtb3ZlIGl0IHRvIGEgc2VwZXJhdGUgcmVnaXN0cnkgaGVscGVyIHByb2dyYW1tCiAqLwpzdGF0aWMgaW50IE5hdGl2ZVJlZ0xvYWRLZXkoIEhLRVkgaGtleSwgY2hhciogZm4sIGludCBsZXZlbCApCnsKCWludCBmZCA9IDA7CglzdHJ1Y3Qgc3RhdCBzdDsKICAgICAgICBET1NfRlVMTF9OQU1FIGZ1bGxfbmFtZTsKCWludCByZXQgPSBGQUxTRTsKCXZvaWQgKiBiYXNlOwoJY2hhciAqZmlsZXR5cGUgPSAidW5rbm93biI7CgkJCQogICAgICAgIGlmICghRE9TRlNfR2V0RnVsbE5hbWUoIGZuLCAwLCAmZnVsbF9uYW1lICkpIHJldHVybiBGQUxTRTsKCQoJLyogbWFwIHRoZSByZWdpc3RyeSBpbnRvIHRoZSBtZW1vcnkgKi8KCWlmICgoZmQgPSBvcGVuKGZ1bGxfbmFtZS5sb25nX25hbWUsIE9fUkRPTkxZIHwgT19OT05CTE9DSykpID09IC0xKSByZXR1cm4gRkFMU0U7CglpZiAoKGZzdGF0KGZkLCAmc3QpID09IC0xKSkgZ290byBlcnJvcjsKCWlmICghc3Quc3Rfc2l6ZSkgZ290byBlcnJvcjsKCWlmICgoYmFzZSA9IG1tYXAoTlVMTCwgc3Quc3Rfc2l6ZSwgUFJPVF9SRUFELCBNQVBfUFJJVkFURSwgZmQsIDApKSA9PSBNQVBfRkFJTEVEKSBnb3RvIGVycm9yOwoKCXN3aXRjaCAoKihMUERXT1JEKWJhc2UpCgl7CgkgIC8qIHdpbmRvd3MgOTUgJ0NSRUcnICovCgkgIGNhc2UgVzk1X1JFR19DUkVHX0lEOgoJICAgIHsKCSAgICAgIF93OTVjcmVnICpjcmVnOwoJICAgICAgX3c5NXJna24gKnJna247CgkgICAgICBfdzk1ZGtlICpka2UsICpyb290X2RrZTsKCSAgICAgIGNyZWcgPSBiYXNlOwoJICAgICAgZmlsZXR5cGUgPSAid2luOTUiOwoJICAgICAgVFJBQ0UoIkxvYWRpbmcgJXMgcmVnaXN0cnkgJyVzJyAnJXMnXG4iLCBmaWxldHlwZSwgZm4sIGZ1bGxfbmFtZS5sb25nX25hbWUpOwoKCSAgICAgIC8qIGxvYWQgdGhlIGhlYWRlciAocmdrbikgKi8KCSAgICAgIHJna24gPSAoX3c5NXJna24qKShjcmVnICsgMSk7CgkgICAgICBpZiAocmdrbi0+aWQgIT0gVzk1X1JFR19SR0tOX0lEKSAKCSAgICAgIHsKCQlFUlIoInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJWx4XG4iLCByZ2tuLT5pZCk7CgkJZ290byBlcnJvcjE7CgkgICAgICB9CgkgICAgICBpZiAocmdrbi0+cm9vdF9vZmYgIT0gMHgyMCkKCSAgICAgIHsKCQlFUlIoInJna24tPnJvb3Rfb2ZmIG5vdCAweDIwLCBwbGVhc2UgcmVwb3J0ICFcbiIpOwoJCWdvdG8gZXJyb3IxOwoJICAgICAgfQoJICAgICAgaWYgKHJna24tPmxhc3RfZGtlID4gcmdrbi0+c2l6ZSkKCSAgICAgIHsKCQlFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgbGFzdF9ka2UgPiBzaXplIVxuIik7CgkJZ290byBlcnJvcjE7CgkgICAgICB9CgkgICAgICAvKiB2ZXJpZnkgbGFzdCBka2UgKi8KCSAgICAgIGRrZSA9IChfdzk1ZGtlKikoKGNoYXIqKXJna24gKyByZ2tuLT5sYXN0X2RrZSk7CgkgICAgICBpZiAoZGtlLT54MSAhPSAweDgwMDAwMDAwKQoJICAgICAgeyAvKiB3cm9uZyBtYWdpYyAqLwoJCUVSUigibGFzdCBka2UgaW52YWxpZCAhXG4iKTsKCQlnb3RvIGVycm9yMTsKCSAgICAgIH0KCSAgICAgIGlmIChyZ2tuLT5zaXplID4gY3JlZy0+cmdkYl9vZmYpCgkgICAgICB7CgkJRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIHJna24gc2l6ZSA+IHJnZGJfb2ZmICFcbiIpOwoJCWdvdG8gZXJyb3IxOwoJICAgICAgfQoJICAgICAgcm9vdF9ka2UgPSAoX3c5NWRrZSopKChjaGFyKilyZ2tuICsgcmdrbi0+cm9vdF9vZmYpOwoJICAgICAgaWYgKCAocm9vdF9ka2UtPnByZXZsdmwgIT0gMHhmZmZmZmZmZikKCSAgICAgICAgfHwgKHJvb3RfZGtlLT5uZXh0ICE9IDB4ZmZmZmZmZmYpICkKCSAgICAgIHsKCQlFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgaW52YWxpZCByb290IGRrZSAhXG4iKTsKCQlnb3RvIGVycm9yMTsKCSAgICAgIH0KCgkgICAgICByZXQgPSBfdzk1X3BhcnNlX2RrZShoa2V5LCBjcmVnLCByZ2tuLCByb290X2RrZSwgbGV2ZWwpOwoJICAgIH0KCSAgICBicmVhazsKCSAgLyogbnQgJ3JlZ2YnKi8KCSAgY2FzZSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEOgoJICAgIHsKCSAgICAgIG50X3JlZ2YgKiByZWdmOwoJICAgICAgbnRfaGJpbiAqIGhiaW47CgkgICAgICBudF9oYmluX3N1YiAqIGhiaW5fc3ViOwoJICAgICAgbnRfbmsqIG5rOwoKCSAgICAgIGZpbGV0eXBlID0gIk5UIjsKCSAgICAgIFRSQUNFKCJMb2FkaW5nICVzIHJlZ2lzdHJ5ICclcycgJyVzJ1xuIiwgZmlsZXR5cGUsIGZuLCBmdWxsX25hbWUubG9uZ19uYW1lKTsKCgkgICAgICAvKiBzdGFydCBibG9jayAqLwoJICAgICAgcmVnZiA9IGJhc2U7CgoJICAgICAgLyogaGJpbiBibG9jayAqLwoJICAgICAgaGJpbiA9IChudF9oYmluKikoKGNoYXIqKSBiYXNlICsgMHgxMDAwKTsKCSAgICAgIGlmIChoYmluLT5pZCAhPSBOVF9SRUdfUE9PTF9CTE9DS19JRCkKCSAgICAgIHsKCSAgICAgICAgRVJSKCAiaGJpbiBibG9jayBpbnZhbGlkXG4iKTsKCSAgICAgICAgZ290byBlcnJvcjE7CgkgICAgICB9CgoJICAgICAgLyogaGJpbl9zdWIgYmxvY2sgKi8KCSAgICAgIGhiaW5fc3ViID0gKG50X2hiaW5fc3ViKikmKGhiaW4tPmhiaW5fc3ViKTsKCSAgICAgIGlmICgoaGJpbl9zdWItPmRhdGFbMF0gIT0gJ24nKSB8fCAoaGJpbl9zdWItPmRhdGFbMV0gIT0gJ2snKSkKCSAgICAgIHsKCSAgICAgICAgRVJSKCAiaGJpbl9zdWIgYmxvY2sgaW52YWxpZFxuIik7CgkgICAgICAgIGdvdG8gZXJyb3IxOwoJICAgICAgfQoKCSAgICAgIC8qIG5rIGJsb2NrICovCgkgICAgICBuayA9IChudF9uayopJihoYmluX3N1Yi0+ZGF0YVswXSk7CgkgICAgICBpZiAobmstPlR5cGUgIT0gTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpCgkgICAgICB7CgkgICAgICAgIEVSUiggInNwZWNpYWwgbmsgYmxvY2sgbm90IGZvdW5kXG4iKTsKCSAgICAgICAgZ290byBlcnJvcjE7CgkgICAgICB9CgoJICAgICAgcmV0ID0gX250X3BhcnNlX25rIChoa2V5LCAoY2hhciAqKSBiYXNlICsgMHgxMDAwLCBuaywgbGV2ZWwpOwoJICAgIH0KCSAgICBicmVhazsKCSAgZGVmYXVsdDoKCSAgICB7CgkgICAgICBFUlIoInVua25vd24gcmVnaXN0cnkgc2lnbmF0dXJlICFcbiIpOwoJICAgICAgZ290byBlcnJvcjE7CgkgICAgfQoJfQplcnJvcjE6CWlmKCFyZXQpCgl7CgkgIEVSUigiZXJyb3IgbG9hZGluZyAlcyByZWdpc3RyeSBmaWxlICVzXG4iLAoJCQkJCQlmaWxldHlwZSwgZnVsbF9uYW1lLmxvbmdfbmFtZSk7CgkgIGlmICghc3RyY21wKGZpbGV0eXBlLCAid2luOTUiKSkKCSAgICBFUlIoIlBsZWFzZSByZXBvcnQgdG8gYS5tb2hyQG1haWx0by5kZS5cbiIpOwoJICBFUlIoIk1ha2UgYSBiYWNrdXAgb2YgdGhlIGZpbGUsIHJ1biBhIGdvb2QgcmVnIGNsZWFuZXIgcHJvZ3JhbSBhbmQgdHJ5IGFnYWluICFcbiIpOwoJfQoJbXVubWFwKGJhc2UsIHN0LnN0X3NpemUpOwplcnJvcjoJY2xvc2UoZmQpOwoJcmV0dXJuIHJldDsJCn0KCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewoJY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCgl1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7Cgl1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7Cgl1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCgl1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgKi8Kdm9pZApfX3czMV9kdW1wdHJlZSgJdW5zaWduZWQgc2hvcnQgaWR4LAoJCXVuc2lnbmVkIGNoYXIgKnR4dCwKCQlzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYiwKCQlzdHJ1Y3QgX3czMV9oZWFkZXIgKmhlYWQsCgkJSEtFWSBoa2V5LAoJCXRpbWVfdAkJbGFzdG1vZGlmaWVkLAoJCWludAkJbGV2ZWwKKSB7CglzdHJ1Y3QgX3czMV9kaXJlbnQJKmRpcjsKCXN0cnVjdCBfdzMxX2tleWVudAkqa2V5OwoJc3RydWN0IF93MzFfdmFsZW50CSp2YWw7CiAgICAgICAgSEtFWSBzdWJrZXkgPSAwOwoJc3RhdGljIGNoYXIJCXRhaWxbNDAwXTsKCgl3aGlsZSAoaWR4IT0wKSB7CgkJZGlyPShzdHJ1Y3QgX3czMV9kaXJlbnQqKSZ0YWJbaWR4XTsKCgkJaWYgKGRpci0+a2V5X2lkeCkgewoJCQlrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgoJCQltZW1jcHkodGFpbCwmdHh0W2tleS0+c3RyaW5nX29mZl0sa2V5LT5sZW5ndGgpOwoJCQl0YWlsW2tleS0+bGVuZ3RoXT0nXDAnOwoJCQkvKiBhbGwgdG9wbGV2ZWwgZW50cmllcyBBTkQgdGhlIGVudHJpZXMgaW4gdGhlIAoJCQkgKiB0b3BsZXZlbCBzdWJkaXJlY3RvcnkgYmVsb25nIHRvIFxTT0ZUV0FSRVxDbGFzc2VzCgkJCSAqLwoJCQlpZiAoIWxldmVsICYmICFzdHJjbXAodGFpbCwiLmNsYXNzZXMiKSkgewoJCQkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLGhrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCQkJaWR4PWRpci0+c2libGluZ19pZHg7CgkJCQljb250aW51ZTsKCQkJfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3Via2V5KSBSZWdDbG9zZUtleSggc3Via2V5ICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChSZWdDcmVhdGVLZXlBKCBoa2V5LCB0YWlsLCAmc3Via2V5ICkgIT0gRVJST1JfU1VDQ0VTUykgc3Via2V5ID0gMDsKCQkJLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCgkJCWlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKCQkJCWlmIChkaXItPnZhbHVlX2lkeCkgewoJCQkJCXZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKCQkJCQltZW1jcHkodGFpbCwmdHh0W3ZhbC0+c3RyaW5nX29mZl0sdmFsLT5sZW5ndGgpOwoJCQkJCXRhaWxbdmFsLT5sZW5ndGhdPSdcMCc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdTZXRWYWx1ZUEoIHN1YmtleSwgTlVMTCwgUkVHX1NaLCB0YWlsLCAwICk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQlUUkFDRSgic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKCQl9CgkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHN1YmtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJaWR4PWRpci0+c2libGluZ19pZHg7Cgl9CiAgICAgICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzMxX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kdm9pZCBfdzMxX2xvYWRyZWcodm9pZCkgewoJSEZJTEUJCQloZjsKCXN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwoJc3RydWN0IF93MzFfdGFiZW50CSp0YWI7Cgl1bnNpZ25lZCBjaGFyCQkqdHh0OwoJdW5zaWduZWQgaW50CQlsZW47CglPRlNUUlVDVAkJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZpbmZvOwoJdGltZV90CQkJbGFzdG1vZGlmaWVkOwoKCVRSQUNFKCIodm9pZClcbiIpOwoKCWhmID0gT3BlbkZpbGUoInJlZy5kYXQiLCZvZnMsT0ZfUkVBRCk7CglpZiAoaGY9PUhGSUxFX0VSUk9SKQoJCXJldHVybjsKCgkvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KCWlmIChzaXplb2YoaGVhZCkhPV9scmVhZChoZiwmaGVhZCxzaXplb2YoaGVhZCkpKSB7CgkJRVJSKCJyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpIT0wKSB7CgkJRVJSKCJyZWcuZGF0IGhhcyBiYWQgc2lnbmF0dXJlLlxuIik7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCWxlbiA9IGhlYWQudGFiY250ICogc2l6ZW9mKHN0cnVjdCBfdzMxX3RhYmVudCk7CgkvKiByZWFkIGFuZCBkdW1wIGluZGV4IHRhYmxlICovCgl0YWIgPSB4bWFsbG9jKGxlbik7CglpZiAobGVuIT1fbHJlYWQoaGYsdGFiLGxlbikpIHsKCQlFUlIoImNvdWxkbid0IHJlYWQgJWQgYnl0ZXMuXG4iLGxlbik7IAoJCWZyZWUodGFiKTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJLyogcmVhZCB0ZXh0ICovCgl0eHQgPSB4bWFsbG9jKGhlYWQudGV4dHNpemUpOwoJaWYgKC0xPT1fbGxzZWVrKGhmLGhlYWQudGV4dG9mZixTRUVLX1NFVCkpIHsKCQlFUlIoImNvdWxkbid0IHNlZWsgdG8gdGV4dGJsb2NrLlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoJaWYgKGhlYWQudGV4dHNpemUhPV9scmVhZChoZix0eHQsaGVhZC50ZXh0c2l6ZSkpIHsKCQlFUlIoInRleHRibG9jayB0b28gc2hvcnQgKCVkIGluc3RlYWQgb2YgJWxkKS5cbiIsbGVuLGhlYWQudGV4dHNpemUpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCglpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmLCZoZmluZm8pKSB7CgkJRVJSKCJHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoJbGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoJX193MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQsSEtFWV9DTEFTU0VTX1JPT1QsbGFzdG1vZGlmaWVkLDApOwoJZnJlZSh0YWIpOwoJZnJlZSh0eHQpOwoJX2xjbG9zZShoZik7CglyZXR1cm47Cn0KCgpzdGF0aWMgdm9pZCBzYXZlX2F0X2V4aXQoIEhLRVkgaGtleSwgY29uc3QgY2hhciAqcGF0aCApCnsKICAgIGNvbnN0IGNoYXIgKmNvbmZkaXIgPSBnZXRfY29uZmlnX2RpcigpOwogICAgc2l6ZV90IGxlbiA9IHN0cmxlbihjb25mZGlyKSArIHN0cmxlbihwYXRoKSArIDI7CiAgICBpZiAobGVuID4gUkVRVUVTVF9NQVhfVkFSX1NJWkUpCiAgICB7CiAgICAgICAgRVJSKCAiY29uZmlnIGRpciAnJXMnIHRvbyBsb25nXG4iLCBjb25mZGlyICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgU0VSVkVSX1NUQVJUX1JFUQogICAgewogICAgICAgIHN0cnVjdCBzYXZlX3JlZ2lzdHJ5X2F0ZXhpdF9yZXF1ZXN0ICpyZXEgPSBzZXJ2ZXJfYWxsb2NfcmVxKCBzaXplb2YoKnJlcSksIGxlbiApOwogICAgICAgIHNwcmludGYoIHNlcnZlcl9kYXRhX3B0cihyZXEpLCAiJXMvJXMiLCBjb25mZGlyLCBwYXRoICk7CiAgICAgICAgcmVxLT5oa2V5ID0gaGtleTsKICAgICAgICBzZXJ2ZXJfY2FsbCggUkVRX1NBVkVfUkVHSVNUUllfQVRFWElUICk7CiAgICB9CiAgICBTRVJWRVJfRU5EX1JFUTsKfQoKLyogY29uZmlndXJlIHNhdmUgZmlsZXMgYW5kIHN0YXJ0IHRoZSBwZXJpb2RpYyBzYXZpbmcgdGltZXIgKi8Kc3RhdGljIHZvaWQgU0hFTExfSW5pdFJlZ2lzdHJ5U2F2aW5nKCBIS0VZIGhrZXlfdXNlcnNfZGVmYXVsdCApCnsKICAgIGludCBhbGwgPSBQUk9GSUxFX0dldFdpbmVJbmlCb29sKCAicmVnaXN0cnkiLCAiU2F2ZU9ubHlVcGRhdGVkS2V5cyIsIDEgKTsKICAgIGludCBwZXJpb2QgPSBQUk9GSUxFX0dldFdpbmVJbmlJbnQoICJyZWdpc3RyeSIsICJQZXJpb2RpY1NhdmUiLCAwICk7CgogICAgLyogc2V0IHNhdmluZyBsZXZlbCAoMCBmb3Igc2F2aW5nIGV2ZXJ5dGhpbmcsIDEgZm9yIHNhdmluZyBvbmx5IG1vZGlmaWVkIGtleXMpICovCiAgICBTRVJWRVJfU1RBUlRfUkVRCiAgICB7CiAgICAgICAgc3RydWN0IHNldF9yZWdpc3RyeV9sZXZlbHNfcmVxdWVzdCAqcmVxID0gc2VydmVyX2FsbG9jX3JlcSggc2l6ZW9mKCpyZXEpLCAwICk7CiAgICAgICAgcmVxLT5jdXJyZW50ID0gMTsKICAgICAgICByZXEtPnNhdmluZyAgPSAhYWxsOwogICAgICAgIHJlcS0+cGVyaW9kICA9IHBlcmlvZCAqIDEwMDA7CiAgICAgICAgc2VydmVyX2NhbGwoIFJFUV9TRVRfUkVHSVNUUllfTEVWRUxTICk7CiAgICB9CiAgICBTRVJWRVJfRU5EX1JFUTsKCiAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgicmVnaXN0cnkiLCJXcml0ZXRvSG9tZVJlZ2lzdHJpZXMiLDEpKQogICAgewogICAgICAgIHNhdmVfYXRfZXhpdCggSEtFWV9DVVJSRU5UX1VTRVIsIFNBVkVfQ1VSUkVOVF9VU0VSICk7CiAgICAgICAgc2F2ZV9hdF9leGl0KCBIS0VZX0xPQ0FMX01BQ0hJTkUsIFNBVkVfTE9DQUxfTUFDSElORSApOwogICAgICAgIHNhdmVfYXRfZXhpdCggaGtleV91c2Vyc19kZWZhdWx0LCBTQVZFX0RFRkFVTFRfVVNFUiApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2V0TG9hZExldmVsIFtJbnRlcm5hbF0KICoKICogc2V0IGxldmVsIHRvIDAgZm9yIGxvYWRpbmcgc3lzdGVtIGZpbGVzCiAqIHNldCBsZXZlbCB0byAxIGZvciBsb2FkaW5nIHVzZXIgZmlsZXMKICovCnN0YXRpYyB2b2lkIFNldExvYWRMZXZlbChpbnQgbGV2ZWwpCnsKICAgIFNFUlZFUl9TVEFSVF9SRVEKICAgIHsKICAgICAgICBzdHJ1Y3Qgc2V0X3JlZ2lzdHJ5X2xldmVsc19yZXF1ZXN0ICpyZXEgPSBzZXJ2ZXJfYWxsb2NfcmVxKCBzaXplb2YoKnJlcSksIDAgKTsKCglyZXEtPmN1cnJlbnQgPSBsZXZlbDsKCXJlcS0+c2F2aW5nICA9IDA7CiAgICAgICAgcmVxLT5wZXJpb2QgID0gMDsKCXNlcnZlcl9jYWxsKCBSRVFfU0VUX1JFR0lTVFJZX0xFVkVMUyApOwogICAgfQogICAgU0VSVkVSX0VORF9SRVE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX0xvYWRSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwojZGVmaW5lIFJFR19ET05UTE9BRCAtMQojZGVmaW5lIFJFR19XSU4zMSAgMAojZGVmaW5lIFJFR19XSU45NSAgMQojZGVmaW5lIFJFR19XSU5OVCAgMgoKdm9pZCBTSEVMTF9Mb2FkUmVnaXN0cnkoIHZvaWQgKQp7CiAgSEtFWQloa2V5OwogIGNoYXIgd2luZGlyW01BWF9QQVRITkFNRV9MRU5dOwogIGNoYXIgcGF0aFtNQVhfUEFUSE5BTUVfTEVOXTsKICBpbnQgIHN5c3RlbXR5cGUgPSBSRUdfV0lOMzE7CiAgSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQ7CgogIFRSQUNFKCIodm9pZClcbiIpOwoKICBpZiAoIUNMSUVOVF9Jc0Jvb3RUaHJlYWQoKSkgcmV0dXJuOyAgLyogYWxyZWFkeSBsb2FkZWQgKi8KCiAgUkVHSVNUUllfSW5pdCgpOwogIFNldExvYWRMZXZlbCgwKTsKCiAgaWYgKFJlZ0NyZWF0ZUtleUEoSEtFWV9VU0VSUywgIi5EZWZhdWx0IiwgJmhrZXlfdXNlcnNfZGVmYXVsdCkpCgkgIGhrZXlfdXNlcnNfZGVmYXVsdCA9IDA7CgogIEdldFdpbmRvd3NEaXJlY3RvcnlBKCB3aW5kaXIsIE1BWF9QQVRITkFNRV9MRU4gKTsKCiAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woICJSZWdpc3RyeSIsICJMb2FkV2luZG93c1JlZ2lzdHJ5RmlsZXMiLCAxKSkKICB7CiAgICAvKiB0ZXN0ICV3aW5kaXIlL3N5c3RlbTMyL2NvbmZpZy9zeXN0ZW0gLS0+IHdpbm50ICovCiAgICBzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgIHN0cm5jYXQocGF0aCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc3lzdGVtIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgaWYoR2V0RmlsZUF0dHJpYnV0ZXNBKHBhdGgpICE9IChEV09SRCktMSkgCiAgICB7CiAgICAgIHN5c3RlbXR5cGUgPSBSRUdfV0lOTlQ7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAvKiB0ZXN0ICV3aW5kaXIlL3N5c3RlbS5kYXQgLS0+IHdpbjk1ICovCiAgICAgIHN0cmNweShwYXRoLCB3aW5kaXIpOwogICAgICBzdHJuY2F0KHBhdGgsICJcXHN5c3RlbS5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzQShwYXRoKSAhPSAoRFdPUkQpLTEpCiAgICAgIHsKICAgICAgICBzeXN0ZW10eXBlID0gUkVHX1dJTjk1OwogICAgICB9CiAgICB9CgogICAgaWYgKChzeXN0ZW10eXBlPT1SRUdfV0lOTlQpCiAgICAgICYmICghIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggIldpbmUiLCAiUHJvZmlsZSIsICIiLCBwYXRoLCBNQVhfUEFUSE5BTUVfTEVOKSkpCiAgICB7CiAgICAgICBNRVNTQUdFKCJXaGVuIHlvdSBhcmUgcnVubmluZyB3aXRoIGEgbmF0aXZlIE5UIGRpcmVjdG9yeSBzcGVjaWZ5XG4iKTsKICAgICAgIE1FU1NBR0UoIidQcm9maWxlPTxwcm9maWxlZGlyZWN0b3J5Picgb3IgZGlzYWJsZSBsb2FkaW5nIG9mIFdpbmRvd3NcbiIpOwogICAgICAgTUVTU0FHRSgicmVnaXN0cnkgKExvYWRXaW5kb3dzUmVnaXN0cnlGaWxlcz1OKVxuIik7CiAgICAgICBzeXN0ZW10eXBlID0gUkVHX0RPTlRMT0FEOwogICAgfQogIH0KICBlbHNlCiAgewogICAgLyogb25seSB3aW5lIHJlZ2lzdHJ5ICovCiAgICBzeXN0ZW10eXBlID0gUkVHX0RPTlRMT0FEOwogIH0gIAoKICBzd2l0Y2ggKHN5c3RlbXR5cGUpCiAgewogICAgY2FzZSBSRUdfV0lOMzE6CiAgICAgIF93MzFfbG9hZHJlZygpOwogICAgICBicmVhazsKCiAgICBjYXNlIFJFR19XSU45NTogIAogICAgICAvKiBMb2FkIHdpbmRvd3MgOTUgZW50cmllcyAqLwogICAgICBOYXRpdmVSZWdMb2FkS2V5KEhLRVlfTE9DQUxfTUFDSElORSwgIkM6XFxzeXN0ZW0uMXN0IiwgMCk7CgogICAgICBzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgICAgc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0uZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICBOYXRpdmVSZWdMb2FkS2V5KEhLRVlfTE9DQUxfTUFDSElORSwgcGF0aCwgMCk7CgogICAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiV2luZSIsICJQcm9maWxlIiwgIiIsIHBhdGgsIE1BWF9QQVRITkFNRV9MRU4pKQogICAgICB7CgkvKiB1c2VyIHNwZWNpZmljIHVzZXIuZGF0ICovCglzdHJuY2F0KHBhdGgsICJcXHVzZXIuZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICAgIGlmICghTmF0aXZlUmVnTG9hZEtleSggSEtFWV9DVVJSRU5UX1VTRVIsIHBhdGgsIDEgKSkKCXsKCSAgTUVTU0FHRSgiY2FuJ3QgbG9hZCB3aW45NSB1c2VyLXJlZ2lzdHJ5ICVzXG4iLCBwYXRoKTsKCSAgTUVTU0FHRSgiY2hlY2sgd2luZS5jb25mLCBzZWN0aW9uIFtXaW5lXSwgdmFsdWUgJ1Byb2ZpbGUnXG4iKTsKCX0KCS8qIGRlZmF1bHQgdXNlci5kYXQgKi8KCWlmIChoa2V5X3VzZXJzX2RlZmF1bHQpCgl7CiAgICAgICAgICBzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgICAgICAgIHN0cm5jYXQocGF0aCwgIlxcdXNlci5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgICAgICBOYXRpdmVSZWdMb2FkS2V5KGhrZXlfdXNlcnNfZGVmYXVsdCwgcGF0aCwgMSk7Cgl9CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgLyogZ2xvYmFsIHVzZXIuZGF0ICovCglzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgICAgICBzdHJuY2F0KHBhdGgsICJcXHVzZXIuZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoSEtFWV9DVVJSRU5UX1VTRVIsIHBhdGgsIDEpOwogICAgICB9CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgUkVHX1dJTk5UOiAgCiAgICAgIC8qIGRlZmF1bHQgdXNlci5kYXQgKi8KICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggIldpbmUiLCAiUHJvZmlsZSIsICIiLCBwYXRoLCBNQVhfUEFUSE5BTUVfTEVOKSkKICAgICAgewogICAgICAgIHN0cm5jYXQocGF0aCwgIlxcbnR1c2VyLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgICBpZighTmF0aXZlUmVnTG9hZEtleSggSEtFWV9DVVJSRU5UX1VTRVIsIHBhdGgsIDEgKSkKICAgICAgICB7CiAgICAgICAgICAgTUVTU0FHRSgiY2FuJ3QgbG9hZCBOVCB1c2VyLXJlZ2lzdHJ5ICVzXG4iLCBwYXRoKTsKCSAgIE1FU1NBR0UoImNoZWNrIHdpbmUuY29uZiwgc2VjdGlvbiBbV2luZV0sIHZhbHVlICdQcm9maWxlJ1xuIik7CiAgICAgICAgfQogICAgICB9CgogICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCiAgICAgIGlmIChoa2V5X3VzZXJzX2RlZmF1bHQpCiAgICAgIHsKICAgICAgICBzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgICAgICBzdHJuY2F0KHBhdGgsICJcXHN5c3RlbTMyXFxjb25maWdcXGRlZmF1bHQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgICAgTmF0aXZlUmVnTG9hZEtleShoa2V5X3VzZXJzX2RlZmF1bHQsIHBhdGgsIDEpOwogICAgICB9CgogICAgICAvKgogICAgICAqIEZJWE1FCiAgICAgICogIG1hcCBITE1cU3lzdGVtXENvbnRyb2xTZXQwMDEgdG8gSExNXFN5c3RlbVxDdXJyZW50Q29udHJvbFNldAogICAgICAqLwoKICAgICAgaWYgKCFSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwgIlNZU1RFTSIsICZoa2V5KSkKICAgICAgewoJc3RyY3B5KHBhdGgsIHdpbmRpcik7CglzdHJuY2F0KHBhdGgsICJcXHN5c3RlbTMyXFxjb25maWdcXHN5c3RlbSIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKCU5hdGl2ZVJlZ0xvYWRLZXkoaGtleSwgcGF0aCwgMSk7CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgIH0KCiAgICAgIGlmICghUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsICJTT0ZUV0FSRSIsICZoa2V5KSkKICAgICAgewoJc3RyY3B5KHBhdGgsIHdpbmRpcik7CglzdHJuY2F0KHBhdGgsICJcXHN5c3RlbTMyXFxjb25maWdcXHNvZnR3YXJlIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwoJTmF0aXZlUmVnTG9hZEtleShoa2V5LCBwYXRoLCAxKTsKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgfQoKICAgICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgIHN0cm5jYXQocGF0aCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc2FtIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICBOYXRpdmVSZWdMb2FkS2V5KEhLRVlfTE9DQUxfTUFDSElORSwgcGF0aCwgMCk7CgogICAgICBzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgICAgc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0zMlxcY29uZmlnXFxzZWN1cml0eSIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgTmF0aXZlUmVnTG9hZEtleShIS0VZX0xPQ0FMX01BQ0hJTkUsIHBhdGgsIDApOwoKICAgICAgLyogdGhpcyBrZXkgaXMgZ2VuZXJhdGVkIHdoZW4gdGhlIG50LWNvcmUgYm9vdGVkIHN1Y2Nlc3NmdWxseSAqLwogICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXENsb25lIiwmaGtleSkpCiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgIGJyZWFrOwogIH0gLyogc3dpdGNoICovCiAgCiAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2wgKCJyZWdpc3RyeSIsIkxvYWRHbG9iYWxSZWdpc3RyeUZpbGVzIiwgMSkpCiAgewogICAgICAvKiAKICAgICAgICogTG9hZCB0aGUgZ2xvYmFsIEhLVSBoaXZlIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpcgogICAgICAgKi8gCiAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfVVNFUlMsIFNBVkVfVVNFUlNfREVGQVVMVCApOwoKICAgICAgLyogCiAgICAgICAqIExvYWQgdGhlIGdsb2JhbCBtYWNoaW5lIGRlZmF1bHRzIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpcgogICAgICAgKi8KICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9MT0NBTF9NQUNISU5FLCBTQVZFX0xPQ0FMX01BQ0hJTkVfREVGQVVMVCApOwogIH0KCiAgU2V0TG9hZExldmVsKDEpOwoKICAvKgogICAqIExvYWQgdGhlIHVzZXIgc2F2ZWQgcmVnaXN0cmllcyAKICAgKi8KICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgicmVnaXN0cnkiLCAiTG9hZEhvbWVSZWdpc3RyeUZpbGVzIiwgMSkpCiAgewogICAgICBjb25zdCBjaGFyICpjb25mZGlyID0gZ2V0X2NvbmZpZ19kaXIoKTsKICAgICAgdW5zaWduZWQgaW50IGxlbiA9IHN0cmxlbihjb25mZGlyKSArIDIwOwogICAgICBjaGFyICpmbiA9IHBhdGg7CgogICAgICBpZiAobGVuID4gc2l6ZW9mKHBhdGgpKSBmbiA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICk7CiAgICAgIC8qIAogICAgICAgKiBMb2FkIHVzZXIncyBwZXJzb25hbCB2ZXJzaW9ucyBvZiBnbG9iYWwgSEtVLy5EZWZhdWx0IGtleXMKICAgICAgICovCiAgICAgIGlmIChmbikKICAgICAgewogICAgICAgICAgY2hhciAqc3RyOwogICAgICAgICAgc3RyY3B5KCBmbiwgY29uZmRpciApOwogICAgICAgICAgc3RyID0gZm4gKyBzdHJsZW4oZm4pOwogICAgICAgICAgKnN0cisrID0gJy8nOwoKICAgICAgICAgIC8qIHRyeSB0byBsb2FkIEhLVVwuRGVmYXVsdCBrZXkgb25seSAqLwogICAgICAgICAgc3RyY3B5KCBzdHIsIFNBVkVfREVGQVVMVF9VU0VSICk7CiAgICAgICAgICBpZiAoX3dpbmVfbG9hZHJlZyggaGtleV91c2Vyc19kZWZhdWx0LCBmbiApKQogICAgICAgICAgewogICAgICAgICAgICAgIC8qIGlmIG5vdCBmb3VuZCBsb2FkIG9sZCBmaWxlIGNvbnRhaW5pbmcgYm90aCBIS1VcLkRlZmF1bHQgYW5kIEhLVVx1c2VyICovCiAgICAgICAgICAgICAgc3RyY3B5KCBzdHIsIFNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCApOwogICAgICAgICAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfVVNFUlMsIGZuICk7IAogICAgICAgICAgfQoKICAgICAgICAgIHN0cmNweSggc3RyLCBTQVZFX0NVUlJFTlRfVVNFUiApOwogICAgICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9DVVJSRU5UX1VTRVIsIGZuICk7CgogICAgICAgICAgc3RyY3B5KCBzdHIsIFNBVkVfTE9DQUxfTUFDSElORSApOwogICAgICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9MT0NBTF9NQUNISU5FLCBmbiApOwoKICAgICAgICAgIGlmIChmbiAhPSBwYXRoKSBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZm4gKTsKICAgICAgfQogIH0KICBTSEVMTF9Jbml0UmVnaXN0cnlTYXZpbmcoIGhrZXlfdXNlcnNfZGVmYXVsdCApOwogIFJlZ0Nsb3NlS2V5KCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKiBBUEkgRlVOQ1RJT05TICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRmx1c2hLZXkgW0tFUk5FTC4yMjddIFtBRFZBUEkzMi4xNDNdCiAqIEltbWVkaWF0ZWx5IHdyaXRlcyBrZXkgdG8gcmVnaXN0cnkuCiAqIE9ubHkgcmV0dXJucyBhZnRlciBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gdG8gZGlzay4KICoKICogRklYTUU6IGRvZXMgaXQgcmVhbGx5IHdhaXQgdW50aWwgZGF0YSBpcyB3cml0dGVuID8KICoKICogUEFSQU1TCiAqICAgIGhrZXkgW0ldIEhhbmRsZSBvZiBrZXkgdG8gd3JpdGUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdGbHVzaEtleSggSEtFWSBoa2V5ICkKewogICAgRklYTUUoICIoJXgpOiBzdHViXG4iLCBoa2V5ICk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnVW5Mb2FkS2V5QSBbQURWQVBJMzIuMTcyXQogKi8KTE9ORyBXSU5BUEkgUmVnVW5Mb2FkS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXkgKQp7CiAgICBGSVhNRSgiKCV4LCVzKTogc3R1YlxuIixoa2V5LCBkZWJ1Z3N0cl9hKGxwU3ViS2V5KSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleVcgW0FEVkFQSTMyLjE2NF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgcmVzdG9yZSBiZWdpbnMKICogICAgbHBGaWxlICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBjb250YWluaW5nIHNhdmVkIHRyZWUKICogICAgZHdGbGFncyBbSV0gT3B0aW9uYWwgZmxhZ3MKICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgVFJBQ0UoIigleCwlcywlbGQpXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIEl0IHNlZW1zIHRvIGRvIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoIWxwRmlsZSB8fCAhKmxwRmlsZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgRklYTUUoIigleCwlcywlbGQpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIENoZWNrIGZvciBmaWxlIGV4aXN0ZW5jZSAqLwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5QSBbQURWQVBJMzIuMTYzXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVzdG9yZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIExQV1NUUiBscEZpbGVXID0gSEVBUF9zdHJkdXBBdG9XKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBscEZpbGUgKTsKICAgIExPTkcgcmV0ID0gUmVnUmVzdG9yZUtleVcoIGhrZXksIGxwRmlsZVcsIGR3RmxhZ3MgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBscEZpbGVXICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5QSBbQURWQVBJMzIuMTYxXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5LCBMUENTVFIgbHBOZXdGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBPbGRGaWxlICkKewogICAgRklYTUUoIigleCwlcywlcywlcyk6IHN0dWJcbiIsIGhrZXksIGRlYnVnc3RyX2EobHBTdWJLZXkpLAogICAgICAgICAgZGVidWdzdHJfYShscE5ld0ZpbGUpLGRlYnVnc3RyX2EobHBPbGRGaWxlKSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCgoKCgovKiAxNi1iaXQgZnVuY3Rpb25zICovCgovKiAwIGFuZCAxIGFyZSB2YWxpZCByb290a2V5cyBpbiB3aW4xNiBzaGVsbC5kbGwgYW5kIGFyZSB1c2VkIGJ5CiAqIHNvbWUgcHJvZ3JhbXMuIERvIG5vdCByZW1vdmUgdGhvc2UgY2FzZXMuIC1NTQogKi8Kc3RhdGljIGlubGluZSB2b2lkIGZpeF93aW4xNl9oa2V5KCBIS0VZICpoa2V5ICkKewogICAgaWYgKCpoa2V5ID09IDAgfHwgKmhrZXkgPT0gMSkgKmhrZXkgPSBIS0VZX0NMQVNTRVNfUk9PVDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRW51bUtleTE2ICAgW0tFUk5FTC4yMTZdIFtTSEVMTC43XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXkxNiggSEtFWSBoa2V5LCBEV09SRCBpbmRleCwgTFBTVFIgbmFtZSwgRFdPUkQgbmFtZV9sZW4gKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdFbnVtS2V5QSggaGtleSwgaW5kZXgsIG5hbWUsIG5hbWVfbGVuICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ09wZW5LZXkxNiAgIFtLRVJORUwuMjE3XSBbU0hFTEwuMV0KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQSEtFWSByZXRrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdPcGVuS2V5QSggaGtleSwgbmFtZSwgcmV0a2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0NyZWF0ZUtleTE2ICAgW0tFUk5FTC4yMThdIFtTSEVMTC4yXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUEhLRVkgcmV0a2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5QSggaGtleSwgbmFtZSwgcmV0a2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0RlbGV0ZUtleTE2ICAgW0tFUk5FTC4yMTldIFtTSEVMTC40XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRGVsZXRlS2V5QSggaGtleSwgbmFtZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdDbG9zZUtleTE2ICAgW0tFUk5FTC4yMjBdIFtTSEVMTC4zXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0Nsb3NlS2V5MTYoIEhLRVkgaGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0Nsb3NlS2V5KCBoa2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1NldFZhbHVlMTYgICBbS0VSTkVMLjIyMV0gW1NIRUxMLjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgRFdPUkQgdHlwZSwgTFBDU1RSIGRhdGEsIERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVBKCBoa2V5LCBuYW1lLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdEZWxldGVWYWx1ZTE2ICBbS0VSTkVMLjIyMl0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTE2KCBIS0VZIGhrZXksIExQU1RSIG5hbWUgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdEZWxldGVWYWx1ZUEoIGhrZXksIG5hbWUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRW51bVZhbHVlMTYgICBbS0VSTkVMLjIyM10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUxNiggSEtFWSBoa2V5LCBEV09SRCBpbmRleCwgTFBTVFIgdmFsdWUsIExQRFdPUkQgdmFsX2NvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgcmVzZXJ2ZWQsIExQRFdPUkQgdHlwZSwgTFBCWVRFIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdFbnVtVmFsdWVBKCBoa2V5LCBpbmRleCwgdmFsdWUsIHZhbF9jb3VudCwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUxNiAgIFtLRVJORUwuMjI0XSBbU0hFTEwuNl0KICoKICogTk9URVMKICogICAgSXMgdGhpcyBIQUNLIHN0aWxsIGFwcGxpY2FibGU/CiAqCiAqIEhBQ0sKICogICAgVGhlIDE2Yml0IFJlZ1F1ZXJ5VmFsdWUgZG9lc24ndCBoYW5kbGUgc2VsZWN0b3JibG9ja3MgYW55d2F5LCBzbyB3ZSBqdXN0CiAqICAgIG1hc2sgb3V0IHRoZSBoaWdoIDE2IGJpdC4gIFRoaXMgKG5vdCBzbyBtdWNoIGluY2lkZW50bHkpIGhvcGVmdWxseSBmaXhlcwogKiAgICBBbGR1cyBGSDQpCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUFNUUiBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICBpZiAoY291bnQpICpjb3VudCAmPSAweGZmZmY7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUEoIGhrZXksIG5hbWUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWVFeDE2ICAgW0tFUk5FTC4yMjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQRFdPUkQgcmVzZXJ2ZWQsIExQRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeEEoIGhrZXksIG5hbWUsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdTZXRWYWx1ZUV4MTYgICBbS0VSTkVMLjIyNl0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIERXT1JEIHJlc2VydmVkLCBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05TVCBCWVRFICpkYXRhLCBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgaWYgKCFjb3VudCAmJiAodHlwZT09UkVHX1NaKSkgY291bnQgPSBzdHJsZW4oZGF0YSk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVFeEEoIGhrZXksIG5hbWUsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdGbHVzaEtleTE2ICAgW0tFUk5FTC4yMjddCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkxNiggSEtFWSBoa2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRmx1c2hLZXkoIGhrZXkgKTsKfQo=