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+ZGF0YVswXSk7CgkgICAgICBpZiAobmstPlR5cGUgIT0gTlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpCgkgICAgICB7CgkgICAgICAgIEVSUiggInNwZWNpYWwgbmsgYmxvY2sgbm90IGZvdW5kXG4iKTsKCSAgICAgICAgZ290byBlcnJvcjE7CgkgICAgICB9CgoJICAgICAgcmV0ID0gX250X3BhcnNlX25rIChoa2V5LCAoY2hhciAqKSBiYXNlICsgMHgxMDAwLCBuaywgbGV2ZWwpOwoJICAgIH0KCSAgICBicmVhazsKCSAgZGVmYXVsdDoKCSAgICB7CgkgICAgICBFUlIoInVua25vd24gcmVnaXN0cnkgc2lnbmF0dXJlICFcbiIpOwoJICAgICAgZ290byBlcnJvcjE7CgkgICAgfQoJfQplcnJvcjE6CWlmKCFyZXQpCgl7CgkgIEVSUigiZXJyb3IgbG9hZGluZyAlcyByZWdpc3RyeSBmaWxlICVzXG4iLAoJCQkJCQlmaWxldHlwZSwgZnVsbF9uYW1lLmxvbmdfbmFtZSk7CgkgIGlmICghc3RyY21wKGZpbGV0eXBlLCAid2luOTUiKSkKCSAgICBFUlIoIlBsZWFzZSByZXBvcnQgdG8gYS5tb2hyQG1haWx0by5kZS5cbiIpOwoJICBFUlIoIk1ha2UgYSBiYWNrdXAgb2YgdGhlIGZpbGUsIHJ1biBhIGdvb2QgcmVnIGNsZWFuZXIgcHJvZ3JhbSBhbmQgdHJ5IGFnYWluICFcbiIpOwoJfQoJbXVubWFwKGJhc2UsIHN0LnN0X3NpemUpOwplcnJvcjoJY2xvc2UoZmQpOwoJcmV0dXJuIHJldDsJCn0KCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VlZGVkIGJ5IGEgd29yZCBhdCBvZmZzZXQtMi4gVGhpcyB3b3JkCiAgICBoYXMgdGhlIHZhbHVlICgyKmluZGV4KSsxLCB3aGVyZSBpbmRleCBpcyB0aGUgcmVmZXJyaW5nIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGluIHRoZSB0YWJsZS4gSSBoYXZlIG5vIHN1Z2dlc3Rpb24gZm9yIHRoZSAyKiBhbmQgdGhlICsxLgogICAgRm9sbG93aW5nIHRoZSB3b3JkLCB0aGVyZSBhcmUgTiBieXRlcyBvZiBkYXRhLCBhcyBwZXIgdGhlIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGxlbmd0aC4gVGhlIG9mZnNldCBvZiB0aGUga2V5ZW50L3ZhbGVudCBlbnRyeSBpcyBmcm9tIHRoZSBzdGFydAogICAgb2YgdGhlIHRleHQgdGFibGUgdG8gdGhlIGZpcnN0IGRhdGEgYnl0ZS4KCiAgICBUaGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbSBNaWNyb3NvZnQuIFRoZSBkYXRhIGZvcm1hdCBpcwogICAgZGVkdWNlZCBmcm9tIHRoZSByZWcuZGF0IGZpbGUgYnkgbWUuIE1pc3Rha2VzIG1heQogICAgaGF2ZSBiZWVuIG1hZGUuIEkgY2xhaW0gbm8gcmlnaHRzIGFuZCBnaXZlIG5vIGd1YXJhbnRlZXMgZm9yIHRoaXMgcHJvZ3JhbS4KCiAgICBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vCiovCgovKiByZWcuZGF0IGhlYWRlciBmb3JtYXQgKi8Kc3RydWN0IF93MzFfaGVhZGVyIHsKCWNoYXIJCWNvb2tpZVs4XTsJLyogJ1NIQ0MzLjEwJyAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYxOwkvKiBvZmZzZXQgb2YgaGFzaCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYyOwkvKiBvZmZzZXQgb2YgaW5kZXggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFiY250OwkJLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gaW5kZXggdGFibGUgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dG9mZjsJLyogb2Zmc2V0IG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0c2l6ZTsJLyogYnl0ZSBzaXplIG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgc2hvcnQJaGFzaHNpemU7CS8qIGhhc2ggc2l6ZSAqLwoJdW5zaWduZWQgc2hvcnQJZnJlZWlkeDsJLyogZnJlZSBpbmRleCAqLwp9OwoKLyogZ2VuZXJpYyBmb3JtYXQgb2YgdGFibGUgZW50cmllcyAqLwpzdHJ1Y3QgX3czMV90YWJlbnQgewoJdW5zaWduZWQgc2hvcnQgdzAsIHcxLCB3MiwgdzM7Cn07CgovKiBkaXJlY3RvcnkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9kaXJlbnQgewoJdW5zaWduZWQgc2hvcnQJc2libGluZ19pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHNpYmxpbmcgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAljaGlsZF9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGNoaWxkIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJa2V5X2lkeDsJLyogdGFibGUgaW5kZXggb2Yga2V5IGtleWVudCAqLwoJdW5zaWduZWQgc2hvcnQJdmFsdWVfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiB2YWx1ZSB2YWxlbnQgKi8KfTsKCi8qIGtleSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2tleWVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogdmFsdWUgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV92YWxlbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdG8gZGlzcGxheSBhIGRpcmVjdG9yeSB0cmVlICovCnZvaWQKX193MzFfZHVtcHRyZWUoCXVuc2lnbmVkIHNob3J0IGlkeCwKCQl1bnNpZ25lZCBjaGFyICp0eHQsCgkJc3RydWN0IF93MzFfdGFiZW50ICp0YWIsCgkJc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAoJCUhLRVkgaGtleSwKCQl0aW1lX3QJCWxhc3Rtb2RpZmllZCwKCQlpbnQJCWxldmVsCikgewoJc3RydWN0IF93MzFfZGlyZW50CSpkaXI7CglzdHJ1Y3QgX3czMV9rZXllbnQJKmtleTsKCXN0cnVjdCBfdzMxX3ZhbGVudAkqdmFsOwogICAgICAgIEhLRVkgc3Via2V5ID0gMDsKCXN0YXRpYyBjaGFyCQl0YWlsWzQwMF07CgoJd2hpbGUgKGlkeCE9MCkgewoJCWRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgoJCWlmIChkaXItPmtleV9pZHgpIHsKCQkJa2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKCQkJbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKCQkJdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKCQkJLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZSAKCQkJICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwoJCQkgKi8KCQkJaWYgKCFsZXZlbCAmJiAhc3RyY21wKHRhaWwsIi5jbGFzc2VzIikpIHsKCQkJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxoa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQkJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJCQkJY29udGludWU7CgkJCX0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoUmVnQ3JlYXRlS2V5QSggaGtleSwgdGFpbCwgJnN1YmtleSApICE9IEVSUk9SX1NVQ0NFU1MpIHN1YmtleSA9IDA7CgkJCS8qIG9ubHkgYWRkIGlmIGxlYWYgbm9kZSBvciB2YWx1ZWQgbm9kZSAqLwoJCQlpZiAoZGlyLT52YWx1ZV9pZHghPTB8fGRpci0+Y2hpbGRfaWR4PT0wKSB7CgkJCQlpZiAoZGlyLT52YWx1ZV9pZHgpIHsKCQkJCQl2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CgkJCQkJbWVtY3B5KHRhaWwsJnR4dFt2YWwtPnN0cmluZ19vZmZdLHZhbC0+bGVuZ3RoKTsKCQkJCQl0YWlsW3ZhbC0+bGVuZ3RoXT0nXDAnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnU2V0VmFsdWVBKCBzdWJrZXksIE5VTEwsIFJFR19TWiwgdGFpbCwgMCApOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJVFJBQ0UoInN0cmFuZ2U6IG5vIGRpcmVjdG9yeSBrZXkgbmFtZSwgaWR4PSUwNHhcbiIsIGlkeCk7CgkJfQoJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxzdWJrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJfQogICAgICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3czMV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnZvaWQgX3czMV9sb2FkcmVnKHZvaWQpIHsKCUhGSUxFCQkJaGY7CglzdHJ1Y3QgX3czMV9oZWFkZXIJaGVhZDsKCXN0cnVjdCBfdzMxX3RhYmVudAkqdGFiOwoJdW5zaWduZWQgY2hhcgkJKnR4dDsKCXVuc2lnbmVkIGludAkJbGVuOwoJT0ZTVFJVQ1QJCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmaW5mbzsKCXRpbWVfdAkJCWxhc3Rtb2RpZmllZDsKCglUUkFDRSgiKHZvaWQpXG4iKTsKCgloZiA9IE9wZW5GaWxlKCJyZWcuZGF0Iiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmPT1IRklMRV9FUlJPUikKCQlyZXR1cm47CgoJLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCglpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQoaGYsJmhlYWQsc2l6ZW9mKGhlYWQpKSkgewoJCUVSUigicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSE9MCkgewoJCUVSUigicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCglsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwoJLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwoJdGFiID0geG1hbGxvYyhsZW4pOwoJaWYgKGxlbiE9X2xyZWFkKGhmLHRhYixsZW4pKSB7CgkJRVJSKCJjb3VsZG4ndCByZWFkICVkIGJ5dGVzLlxuIixsZW4pOyAKCQlmcmVlKHRhYik7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCS8qIHJlYWQgdGV4dCAqLwoJdHh0ID0geG1hbGxvYyhoZWFkLnRleHRzaXplKTsKCWlmICgtMT09X2xsc2VlayhoZixoZWFkLnRleHRvZmYsU0VFS19TRVQpKSB7CgkJRVJSKCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWlmIChoZWFkLnRleHRzaXplIT1fbHJlYWQoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CgkJRVJSKCJ0ZXh0YmxvY2sgdG9vIHNob3J0ICglZCBpbnN0ZWFkIG9mICVsZCkuXG4iLGxlbixoZWFkLnRleHRzaXplKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZiwmaGZpbmZvKSkgewoJCUVSUigiR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUgZmFpbGVkPy5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCV9fdzMxX2R1bXB0cmVlKHRhYlswXS53MSx0eHQsdGFiLCZoZWFkLEhLRVlfQ0xBU1NFU19ST09ULGxhc3Rtb2RpZmllZCwwKTsKCWZyZWUodGFiKTsKCWZyZWUodHh0KTsKCV9sY2xvc2UoaGYpOwoJcmV0dXJuOwp9CgoKc3RhdGljIHZvaWQgc2F2ZV9hdF9leGl0KCBIS0VZIGhrZXksIGNvbnN0IGNoYXIgKnBhdGggKQp7CiAgICBjb25zdCBjaGFyICpjb25mZGlyID0gZ2V0X2NvbmZpZ19kaXIoKTsKICAgIHNpemVfdCBsZW4gPSBzdHJsZW4oY29uZmRpcikgKyBzdHJsZW4ocGF0aCkgKyAyOwogICAgaWYgKGxlbiA+IFJFUVVFU1RfTUFYX1ZBUl9TSVpFKQogICAgewogICAgICAgIEVSUiggImNvbmZpZyBkaXIgJyVzJyB0b28gbG9uZ1xuIiwgY29uZmRpciApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIFNFUlZFUl9TVEFSVF9SRVEKICAgIHsKICAgICAgICBzdHJ1Y3Qgc2F2ZV9yZWdpc3RyeV9hdGV4aXRfcmVxdWVzdCAqcmVxID0gc2VydmVyX2FsbG9jX3JlcSggc2l6ZW9mKCpyZXEpLCBsZW4gKTsKICAgICAgICBzcHJpbnRmKCBzZXJ2ZXJfZGF0YV9wdHIocmVxKSwgIiVzLyVzIiwgY29uZmRpciwgcGF0aCApOwogICAgICAgIHJlcS0+aGtleSA9IGhrZXk7CiAgICAgICAgc2VydmVyX2NhbGwoIFJFUV9TQVZFX1JFR0lTVFJZX0FURVhJVCApOwogICAgfQogICAgU0VSVkVSX0VORF9SRVE7Cn0KCi8qIGNvbmZpZ3VyZSBzYXZlIGZpbGVzIGFuZCBzdGFydCB0aGUgcGVyaW9kaWMgc2F2aW5nIHRpbWVyICovCnN0YXRpYyB2b2lkIFNIRUxMX0luaXRSZWdpc3RyeVNhdmluZyggSEtFWSBoa2V5X3VzZXJzX2RlZmF1bHQgKQp7CiAgICBpbnQgYWxsID0gUFJPRklMRV9HZXRXaW5lSW5pQm9vbCggInJlZ2lzdHJ5IiwgIlNhdmVPbmx5VXBkYXRlZEtleXMiLCAxICk7CiAgICBpbnQgcGVyaW9kID0gUFJPRklMRV9HZXRXaW5lSW5pSW50KCAicmVnaXN0cnkiLCAiUGVyaW9kaWNTYXZlIiwgMCApOwoKICAgIC8qIHNldCBzYXZpbmcgbGV2ZWwgKDAgZm9yIHNhdmluZyBldmVyeXRoaW5nLCAxIGZvciBzYXZpbmcgb25seSBtb2RpZmllZCBrZXlzKSAqLwogICAgU0VSVkVSX1NUQVJUX1JFUQogICAgewogICAgICAgIHN0cnVjdCBzZXRfcmVnaXN0cnlfbGV2ZWxzX3JlcXVlc3QgKnJlcSA9IHNlcnZlcl9hbGxvY19yZXEoIHNpemVvZigqcmVxKSwgMCApOwogICAgICAgIHJlcS0+Y3VycmVudCA9IDE7CiAgICAgICAgcmVxLT5zYXZpbmcgID0gIWFsbDsKICAgICAgICByZXEtPnBlcmlvZCAgPSBwZXJpb2QgKiAxMDAwOwogICAgICAgIHNlcnZlcl9jYWxsKCBSRVFfU0VUX1JFR0lTVFJZX0xFVkVMUyApOwogICAgfQogICAgU0VSVkVSX0VORF9SRVE7CgogICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woInJlZ2lzdHJ5IiwiV3JpdGV0b0hvbWVSZWdpc3RyaWVzIiwxKSkKICAgIHsKICAgICAgICBzYXZlX2F0X2V4aXQoIEhLRVlfQ1VSUkVOVF9VU0VSLCBTQVZFX0NVUlJFTlRfVVNFUiApOwogICAgICAgIHNhdmVfYXRfZXhpdCggSEtFWV9MT0NBTF9NQUNISU5FLCBTQVZFX0xPQ0FMX01BQ0hJTkUgKTsKICAgICAgICBzYXZlX2F0X2V4aXQoIGhrZXlfdXNlcnNfZGVmYXVsdCwgU0FWRV9ERUZBVUxUX1VTRVIgKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNldExvYWRMZXZlbCBbSW50ZXJuYWxdCiAqCiAqIHNldCBsZXZlbCB0byAwIGZvciBsb2FkaW5nIHN5c3RlbSBmaWxlcwogKiBzZXQgbGV2ZWwgdG8gMSBmb3IgbG9hZGluZyB1c2VyIGZpbGVzCiAqLwpzdGF0aWMgdm9pZCBTZXRMb2FkTGV2ZWwoaW50IGxldmVsKQp7CiAgICBTRVJWRVJfU1RBUlRfUkVRCiAgICB7CiAgICAgICAgc3RydWN0IHNldF9yZWdpc3RyeV9sZXZlbHNfcmVxdWVzdCAqcmVxID0gc2VydmVyX2FsbG9jX3JlcSggc2l6ZW9mKCpyZXEpLCAwICk7CgoJcmVxLT5jdXJyZW50ID0gbGV2ZWw7CglyZXEtPnNhdmluZyAgPSAwOwogICAgICAgIHJlcS0+cGVyaW9kICA9IDA7CglzZXJ2ZXJfY2FsbCggUkVRX1NFVF9SRUdJU1RSWV9MRVZFTFMgKTsKICAgIH0KICAgIFNFUlZFUl9FTkRfUkVROwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEVMTF9Mb2FkUmVnaXN0cnkgW0ludGVybmFsXQogKi8KI2RlZmluZSBSRUdfRE9OVExPQUQgLTEKI2RlZmluZSBSRUdfV0lOMzEgIDAKI2RlZmluZSBSRUdfV0lOOTUgIDEKI2RlZmluZSBSRUdfV0lOTlQgIDIKCnZvaWQgU0hFTExfTG9hZFJlZ2lzdHJ5KCB2b2lkICkKewogIEhLRVkJaGtleTsKICBjaGFyIHdpbmRpcltNQVhfUEFUSE5BTUVfTEVOXTsKICBjaGFyIHBhdGhbTUFYX1BBVEhOQU1FX0xFTl07CiAgaW50ICBzeXN0ZW10eXBlID0gUkVHX1dJTjMxOwogIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0OwoKICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgaWYgKCFDTElFTlRfSXNCb290VGhyZWFkKCkpIHJldHVybjsgIC8qIGFscmVhZHkgbG9hZGVkICovCgogIFJFR0lTVFJZX0luaXQoKTsKICBTZXRMb2FkTGV2ZWwoMCk7CgogIGlmIChSZWdDcmVhdGVLZXlBKEhLRVlfVVNFUlMsICIuRGVmYXVsdCIsICZoa2V5X3VzZXJzX2RlZmF1bHQpKQoJICBoa2V5X3VzZXJzX2RlZmF1bHQgPSAwOwoKICBHZXRXaW5kb3dzRGlyZWN0b3J5QSggd2luZGlyLCBNQVhfUEFUSE5BTUVfTEVOICk7CgogIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sKCAiUmVnaXN0cnkiLCAiTG9hZFdpbmRvd3NSZWdpc3RyeUZpbGVzIiwgMSkpCiAgewogICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0zMi9jb25maWcvc3lzdGVtIC0tPiB3aW5udCAqLwogICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICBzdHJuY2F0KHBhdGgsICJcXHN5c3RlbTMyXFxjb25maWdcXHN5c3RlbSIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzQShwYXRoKSAhPSAoRFdPUkQpLTEpIAogICAgewogICAgICBzeXN0ZW10eXBlID0gUkVHX1dJTk5UOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0uZGF0IC0tPiB3aW45NSAqLwogICAgICBzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgICAgc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0uZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICBpZihHZXRGaWxlQXR0cmlidXRlc0EocGF0aCkgIT0gKERXT1JEKS0xKQogICAgICB7CiAgICAgICAgc3lzdGVtdHlwZSA9IFJFR19XSU45NTsKICAgICAgfQogICAgfQoKICAgIGlmICgoc3lzdGVtdHlwZT09UkVHX1dJTk5UKQogICAgICAmJiAoISBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJXaW5lIiwgIlByb2ZpbGUiLCAiIiwgcGF0aCwgTUFYX1BBVEhOQU1FX0xFTikpKQogICAgewogICAgICAgTUVTU0FHRSgiV2hlbiB5b3UgYXJlIHJ1bm5pbmcgd2l0aCBhIG5hdGl2ZSBOVCBkaXJlY3Rvcnkgc3BlY2lmeVxuIik7CiAgICAgICBNRVNTQUdFKCInUHJvZmlsZT08cHJvZmlsZWRpcmVjdG9yeT4nIG9yIGRpc2FibGUgbG9hZGluZyBvZiBXaW5kb3dzXG4iKTsKICAgICAgIE1FU1NBR0UoInJlZ2lzdHJ5IChMb2FkV2luZG93c1JlZ2lzdHJ5RmlsZXM9TilcbiIpOwogICAgICAgc3lzdGVtdHlwZSA9IFJFR19ET05UTE9BRDsKICAgIH0KICB9CiAgZWxzZQogIHsKICAgIC8qIG9ubHkgd2luZSByZWdpc3RyeSAqLwogICAgc3lzdGVtdHlwZSA9IFJFR19ET05UTE9BRDsKICB9ICAKCiAgc3dpdGNoIChzeXN0ZW10eXBlKQogIHsKICAgIGNhc2UgUkVHX1dJTjMxOgogICAgICBfdzMxX2xvYWRyZWcoKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBSRUdfV0lOOTU6ICAKICAgICAgLyogTG9hZCB3aW5kb3dzIDk1IGVudHJpZXMgKi8KICAgICAgTmF0aXZlUmVnTG9hZEtleShIS0VZX0xPQ0FMX01BQ0hJTkUsICJDOlxcc3lzdGVtLjFzdCIsIDApOwoKICAgICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgIHN0cm5jYXQocGF0aCwgIlxcc3lzdGVtLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgTmF0aXZlUmVnTG9hZEtleShIS0VZX0xPQ0FMX01BQ0hJTkUsIHBhdGgsIDApOwoKICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggIldpbmUiLCAiUHJvZmlsZSIsICIiLCBwYXRoLCBNQVhfUEFUSE5BTUVfTEVOKSkKICAgICAgewoJLyogdXNlciBzcGVjaWZpYyB1c2VyLmRhdCAqLwoJc3RybmNhdChwYXRoLCAiXFx1c2VyLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgICBpZiAoIU5hdGl2ZVJlZ0xvYWRLZXkoIEhLRVlfQ1VSUkVOVF9VU0VSLCBwYXRoLCAxICkpCgl7CgkgIE1FU1NBR0UoImNhbid0IGxvYWQgd2luOTUgdXNlci1yZWdpc3RyeSAlc1xuIiwgcGF0aCk7CgkgIE1FU1NBR0UoImNoZWNrIHdpbmUuY29uZiwgc2VjdGlvbiBbV2luZV0sIHZhbHVlICdQcm9maWxlJ1xuIik7Cgl9CgkvKiBkZWZhdWx0IHVzZXIuZGF0ICovCglpZiAoaGtleV91c2Vyc19kZWZhdWx0KQoJewogICAgICAgICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgICAgICBzdHJuY2F0KHBhdGgsICJcXHVzZXIuZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICAgICAgTmF0aXZlUmVnTG9hZEtleShoa2V5X3VzZXJzX2RlZmF1bHQsIHBhdGgsIDEpOwoJfQogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgIC8qIGdsb2JhbCB1c2VyLmRhdCAqLwoJc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgICAgc3RybmNhdChwYXRoLCAiXFx1c2VyLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgICBOYXRpdmVSZWdMb2FkS2V5KEhLRVlfQ1VSUkVOVF9VU0VSLCBwYXRoLCAxKTsKICAgICAgfQogICAgICBicmVhazsKCiAgICBjYXNlIFJFR19XSU5OVDogIAogICAgICAvKiBkZWZhdWx0IHVzZXIuZGF0ICovCiAgICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJXaW5lIiwgIlByb2ZpbGUiLCAiIiwgcGF0aCwgTUFYX1BBVEhOQU1FX0xFTikpCiAgICAgIHsKICAgICAgICBzdHJuY2F0KHBhdGgsICJcXG50dXNlci5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgICAgaWYoIU5hdGl2ZVJlZ0xvYWRLZXkoIEhLRVlfQ1VSUkVOVF9VU0VSLCBwYXRoLCAxICkpCiAgICAgICAgewogICAgICAgICAgIE1FU1NBR0UoImNhbid0IGxvYWQgTlQgdXNlci1yZWdpc3RyeSAlc1xuIiwgcGF0aCk7CgkgICBNRVNTQUdFKCJjaGVjayB3aW5lLmNvbmYsIHNlY3Rpb24gW1dpbmVdLCB2YWx1ZSAnUHJvZmlsZSdcbiIpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLyogZGVmYXVsdCB1c2VyLmRhdCAqLwogICAgICBpZiAoaGtleV91c2Vyc19kZWZhdWx0KQogICAgICB7CiAgICAgICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgICAgc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0zMlxcY29uZmlnXFxkZWZhdWx0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoaGtleV91c2Vyc19kZWZhdWx0LCBwYXRoLCAxKTsKICAgICAgfQoKICAgICAgLyoKICAgICAgKiBGSVhNRQogICAgICAqICBtYXAgSExNXFN5c3RlbVxDb250cm9sU2V0MDAxIHRvIEhMTVxTeXN0ZW1cQ3VycmVudENvbnRyb2xTZXQKICAgICAgKi8KCiAgICAgIGlmICghUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsICJTWVNURU0iLCAmaGtleSkpCiAgICAgIHsKCXN0cmNweShwYXRoLCB3aW5kaXIpOwoJc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0zMlxcY29uZmlnXFxzeXN0ZW0iLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CglOYXRpdmVSZWdMb2FkS2V5KGhrZXksIHBhdGgsIDEpOwogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICB9CgogICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCAiU09GVFdBUkUiLCAmaGtleSkpCiAgICAgIHsKCXN0cmNweShwYXRoLCB3aW5kaXIpOwoJc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0zMlxcY29uZmlnXFxzb2Z0d2FyZSIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKCU5hdGl2ZVJlZ0xvYWRLZXkoaGtleSwgcGF0aCwgMSk7CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgIH0KCiAgICAgIHN0cmNweShwYXRoLCB3aW5kaXIpOwogICAgICBzdHJuY2F0KHBhdGgsICJcXHN5c3RlbTMyXFxjb25maWdcXHNhbSIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgTmF0aXZlUmVnTG9hZEtleShIS0VZX0xPQ0FMX01BQ0hJTkUsIHBhdGgsIDApOwoKICAgICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICAgIHN0cm5jYXQocGF0aCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc2VjdXJpdHkiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoSEtFWV9MT0NBTF9NQUNISU5FLCBwYXRoLCAwKTsKCiAgICAgIC8qIHRoaXMga2V5IGlzIGdlbmVyYXRlZCB3aGVuIHRoZSBudC1jb3JlIGJvb3RlZCBzdWNjZXNzZnVsbHkgKi8KICAgICAgaWYgKCFSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDbG9uZSIsJmhrZXkpKQogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICBicmVhazsKICB9IC8qIHN3aXRjaCAqLwogIAogIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sICgicmVnaXN0cnkiLCJMb2FkR2xvYmFsUmVnaXN0cnlGaWxlcyIsIDEpKQogIHsKICAgICAgLyogCiAgICAgICAqIExvYWQgdGhlIGdsb2JhbCBIS1UgaGl2ZSBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIKICAgICAgICovIAogICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX1VTRVJTLCBTQVZFX1VTRVJTX0RFRkFVTFQgKTsKCiAgICAgIC8qIAogICAgICAgKiBMb2FkIHRoZSBnbG9iYWwgbWFjaGluZSBkZWZhdWx0cyBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIKICAgICAgICovCiAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfTE9DQUxfTUFDSElORSwgU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQgKTsKICB9CgogIFNldExvYWRMZXZlbCgxKTsKCiAgLyoKICAgKiBMb2FkIHRoZSB1c2VyIHNhdmVkIHJlZ2lzdHJpZXMgCiAgICovCiAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2woInJlZ2lzdHJ5IiwgIkxvYWRIb21lUmVnaXN0cnlGaWxlcyIsIDEpKQogIHsKICAgICAgY29uc3QgY2hhciAqY29uZmRpciA9IGdldF9jb25maWdfZGlyKCk7CiAgICAgIHVuc2lnbmVkIGludCBsZW4gPSBzdHJsZW4oY29uZmRpcikgKyAyMDsKICAgICAgY2hhciAqZm4gPSBwYXRoOwoKICAgICAgaWYgKGxlbiA+IHNpemVvZihwYXRoKSkgZm4gPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbiApOwogICAgICAvKiAKICAgICAgICogTG9hZCB1c2VyJ3MgcGVyc29uYWwgdmVyc2lvbnMgb2YgZ2xvYmFsIEhLVS8uRGVmYXVsdCBrZXlzCiAgICAgICAqLwogICAgICBpZiAoZm4pCiAgICAgIHsKICAgICAgICAgIGNoYXIgKnN0cjsKICAgICAgICAgIHN0cmNweSggZm4sIGNvbmZkaXIgKTsKICAgICAgICAgIHN0ciA9IGZuICsgc3RybGVuKGZuKTsKICAgICAgICAgICpzdHIrKyA9ICcvJzsKCiAgICAgICAgICAvKiB0cnkgdG8gbG9hZCBIS1VcLkRlZmF1bHQga2V5IG9ubHkgKi8KICAgICAgICAgIHN0cmNweSggc3RyLCBTQVZFX0RFRkFVTFRfVVNFUiApOwogICAgICAgICAgaWYgKF93aW5lX2xvYWRyZWcoIGhrZXlfdXNlcnNfZGVmYXVsdCwgZm4gKSkKICAgICAgICAgIHsKICAgICAgICAgICAgICAvKiBpZiBub3QgZm91bmQgbG9hZCBvbGQgZmlsZSBjb250YWluaW5nIGJvdGggSEtVXC5EZWZhdWx0IGFuZCBIS1VcdXNlciAqLwogICAgICAgICAgICAgIHN0cmNweSggc3RyLCBTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQgKTsKICAgICAgICAgICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX1VTRVJTLCBmbiApOyAKICAgICAgICAgIH0KCiAgICAgICAgICBzdHJjcHkoIHN0ciwgU0FWRV9DVVJSRU5UX1VTRVIgKTsKICAgICAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfQ1VSUkVOVF9VU0VSLCBmbiApOwoKICAgICAgICAgIHN0cmNweSggc3RyLCBTQVZFX0xPQ0FMX01BQ0hJTkUgKTsKICAgICAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfTE9DQUxfTUFDSElORSwgZm4gKTsKCiAgICAgICAgICBpZiAoZm4gIT0gcGF0aCkgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGZuICk7CiAgICAgIH0KICB9CiAgU0hFTExfSW5pdFJlZ2lzdHJ5U2F2aW5nKCBoa2V5X3VzZXJzX2RlZmF1bHQgKTsKICBSZWdDbG9zZUtleSggaGtleV91c2Vyc19kZWZhdWx0ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKiogQVBJIEZVTkNUSU9OUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0ZsdXNoS2V5IFtLRVJORUwuMjI3XSBbQURWQVBJMzIuMTQzXQogKiBJbW1lZGlhdGVseSB3cml0ZXMga2V5IHRvIHJlZ2lzdHJ5LgogKiBPbmx5IHJldHVybnMgYWZ0ZXIgZGF0YSBoYXMgYmVlbiB3cml0dGVuIHRvIGRpc2suCiAqCiAqIEZJWE1FOiBkb2VzIGl0IHJlYWxseSB3YWl0IHVudGlsIGRhdGEgaXMgd3JpdHRlbiA/CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdyaXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkoIEhLRVkgaGtleSApCnsKICAgIEZJWE1FKCAiKCV4KTogc3R1YlxuIiwgaGtleSApOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ29ubmVjdFJlZ2lzdHJ5VyBbQURWQVBJMzIuMTI4XQogKgogKiBQQVJBTVMKICogICAgbHBNYWNoaW5lTmFtZSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHJlbW90ZSBjb21wdXRlcgogKiAgICBoSGV5ICAgICAgICAgIFtJXSBQcmVkZWZpbmVkIHJlZ2lzdHJ5IGhhbmRsZQogKiAgICBwaGtSZXN1bHQgICAgIFtJXSBBZGRyZXNzIG9mIGJ1ZmZlciBmb3IgcmVtb3RlIHJlZ2lzdHJ5IGhhbmRsZQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5VyggTFBDV1NUUiBscE1hY2hpbmVOYW1lLCBIS0VZIGhLZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSBwaGtSZXN1bHQgKQp7CiAgICBUUkFDRSgiKCVzLCV4LCVwKTogc3R1YlxuIixkZWJ1Z3N0cl93KGxwTWFjaGluZU5hbWUpLGhLZXkscGhrUmVzdWx0KTsKCiAgICBpZiAoIWxwTWFjaGluZU5hbWUgfHwgISpscE1hY2hpbmVOYW1lKSB7CiAgICAgICAgLyogVXNlIHRoZSBsb2NhbCBtYWNoaW5lIG5hbWUgKi8KICAgICAgICByZXR1cm4gUmVnT3BlbktleTE2KCBoS2V5LCAiIiwgcGhrUmVzdWx0ICk7CiAgICB9CgogICAgRklYTUUoIkNhbm5vdCBjb25uZWN0IHRvICVzXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSkpOwogICAgcmV0dXJuIEVSUk9SX0JBRF9ORVRQQVRIOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnlBIFtBRFZBUEkzMi4xMjddCiAqLwpMT05HIFdJTkFQSSBSZWdDb25uZWN0UmVnaXN0cnlBKCBMUENTVFIgbWFjaGluZSwgSEtFWSBoa2V5LCBMUEhLRVkgcmVza2V5ICkKewogICAgTFBXU1RSIG1hY2hpbmVXID0gSEVBUF9zdHJkdXBBdG9XKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBtYWNoaW5lICk7CiAgICBEV09SRCByZXQgPSBSZWdDb25uZWN0UmVnaXN0cnlXKCBtYWNoaW5lVywgaGtleSwgcmVza2V5ICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWFjaGluZVcgKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0dldEtleVNlY3VyaXR5IFtBRFZBUEkzMi4xNDRdCiAqIFJldHJpZXZlcyBhIGNvcHkgb2Ygc2VjdXJpdHkgZGVzY3JpcHRvciBwcm90ZWN0aW5nIHRoZSByZWdpc3RyeSBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICAgICAgICAgW0ldICAgT3BlbiBoYW5kbGUgb2Yga2V5IHRvIHNldAogKiAgICBTZWN1cml0eUluZm9ybWF0aW9uICAgIFtJXSAgIERlc2NyaXB0b3IgY29udGVudHMKICogICAgcFNlY3VyaXR5RGVzY3JpcHRvciAgICBbT10gICBBZGRyZXNzIG9mIGRlc2NyaXB0b3IgZm9yIGtleQogKiAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yIFtJL09dIEFkZHJlc3Mgb2Ygc2l6ZSBvZiBidWZmZXIgYW5kIGRlc2NyaXB0aW9uCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpMT05HIFdJTkFQSSBSZWdHZXRLZXlTZWN1cml0eSggSEtFWSBoa2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFQ1VSSVRZX0lORk9STUFUSU9OIFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU0VDVVJJVFlfREVTQ1JJUFRPUiBwU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yICkKewogICAgVFJBQ0UoIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LFNlY3VyaXR5SW5mb3JtYXRpb24scFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgIGxwY2JTZWN1cml0eURlc2NyaXB0b3I/KmxwY2JTZWN1cml0eURlc2NyaXB0b3I6MCk7CgogICAgLyogRklYTUU6IENoZWNrIGZvciB2YWxpZCBTZWN1cml0eUluZm9ybWF0aW9uIHZhbHVlcyAqLwoKICAgIGlmICgqbHBjYlNlY3VyaXR5RGVzY3JpcHRvciA8IHNpemVvZihTRUNVUklUWV9ERVNDUklQVE9SKSkKICAgICAgICByZXR1cm4gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUjsKCiAgICBGSVhNRSgiKCV4LCVsZCwlcCwlbGQpOiBzdHViXG4iLGhrZXksU2VjdXJpdHlJbmZvcm1hdGlvbiwKICAgICAgICAgIHBTZWN1cml0eURlc2NyaXB0b3IsbHBjYlNlY3VyaXR5RGVzY3JpcHRvcj8qbHBjYlNlY3VyaXR5RGVzY3JpcHRvcjowKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTm90aWZ5Q2hhbmdlS2V5VmFsdWUgW0FEVkFQSTMyLj8/P10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICBbSV0gSGFuZGxlIG9mIGtleSB0byB3YXRjaAogKiAgICBmV2F0Y2hTdWJUcmVlICAgW0ldIEZsYWcgZm9yIHN1YmtleSBub3RpZmljYXRpb24KICogICAgZmR3Tm90aWZ5RmlsdGVyIFtJXSBDaGFuZ2VzIHRvIGJlIHJlcG9ydGVkCiAqICAgIGhFdmVudCAgICAgICAgICBbSV0gSGFuZGxlIG9mIHNpZ25hbGVkIGV2ZW50CiAqICAgIGZBc3luYyAgICAgICAgICBbSV0gRmxhZyBmb3IgYXN5bmNocm9ub3VzIHJlcG9ydGluZwogKi8KTE9ORyBXSU5BUEkgUmVnTm90aWZ5Q2hhbmdlS2V5VmFsdWUoIEhLRVkgaGtleSwgQk9PTCBmV2F0Y2hTdWJUcmVlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGZkd05vdGlmeUZpbHRlciwgSEFORExFIGhFdmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgZkFzeW5jICkKewogICAgRklYTUUoIigleCwlaSwlbGQsJXgsJWkpOiBzdHViXG4iLGhrZXksZldhdGNoU3ViVHJlZSxmZHdOb3RpZnlGaWx0ZXIsCiAgICAgICAgICBoRXZlbnQsZkFzeW5jKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXlXIFtBRFZBUEkzMi4xNzNdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwU3ViS2V5IFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5IHRvIHVubG9hZAogKi8KTE9ORyBXSU5BUEkgUmVnVW5Mb2FkS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwU3ViS2V5ICkKewogICAgRklYTUUoIigleCwlcyk6IHN0dWJcbiIsaGtleSwgZGVidWdzdHJfdyhscFN1YktleSkpOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1VuTG9hZEtleUEgW0FEVkFQSTMyLjE3Ml0KICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5ICkKewogICAgTFBXU1RSIGxwU3ViS2V5VyA9IEhFQVBfc3RyZHVwQXRvVyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBTdWJLZXkgKTsKICAgIExPTkcgcmV0ID0gUmVnVW5Mb2FkS2V5VyggaGtleSwgbHBTdWJLZXlXICk7CiAgICBpZihscFN1YktleVcpIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBscFN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0S2V5U2VjdXJpdHkgW0FEVkFQSTMyLjE2N10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldIE9wZW4gaGFuZGxlIG9mIGtleSB0byBzZXQKICogICAgU2VjdXJpdHlJbmZvICBbSV0gRGVzY3JpcHRvciBjb250ZW50cwogKiAgICBwU2VjdXJpdHlEZXNjIFtJXSBBZGRyZXNzIG9mIGRlc2NyaXB0b3IgZm9yIGtleQogKi8KTE9ORyBXSU5BUEkgUmVnU2V0S2V5U2VjdXJpdHkoIEhLRVkgaGtleSwgU0VDVVJJVFlfSU5GT1JNQVRJT04gU2VjdXJpdHlJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzYyApCnsKICAgIFRSQUNFKCIoJXgsJWxkLCVwKVxuIixoa2V5LFNlY3VyaXR5SW5mbyxwU2VjdXJpdHlEZXNjKTsKCiAgICAvKiBJdCBzZWVtcyB0byBwZXJmb3JtIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoKFNlY3VyaXR5SW5mbyAmIE9XTkVSX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBHUk9VUF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgREFDTF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgU0FDTF9TRUNVUklUWV9JTkZPUk1BVElPTikpIHsKICAgICAgICAvKiBQYXJhbSBPSyAqLwogICAgfSBlbHNlCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGlmICghcFNlY3VyaXR5RGVzYykKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgRklYTUUoIjooJXgsJWxkLCVwKTogc3R1YlxuIixoa2V5LFNlY3VyaXR5SW5mbyxwU2VjdXJpdHlEZXNjKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleVcgW0FEVkFQSTMyLjE2NF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgcmVzdG9yZSBiZWdpbnMKICogICAgbHBGaWxlICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBjb250YWluaW5nIHNhdmVkIHRyZWUKICogICAgZHdGbGFncyBbSV0gT3B0aW9uYWwgZmxhZ3MKICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgVFJBQ0UoIigleCwlcywlbGQpXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIEl0IHNlZW1zIHRvIGRvIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoIWxwRmlsZSB8fCAhKmxwRmlsZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgRklYTUUoIigleCwlcywlbGQpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIENoZWNrIGZvciBmaWxlIGV4aXN0ZW5jZSAqLwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5QSBbQURWQVBJMzIuMTYzXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVzdG9yZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIExQV1NUUiBscEZpbGVXID0gSEVBUF9zdHJkdXBBdG9XKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBscEZpbGUgKTsKICAgIExPTkcgcmV0ID0gUmVnUmVzdG9yZUtleVcoIGhrZXksIGxwRmlsZVcsIGR3RmxhZ3MgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBscEZpbGVXICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5VyBbQURWQVBJMzIuMTYyXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBTdWJLZXkgIFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5CiAqICAgIGxwTmV3RmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgZmlsZSB3aXRoIG5ldyBkYXRhCiAqICAgIGxwT2xkRmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgYmFja3VwIGZpbGUKICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBTdWJLZXksIExQQ1dTVFIgbHBOZXdGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIGxwT2xkRmlsZSApCnsKICAgIEZJWE1FKCIoJXgsJXMsJXMsJXMpOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwU3ViS2V5KSwgCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5QSBbQURWQVBJMzIuMTYxXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5LCBMUENTVFIgbHBOZXdGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBPbGRGaWxlICkKewogICAgTFBXU1RSIGxwU3ViS2V5VyA9IEhFQVBfc3RyZHVwQXRvVyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBTdWJLZXkgKTsKICAgIExQV1NUUiBscE5ld0ZpbGVXID0gSEVBUF9zdHJkdXBBdG9XKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBscE5ld0ZpbGUgKTsKICAgIExQV1NUUiBscE9sZEZpbGVXID0gSEVBUF9zdHJkdXBBdG9XKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBscE9sZEZpbGUgKTsKICAgIExPTkcgcmV0ID0gUmVnUmVwbGFjZUtleVcoIGhrZXksIGxwU3ViS2V5VywgbHBOZXdGaWxlVywgbHBPbGRGaWxlVyApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxwT2xkRmlsZVcgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBscE5ld0ZpbGVXICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBTdWJLZXlXICk7CiAgICByZXR1cm4gcmV0Owp9CgoKCgoKCi8qIDE2LWJpdCBmdW5jdGlvbnMgKi8KCi8qIDAgYW5kIDEgYXJlIHZhbGlkIHJvb3RrZXlzIGluIHdpbjE2IHNoZWxsLmRsbCBhbmQgYXJlIHVzZWQgYnkKICogc29tZSBwcm9ncmFtcy4gRG8gbm90IHJlbW92ZSB0aG9zZSBjYXNlcy4gLU1NCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZml4X3dpbjE2X2hrZXkoIEhLRVkgKmhrZXkgKQp7CiAgICBpZiAoKmhrZXkgPT0gMCB8fCAqaGtleSA9PSAxKSAqaGtleSA9IEhLRVlfQ0xBU1NFU19ST09UOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdFbnVtS2V5MTYgICBbS0VSTkVMLjIxNl0gW1NIRUxMLjddCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTE2KCBIS0VZIGhrZXksIERXT1JEIGluZGV4LCBMUFNUUiBuYW1lLCBEV09SRCBuYW1lX2xlbiApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0VudW1LZXlBKCBoa2V5LCBpbmRleCwgbmFtZSwgbmFtZV9sZW4gKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnT3BlbktleTE2ICAgW0tFUk5FTC4yMTddIFtTSEVMTC4xXQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBIS0VZIHJldGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ09wZW5LZXlBKCBoa2V5LCBuYW1lLCByZXRrZXkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnQ3JlYXRlS2V5MTYgICBbS0VSTkVMLjIxOF0gW1NIRUxMLjJdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQSEtFWSByZXRrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdDcmVhdGVLZXlBKCBoa2V5LCBuYW1lLCByZXRrZXkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRGVsZXRlS2V5MTYgICBbS0VSTkVMLjIxOV0gW1NIRUxMLjRdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdEZWxldGVLZXlBKCBoa2V5LCBuYW1lICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0Nsb3NlS2V5MTYgICBbS0VSTkVMLjIyMF0gW1NIRUxMLjNdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ2xvc2VLZXkxNiggSEtFWSBoa2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnQ2xvc2VLZXkoIGhrZXkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnU2V0VmFsdWUxNiAgIFtLRVJORUwuMjIxXSBbU0hFTEwuNV0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBEV09SRCB0eXBlLCBMUENTVFIgZGF0YSwgRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUEoIGhrZXksIG5hbWUsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0RlbGV0ZVZhbHVlMTYgIFtLRVJORUwuMjIyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMTYoIEhLRVkgaGtleSwgTFBTVFIgbmFtZSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0RlbGV0ZVZhbHVlQSggaGtleSwgbmFtZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdFbnVtVmFsdWUxNiAgIFtLRVJORUwuMjIzXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1WYWx1ZTE2KCBIS0VZIGhrZXksIERXT1JEIGluZGV4LCBMUFNUUiB2YWx1ZSwgTFBEV09SRCB2YWxfY291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCByZXNlcnZlZCwgTFBEV09SRCB0eXBlLCBMUEJZVEUgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0VudW1WYWx1ZUEoIGhrZXksIGluZGV4LCB2YWx1ZSwgdmFsX2NvdW50LCByZXNlcnZlZCwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnUXVlcnlWYWx1ZTE2ICAgW0tFUk5FTC4yMjRdIFtTSEVMTC42XQogKgogKiBOT1RFUwogKiAgICBJcyB0aGlzIEhBQ0sgc3RpbGwgYXBwbGljYWJsZT8KICoKICogSEFDSwogKiAgICBUaGUgMTZiaXQgUmVnUXVlcnlWYWx1ZSBkb2Vzbid0IGhhbmRsZSBzZWxlY3RvcmJsb2NrcyBhbnl3YXksIHNvIHdlIGp1c3QKICogICAgbWFzayBvdXQgdGhlIGhpZ2ggMTYgYml0LiAgVGhpcyAobm90IHNvIG11Y2ggaW5jaWRlbnRseSkgaG9wZWZ1bGx5IGZpeGVzCiAqICAgIEFsZHVzIEZINCkKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQU1RSIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIGlmIChjb3VudCkgKmNvdW50ICY9IDB4ZmZmZjsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlQSggaGtleSwgbmFtZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnUXVlcnlWYWx1ZUV4MTYgICBbS0VSTkVMLjIyNV0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXgxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBEV09SRCByZXNlcnZlZCwgTFBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUV4QSggaGtleSwgbmFtZSwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1NldFZhbHVlRXgxNiAgIFtLRVJORUwuMjI2XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXgxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgRFdPUkQgcmVzZXJ2ZWQsIERXT1JEIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlNUIEJZVEUgKmRhdGEsIERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVFeEEoIGhrZXksIG5hbWUsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9Cg==