LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGxpbWl0cy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpZmRlZiBIQVZFX1NZU19FUlJOT19ICiNpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDx0aW1lLmg+CiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgInNlcnZlci5oIgojaW5jbHVkZSAic2VydmljZXMuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTChyZWcpOwoKc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCh2b2lkKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUICAgICAgICAgIEVUQ0RJUiIvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUICBFVENESVIiL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0NVUlJFTlRfVVNFUiAgICAgICAgICAgInVzZXIucmVnIgojZGVmaW5lIFNBVkVfREVGQVVMVF9VU0VSICAgICAgICAgICAidXNlcmRlZi5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUICAgICJ3aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FICAgICAgICAgICJzeXN0ZW0ucmVnIgoKCnN0YXRpYyB2b2lkICp4bWFsbG9jKCBzaXplX3Qgc2l6ZSApCnsKICAgIHZvaWQgKnJlczsKIAogICAgcmVzID0gbWFsbG9jIChzaXplID8gc2l6ZSA6IDEpOwogICAgaWYgKHJlcyA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiVmlydHVhbCBtZW1vcnkgZXhoYXVzdGVkLlxuIik7CiAgICAgICAgZXhpdCAoMSk7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSRUdJU1RSWV9Jbml0IFtJbnRlcm5hbF0KICogUmVnaXN0cnkgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBzb21lIGRlZmF1bHQga2V5cy4gCiAqLwpzdGF0aWMgdm9pZCBSRUdJU1RSWV9Jbml0KHZvaWQpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJVFJBQ0UoIih2b2lkKVxuIik7CgoJUmVnQ3JlYXRlS2V5QShIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXhBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3dzIE5UXFxDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50QnVpbGROdW1iZXIKCSAqCQkJCQkJQ3VycmVudFR5cGUKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE93bmVyCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPcmdhbml6YXRpb24KCSAqCgkgKi8KCS8qIFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTTk1QXFxQYXJhbWV0ZXJzXFxSRkMxMTU2QWdlbnQKCSAqIAkJCQkJc3RyaW5nCVN5c0NvbnRhY3QKCSAqIAkJCQkJc3RyaW5nCVN5c0xvY2F0aW9uCgkgKiAJCQkJCQlTeXNTZXJ2aWNlcwoJICovCglpZiAoLTEhPWdldGhvc3RuYW1lKGJ1ZiwyMDApKSB7CgkJUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXENvbnRyb2xcXENvbXB1dGVyTmFtZVxcQ29tcHV0ZXJOYW1lIiwmaGtleSk7CgkJUmVnU2V0VmFsdWVFeEEoaGtleSwiQ29tcHV0ZXJOYW1lIiwwLFJFR19TWixidWYsc3RybGVuKGJ1ZikrMSk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqIExPQUQgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmluZF9vcl9hZGRfa2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbmxpbmUgSEtFWSBfZmluZF9vcl9hZGRfa2V5KCBIS0VZIGhrZXksIExQV1NUUiBrZXluYW1lICkKewogICAgSEtFWSBzdWJrZXk7CiAgICBpZiAoUmVnQ3JlYXRlS2V5VyggaGtleSwga2V5bmFtZSwgJnN1YmtleSApICE9IEVSUk9SX1NVQ0NFU1MpIHN1YmtleSA9IDA7CiAgICBpZiAoa2V5bmFtZSkgZnJlZSgga2V5bmFtZSApOwogICAgcmV0dXJuIHN1YmtleTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmluZF9vcl9hZGRfdmFsdWUgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX2ZpbmRfb3JfYWRkX3ZhbHVlKCBIS0VZIGhrZXksIExQV1NUUiBuYW1lLCBEV09SRCB0eXBlLCBMUEJZVEUgZGF0YSwgRFdPUkQgbGVuICkKewogICAgUmVnU2V0VmFsdWVFeFcoIGhrZXksIG5hbWUsIDAsIHR5cGUsIGRhdGEsIGxlbiApOwogICAgaWYgKG5hbWUpIGZyZWUoIG5hbWUgKTsKICAgIGlmIChkYXRhKSBmcmVlKCBkYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfbGluZSBbSW50ZXJuYWxdCiAqCiAqIHJlYWRzIGEgbGluZSBpbmNsdWRpbmcgZHluYW1pY2FsbHkgZW5sYXJnaW5nIHRoZSByZWFkYnVmZmVyIGFuZCB0aHJvd2luZwogKiBhd2F5IGNvbW1lbnRzCiAqLwpzdGF0aWMgaW50IF93aW5lX3JlYWRfbGluZSggRklMRSAqRiwgY2hhciAqKmJ1ZiwgaW50ICpsZW4gKQp7CgljaGFyCSpzLCpjdXJyZWFkOwoJaW50CW15bGVuLGN1cm9mZjsKCgljdXJyZWFkCT0gKmJ1ZjsKCW15bGVuCT0gKmxlbjsKCSoqYnVmCT0gJ1wwJzsKCXdoaWxlICgxKSB7CgkJd2hpbGUgKDEpIHsKCQkJcz1mZ2V0cyhjdXJyZWFkLG15bGVuLEYpOwoJCQlpZiAocz09TlVMTCkKCQkJCXJldHVybiAwOyAvKiBFT0YgKi8KCQkJaWYgKE5VTEw9PShzPXN0cmNocihjdXJyZWFkLCdcbicpKSkgewoJCQkJLyogYnVmZmVyIHdhc24ndCBsYXJnZSBlbm91Z2ggKi8KCQkJCWN1cm9mZgk9IHN0cmxlbigqYnVmKTsKCQkJCWN1cnJlYWQJPSByZWFsbG9jKCpidWYsKmxlbioyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihjdXJyZWFkID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiT3V0IG9mIG1lbW9yeSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKmJ1Zgk9IGN1cnJlYWQ7CgkJCQljdXJyZWFkKz0gY3Vyb2ZmOwoJCQkJbXlsZW4JPSAqbGVuOwkvKiB3ZSBmaWxsZWQgdXAgdGhlIGJ1ZmZlciBhbmQgCgkJCQkJCSAqIGdvdCBuZXcgJypsZW4nIGJ5dGVzIHRvIGZpbGwKCQkJCQkJICovCgkJCQkqbGVuCT0gKmxlbiAqIDI7CgkJCX0gZWxzZSB7CgkJCQkqcz0nXDAnOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLyogdGhyb3cgYXdheSBjb21tZW50cyAqLwoJCWlmICgqKmJ1Zj09JyMnIHx8ICoqYnVmPT0nOycpIHsKCQkJY3VycmVhZAk9ICpidWY7CgkJCW15bGVuCT0gKmxlbjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzKSAJLyogZ290IGVuZCBvZiBsaW5lICovCgkJCWJyZWFrOwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfVVNUUklORyBbSW50ZXJuYWxdCiAqCiAqIGNvbnZlcnRzIGEgY2hhciogaW50byBhIFVOSUNPREUgc3RyaW5nICh1cCB0byBhIHNwZWNpYWwgY2hhcikKICogYW5kIHJldHVybnMgdGhlIHBvc2l0aW9uIGV4YWN0bHkgYWZ0ZXIgdGhhdCBzdHJpbmcKICovCnN0YXRpYyBjaGFyKiBfd2luZV9yZWFkX1VTVFJJTkcoIGNoYXIgKmJ1ZiwgTFBXU1RSICpzdHIgKQp7CgljaGFyCSpzOwoJTFBXU1RSCXdzOwoKCS8qIHJlYWQgdXAgdG8gIj0iIG9yICJcMCIgb3IgIlxuIiAqLwoJcwk9IGJ1ZjsKCSpzdHIJPSAoTFBXU1RSKXhtYWxsb2MoMipzdHJsZW4oYnVmKSsyKTsKCXdzCT0gKnN0cjsKCXdoaWxlICgqcyAmJiAoKnMhPSdcbicpICYmICgqcyE9Jz0nKSkgewoJCWlmICgqcyE9J1xcJykKCQkJKndzKys9KigodW5zaWduZWQgY2hhciopcysrKTsKCQllbHNlIHsKCQkJcysrOwoJCQlpZiAoISpzKSB7CgkJCQkvKiBEYW5nbGluZyBcIC4uLiBtYXkgb25seSBoYXBwZW4gaWYgYSByZWdpc3RyeQoJCQkJICogd3JpdGUgd2FzIHNob3J0LiBGSVhNRTogV2hhdCB0byBkbz8KCQkJCSAqLwoJCQkJIGJyZWFrOwoJCQl9CgkJCWlmICgqcz09J1xcJykgewoJCQkJKndzKys9J1xcJzsKCQkJCXMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWlmICgqcyE9J3UnKSB7CgkJCQlXQVJOKCJOb24gdW5pY29kZSBlc2NhcGUgc2VxdWVuY2UgXFwlYyBmb3VuZCBpbiB8JXN8XG4iLCpzLGJ1Zik7CgkJCQkqd3MrKz0nXFwnOwoJCQkJKndzKys9KnMrKzsKCQkJfSBlbHNlIHsKCQkJCWNoYXIJeGJ1Zls1XTsKCQkJCWludAl3YzsKCgkJCQlzKys7CgkJCQltZW1jcHkoeGJ1ZixzLDQpO3hidWZbNF09J1wwJzsKCQkJCWlmICghc3NjYW5mKHhidWYsIiV4Iiwmd2MpKQoJCQkJCVdBUk4oIlN0cmFuZ2UgZXNjYXBlIHNlcXVlbmNlICVzIGZvdW5kIGluIHwlc3xcbiIseGJ1ZixidWYpOwoJCQkJcys9NDsKCQkJCSp3cysrCT0odW5zaWduZWQgc2hvcnQpd2M7CgkJCX0KCQl9Cgl9Cgkqd3MJPSAwOwoJcmV0dXJuIHM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJrZXkgW0ludGVybmFsXQogKgogKiBOT1RFUwogKiAgICBJdCBzZWVtcyBsaWtlIHRoaXMgaXMgcmV0dXJuaW5nIGEgYm9vbGVhbi4gIFNob3VsZCBpdD8KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiAxCiAqICAgIEZhaWx1cmU6IDAKICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YmtleSggRklMRSAqRiwgSEtFWSBoa2V5LCBpbnQgbGV2ZWwsIGNoYXIgKipidWYsIGludCAqYnVmbGVuICkKewogICAgCUhLRVkgc3Via2V5OwoJaW50CQlpOwoJY2hhcgkJKnM7CglMUFdTVFIJCW5hbWU7CgogICAgVFJBQ0UoIiglcCwleCwlZCwlcywlZClcbiIsIEYsIGhrZXksIGxldmVsLCBkZWJ1Z3N0cl9hKCpidWYpLCAqYnVmbGVuKTsKCiAgICAvKiBHb29kLiAgV2UgYWxyZWFkeSBnb3QgYSBsaW5lIGhlcmUgLi4uIHNvIHBhcnNlIGl0ICovCiAgICBzdWJrZXkgPSAwOwogICAgd2hpbGUgKDEpIHsKICAgICAgICBpPTA7cz0qYnVmOwogICAgICAgIHdoaWxlICgqcz09J1x0JykgewogICAgICAgICAgICBzKys7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9CiAgICAgICAgaWYgKGk+bGV2ZWwpIHsKICAgICAgICAgICAgaWYgKCFzdWJrZXkpIHsKICAgICAgICAgICAgICAgIFdBUk4oIkdvdCBhIHN1YmhpZXJhcmNoeSB3aXRob3V0IHJlc3AuIGtleT9cbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCSAgICBpZiAoIV93aW5lX2xvYWRzdWJrZXkoRixzdWJrZXksbGV2ZWwrMSxidWYsYnVmbGVuKSkKCSAgICAgICBpZiAoIV93aW5lX3JlYWRfbGluZShGLGJ1ZixidWZsZW4pKQoJCSAgZ290byBkb25lOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoJCS8qIGxldCB0aGUgY2FsbGVyIGhhbmRsZSB0aGlzIGxpbmUgKi8KCQlpZiAoaTxsZXZlbCB8fCAqKmJ1Zj09J1wwJykKCQkJZ290byBkb25lOwoKCQkvKiBpdCBjYW4gYmU6IGEgdmFsdWUgb3IgYSBrZXluYW1lLiBQYXJzZSB0aGUgbmFtZSBmaXJzdCAqLwoJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsJm5hbWUpOwoKCQkvKiBzd2l0Y2goKSBkZWZhdWx0OiBoYWNrIHRvIGF2b2lkIGdvdG9zICovCgkJc3dpdGNoICgwKSB7CgkJZGVmYXVsdDoKCQkJaWYgKCpzPT0nXDAnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwoJCQkJc3Via2V5PV9maW5kX29yX2FkZF9rZXkoaGtleSxuYW1lKTsKCQkJfSBlbHNlIHsKCQkJCUxQQllURQkJZGF0YTsKCQkJCWludAkJbGVuLGxhc3Rtb2RpZmllZCx0eXBlOwoKCQkJCWlmICgqcyE9Jz0nKSB7CgkJCQkJV0FSTigiVW5leHBlY3RlZCBjaGFyYWN0ZXI6ICVjXG4iLCpzKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCXMrKzsKCQkJCWlmICgyIT1zc2NhbmYocywiJWQsJWQsIiwmdHlwZSwmbGFzdG1vZGlmaWVkKSkgewoJCQkJCVdBUk4oIkhhdmVuJ3QgdW5kZXJzdG9vZCBwb3NzaWJsZSB2YWx1ZSBpbiB8JXN8LCBza2lwcGluZy5cbiIsKmJ1Zik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQkvKiBza2lwIHRoZSAyICwgKi8KCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlzPXN0cmNocihzLCcsJyk7CgkJCQlpZiAoIXMrKykgewoJCQkJCVdBUk4oIkhhdmVuJ3QgdW5kZXJzdG9vZCBwb3NzaWJsZSB2YWx1ZSBpbiB8JXN8LCBza2lwcGluZy5cbiIsKmJ1Zik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlpZiAodHlwZSA9PSBSRUdfU1ogfHwgdHlwZSA9PSBSRUdfRVhQQU5EX1NaKSB7CgkJCQkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywoTFBXU1RSKikmZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4gPSBsc3RybGVuVygoTFBXU1RSKWRhdGEpKjIrMjsKCQkJCX0gZWxzZSB7CgkJCQkJbGVuPXN0cmxlbihzKS8yOwoJCQkJCWRhdGEgPSAoTFBCWVRFKXhtYWxsb2MobGVuKzEpOwoJCQkJCWZvciAoaT0wO2k8bGVuO2krKykgewoJCQkJCQlkYXRhW2ldPTA7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldPSgqcy0nMCcpPDw0OwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ2EnKydceGEnKTw8NDsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV09KCpzLSdBJysnXHhhJyk8PDQ7CgkJCQkJCXMrKzsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV18PSpzLScwJzsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV18PSpzLSdhJysnXHhhJzsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV18PSpzLSdBJysnXHhhJzsKCQkJCQkJcysrOwoJCQkJCX0KCQkJCX0KCQkJCV9maW5kX29yX2FkZF92YWx1ZShoa2V5LG5hbWUsdHlwZSxkYXRhLGxlbik7CgkJCX0KCQl9CgkJLyogcmVhZCB0aGUgbmV4dCBsaW5lICovCgkJaWYgKCFfd2luZV9yZWFkX2xpbmUoRixidWYsYnVmbGVuKSkKCQkJZ290byBkb25lOwogICAgfQogZG9uZToKICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKICAgIHJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2Fkc3VicmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YnJlZyggRklMRSAqRiwgSEtFWSBoa2V5LCBjb25zdCBjaGFyICpmbiApCnsKCWludAl2ZXI7CgljaGFyCSpidWY7CglpbnQJYnVmbGVuOwoKCWJ1Zj14bWFsbG9jKDEwKTtidWZsZW49MTA7CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXNzY2FuZihidWYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAodmVyIT0xKSB7CiAgICAgICAgICAgIGlmICh2ZXIgPT0gMikgIC8qIG5ldyB2ZXJzaW9uICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEhBTkRMRSBmaWxlOwogICAgICAgICAgICAgICAgaWYgKChmaWxlID0gRklMRV9DcmVhdGVGaWxlKCBmbiwgR0VORVJJQ19SRUFELCAwLCBOVUxMLCBPUEVOX0VYSVNUSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfQVRUUklCVVRFX05PUk1BTCwgLTEsIFRSVUUgKSkgIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RydWN0IGxvYWRfcmVnaXN0cnlfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKICAgICAgICAgICAgICAgICAgICByZXEtPmhrZXkgICAgPSBoa2V5OwogICAgICAgICAgICAgICAgICAgIHJlcS0+ZmlsZSAgICA9IGZpbGU7CiAgICAgICAgICAgICAgICAgICAgcmVxLT5uYW1lWzBdID0gMDsKICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJfY2FsbCggUkVRX0xPQURfUkVHSVNUUlkgKTsKICAgICAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggZmlsZSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZnJlZSggYnVmICk7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKCQlUUkFDRSgiT2xkIGZvcm1hdCAoJWQpIHJlZ2lzdHJ5IGZvdW5kLCBpZ25vcmluZyBpdC4gKGJ1ZiB3YXMgJXMpLlxuIix2ZXIsYnVmKTsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCX0KCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfbG9hZHN1YmtleShGLGhrZXksMCwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJZnJlZShidWYpOwoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfd2luZV9sb2FkcmVnKCBIS0VZIGhrZXksIGNoYXIgKmZuICkKewogICAgRklMRSAqRjsKCiAgICBUUkFDRSgiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EoZm4pKTsKCiAgICBGID0gZm9wZW4oZm4sInJiIik7CiAgICBpZiAoRj09TlVMTCkgewogICAgICAgIFdBUk4oIkNvdWxkbid0IG9wZW4gJXMgZm9yIHJlYWRpbmc6ICVzXG4iLGZuLHN0cmVycm9yKGVycm5vKSApOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIF93aW5lX2xvYWRzdWJyZWcoRixoa2V5LGZuKTsKICAgIGZjbG9zZShGKTsKICAgIHJldHVybiAwOwp9CgovKiBOVCBSRUdJU1RSWSBMT0FERVIgKi8KCiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKCiNpZm5kZWYgTUFQX0ZBSUxFRAojZGVmaW5lIE1BUF9GQUlMRUQgKChMUFZPSUQpLTEpCiNlbmRpZgoKI2RlZmluZSAgTlRfUkVHX0JMT0NLX1NJWkUJCTB4MTAwMAoKI2RlZmluZSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEICAgICAgIDB4NjY2NzY1NzIJLyogcmVnZiAqLwojZGVmaW5lIE5UX1JFR19QT09MX0JMT0NLX0lEICAgICAgICAgMHg2RTY5NjI2OAkvKiBoYmluICovCiNkZWZpbmUgTlRfUkVHX0tFWV9CTE9DS19JRCAgICAgICAgICAweDZiNmUgLyogbmsgKi8KI2RlZmluZSBOVF9SRUdfVkFMVUVfQkxPQ0tfSUQgICAgICAgIDB4NmI3NiAvKiB2ayAqLwoKLyogc3ViYmxvY2tzIG9mIG5rICovCiNkZWZpbmUgTlRfUkVHX0hBU0hfQkxPQ0tfSUQgICAgICAgICAweDY2NmMgLyogbGYgKi8KI2RlZmluZSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEICAgICAgIDB4Njk2YyAvKiBsaSAqLwojZGVmaW5lIE5UX1JFR19SSV9CTE9DS19JRAkgICAgIDB4Njk3MiAvKiByaSAqLwoKI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX1RZUEUgICAgICAgIDB4MjAKI2RlZmluZSBOVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSAgIDB4MmMKCnR5cGVkZWYgc3RydWN0IAp7CglEV09SRAlpZDsJCS8qIDB4NjY2NzY1NzIgJ3JlZ2YnKi8KCURXT1JECXVrMTsJCS8qIDB4MDQgKi8KCURXT1JECXVrMjsJCS8qIDB4MDggKi8KCUZJTEVUSU1FCURhdGVNb2RpZmllZDsJLyogMHgwYyAqLwoJRFdPUkQJdWszOwkJLyogMHgxNCAqLwoJRFdPUkQJdWs0OwkJLyogMHgxOCAqLwoJRFdPUkQJdWs1OwkJLyogMHgxYyAqLwoJRFdPUkQJdWs2OwkJLyogMHgyMCAqLwoJRFdPUkQJUm9vdEtleUJsb2NrOwkvKiAweDI0ICovCglEV09SRAlCbG9ja1NpemU7CS8qIDB4MjggKi8KCURXT1JEICAgdWs3WzExNl07CQoJRFdPUkQJQ2hlY2tzdW07IC8qIGF0IG9mZnNldCAweDFGQyAqLwp9IG50X3JlZ2Y7Cgp0eXBlZGVmIHN0cnVjdAp7CglEV09SRAlibG9ja3NpemU7CglCWVRFCWRhdGFbMV07Cn0gbnRfaGJpbl9zdWI7Cgp0eXBlZGVmIHN0cnVjdAp7CglEV09SRAlpZDsJCS8qIDB4NkU2OTYyNjggJ2hiaW4nICovCglEV09SRAlvZmZfcHJldjsKCURXT1JECW9mZl9uZXh0OwoJRFdPUkQJdWsxOwoJRFdPUkQJdWsyOwkJLyogMHgxMCAqLwoJRFdPUkQJdWszOwkJLyogMHgxNCAqLwoJRFdPUkQJdWs0OwkJLyogMHgxOCAqLwoJRFdPUkQJc2l6ZTsJCS8qIDB4MUMgKi8KCW50X2hiaW5fc3ViCWhiaW5fc3ViOwkvKiAweDIwICovCn0gbnRfaGJpbjsKCi8qCiAqIHRoZSB2YWx1ZV9saXN0IGNvbnNpc3RzIG9mIG9mZnNldHMgdG8gdGhlIHZhbHVlcyAodmspCiAqLwp0eXBlZGVmIHN0cnVjdAp7CglXT1JECVN1YkJsb2NrSWQ7CQkvKiAweDAwIDB4NkI2RSAqLwoJV09SRAlUeXBlOwkJCS8qIDB4MDIgZm9yIHRoZSByb290LWtleTogMHgyQywgb3RoZXJ3aXNlIDB4MjAqLwoJRklMRVRJTUUJd3JpdGV0aW1lOwkvKiAweDA0ICovCglEV09SRAl1azE7CQkJLyogMHgwQyAqLwoJRFdPUkQJcGFyZW50X29mZjsJCS8qIDB4MTAgT2Zmc2V0IG9mIE93bmVyL1BhcmVudCBrZXkgKi8KCURXT1JECW5yX3N1YmtleXM7CQkvKiAweDE0IG51bWJlciBvZiBzdWItS2V5cyAqLwoJRFdPUkQJdWs4OwkJCS8qIDB4MTggKi8KCURXT1JECWxmX29mZjsJCQkvKiAweDFDIE9mZnNldCBvZiB0aGUgc3ViLWtleSBsZi1SZWNvcmRzICovCglEV09SRAl1azI7CQkJLyogMHgyMCAqLwoJRFdPUkQJbnJfdmFsdWVzOwkJLyogMHgyNCBudW1iZXIgb2YgdmFsdWVzICovCglEV09SRAl2YWx1ZWxpc3Rfb2ZmOwkJLyogMHgyOCBPZmZzZXQgb2YgdGhlIFZhbHVlLUxpc3QgKi8KCURXT1JECW9mZl9zazsJCQkvKiAweDJjIE9mZnNldCBvZiB0aGUgc2stUmVjb3JkICovCglEV09SRAlvZmZfY2xhc3M7CQkvKiAweDMwIE9mZnNldCBvZiB0aGUgQ2xhc3MtTmFtZSAqLwoJRFdPUkQJdWszOwkJCS8qIDB4MzQgKi8KCURXT1JECXVrNDsJCQkvKiAweDM4ICovCglEV09SRAl1azU7CQkJLyogMHgzYyAqLwoJRFdPUkQJdWs2OwkJCS8qIDB4NDAgKi8KCURXT1JECXVrNzsJCQkvKiAweDQ0ICovCglXT1JECW5hbWVfbGVuOwkJLyogMHg0OCBuYW1lLWxlbmd0aCAqLwoJV09SRAljbGFzc19sZW47CQkvKiAweDRhIGNsYXNzLW5hbWUgbGVuZ3RoICovCgljaGFyCW5hbWVbMV07CQkvKiAweDRjIGtleS1uYW1lICovCn0gbnRfbms7Cgp0eXBlZGVmIHN0cnVjdAp7CglEV09SRAlvZmZfbms7CS8qIDB4MDAgKi8KCURXT1JECW5hbWU7CS8qIDB4MDQgKi8KfSBoYXNoX3JlYzsKCnR5cGVkZWYgc3RydWN0CnsKCVdPUkQJaWQ7CQkvKiAweDAwIDB4NjY2YyAqLwoJV09SRAlucl9rZXlzOwkvKiAweDA2ICovCgloYXNoX3JlYwloYXNoX3JlY1sxXTsKfSBudF9sZjsKCi8qCiBsaXN0IG9mIHN1YmtleXMgd2l0aG91dCBoYXNoCgogbGkgLS0rLS0+bmsKICAgICAgfAogICAgICArLS0+bmsKICovCnR5cGVkZWYgc3RydWN0CnsKCVdPUkQJaWQ7CQkvKiAweDAwIDB4Njk2YyAqLwoJV09SRAlucl9rZXlzOwoJRFdPUkQJb2ZmX25rWzFdOwp9IG50X2xpOwoKLyoKIHRoaXMgaXMgYSBpbnRlcm1lZGlhdGUgbm9kZQoKIHJpIC0tKy0tPmxpLS0rLS0+bmsKICAgICAgfCAgICAgICArCiAgICAgIHwgICAgICAgKy0tPm5rCiAgICAgIHwKICAgICAgKy0tPmxpLS0rLS0+bmsKICAgICAgICAgICAgICArCgkgICAgICArLS0+bmsKICovCnR5cGVkZWYgc3RydWN0CnsKCVdPUkQJaWQ7CQkvKiAweDAwIDB4Njk3MiAqLwoJV09SRAlucl9saTsJCS8qIDB4MDIgbnVtYmVyIG9mZiBvZmZzZXRzICovCglEV09SRAlvZmZfbGlbMV07CS8qIDB4MDQgcG9pbnRzIHRvIGxpICovCn0gbnRfcmk7Cgp0eXBlZGVmIHN0cnVjdAp7CglXT1JECWlkOwkJLyogMHgwMCAndmsnICovCglXT1JECW5hbV9sZW47CglEV09SRAlkYXRhX2xlbjsKCURXT1JECWRhdGFfb2ZmOwoJRFdPUkQJdHlwZTsKCVdPUkQJZmxhZzsKCVdPUkQJdWsxOwoJY2hhcgluYW1lWzFdOwp9IG50X3ZrOwoKTFBTVFIgX3N0cmR1cG5BKCBMUENTVFIgc3RyLCBpbnQgbGVuICkKewogICAgTFBTVFIgcmV0OwoKICAgIGlmICghc3RyKSByZXR1cm4gTlVMTDsKICAgIHJldCA9IHhtYWxsb2MoIGxlbiArIDEgKTsKICAgIG1lbWNweSggcmV0LCBzdHIsIGxlbiApOwogICAgcmV0W2xlbl0gPSAweDAwOwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBfbnRfcGFyc2VfbmsoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgbnRfbmsgKiBuaywgaW50IGxldmVsKTsKc3RhdGljIGludCBfbnRfcGFyc2VfdmsoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgbnRfdmsgKiB2ayk7CnN0YXRpYyBpbnQgX250X3BhcnNlX2xmKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIGludCBzdWJrZXlzLCBudF9sZiAqIGxmLCBpbnQgbGV2ZWwpOwoKCi8qCiAqIGdldHMgYSB2YWx1ZQogKgogKiB2ay0+ZmxhZzoKICogIDAgdmFsdWUgaXMgYSBkZWZhdWx0IHZhbHVlCiAqICAxIHRoZSB2YWx1ZSBoYXMgYSBuYW1lCiAqCiAqIHZrLT5kYXRhX2xlbgogKiAgbGVuIG9mIHRoZSB3aG9sZSBkYXRhIGJsb2NrCiAqICAtIHJlZ19zeiAodW5pY29kZSkKICogICAgYnl0ZXMgaW5jbHVkaW5nIHRoZSB0ZXJtaW5hdGluZyBcMCA9IDIqKG51bWJlcl9vZl9jaGFycysxKQogKiAgLSByZWdfZHdvcmQsIHJlZ19iaW5hcnk6CiAqICAgIGlmIGhpZ2hlc3QgYml0IG9mIGRhdGFfbGVuIGlzIHNldCBkYXRhX29mZiBjb250YWlucyB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQgX250X3BhcnNlX3ZrKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIG50X3ZrICogdmspCnsKCVdDSEFSIG5hbWUgWzI1Nl07CglEV09SRCBsZW4sIHJldDsKCUJZVEUgKiBwZGF0YSA9IChCWVRFICopKGJhc2UrdmstPmRhdGFfb2ZmKzQpOyAvKiBzdGFydCBvZiBkYXRhICovCgoJaWYodmstPmlkICE9IE5UX1JFR19WQUxVRV9CTE9DS19JRCkgZ290byBlcnJvcjsKCiAgICAgICAgaWYgKCEobGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfQUNQLCAwLCB2ay0+bmFtZSwgdmstPm5hbV9sZW4sIG5hbWUsIDI1NiApKSAmJiB2ay0+bmFtX2xlbikKICAgICAgICB7CiAgICAgICAgICAgIEVSUigibmFtZSB0b28gbGFyZ2UgJyUuKnMnICglZClcbiIsIHZrLT5uYW1fbGVuLCB2ay0+bmFtZSwgdmstPm5hbV9sZW4gKTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgICAgICBuYW1lW2xlbl0gPSAwOwoKCXJldCA9IFJlZ1NldFZhbHVlRXhXKCBoa2V5LCAodmstPmZsYWcgJiAweDAwMDAwMDAxKSA/IG5hbWUgOiBOVUxMLCAwLCB2ay0+dHlwZSwKCQkJKHZrLT5kYXRhX2xlbiAmIDB4ODAwMDAwMDApID8gKExQQllURSkmKHZrLT5kYXRhX29mZik6IHBkYXRhLAoJCQkodmstPmRhdGFfbGVuICYgMHg3ZmZmZmZmZikgKTsKCWlmIChyZXQpIEVSUigiUmVnU2V0VmFsdWVFeCBmYWlsZWQgKDB4JTA4bHgpXG4iLCByZXQpOwoJcmV0dXJuIFRSVUU7CmVycm9yOgoJRVJSKCJ1bmtub3duIGJsb2NrIGZvdW5kICgweCUwNHgpLCBwbGVhc2UgcmVwb3J0IVxuIiwgdmstPmlkKTsKCXJldHVybiBGQUxTRTsKfQoKLyoKICogZ2V0IHRoZSBzdWJrZXlzCiAqCiAqIHRoaXMgc3RydWN0dXJlIGNvbnRhaW5zIHRoZSBoYXNoIG9mIGEga2V5bmFtZSBhbmQgcG9pbnRzIHRvIGFsbAogKiBzdWJrZXlzCiAqCiAqIGV4Y2VwdGlvbjogaWYgdGhlIGlkIGlzICdpbCcgdGhlcmUgYXJlIG5vIGhhc2ggdmFsdWVzIGFuZCBldmVyeSAKICogZHdvcmQgaXMgYSBvZmZzZXQKICovCnN0YXRpYyBpbnQgX250X3BhcnNlX2xmKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIGludCBzdWJrZXlzLCBudF9sZiAqIGxmLCBpbnQgbGV2ZWwpCnsKCWludCBpOwoKCWlmIChsZi0+aWQgPT0gTlRfUkVHX0hBU0hfQkxPQ0tfSUQpCgl7CgkgIGlmIChzdWJrZXlzICE9IGxmLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCgkgIGZvciAoaT0wOyBpPGxmLT5ucl9rZXlzOyBpKyspCgkgIHsKCSAgICBpZiAoIV9udF9wYXJzZV9uayhoa2V5LCBiYXNlLCAobnRfbmsqKShiYXNlK2xmLT5oYXNoX3JlY1tpXS5vZmZfbmsrNCksIGxldmVsKSkgZ290byBlcnJvcjsKCSAgfQoJfQoJZWxzZSBpZiAobGYtPmlkID09IE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQpCgl7CgkgIG50X2xpICogbGkgPSAobnRfbGkqKWxmOwoJICBpZiAoc3Via2V5cyAhPSBsaS0+bnJfa2V5cykgZ290byBlcnJvcjE7CgoJICBmb3IgKGk9MDsgaTxsaS0+bnJfa2V5czsgaSsrKQoJICB7CgkgICAgaWYgKCFfbnRfcGFyc2VfbmsoaGtleSwgYmFzZSwgKG50X25rKikoYmFzZStsaS0+b2ZmX25rW2ldKzQpLCBsZXZlbCkpIGdvdG8gZXJyb3I7CgkgIH0KCX0KCWVsc2UgaWYgKGxmLT5pZCA9PSBOVF9SRUdfUklfQkxPQ0tfSUQpIC8qIHJpICovCgl7CgkgIG50X3JpICogcmkgPSAobnRfcmkqKWxmOwoJICBpbnQgbGlfc3Via2V5cyA9IDA7CgoJICAvKiBjb3VudCBhbGwgc3Via2V5cyAqLwoJICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykKCSAgewoJICAgIG50X2xpICogbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CgkgICAgaWYobGktPmlkICE9IE5UX1JFR19OT0hBU0hfQkxPQ0tfSUQpIGdvdG8gZXJyb3IyOwoJICAgIGxpX3N1YmtleXMgKz0gbGktPm5yX2tleXM7CgkgIH0KCgkgIC8qIGNoZWNrIG51bWJlciAqLwoJICBpZiAoc3Via2V5cyAhPSBsaV9zdWJrZXlzKSBnb3RvIGVycm9yMTsKCgkgIC8qIGxvb3AgdGhyb3VnaCB0aGUga2V5cyAqLwoJICBmb3IgKGk9MDsgaTxyaS0+bnJfbGk7IGkrKykKCSAgewoJICAgIG50X2xpICogbGkgPSAobnRfbGkqKShiYXNlK3JpLT5vZmZfbGlbaV0rNCk7CgkgICAgaWYgKCFfbnRfcGFyc2VfbGYoaGtleSwgYmFzZSwgbGktPm5yX2tleXMsIChudF9sZiopbGksIGxldmVsKSkgZ290byBlcnJvcjsKCSAgfQoJfQoJZWxzZSAKCXsKCSAgZ290byBlcnJvcjI7Cgl9CglyZXR1cm4gVFJVRTsKCmVycm9yMjogRVJSKCJ1bmtub3duIG5vZGUgaWQgMHglMDR4LCBwbGVhc2UgcmVwb3J0IVxuIiwgbGYtPmlkKTsKCXJldHVybiBUUlVFOwoJCmVycm9yMToJRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhIChpbmNvbnNpc3RlbnQgbnVtYmVyIG9mIHN1YmtleXMpXG4iKTsKCXJldHVybiBGQUxTRTsKCmVycm9yOglFUlIoImVycm9yIHJlYWRpbmcgbGYgYmxvY2tcbiIpOwoJcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgaW50IF9udF9wYXJzZV9uayhIS0VZIGhrZXksIGNoYXIgKiBiYXNlLCBudF9uayAqIG5rLCBpbnQgbGV2ZWwpCnsKCWNoYXIgKiBuYW1lOwoJaW50IGk7CglEV09SRCAqIHZsOwoJSEtFWSBzdWJrZXkgPSBoa2V5OwoKCWlmKG5rLT5TdWJCbG9ja0lkICE9IE5UX1JFR19LRVlfQkxPQ0tfSUQpCgl7CgkgIEVSUigidW5rbm93biBub2RlIGlkIDB4JTA0eCwgcGxlYXNlIHJlcG9ydCFcbiIsIG5rLT5TdWJCbG9ja0lkKTsKCSAgZ290byBlcnJvcjsKCX0KCglpZigobmstPlR5cGUhPU5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKSAmJgoJICAgKCgobnRfbmsqKShiYXNlK25rLT5wYXJlbnRfb2ZmKzQpKS0+U3ViQmxvY2tJZCAhPSBOVF9SRUdfS0VZX0JMT0NLX0lEKSkKCXsKCSAgRVJSKCJyZWdpc3RyeSBmaWxlIGNvcnJ1cHQhXG4iKTsKCSAgZ290byBlcnJvcjsKCX0KCgkvKiBjcmVhdGUgdGhlIG5ldyBrZXkgKi8KCWlmKGxldmVsIDw9IDApCgl7CgkgIG5hbWUgPSBfc3RyZHVwbkEoIG5rLT5uYW1lLCBuay0+bmFtZV9sZW4pOwoJICBpZihSZWdDcmVhdGVLZXlBKCBoa2V5LCBuYW1lLCAmc3Via2V5ICkpIHsgZnJlZShuYW1lKTsgZ290byBlcnJvcjsgfQoJICBmcmVlKG5hbWUpOwoJfQoKCS8qIGxvb3AgdGhyb3VnaCB0aGUgc3Via2V5cyAqLwoJaWYgKG5rLT5ucl9zdWJrZXlzKQoJewoJICBudF9sZiAqIGxmID0gKG50X2xmKikoYmFzZStuay0+bGZfb2ZmKzQpOwoJICBpZiAoIV9udF9wYXJzZV9sZihzdWJrZXksIGJhc2UsIG5rLT5ucl9zdWJrZXlzLCBsZiwgbGV2ZWwtMSkpIGdvdG8gZXJyb3IxOwoJfQoKCS8qIGxvb3AgdHJvdWdoIHRoZSB2YWx1ZSBsaXN0ICovCgl2bCA9IChEV09SRCAqKShiYXNlK25rLT52YWx1ZWxpc3Rfb2ZmKzQpOwoJZm9yIChpPTA7IGk8bmstPm5yX3ZhbHVlczsgaSsrKQoJewoJICBudF92ayAqIHZrID0gKG50X3ZrKikoYmFzZSt2bFtpXSs0KTsKCSAgaWYgKCFfbnRfcGFyc2Vfdmsoc3Via2V5LCBiYXNlLCB2aykpIGdvdG8gZXJyb3IxOwoJfQoKCVJlZ0Nsb3NlS2V5KHN1YmtleSk7CglyZXR1cm4gVFJVRTsKCQplcnJvcjE6CVJlZ0Nsb3NlS2V5KHN1YmtleSk7CmVycm9yOglyZXR1cm4gRkFMU0U7Cn0KCi8qIGVuZCBudCBsb2FkZXIgKi8KCi8qIHdpbmRvd3MgOTUgcmVnaXN0cnkgbG9hZGVyICovCgovKiBTRUNUSU9OIDE6IG1haW4gaGVhZGVyCiAqCiAqIG9uY2UgYXQgb2Zmc2V0IDAKICovCiNkZWZpbmUJVzk1X1JFR19DUkVHX0lECTB4NDc0NTUyNDMKCnR5cGVkZWYgc3RydWN0IAp7CglEV09SRAlpZDsJCS8qICJDUkVHIiA9IFc5NV9SRUdfQ1JFR19JRCAqLwoJRFdPUkQJdmVyc2lvbjsJLyogPz8/PyAweDAwMDEwMDAwICovCglEV09SRAlyZ2RiX29mZjsJLyogMHgwOCBPZmZzZXQgb2YgMXN0IFJHREItYmxvY2sgKi8KCURXT1JECXVrMjsJCS8qIDB4MGMgKi8KCVdPUkQJcmdkYl9udW07CS8qIDB4MTAgIyBvZiBSR0RCLWJsb2NrcyAqLwoJV09SRAl1azM7CglEV09SRAl1a1szXTsKCS8qIHJna24gKi8KfSBfdzk1Y3JlZzsKCi8qIFNFQ1RJT04gMjogRGlyZWN0b3J5IGluZm9ybWF0aW9uICh0cmVlIHN0cnVjdHVyZSkKICoKICogb25jZSBvbiBvZmZzZXQgMHgyMAogKgogKiBzdHJ1Y3R1cmU6IFtyZ2tuXVtka2VdKgkocmVwZWF0IHRpbGwgcmdrbi0+c2l6ZSBpcyByZWFjaGVkKQogKi8KI2RlZmluZQlXOTVfUkVHX1JHS05fSUQJMHg0ZTRiNDc1MgoKdHlwZWRlZiBzdHJ1Y3QKewoJRFdPUkQJaWQ7CQkvKiJSR0tOIiA9IFc5NV9SRUdfUkdLTl9JRCAqLwoJRFdPUkQJc2l6ZTsJCS8qIFNpemUgb2YgdGhlIFJHS04tYmxvY2sgKi8KCURXT1JECXJvb3Rfb2ZmOwkvKiBSZWwuIE9mZnNldCBvZiB0aGUgcm9vdC1yZWNvcmQgKi8KCURXT1JECXVrWzVdOwp9IF93OTVyZ2tuOwoKLyogRGlzayBLZXkgRW50cnkgU3RydWN0dXJlCiAqCiAqIHRoZSAxc3QgZW50cnkgaW4gYSAidXN1YWwiIHJlZ2lzdHJ5IGZpbGUgaXMgYSBudWwtZW50cnkgd2l0aCBzdWJrZXlzOiB0aGUKICogaGl2ZSBpdHNlbGYuIEl0IGxvb2tzIHRoZSBzYW1lIGxpa2Ugb3RoZXIga2V5cy4gRXZlbiB0aGUgSUQtbnVtYmVyIGNhbgogKiBiZSBhbnkgdmFsdWUuCiAqCiAqIFRoZSAiaGFzaCItdmFsdWUgaXMgYSB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIGtleSdzIG5hbWUuIFdpbmRvd3Mgd2lsbCBub3QKICogc2VhcmNoIGZvciB0aGUgbmFtZSwgYnV0IGZvciBhIG1hdGNoaW5nIGhhc2gtdmFsdWUuIGlmIGl0IGZpbmRzIG9uZSwgaXQKICogd2lsbCBjb21wYXJlIHRoZSBhY3R1YWwgc3RyaW5nIGluZm8sIG90aGVyd2lzZSBjb250aW51ZSB3aXRoIHRoZSBuZXh0IGtleS4KICogVG8gY2FsY3VsYXRlIHRoZSBoYXNoIGluaXRpYWxpemUgYSBELVdvcmQgd2l0aCAwIGFuZCBhZGQgYWxsIEFTQ0lJLXZhbHVlcyAKICogb2YgdGhlIHN0cmluZyB3aGljaCBhcmUgc21hbGxlciB0aGFuIDB4ODAgKDEyOCkgdG8gdGhpcyBELVdvcmQuICAgCiAqCiAqIElmIHlvdSB3YW50IHRvIG1vZGlmeSBrZXkgbmFtZXMsIGFsc28gbW9kaWZ5IHRoZSBoYXNoLXZhbHVlcywgc2luY2UgdGhleQogKiBjYW5ub3QgYmUgZm91bmQgYWdhaW4gKGFsdGhvdWdoIHRoZXkgd291bGQgYmUgZGlzcGxheWVkIGluIFJFR0VESVQpCiAqIEVuZCBvZiBsaXN0LXBvaW50ZXJzIGFyZSBmaWxsZWQgd2l0aCAweEZGRkZGRkZGCiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuckhTIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKgogKiB0aGVyZSBpcyBhIG9uZSB0byBvbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gZGtlIGFuZCBka2gKICovCiAvKiBrZXkgc3RydWN0LCBvbmNlIHBlciBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QKewoJRFdPUkQJeDE7CQkvKiBGcmVlIGVudHJ5IGluZGljYXRvcig/KSAqLwoJRFdPUkQJaGFzaDsJCS8qIHN1bSBvZiBieXRlcyBvZiBrZXluYW1lICovCglEV09SRAl4MzsJCS8qIFJvb3Qga2V5IGluZGljYXRvcj8gdXN1YWxseSAweEZGRkZGRkZGICovCglEV09SRAlwcmV2bHZsOwkvKiBvZmZzZXQgb2YgcHJldmlvdXMga2V5ICovCglEV09SRAluZXh0c3ViOwkvKiBvZmZzZXQgb2YgY2hpbGQga2V5ICovCglEV09SRAluZXh0OwkJLyogb2Zmc2V0IG9mIHNpYmxpbmcga2V5ICovCglXT1JECW5yTFM7CQkvKiBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KCVdPUkQJbnJNUzsJCS8qIG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwp9IF93OTVka2U7CgovKiBTRUNUSU9OIDM6IGtleSBpbmZvcm1hdGlvbiwgdmFsdWVzIGFuZCBkYXRhCiAqCiAqIHN0cnVjdHVyZToKICogIHNlY3Rpb246CVtibG9ja3NdKgkJKHJlcGVhdCBjcmVnLT5yZ2RiX251bSB0aW1lcykKICogIGJsb2NrczoJW3JnZGJdIFtzdWJibG9ja3NdKiAJKHJlcGVhdCB0aWxsIGJsb2NrIHNpemUgcmVhY2hlZCApCiAqICBzdWJibG9ja3M6CVtka2hdIFtka3ZdKgkJKHJlcGVhdCBka2gtPnZhbHVlcyB0aW1lcyApCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgdmFsdWUgYXQgb2Zmc2V0CiAqIDEwIGVxdWFscyB0aGUgdmFsdWUgYXQgb2Zmc2V0IDQgbWludXMgdGhlIHZhbHVlIGF0IG9mZnNldCA4LiBJIGhhdmUgbm8KICogaWRlYSBhdCB0aGUgbW9tZW50IHdoYXQgdGhpcyBtZWFucy4gIChLZXZpbiBDb3plbnMpCiAqLwoKLyogYmxvY2sgaGVhZGVyLCBvbmNlIHBlciBibG9jayAqLwojZGVmaW5lIFc5NV9SRUdfUkdEQl9JRAkweDQyNDQ0NzUyCgp0eXBlZGVmIHN0cnVjdAp7CglEV09SRAlpZDsJLyogMHgwMCAncmdkYicgPSBXOTVfUkVHX1JHREJfSUQgKi8KCURXT1JECXNpemU7CS8qIDB4MDQgKi8KCURXT1JECXVrMTsJLyogMHgwOCAqLwoJRFdPUkQJdWsyOwkvKiAweDBjICovCglEV09SRAl1azM7CS8qIDB4MTAgKi8KCURXT1JECXVrNDsJLyogMHgxNCAqLwoJRFdPUkQJdWs1OwkvKiAweDE4ICovCglEV09SRAl1azY7CS8qIDB4MWMgKi8KCS8qIGRraCAqLwp9IF93OTVyZ2RiOwoKLyogRGlzayBLZXkgSGVhZGVyIHN0cnVjdHVyZSAoUkdEQiBwYXJ0KSwgb25jZSBwZXIga2V5ICovCnR5cGVkZWYJc3RydWN0IAp7CglEV09SRAluZXh0a2V5b2ZmOyAJLyogMHgwMCBvZmZzZXQgdG8gbmV4dCBka2gqLwoJV09SRAluckxTOwkJLyogMHgwNCBpZCBpbnNpZGUgdGhlIHJnZGIgYmxvY2sgKi8KCVdPUkQJbnJNUzsJCS8qIDB4MDYgbnVtYmVyIG9mIHRoZSByZ2RiIGJsb2NrICovCglEV09SRAlieXRlc3VzZWQ7CS8qIDB4MDggKi8KCVdPUkQJa2V5bmFtZWxlbjsJLyogMHgwYyBsZW4gb2YgbmFtZSAqLwoJV09SRAl2YWx1ZXM7CQkvKiAweDBlIG51bWJlciBvZiB2YWx1ZXMgKi8KCURXT1JECXh4MTsJCS8qIDB4MTAgKi8KCWNoYXIJbmFtZVsxXTsJLyogMHgxNCAqLwoJLyogZGt2ICovCQkvKiAweDE0ICsga2V5bmFtZWxlbiAqLwp9IF93OTVka2g7CgovKiBEaXNrIEtleSBWYWx1ZSBzdHJ1Y3R1cmUsIG9uY2UgcGVyIHZhbHVlICovCnR5cGVkZWYJc3RydWN0CnsKCURXT1JECXR5cGU7CQkvKiAweDAwICovCglEV09SRAl4MTsJCS8qIDB4MDQgKi8KCVdPUkQJdmFsbmFtZWxlbjsJLyogMHgwOCBsZW5ndGggb2YgbmFtZSwgMCBpcyBkZWZhdWx0IGtleSAqLwoJV09SRAl2YWxkYXRhbGVuOwkvKiAweDBBIGxlbmd0aCBvZiBkYXRhICovCgljaGFyCW5hbWVbMV07CS8qIDB4MGMgKi8KCS8qIHJhdyBkYXRhICovCQkvKiAweDBjICsgdmFsbmFtZWxlbiAqLwp9IF93OTVka3Y7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfbG9va3VwX2RraCBbSW50ZXJuYWxdCiAqCiAqIHNlZWtzIHRoZSBka2ggYmVsb25naW5nIHRvIGEgZGtlCiAqLwpzdGF0aWMgX3c5NWRraCAqIF93OTVfbG9va3VwX2RraCAoX3c5NWNyZWcgKmNyZWcsIGludCBuckxTLCBpbnQgbnJNUykKewoJX3c5NXJnZGIgKiByZ2RiOwoJX3c5NWRraCAqIGRraDsKCWludCBpOwoJCgkvKiBnZXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgcmdkYiBkYXRhc3RvcmUgKi8KCXJnZGIgPSAoX3c5NXJnZGIqKSgoY2hhciopY3JlZytjcmVnLT5yZ2RiX29mZik7CgoJLyogY2hlY2s6IHJlcXVlc3RlZCBibG9jayA8IGxhc3RfYmxvY2spICovCglpZiAoY3JlZy0+cmdkYl9udW0gPD0gbnJNUykJCQkJCgl7CgkgIEVSUigicmVnaXN0cnkgZmlsZSBjb3JydXB0ISByZXF1ZXN0ZWQgYmxvY2sgbm8uIGJleW9uZCBlbmQuXG4iKTsKCSAgZ290byBlcnJvcjsKCX0KCQoJLyogZmluZCB0aGUgcmlnaHQgYmxvY2sgKi8KCWZvcihpPTA7IGk8bnJNUyA7aSsrKQoJewoJICBpZihyZ2RiLT5pZCAhPSBXOTVfUkVHX1JHREJfSUQpCQkJLyogY2hlY2sgdGhlIG1hZ2ljICovCgkgIHsKCSAgICBFUlIoInJlZ2lzdHJ5IGZpbGUgY29ycnVwdCEgYmFkIG1hZ2ljIDB4JTA4bHhcbiIsIHJnZGItPmlkKTsKCSAgICBnb3RvIGVycm9yOwoJICB9CgkgIHJnZGIgPSAoX3c5NXJnZGIqKSAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSk7CQkvKiBmaW5kIG5leHQgYmxvY2sgKi8KCX0KCglka2ggPSAoX3c5NWRraCopKHJnZGIgKyAxKTsJCQkJLyogZmlyc3Qgc3ViIGJsb2NrIHdpdGhpbiB0aGUgcmdkYiAqLwoKCWRvCgl7CgkgIGlmKG5yTFM9PWRraC0+bnJMUyApIHJldHVybiBka2g7CgkgIGRraCA9IChfdzk1ZGtoKikoKGNoYXIqKWRraCArIGRraC0+bmV4dGtleW9mZik7CS8qIGZpbmQgbmV4dCBzdWJibG9jayAqLwoJfSB3aGlsZSAoKGNoYXIgKilka2ggPCAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSkpOwoKZXJyb3I6CXJldHVybiBOVUxMOwp9CQogCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9wYXJzZV9ka3YgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfdzk1X3BhcnNlX2RrdiAoCglIS0VZIGhrZXksCglfdzk1ZGtoICogZGtoLAoJaW50IG5yTFMsCglpbnQgbnJNUyApCnsKCV93OTVka3YgKiBka3Y7CglpbnQgaTsKCURXT1JEIHJldDsKCWNoYXIgKiBuYW1lOwoJCQkKCS8qIGZpcnN0IHZhbHVlIGJsb2NrICovCglka3YgPSAoX3c5NWRrdiopKChjaGFyKilka2grZGtoLT5rZXluYW1lbGVuKzB4MTQpOwoKCS8qIGxvb3AgdHJvdWdodCB0aGUgdmFsdWVzICovCglmb3IgKGk9MDsgaTwgZGtoLT52YWx1ZXM7IGkrKykKCXsKCSAgbmFtZSA9IF9zdHJkdXBuQShka3YtPm5hbWUsIGRrdi0+dmFsbmFtZWxlbik7CgkgIHJldCA9IFJlZ1NldFZhbHVlRXhBKGhrZXksIG5hbWUsIDAsIGRrdi0+dHlwZSwgJihka3YtPm5hbWVbZGt2LT52YWxuYW1lbGVuXSksZGt2LT52YWxkYXRhbGVuKTsgCgkgIGlmIChyZXQpIEZJWE1FKCJSZWdTZXRWYWx1ZUV4IHJldHVybmVkOiAweCUwOGx4XG4iLCByZXQpOwoJICBmcmVlIChuYW1lKTsKCgkgIC8qIG5leHQgdmFsdWUgKi8KCSAgZGt2ID0gKF93OTVka3YqKSgoY2hhciopZGt2K2Rrdi0+dmFsbmFtZWxlbitka3YtPnZhbGRhdGFsZW4rMHgwYyk7Cgl9CglyZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X3BhcnNlX2RrZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93OTVfcGFyc2VfZGtlKCAKCUhLRVkgaGtleSwKCV93OTVjcmVnICogY3JlZywKCV93OTVyZ2tuICpyZ2tuLAoJX3c5NWRrZSAqIGRrZSwKCWludCBsZXZlbCApCnsKCV93OTVka2ggKiBka2g7CglIS0VZIGhzdWJrZXkgPSBoa2V5OwoJY2hhciAqIG5hbWU7CglpbnQgcmV0ID0gRkFMU0U7CgoJLyogZ2V0IHN0YXJ0IGFkZHJlc3Mgb2Ygcm9vdCBrZXkgYmxvY2sgKi8KCWlmICghZGtlKSBka2UgPSAoX3c5NWRrZSopKChjaGFyKilyZ2tuICsgcmdrbi0+cm9vdF9vZmYpOwoJCgkvKiBzcGVjaWFsIHJvb3Qga2V5ICovCglpZiAoZGtlLT5uckxTID09IDB4ZmZmZiB8fCBka2UtPm5yTVM9PTB4ZmZmZikJCS8qIGVnLiB0aGUgcm9vdCBrZXkgaGFzIG5vIG5hbWUgKi8KCXsKCSAgLyogcGFyc2UgdGhlIG9uZSBzdWJrZXkqLwoJICBpZiAoZGtlLT5uZXh0c3ViICE9IDB4ZmZmZmZmZmYpIAoJICB7CiAgICAJICAgIHJldHVybiBfdzk1X3BhcnNlX2RrZShoc3Via2V5LCBjcmVnLCByZ2tuLCAoX3c5NWRrZSopKChjaGFyKilyZ2tuK2RrZS0+bmV4dHN1YiksIGxldmVsKTsKCSAgfQoJICAvKiBoYXMgbm8gc2libGluZyBrZXlzICovCgkgIGdvdG8gZXJyb3I7Cgl9CgoJLyogc2VhcmNoIHN1YmJsb2NrICovCglpZiAoIShka2ggPSBfdzk1X2xvb2t1cF9ka2goY3JlZywgZGtlLT5uckxTLCBka2UtPm5yTVMpKSkKCXsKCSAgZnByaW50ZihzdGRlcnIsICJka2UgcG9pbnRpbmcgdG8gbWlzc2luZyBka2ggIVxuIik7CgkgIGdvdG8gZXJyb3I7Cgl9CgoJaWYgKCBsZXZlbCA8PSAwICkKCXsKCSAgLyogd2FsayBzaWJsaW5nIGtleXMgKi8KCSAgaWYgKGRrZS0+bmV4dCAhPSAweGZmZmZmZmZmICkKCSAgewogICAgCSAgICBpZiAoIV93OTVfcGFyc2VfZGtlKGhrZXksIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0KSwgbGV2ZWwpKSBnb3RvIGVycm9yOwoJICB9CgoJICAvKiBjcmVhdGUgc3Via2V5IGFuZCBpbnNlcnQgdmFsdWVzICovCgkgIG5hbWUgPSBfc3RyZHVwbkEoIGRraC0+bmFtZSwgZGtoLT5rZXluYW1lbGVuKTsKCSAgaWYgKFJlZ0NyZWF0ZUtleUEoaGtleSwgbmFtZSwgJmhzdWJrZXkpKSB7IGZyZWUobmFtZSk7IGdvdG8gZXJyb3I7IH0KCSAgZnJlZShuYW1lKTsKCSAgaWYgKCFfdzk1X3BhcnNlX2Rrdihoc3Via2V5LCBka2gsIGRrZS0+bnJMUywgZGtlLT5uck1TKSkgZ290byBlcnJvcjE7Cgl9ICAKCQogCS8qIG5leHQgc3ViIGtleSAqLwoJaWYgKGRrZS0+bmV4dHN1YiAhPSAweGZmZmZmZmZmKSAKCXsKICAgIAkgIGlmICghX3c5NV9wYXJzZV9ka2UoaHN1YmtleSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHRzdWIpLCBsZXZlbC0xKSkgZ290byBlcnJvcjE7Cgl9CgoJcmV0ID0gVFJVRTsKZXJyb3IxOglpZiAoaHN1YmtleSAhPSBoa2V5KSBSZWdDbG9zZUtleShoc3Via2V5KTsKZXJyb3I6CXJldHVybiByZXQ7Cn0KLyogZW5kIHdpbmRvd3MgOTUgbG9hZGVyICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCU5hdGl2ZVJlZ0xvYWRLZXkgW0ludGVybmFsXQogKgogKiBMb2FkcyBhIG5hdGl2ZSByZWdpc3RyeSBmaWxlICh3aW45NS9udCkKICogCWhrZXkJcm9vdCBrZXkKICoJZm4JZmlsZW5hbWUKICoJbGV2ZWwJbnVtYmVyIG9mIGxldmVscyB0byBjdXQgYXdheSAoZWcuICIuRGVmYXVsdCIgaW4gdXNlci5kYXQpCiAqCiAqIHRoaXMgZnVuY3Rpb24gaW50ZW50aW9uYWxseSB1c2VzIHVuaXggZmlsZSBmdW5jdGlvbnMgdG8gbWFrZSBpdCBwb3NzaWJsZQogKiB0byBtb3ZlIGl0IHRvIGEgc2VwZXJhdGUgcmVnaXN0cnkgaGVscGVyIHByb2dyYW1tCiAqLwpzdGF0aWMgaW50IE5hdGl2ZVJlZ0xvYWRLZXkoIEhLRVkgaGtleSwgY2hhciogZm4sIGludCBsZXZlbCApCnsKCWludCBmZCA9IDA7CglzdHJ1Y3Qgc3RhdCBzdDsKICAgICAgICBET1NfRlVMTF9OQU1FIGZ1bGxfbmFtZTsKCWludCByZXQgPSBGQUxTRTsKCXZvaWQgKiBiYXNlOwoJCQkKICAgICAgICBpZiAoIURPU0ZTX0dldEZ1bGxOYW1lKCBmbiwgMCwgJmZ1bGxfbmFtZSApKSByZXR1cm4gRkFMU0U7CgkKCS8qIG1hcCB0aGUgcmVnaXN0cnkgaW50byB0aGUgbWVtb3J5ICovCglpZiAoKGZkID0gb3BlbihmdWxsX25hbWUubG9uZ19uYW1lLCBPX1JET05MWSB8IE9fTk9OQkxPQ0spKSA9PSAtMSkgcmV0dXJuIEZBTFNFOwoJaWYgKChmc3RhdChmZCwgJnN0KSA9PSAtMSkpIGdvdG8gZXJyb3I7CglpZiAoIXN0LnN0X3NpemUpIGdvdG8gZXJyb3I7CglpZiAoKGJhc2UgPSBtbWFwKE5VTEwsIHN0LnN0X3NpemUsIFBST1RfUkVBRCwgTUFQX1BSSVZBVEUsIGZkLCAwKSkgPT0gTUFQX0ZBSUxFRCkgZ290byBlcnJvcjsKCglzd2l0Y2ggKCooTFBEV09SRCliYXNlKQoJewoJICAvKiB3aW5kb3dzIDk1ICdjcmVnJyAqLwoJICBjYXNlIFc5NV9SRUdfQ1JFR19JRDoKCSAgICB7CgkgICAgICBfdzk1Y3JlZyAqIGNyZWc7CgkgICAgICBfdzk1cmdrbiAqIHJna247CgkgICAgICBjcmVnID0gYmFzZTsKCSAgICAgIFRSQUNFKCJMb2FkaW5nIHdpbjk1IHJlZ2lzdHJ5ICclcycgJyVzJ1xuIixmbiwgZnVsbF9uYW1lLmxvbmdfbmFtZSk7CgoJICAgICAgLyogbG9hZCB0aGUgaGVhZGVyIChyZ2tuKSAqLwoJICAgICAgcmdrbiA9IChfdzk1cmdrbiopKGNyZWcgKyAxKTsKCSAgICAgIGlmIChyZ2tuLT5pZCAhPSBXOTVfUkVHX1JHS05fSUQpIAoJICAgICAgewoJCUVSUigic2Vjb25kIElGRiBoZWFkZXIgbm90IFJHS04sIGJ1dCAlbHhcbiIsIHJna24tPmlkKTsKCQlnb3RvIGVycm9yMTsKCSAgICAgIH0KCgkgICAgICByZXQgPSBfdzk1X3BhcnNlX2RrZShoa2V5LCBjcmVnLCByZ2tuLCBOVUxMLCBsZXZlbCk7CgkgICAgfQoJICAgIGJyZWFrOwoJICAvKiBudCAncmVnZicqLwoJICBjYXNlIE5UX1JFR19IRUFERVJfQkxPQ0tfSUQ6CgkgICAgewoJICAgICAgbnRfcmVnZiAqIHJlZ2Y7CgkgICAgICBudF9oYmluICogaGJpbjsKCSAgICAgIG50X2hiaW5fc3ViICogaGJpbl9zdWI7CgkgICAgICBudF9uayogbms7CgoJICAgICAgVFJBQ0UoIkxvYWRpbmcgbnQgcmVnaXN0cnkgJyVzJyAnJXMnXG4iLGZuLCBmdWxsX25hbWUubG9uZ19uYW1lKTsKCgkgICAgICAvKiBzdGFydCBibG9jayAqLwoJICAgICAgcmVnZiA9IGJhc2U7CgoJICAgICAgLyogaGJpbiBibG9jayAqLwoJICAgICAgaGJpbiA9IChudF9oYmluKikoKGNoYXIqKSBiYXNlICsgMHgxMDAwKTsKCSAgICAgIGlmIChoYmluLT5pZCAhPSBOVF9SRUdfUE9PTF9CTE9DS19JRCkKCSAgICAgIHsKCSAgICAgICAgRVJSKCAiJXMgaGJpbiBibG9jayBpbnZhbGlkXG4iLCBmbik7CgkgICAgICAgIGdvdG8gZXJyb3IxOwoJICAgICAgfQoKCSAgICAgIC8qIGhiaW5fc3ViIGJsb2NrICovCgkgICAgICBoYmluX3N1YiA9IChudF9oYmluX3N1YiopJihoYmluLT5oYmluX3N1Yik7CgkgICAgICBpZiAoKGhiaW5fc3ViLT5kYXRhWzBdICE9ICduJykgfHwgKGhiaW5fc3ViLT5kYXRhWzFdICE9ICdrJykpCgkgICAgICB7CgkgICAgICAgIEVSUiggIiVzIGhiaW5fc3ViIGJsb2NrIGludmFsaWRcbiIsIGZuKTsKCSAgICAgICAgZ290byBlcnJvcjE7CgkgICAgICB9CgoJICAgICAgLyogbmsgYmxvY2sgKi8KCSAgICAgIG5rID0gKG50X25rKikmKGhiaW5fc3ViLT5kYXRhWzBdKTsKCSAgICAgIGlmIChuay0+VHlwZSAhPSBOVF9SRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRSkKCSAgICAgIHsKCSAgICAgICAgRVJSKCAiJXMgc3BlY2lhbCBuayBibG9jayBub3QgZm91bmRcbiIsIGZuKTsKCSAgICAgICAgZ290byBlcnJvcjE7CgkgICAgICB9CgoJICAgICAgcmV0ID0gX250X3BhcnNlX25rIChoa2V5LCAoY2hhciAqKSBiYXNlICsgMHgxMDAwLCBuaywgbGV2ZWwpOwoJICAgIH0KCSAgICBicmVhazsKCSAgZGVmYXVsdDoKCSAgICB7CgkgICAgICBFUlIoInVua25vd24gc2lnbmF0dXJlIGluIHJlZ2lzdHJ5IGZpbGUgJXMuXG4iLGZuKTsKCSAgICAgIGdvdG8gZXJyb3IxOwoJICAgIH0KCX0KCWlmKCFyZXQpIEVSUigiZXJyb3IgbG9hZGluZyByZWdpc3RyeSBmaWxlICVzXG4iLCBmbik7CmVycm9yMToJbXVubWFwKGJhc2UsIHN0LnN0X3NpemUpOwplcnJvcjoJY2xvc2UoZmQpOwoJcmV0dXJuIHJldDsJCn0KCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VlZGVkIGJ5IGEgd29yZCBhdCBvZmZzZXQtMi4gVGhpcyB3b3JkCiAgICBoYXMgdGhlIHZhbHVlICgyKmluZGV4KSsxLCB3aGVyZSBpbmRleCBpcyB0aGUgcmVmZXJyaW5nIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGluIHRoZSB0YWJsZS4gSSBoYXZlIG5vIHN1Z2dlc3Rpb24gZm9yIHRoZSAyKiBhbmQgdGhlICsxLgogICAgRm9sbG93aW5nIHRoZSB3b3JkLCB0aGVyZSBhcmUgTiBieXRlcyBvZiBkYXRhLCBhcyBwZXIgdGhlIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGxlbmd0aC4gVGhlIG9mZnNldCBvZiB0aGUga2V5ZW50L3ZhbGVudCBlbnRyeSBpcyBmcm9tIHRoZSBzdGFydAogICAgb2YgdGhlIHRleHQgdGFibGUgdG8gdGhlIGZpcnN0IGRhdGEgYnl0ZS4KCiAgICBUaGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbSBNaWNyb3NvZnQuIFRoZSBkYXRhIGZvcm1hdCBpcwogICAgZGVkdWNlZCBmcm9tIHRoZSByZWcuZGF0IGZpbGUgYnkgbWUuIE1pc3Rha2VzIG1heQogICAgaGF2ZSBiZWVuIG1hZGUuIEkgY2xhaW0gbm8gcmlnaHRzIGFuZCBnaXZlIG5vIGd1YXJhbnRlZXMgZm9yIHRoaXMgcHJvZ3JhbS4KCiAgICBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vCiovCgovKiByZWcuZGF0IGhlYWRlciBmb3JtYXQgKi8Kc3RydWN0IF93MzFfaGVhZGVyIHsKCWNoYXIJCWNvb2tpZVs4XTsJLyogJ1NIQ0MzLjEwJyAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYxOwkvKiBvZmZzZXQgb2YgaGFzaCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYyOwkvKiBvZmZzZXQgb2YgaW5kZXggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFiY250OwkJLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gaW5kZXggdGFibGUgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dG9mZjsJLyogb2Zmc2V0IG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0c2l6ZTsJLyogYnl0ZSBzaXplIG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgc2hvcnQJaGFzaHNpemU7CS8qIGhhc2ggc2l6ZSAqLwoJdW5zaWduZWQgc2hvcnQJZnJlZWlkeDsJLyogZnJlZSBpbmRleCAqLwp9OwoKLyogZ2VuZXJpYyBmb3JtYXQgb2YgdGFibGUgZW50cmllcyAqLwpzdHJ1Y3QgX3czMV90YWJlbnQgewoJdW5zaWduZWQgc2hvcnQgdzAsIHcxLCB3MiwgdzM7Cn07CgovKiBkaXJlY3RvcnkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9kaXJlbnQgewoJdW5zaWduZWQgc2hvcnQJc2libGluZ19pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHNpYmxpbmcgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAljaGlsZF9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGNoaWxkIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJa2V5X2lkeDsJLyogdGFibGUgaW5kZXggb2Yga2V5IGtleWVudCAqLwoJdW5zaWduZWQgc2hvcnQJdmFsdWVfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiB2YWx1ZSB2YWxlbnQgKi8KfTsKCi8qIGtleSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2tleWVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogdmFsdWUgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV92YWxlbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdG8gZGlzcGxheSBhIGRpcmVjdG9yeSB0cmVlICovCnZvaWQKX193MzFfZHVtcHRyZWUoCXVuc2lnbmVkIHNob3J0IGlkeCwKCQl1bnNpZ25lZCBjaGFyICp0eHQsCgkJc3RydWN0IF93MzFfdGFiZW50ICp0YWIsCgkJc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAoJCUhLRVkgaGtleSwKCQl0aW1lX3QJCWxhc3Rtb2RpZmllZCwKCQlpbnQJCWxldmVsCikgewoJc3RydWN0IF93MzFfZGlyZW50CSpkaXI7CglzdHJ1Y3QgX3czMV9rZXllbnQJKmtleTsKCXN0cnVjdCBfdzMxX3ZhbGVudAkqdmFsOwogICAgICAgIEhLRVkgc3Via2V5ID0gMDsKCXN0YXRpYyBjaGFyCQl0YWlsWzQwMF07CgoJd2hpbGUgKGlkeCE9MCkgewoJCWRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgoJCWlmIChkaXItPmtleV9pZHgpIHsKCQkJa2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKCQkJbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKCQkJdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKCQkJLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZSAKCQkJICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwoJCQkgKi8KCQkJaWYgKCFsZXZlbCAmJiAhbHN0cmNtcEEodGFpbCwiLmNsYXNzZXMiKSkgewoJCQkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLGhrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCQkJaWR4PWRpci0+c2libGluZ19pZHg7CgkJCQljb250aW51ZTsKCQkJfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3Via2V5KSBSZWdDbG9zZUtleSggc3Via2V5ICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChSZWdDcmVhdGVLZXlBKCBoa2V5LCB0YWlsLCAmc3Via2V5ICkgIT0gRVJST1JfU1VDQ0VTUykgc3Via2V5ID0gMDsKCQkJLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCgkJCWlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKCQkJCWlmIChkaXItPnZhbHVlX2lkeCkgewoJCQkJCXZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKCQkJCQltZW1jcHkodGFpbCwmdHh0W3ZhbC0+c3RyaW5nX29mZl0sdmFsLT5sZW5ndGgpOwoJCQkJCXRhaWxbdmFsLT5sZW5ndGhdPSdcMCc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdTZXRWYWx1ZUEoIHN1YmtleSwgTlVMTCwgUkVHX1NaLCB0YWlsLCAwICk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQlUUkFDRSgic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKCQl9CgkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHN1YmtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJaWR4PWRpci0+c2libGluZ19pZHg7Cgl9CiAgICAgICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzMxX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kdm9pZCBfdzMxX2xvYWRyZWcodm9pZCkgewoJSEZJTEUJCQloZjsKCXN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwoJc3RydWN0IF93MzFfdGFiZW50CSp0YWI7Cgl1bnNpZ25lZCBjaGFyCQkqdHh0OwoJaW50CQkJbGVuOwoJT0ZTVFJVQ1QJCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmaW5mbzsKCXRpbWVfdAkJCWxhc3Rtb2RpZmllZDsKCglUUkFDRSgiKHZvaWQpXG4iKTsKCgloZiA9IE9wZW5GaWxlKCJyZWcuZGF0Iiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmPT1IRklMRV9FUlJPUikKCQlyZXR1cm47CgoJLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCglpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQoaGYsJmhlYWQsc2l6ZW9mKGhlYWQpKSkgewoJCUVSUigicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSE9MCkgewoJCUVSUigicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCglsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwoJLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwoJdGFiID0geG1hbGxvYyhsZW4pOwoJaWYgKGxlbiE9X2xyZWFkKGhmLHRhYixsZW4pKSB7CgkJRVJSKCJjb3VsZG4ndCByZWFkICVkIGJ5dGVzLlxuIixsZW4pOyAKCQlmcmVlKHRhYik7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCS8qIHJlYWQgdGV4dCAqLwoJdHh0ID0geG1hbGxvYyhoZWFkLnRleHRzaXplKTsKCWlmICgtMT09X2xsc2VlayhoZixoZWFkLnRleHRvZmYsU0VFS19TRVQpKSB7CgkJRVJSKCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWlmIChoZWFkLnRleHRzaXplIT1fbHJlYWQoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CgkJRVJSKCJ0ZXh0YmxvY2sgdG9vIHNob3J0ICglZCBpbnN0ZWFkIG9mICVsZCkuXG4iLGxlbixoZWFkLnRleHRzaXplKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZiwmaGZpbmZvKSkgewoJCUVSUigiR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUgZmFpbGVkPy5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCV9fdzMxX2R1bXB0cmVlKHRhYlswXS53MSx0eHQsdGFiLCZoZWFkLEhLRVlfQ0xBU1NFU19ST09ULGxhc3Rtb2RpZmllZCwwKTsKCWZyZWUodGFiKTsKCWZyZWUodHh0KTsKCV9sY2xvc2UoaGYpOwoJcmV0dXJuOwp9CgoKLyogY29uZmlndXJlIHNhdmUgZmlsZXMgYW5kIHN0YXJ0IHRoZSBwZXJpb2RpYyBzYXZpbmcgdGltZXIgKi8Kc3RhdGljIHZvaWQgU0hFTExfSW5pdFJlZ2lzdHJ5U2F2aW5nKCBIS0VZIGhrZXlfdXNlcnNfZGVmYXVsdCApCnsKICAgIHN0cnVjdCBzZXRfcmVnaXN0cnlfbGV2ZWxzX3JlcXVlc3QgKnJlcSA9IGdldF9yZXFfYnVmZmVyKCk7CgogICAgaW50IGFsbCA9IFBST0ZJTEVfR2V0V2luZUluaUJvb2woICJyZWdpc3RyeSIsICJTYXZlT25seVVwZGF0ZWRLZXlzIiwgMSApOwogICAgaW50IHBlcmlvZCA9IFBST0ZJTEVfR2V0V2luZUluaUludCggInJlZ2lzdHJ5IiwgIlBlcmlvZGljU2F2ZSIsIDAgKTsKCiAgICAvKiBzZXQgc2F2aW5nIGxldmVsICgwIGZvciBzYXZpbmcgZXZlcnl0aGluZywgMSBmb3Igc2F2aW5nIG9ubHkgbW9kaWZpZWQga2V5cykgKi8KICAgIHJlcS0+Y3VycmVudCA9IDE7CiAgICByZXEtPnNhdmluZyAgPSAhYWxsOwogICAgcmVxLT5wZXJpb2QgID0gcGVyaW9kICogMTAwMDsKICAgIHNlcnZlcl9jYWxsKCBSRVFfU0VUX1JFR0lTVFJZX0xFVkVMUyApOwoKICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sKCJyZWdpc3RyeSIsIldyaXRldG9Ib21lUmVnaXN0cmllcyIsMSkpCiAgICB7CiAgICAgICAgc3RydWN0IHNhdmVfcmVnaXN0cnlfYXRleGl0X3JlcXVlc3QgKnJlcSA9IGdldF9yZXFfYnVmZmVyKCk7CiAgICAgICAgY29uc3QgY2hhciAqY29uZmRpciA9IGdldF9jb25maWdfZGlyKCk7CiAgICAgICAgY2hhciAqc3RyID0gcmVxLT5maWxlICsgc3RybGVuKGNvbmZkaXIpOwoKICAgICAgICBpZiAoc3RyICsgMjAgPiByZXEtPmZpbGUgKyBzZXJ2ZXJfcmVtYWluaW5nKHJlcS0+ZmlsZSkpCiAgICAgICAgewogICAgICAgICAgICBFUlIoImNvbmZpZyBkaXIgJyVzJyB0b28gbG9uZ1xuIiwgY29uZmRpciApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBzdHJjcHkoIHJlcS0+ZmlsZSwgY29uZmRpciApOwogICAgICAgIHN0cmNweSggc3RyLCAiLyIgU0FWRV9DVVJSRU5UX1VTRVIgKTsKICAgICAgICByZXEtPmhrZXkgPSBIS0VZX0NVUlJFTlRfVVNFUjsKICAgICAgICBzZXJ2ZXJfY2FsbCggUkVRX1NBVkVfUkVHSVNUUllfQVRFWElUICk7CgogICAgICAgIHN0cmNweSggcmVxLT5maWxlLCBjb25mZGlyICk7CiAgICAgICAgc3RyY3B5KCBzdHIsICIvIiBTQVZFX0xPQ0FMX01BQ0hJTkUgKTsKICAgICAgICByZXEtPmhrZXkgPSBIS0VZX0xPQ0FMX01BQ0hJTkU7CiAgICAgICAgc2VydmVyX2NhbGwoIFJFUV9TQVZFX1JFR0lTVFJZX0FURVhJVCApOwoKICAgICAgICBzdHJjcHkoIHJlcS0+ZmlsZSwgY29uZmRpciApOwogICAgICAgIHN0cmNweSggc3RyLCAiLyIgU0FWRV9ERUZBVUxUX1VTRVIgKTsKICAgICAgICByZXEtPmhrZXkgPSBoa2V5X3VzZXJzX2RlZmF1bHQ7CiAgICAgICAgc2VydmVyX2NhbGwoIFJFUV9TQVZFX1JFR0lTVFJZX0FURVhJVCApOwoKICAgICAgICBzdHJjcHkoIHJlcS0+ZmlsZSwgY29uZmRpciApOwogICAgICAgIHN0cmNweSggc3RyLCAiLyIgU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUICk7CiAgICAgICAgcmVxLT5oa2V5ID0gSEtFWV9VU0VSUzsKICAgICAgICBzZXJ2ZXJfY2FsbCggUkVRX1NBVkVfUkVHSVNUUllfQVRFWElUICk7CiAgICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTZXRMb2FkTGV2ZWwgW0ludGVybmFsXQogKgogKiBzZXQgbGV2ZWwgdG8gMCBmb3IgbG9hZGluZyBzeXN0ZW0gZmlsZXMKICogc2V0IGxldmVsIHRvIDEgZm9yIGxvYWRpbmcgdXNlciBmaWxlcwogKi8Kc3RhdGljIHZvaWQgU2V0TG9hZExldmVsKGludCBsZXZlbCkKewoJc3RydWN0IHNldF9yZWdpc3RyeV9sZXZlbHNfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKCglyZXEtPmN1cnJlbnQgPSBsZXZlbDsKCXJlcS0+c2F2aW5nICA9IDA7CiAgICAgICAgcmVxLT5wZXJpb2QgID0gMDsKCXNlcnZlcl9jYWxsKCBSRVFfU0VUX1JFR0lTVFJZX0xFVkVMUyApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEVMTF9Mb2FkUmVnaXN0cnkgW0ludGVybmFsXQogKi8KI2RlZmluZSBSRUdfRE9OVExPQUQgLTEKI2RlZmluZSBSRUdfV0lOMzEgIDAKI2RlZmluZSBSRUdfV0lOOTUgIDEKI2RlZmluZSBSRUdfV0lOTlQgIDIKCnZvaWQgU0hFTExfTG9hZFJlZ2lzdHJ5KCB2b2lkICkKewogIEhLRVkJaGtleTsKICBjaGFyIHdpbmRpcltNQVhfUEFUSE5BTUVfTEVOXTsKICBjaGFyIHBhdGhbTUFYX1BBVEhOQU1FX0xFTl07CiAgaW50ICBzeXN0ZW10eXBlID0gUkVHX1dJTjMxOwogIEhLRVkgaGtleV91c2Vyc19kZWZhdWx0OwoKICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgaWYgKCFDTElFTlRfSXNCb290VGhyZWFkKCkpIHJldHVybjsgIC8qIGFscmVhZHkgbG9hZGVkICovCgogIFJFR0lTVFJZX0luaXQoKTsKICBTZXRMb2FkTGV2ZWwoMCk7CgogIGlmIChSZWdDcmVhdGVLZXlBKEhLRVlfVVNFUlMsICIuRGVmYXVsdCIsICZoa2V5X3VzZXJzX2RlZmF1bHQpKQoJICBoa2V5X3VzZXJzX2RlZmF1bHQgPSAwOwoKICBHZXRXaW5kb3dzRGlyZWN0b3J5QSggd2luZGlyLCBNQVhfUEFUSE5BTUVfTEVOICk7CgogIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sKCAiUmVnaXN0cnkiLCAiTG9hZFdpbmRvd3NSZWdpc3RyeUZpbGVzIiwgMSkpCiAgewogICAgLyogdGVzdCAld2luZGlyJS9zeXN0ZW0zMi9jb25maWcvc3lzdGVtIC0tPiB3aW5udCAqLwogICAgc3RyY3B5KHBhdGgsIHdpbmRpcik7CiAgICBzdHJuY2F0KHBhdGgsICJcXHN5c3RlbTMyXFxjb25maWdcXHN5c3RlbSIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzQShwYXRoKSAhPSAtMSkgCiAgICB7CiAgICAgIHN5c3RlbXR5cGUgPSBSRUdfV0lOTlQ7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAvKiB0ZXN0ICV3aW5kaXIlL3N5c3RlbS5kYXQgLS0+IHdpbjk1ICovCiAgICAgIHN0cmNweShwYXRoLCB3aW5kaXIpOwogICAgICBzdHJuY2F0KHBhdGgsICJcXHN5c3RlbS5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgIGlmKEdldEZpbGVBdHRyaWJ1dGVzQShwYXRoKSAhPSAtMSkKICAgICAgewogICAgICAgIHN5c3RlbXR5cGUgPSBSRUdfV0lOOTU7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoKHN5c3RlbXR5cGU9PVJFR19XSU5OVCkKICAgICAgJiYgKCEgUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiV2luZSIsICJQcm9maWxlIiwgIiIsIHBhdGgsIE1BWF9QQVRITkFNRV9MRU4pKSkKICAgIHsKICAgICAgIE1FU1NBR0UoIldoZW4geW91IGFyZSBydW5uaW5nIHdpdGggYSBuYXRpdmUgTlQgZGlyZWN0b3J5IHNwZWNpZnlcbiIpOwogICAgICAgTUVTU0FHRSgiJ1Byb2ZpbGU9PHByb2ZpbGVkaXJlY3Rvcnk+JyBvciBkaXNhYmxlIGxvYWRpbmcgb2YgV2luZG93c1xuIik7CiAgICAgICBNRVNTQUdFKCJyZWdpc3RyeSAoTG9hZFdpbmRvd3NSZWdpc3RyeUZpbGVzPU4pXG4iKTsKICAgICAgIHN5c3RlbXR5cGUgPSBSRUdfRE9OVExPQUQ7CiAgICB9CiAgfQogIGVsc2UKICB7CiAgICAvKiBvbmx5IHdpbmUgcmVnaXN0cnkgKi8KICAgIHN5c3RlbXR5cGUgPSBSRUdfRE9OVExPQUQ7CiAgfSAgCgogIHN3aXRjaCAoc3lzdGVtdHlwZSkKICB7CiAgICBjYXNlIFJFR19XSU4zMToKICAgICAgX3czMV9sb2FkcmVnKCk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgUkVHX1dJTjk1OiAgCiAgICAgIC8qIExvYWQgd2luZG93cyA5NSBlbnRyaWVzICovCiAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoSEtFWV9MT0NBTF9NQUNISU5FLCAiQzpcXHN5c3RlbS4xc3QiLCAwKTsKCiAgICAgIHN0cmNweShwYXRoLCB3aW5kaXIpOwogICAgICBzdHJuY2F0KHBhdGgsICJcXHN5c3RlbS5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoSEtFWV9MT0NBTF9NQUNISU5FLCBwYXRoLCAwKTsKCiAgICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJXaW5lIiwgIlByb2ZpbGUiLCAiIiwgcGF0aCwgTUFYX1BBVEhOQU1FX0xFTikpCiAgICAgIHsKCS8qIHVzZXIgc3BlY2lmaWMgdXNlci5kYXQgKi8KCXN0cm5jYXQocGF0aCwgIlxcdXNlci5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgICAgaWYgKCFOYXRpdmVSZWdMb2FkS2V5KCBIS0VZX0NVUlJFTlRfVVNFUiwgcGF0aCwgMSApKQoJewoJICBNRVNTQUdFKCJjYW4ndCBsb2FkIHdpbjk1IHVzZXItcmVnaXN0cnkgJXNcbiIsIHBhdGgpOwoJICBNRVNTQUdFKCJjaGVjayB3aW5lLmNvbmYsIHNlY3Rpb24gW1dpbmVdLCB2YWx1ZSAnUHJvZmlsZSdcbiIpOwoJfQoJLyogZGVmYXVsdCB1c2VyLmRhdCAqLwoJaWYgKGhrZXlfdXNlcnNfZGVmYXVsdCkKCXsKICAgICAgICAgIHN0cmNweShwYXRoLCB3aW5kaXIpOwogICAgICAgICAgc3RybmNhdChwYXRoLCAiXFx1c2VyLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoaGtleV91c2Vyc19kZWZhdWx0LCBwYXRoLCAxKTsKCX0KICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICAvKiBnbG9iYWwgdXNlci5kYXQgKi8KCXN0cmNweShwYXRoLCB3aW5kaXIpOwogICAgICAgIHN0cm5jYXQocGF0aCwgIlxcdXNlci5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgICAgTmF0aXZlUmVnTG9hZEtleShIS0VZX0NVUlJFTlRfVVNFUiwgcGF0aCwgMSk7CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgY2FzZSBSRUdfV0lOTlQ6ICAKICAgICAgLyogZGVmYXVsdCB1c2VyLmRhdCAqLwogICAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiV2luZSIsICJQcm9maWxlIiwgIiIsIHBhdGgsIE1BWF9QQVRITkFNRV9MRU4pKQogICAgICB7CiAgICAgICAgc3RybmNhdChwYXRoLCAiXFxudHVzZXIuZGF0IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICAgIGlmKCFOYXRpdmVSZWdMb2FkS2V5KCBIS0VZX0NVUlJFTlRfVVNFUiwgcGF0aCwgMSApKQogICAgICAgIHsKICAgICAgICAgICBNRVNTQUdFKCJjYW4ndCBsb2FkIE5UIHVzZXItcmVnaXN0cnkgJXNcbiIsIHBhdGgpOwoJICAgTUVTU0FHRSgiY2hlY2sgd2luZS5jb25mLCBzZWN0aW9uIFtXaW5lXSwgdmFsdWUgJ1Byb2ZpbGUnXG4iKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8qIGRlZmF1bHQgdXNlci5kYXQgKi8KICAgICAgaWYgKGhrZXlfdXNlcnNfZGVmYXVsdCkKICAgICAgewogICAgICAgIHN0cmNweShwYXRoLCB3aW5kaXIpOwogICAgICAgIHN0cm5jYXQocGF0aCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcZGVmYXVsdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4ocGF0aCkgLSAxKTsKICAgICAgICBOYXRpdmVSZWdMb2FkS2V5KGhrZXlfdXNlcnNfZGVmYXVsdCwgcGF0aCwgMSk7CiAgICAgIH0KCiAgICAgIC8qCiAgICAgICogRklYTUUKICAgICAgKiAgbWFwIEhMTVxTeXN0ZW1cQ29udHJvbFNldDAwMSB0byBITE1cU3lzdGVtXEN1cnJlbnRDb250cm9sU2V0CiAgICAgICovCgogICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCAiU1lTVEVNIiwgJmhrZXkpKQogICAgICB7CglzdHJjcHkocGF0aCwgd2luZGlyKTsKCXN0cm5jYXQocGF0aCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc3lzdGVtIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwoJTmF0aXZlUmVnTG9hZEtleShoa2V5LCBwYXRoLCAxKTsKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgfQoKICAgICAgaWYgKCFSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwgIlNPRlRXQVJFIiwgJmhrZXkpKQogICAgICB7CglzdHJjcHkocGF0aCwgd2luZGlyKTsKCXN0cm5jYXQocGF0aCwgIlxcc3lzdGVtMzJcXGNvbmZpZ1xcc29mdHdhcmUiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CglOYXRpdmVSZWdMb2FkS2V5KGhrZXksIHBhdGgsIDEpOwogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICB9CgogICAgICBzdHJjcHkocGF0aCwgd2luZGlyKTsKICAgICAgc3RybmNhdChwYXRoLCAiXFxzeXN0ZW0zMlxcY29uZmlnXFxzYW0iLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKHBhdGgpIC0gMSk7CiAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoSEtFWV9MT0NBTF9NQUNISU5FLCBwYXRoLCAwKTsKCiAgICAgIHN0cmNweShwYXRoLCB3aW5kaXIpOwogICAgICBzdHJuY2F0KHBhdGgsICJcXHN5c3RlbTMyXFxjb25maWdcXHNlY3VyaXR5IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihwYXRoKSAtIDEpOwogICAgICBOYXRpdmVSZWdMb2FkS2V5KEhLRVlfTE9DQUxfTUFDSElORSwgcGF0aCwgMCk7CgogICAgICAvKiB0aGlzIGtleSBpcyBnZW5lcmF0ZWQgd2hlbiB0aGUgbnQtY29yZSBib290ZWQgc3VjY2Vzc2Z1bGx5ICovCiAgICAgIGlmICghUmVnQ3JlYXRlS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ2xvbmUiLCZoa2V5KSkKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgYnJlYWs7CiAgfSAvKiBzd2l0Y2ggKi8KICAKICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCAoInJlZ2lzdHJ5IiwiTG9hZEdsb2JhbFJlZ2lzdHJ5RmlsZXMiLCAxKSkKICB7CiAgICAgIC8qIAogICAgICAgKiBMb2FkIHRoZSBnbG9iYWwgSEtVIGhpdmUgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyCiAgICAgICAqLyAKICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9VU0VSUywgU0FWRV9VU0VSU19ERUZBVUxUICk7CgogICAgICAvKiAKICAgICAgICogTG9hZCB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyCiAgICAgICAqLwogICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX0xPQ0FMX01BQ0hJTkUsIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUICk7CiAgfQoKICBTZXRMb2FkTGV2ZWwoMSk7CgogIC8qCiAgICogTG9hZCB0aGUgdXNlciBzYXZlZCByZWdpc3RyaWVzIAogICAqLwogIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sKCJyZWdpc3RyeSIsICJMb2FkSG9tZVJlZ2lzdHJ5RmlsZXMiLCAxKSkKICB7CiAgICAgIGNvbnN0IGNoYXIgKmNvbmZkaXIgPSBnZXRfY29uZmlnX2RpcigpOwogICAgICBpbnQgbGVuID0gc3RybGVuKGNvbmZkaXIpICsgMjA7CiAgICAgIGNoYXIgKmZuID0gcGF0aDsKCiAgICAgIGlmIChsZW4gPiBzaXplb2YocGF0aCkpIGZuID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4gKTsKICAgICAgLyogCiAgICAgICAqIExvYWQgdXNlcidzIHBlcnNvbmFsIHZlcnNpb25zIG9mIGdsb2JhbCBIS1UvLkRlZmF1bHQga2V5cwogICAgICAgKi8KICAgICAgaWYgKGZuKQogICAgICB7CiAgICAgICAgICBjaGFyICpzdHI7CiAgICAgICAgICBzdHJjcHkoIGZuLCBjb25mZGlyICk7CiAgICAgICAgICBzdHIgPSBmbiArIHN0cmxlbihmbik7CiAgICAgICAgICAqc3RyKysgPSAnLyc7CgogICAgICAgICAgLyogdHJ5IHRvIGxvYWQgSEtVXC5EZWZhdWx0IGtleSBvbmx5ICovCiAgICAgICAgICBzdHJjcHkoIHN0ciwgU0FWRV9ERUZBVUxUX1VTRVIgKTsKICAgICAgICAgIGlmIChfd2luZV9sb2FkcmVnKCBoa2V5X3VzZXJzX2RlZmF1bHQsIGZuICkpCiAgICAgICAgICB7CiAgICAgICAgICAgICAgLyogaWYgbm90IGZvdW5kIGxvYWQgb2xkIGZpbGUgY29udGFpbmluZyBib3RoIEhLVVwuRGVmYXVsdCBhbmQgSEtVXHVzZXIgKi8KICAgICAgICAgICAgICBzdHJjcHkoIHN0ciwgU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUICk7CiAgICAgICAgICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9VU0VSUywgZm4gKTsgCiAgICAgICAgICB9CgogICAgICAgICAgc3RyY3B5KCBzdHIsIFNBVkVfQ1VSUkVOVF9VU0VSICk7CiAgICAgICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX0NVUlJFTlRfVVNFUiwgZm4gKTsKCiAgICAgICAgICBzdHJjcHkoIHN0ciwgU0FWRV9MT0NBTF9NQUNISU5FICk7CiAgICAgICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX0xPQ0FMX01BQ0hJTkUsIGZuICk7CgogICAgICAgICAgaWYgKGZuICE9IHBhdGgpIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBmbiApOwogICAgICB9CiAgfQogIFNIRUxMX0luaXRSZWdpc3RyeVNhdmluZyggaGtleV91c2Vyc19kZWZhdWx0ICk7CiAgUmVnQ2xvc2VLZXkoIGhrZXlfdXNlcnNfZGVmYXVsdCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqIEFQSSBGVU5DVElPTlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdGbHVzaEtleSBbS0VSTkVMLjIyN10gW0FEVkFQSTMyLjE0M10KICogSW1tZWRpYXRlbHkgd3JpdGVzIGtleSB0byByZWdpc3RyeS4KICogT25seSByZXR1cm5zIGFmdGVyIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiB0byBkaXNrLgogKgogKiBGSVhNRTogZG9lcyBpdCByZWFsbHkgd2FpdCB1bnRpbCBkYXRhIGlzIHdyaXR0ZW4gPwogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byB3cml0ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0ZsdXNoS2V5KCBIS0VZIGhrZXkgKQp7CiAgICBGSVhNRSggIigleCk6IHN0dWJcbiIsIGhrZXkgKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nvbm5lY3RSZWdpc3RyeVcgW0FEVkFQSTMyLjEyOF0KICoKICogUEFSQU1TCiAqICAgIGxwTWFjaGluZU5hbWUgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiByZW1vdGUgY29tcHV0ZXIKICogICAgaEhleSAgICAgICAgICBbSV0gUHJlZGVmaW5lZCByZWdpc3RyeSBoYW5kbGUKICogICAgcGhrUmVzdWx0ICAgICBbSV0gQWRkcmVzcyBvZiBidWZmZXIgZm9yIHJlbW90ZSByZWdpc3RyeSBoYW5kbGUKICovCkxPTkcgV0lOQVBJIFJlZ0Nvbm5lY3RSZWdpc3RyeVcoIExQQ1dTVFIgbHBNYWNoaW5lTmFtZSwgSEtFWSBoS2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEhLRVkgcGhrUmVzdWx0ICkKewogICAgVFJBQ0UoIiglcywleCwlcCk6IHN0dWJcbiIsZGVidWdzdHJfdyhscE1hY2hpbmVOYW1lKSxoS2V5LHBoa1Jlc3VsdCk7CgogICAgaWYgKCFscE1hY2hpbmVOYW1lIHx8ICEqbHBNYWNoaW5lTmFtZSkgewogICAgICAgIC8qIFVzZSB0aGUgbG9jYWwgbWFjaGluZSBuYW1lICovCiAgICAgICAgcmV0dXJuIFJlZ09wZW5LZXkxNiggaEtleSwgIiIsIHBoa1Jlc3VsdCApOwogICAgfQoKICAgIEZJWE1FKCJDYW5ub3QgY29ubmVjdCB0byAlc1xuIixkZWJ1Z3N0cl93KGxwTWFjaGluZU5hbWUpKTsKICAgIHJldHVybiBFUlJPUl9CQURfTkVUUEFUSDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ29ubmVjdFJlZ2lzdHJ5QSBbQURWQVBJMzIuMTI3XQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5QSggTFBDU1RSIG1hY2hpbmUsIEhLRVkgaGtleSwgTFBIS0VZIHJlc2tleSApCnsKICAgIExQV1NUUiBtYWNoaW5lVyA9IEhFQVBfc3RyZHVwQXRvVyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWFjaGluZSApOwogICAgRFdPUkQgcmV0ID0gUmVnQ29ubmVjdFJlZ2lzdHJ5VyggbWFjaGluZVcsIGhrZXksIHJlc2tleSApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIG1hY2hpbmVXICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdHZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTQ0XQogKiBSZXRyaWV2ZXMgYSBjb3B5IG9mIHNlY3VyaXR5IGRlc2NyaXB0b3IgcHJvdGVjdGluZyB0aGUgcmVnaXN0cnkga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgICAgICAgIFtJXSAgIE9wZW4gaGFuZGxlIG9mIGtleSB0byBzZXQKICogICAgU2VjdXJpdHlJbmZvcm1hdGlvbiAgICBbSV0gICBEZXNjcmlwdG9yIGNvbnRlbnRzCiAqICAgIHBTZWN1cml0eURlc2NyaXB0b3IgICAgW09dICAgQWRkcmVzcyBvZiBkZXNjcmlwdG9yIGZvciBrZXkKICogICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciBbSS9PXSBBZGRyZXNzIG9mIHNpemUgb2YgYnVmZmVyIGFuZCBkZXNjcmlwdGlvbgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KTE9ORyBXSU5BUEkgUmVnR2V0S2V5U2VjdXJpdHkoIEhLRVkgaGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRUNVUklUWV9JTkZPUk1BVElPTiBTZWN1cml0eUluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciApCnsKICAgIFRSQUNFKCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxTZWN1cml0eUluZm9ybWF0aW9uLHBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yPypscGNiU2VjdXJpdHlEZXNjcmlwdG9yOjApOwoKICAgIC8qIEZJWE1FOiBDaGVjayBmb3IgdmFsaWQgU2VjdXJpdHlJbmZvcm1hdGlvbiB2YWx1ZXMgKi8KCiAgICBpZiAoKmxwY2JTZWN1cml0eURlc2NyaXB0b3IgPCBzaXplb2YoU0VDVVJJVFlfREVTQ1JJUFRPUikpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVI7CgogICAgRklYTUUoIigleCwlbGQsJXAsJWxkKTogc3R1YlxuIixoa2V5LFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICBwU2VjdXJpdHlEZXNjcmlwdG9yLGxwY2JTZWN1cml0eURlc2NyaXB0b3I/KmxwY2JTZWN1cml0eURlc2NyaXB0b3I6MCk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlIFtBRFZBUEkzMi4/Pz9dCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgW0ldIEhhbmRsZSBvZiBrZXkgdG8gd2F0Y2gKICogICAgZldhdGNoU3ViVHJlZSAgIFtJXSBGbGFnIGZvciBzdWJrZXkgbm90aWZpY2F0aW9uCiAqICAgIGZkd05vdGlmeUZpbHRlciBbSV0gQ2hhbmdlcyB0byBiZSByZXBvcnRlZAogKiAgICBoRXZlbnQgICAgICAgICAgW0ldIEhhbmRsZSBvZiBzaWduYWxlZCBldmVudAogKiAgICBmQXN5bmMgICAgICAgICAgW0ldIEZsYWcgZm9yIGFzeW5jaHJvbm91cyByZXBvcnRpbmcKICovCkxPTkcgV0lOQVBJIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlKCBIS0VZIGhrZXksIEJPT0wgZldhdGNoU3ViVHJlZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBmZHdOb3RpZnlGaWx0ZXIsIEhBTkRMRSBoRXZlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIGZBc3luYyApCnsKICAgIEZJWE1FKCIoJXgsJWksJWxkLCV4LCVpKTogc3R1YlxuIixoa2V5LGZXYXRjaFN1YlRyZWUsZmR3Tm90aWZ5RmlsdGVyLAogICAgICAgICAgaEV2ZW50LGZBc3luYyk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnVW5Mb2FkS2V5VyBbQURWQVBJMzIuMTczXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscFN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleSB0byB1bmxvYWQKICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSApCnsKICAgIEZJWE1FKCIoJXgsJXMpOiBzdHViXG4iLGhrZXksIGRlYnVnc3RyX3cobHBTdWJLZXkpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXlBIFtBRFZBUEkzMi4xNzJdCiAqLwpMT05HIFdJTkFQSSBSZWdVbkxvYWRLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSApCnsKICAgIExQV1NUUiBscFN1YktleVcgPSBIRUFQX3N0cmR1cEF0b1coIEdldFByb2Nlc3NIZWFwKCksIDAsIGxwU3ViS2V5ICk7CiAgICBMT05HIHJldCA9IFJlZ1VuTG9hZEtleVcoIGhrZXksIGxwU3ViS2V5VyApOwogICAgaWYobHBTdWJLZXlXKSBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldEtleVNlY3VyaXR5IFtBRFZBUEkzMi4xNjddCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgIFtJXSBPcGVuIGhhbmRsZSBvZiBrZXkgdG8gc2V0CiAqICAgIFNlY3VyaXR5SW5mbyAgW0ldIERlc2NyaXB0b3IgY29udGVudHMKICogICAgcFNlY3VyaXR5RGVzYyBbSV0gQWRkcmVzcyBvZiBkZXNjcmlwdG9yIGZvciBrZXkKICovCkxPTkcgV0lOQVBJIFJlZ1NldEtleVNlY3VyaXR5KCBIS0VZIGhrZXksIFNFQ1VSSVRZX0lORk9STUFUSU9OIFNlY3VyaXR5SW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTRUNVUklUWV9ERVNDUklQVE9SIHBTZWN1cml0eURlc2MgKQp7CiAgICBUUkFDRSgiKCV4LCVsZCwlcClcbiIsaGtleSxTZWN1cml0eUluZm8scFNlY3VyaXR5RGVzYyk7CgogICAgLyogSXQgc2VlbXMgdG8gcGVyZm9ybSB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKChTZWN1cml0eUluZm8gJiBPV05FUl9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgR1JPVVBfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIERBQ0xfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIFNBQ0xfU0VDVVJJVFlfSU5GT1JNQVRJT04pKSB7CiAgICAgICAgLyogUGFyYW0gT0sgKi8KICAgIH0gZWxzZQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBpZiAoIXBTZWN1cml0eURlc2MpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIEZJWE1FKCI6KCV4LCVsZCwlcCk6IHN0dWJcbiIsaGtleSxTZWN1cml0eUluZm8scFNlY3VyaXR5RGVzYyk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1Jlc3RvcmVLZXlXIFtBRFZBUEkzMi4xNjRdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgIFtJXSBIYW5kbGUgb2Yga2V5IHdoZXJlIHJlc3RvcmUgYmVnaW5zCiAqICAgIGxwRmlsZSAgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgY29udGFpbmluZyBzYXZlZCB0cmVlCiAqICAgIGR3RmxhZ3MgW0ldIE9wdGlvbmFsIGZsYWdzCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIFRSQUNFKCIoJXgsJXMsJWxkKVxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBJdCBzZWVtcyB0byBkbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscEZpbGUgfHwgISpscEZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIEZJWE1FKCIoJXgsJXMsJWxkKTogc3R1YlxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBDaGVjayBmb3IgZmlsZSBleGlzdGVuY2UgKi8KCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleUEgW0FEVkFQSTMyLjE2M10KICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscEZpbGUsIERXT1JEIGR3RmxhZ3MgKQp7CiAgICBMUFdTVFIgbHBGaWxlVyA9IEhFQVBfc3RyZHVwQXRvVyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBGaWxlICk7CiAgICBMT05HIHJldCA9IFJlZ1Jlc3RvcmVLZXlXKCBoa2V5LCBscEZpbGVXLCBkd0ZsYWdzICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBGaWxlVyApOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleVcgW0FEVkFQSTMyLjE2Ml0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwU3ViS2V5ICBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleQogKiAgICBscE5ld0ZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIGZpbGUgd2l0aCBuZXcgZGF0YQogKiAgICBscE9sZEZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIGJhY2t1cCBmaWxlCiAqLwpMT05HIFdJTkFQSSBSZWdSZXBsYWNlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwU3ViS2V5LCBMUENXU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBscE9sZEZpbGUgKQp7CiAgICBGSVhNRSgiKCV4LCVzLCVzLCVzKTogc3R1YlxuIiwgaGtleSwgZGVidWdzdHJfdyhscFN1YktleSksIAogICAgICAgICAgZGVidWdzdHJfdyhscE5ld0ZpbGUpLGRlYnVnc3RyX3cobHBPbGRGaWxlKSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleUEgW0FEVkFQSTMyLjE2MV0KICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSwgTFBDU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwT2xkRmlsZSApCnsKICAgIExQV1NUUiBscFN1YktleVcgPSBIRUFQX3N0cmR1cEF0b1coIEdldFByb2Nlc3NIZWFwKCksIDAsIGxwU3ViS2V5ICk7CiAgICBMUFdTVFIgbHBOZXdGaWxlVyA9IEhFQVBfc3RyZHVwQXRvVyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBOZXdGaWxlICk7CiAgICBMUFdTVFIgbHBPbGRGaWxlVyA9IEhFQVBfc3RyZHVwQXRvVyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBPbGRGaWxlICk7CiAgICBMT05HIHJldCA9IFJlZ1JlcGxhY2VLZXlXKCBoa2V5LCBscFN1YktleVcsIGxwTmV3RmlsZVcsIGxwT2xkRmlsZVcgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBscE9sZEZpbGVXICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBOZXdGaWxlVyApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxwU3ViS2V5VyApOwogICAgcmV0dXJuIHJldDsKfQoKCgoKCgovKiAxNi1iaXQgZnVuY3Rpb25zICovCgovKiAwIGFuZCAxIGFyZSB2YWxpZCByb290a2V5cyBpbiB3aW4xNiBzaGVsbC5kbGwgYW5kIGFyZSB1c2VkIGJ5CiAqIHNvbWUgcHJvZ3JhbXMuIERvIG5vdCByZW1vdmUgdGhvc2UgY2FzZXMuIC1NTQogKi8Kc3RhdGljIGlubGluZSB2b2lkIGZpeF93aW4xNl9oa2V5KCBIS0VZICpoa2V5ICkKewogICAgaWYgKCpoa2V5ID09IDAgfHwgKmhrZXkgPT0gMSkgKmhrZXkgPSBIS0VZX0NMQVNTRVNfUk9PVDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRW51bUtleTE2ICAgW0tFUk5FTC4yMTZdIFtTSEVMTC43XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXkxNiggSEtFWSBoa2V5LCBEV09SRCBpbmRleCwgTFBTVFIgbmFtZSwgRFdPUkQgbmFtZV9sZW4gKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdFbnVtS2V5QSggaGtleSwgaW5kZXgsIG5hbWUsIG5hbWVfbGVuICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ09wZW5LZXkxNiAgIFtLRVJORUwuMjE3XSBbU0hFTEwuMV0KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQSEtFWSByZXRrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdPcGVuS2V5QSggaGtleSwgbmFtZSwgcmV0a2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0NyZWF0ZUtleTE2ICAgW0tFUk5FTC4yMThdIFtTSEVMTC4yXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUEhLRVkgcmV0a2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5QSggaGtleSwgbmFtZSwgcmV0a2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0RlbGV0ZUtleTE2ICAgW0tFUk5FTC4yMTldIFtTSEVMTC40XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRGVsZXRlS2V5QSggaGtleSwgbmFtZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdDbG9zZUtleTE2ICAgW0tFUk5FTC4yMjBdIFtTSEVMTC4zXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0Nsb3NlS2V5MTYoIEhLRVkgaGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0Nsb3NlS2V5KCBoa2V5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1NldFZhbHVlMTYgICBbS0VSTkVMLjIyMV0gW1NIRUxMLjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgRFdPUkQgdHlwZSwgTFBDU1RSIGRhdGEsIERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVBKCBoa2V5LCBuYW1lLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdEZWxldGVWYWx1ZTE2ICBbS0VSTkVMLjIyMl0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTE2KCBIS0VZIGhrZXksIExQU1RSIG5hbWUgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdEZWxldGVWYWx1ZUEoIGhrZXksIG5hbWUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRW51bVZhbHVlMTYgICBbS0VSTkVMLjIyM10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUxNiggSEtFWSBoa2V5LCBEV09SRCBpbmRleCwgTFBTVFIgdmFsdWUsIExQRFdPUkQgdmFsX2NvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgcmVzZXJ2ZWQsIExQRFdPUkQgdHlwZSwgTFBCWVRFIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdFbnVtVmFsdWVBKCBoa2V5LCBpbmRleCwgdmFsdWUsIHZhbF9jb3VudCwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUxNiAgIFtLRVJORUwuMjI0XSBbU0hFTEwuNl0KICoKICogTk9URVMKICogICAgSXMgdGhpcyBIQUNLIHN0aWxsIGFwcGxpY2FibGU/CiAqCiAqIEhBQ0sKICogICAgVGhlIDE2Yml0IFJlZ1F1ZXJ5VmFsdWUgZG9lc24ndCBoYW5kbGUgc2VsZWN0b3JibG9ja3MgYW55d2F5LCBzbyB3ZSBqdXN0CiAqICAgIG1hc2sgb3V0IHRoZSBoaWdoIDE2IGJpdC4gIFRoaXMgKG5vdCBzbyBtdWNoIGluY2lkZW50bHkpIGhvcGVmdWxseSBmaXhlcwogKiAgICBBbGR1cyBGSDQpCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUFNUUiBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICBpZiAoY291bnQpICpjb3VudCAmPSAweGZmZmY7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUEoIGhrZXksIG5hbWUsIGRhdGEsIGNvdW50ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWVFeDE2ICAgW0tFUk5FTC4yMjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIExQRFdPUkQgcmVzZXJ2ZWQsIExQRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeEEoIGhrZXksIG5hbWUsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdTZXRWYWx1ZUV4MTYgICBbS0VSTkVMLjIyNl0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIERXT1JEIHJlc2VydmVkLCBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05TVCBCWVRFICpkYXRhLCBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlRXhBKCBoa2V5LCBuYW1lLCByZXNlcnZlZCwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQo=