LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICoKICogRGVjZW1iZXIgMjEsIDE5OTcgLSBLZXZpbiBDb3plbnMKICogRml4ZWQgYnVncyBpbiB0aGUgX3c5NV9sb2FkcmVnKCkgZnVuY3Rpb24uIEFkZGVkIGV4dHJhIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyB0aGUgZm9ybWF0IG9mIHRoZSBXaW5kb3dzICc5NSByZWdpc3RyeSBmaWxlcy4KICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxwd2QuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAid2luLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAiaGVhcC5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2RlZmluZQlERUJVR19XOTVfTE9BRFJFRwkwCgovKiBGSVhNRTogZm9sbG93aW5nIGRlZmluZXMgc2hvdWxkIGJlIGNvbmZpZ3VyZWQgZ2xvYmFsIC4uLiAqLwoKLyogTk9URTogZG8gbm90IGFwcGVuZCBhIC8uIGxpbnV4JyBta2RpcigpIFdJTEwgRkFJTCBpZiB5b3UgZG8gdGhhdCAqLwojZGVmaW5lIFdJTkVfUFJFRklYCQkJIi8ud2luZSIKI2RlZmluZSBTQVZFX1VTRVJTX0RFRkFVTFQJCSIvdXNyL2xvY2FsL2V0Yy93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQJIi91c3IvbG9jYWwvZXRjL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0NVUlJFTlRfVVNFUgkJInVzZXIucmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORQkJInN5c3RlbS5yZWciCgojZGVmaW5lIEtFWV9SRUdJU1RSWQkiU29mdHdhcmVcXFRoZSBXSU5FIHRlYW1cXFdJTkVcXFJlZ2lzdHJ5IgojZGVmaW5lIFZBTF9TQVZFVVBEQVRFRAkiU2F2ZU9ubHlVcGRhdGVkS2V5cyIKCi8qIG9uZSB2YWx1ZSBvZiBhIGtleSAqLwp0eXBlZGVmIHN0cnVjdCB0YWdLRVlWQUxVRQp7CiAgICBMUFdTVFIgICBuYW1lOyAgICAgICAgICAvKiBuYW1lIG9mIHZhbHVlIChVTklDT0RFKSBvciBOVUxMIGZvciB3aW4zMSAqLwogICAgRFdPUkQgICAgdHlwZTsgICAgICAgICAgLyogdHlwZSBvZiB2YWx1ZSAqLwogICAgRFdPUkQgICAgbGVuOyAgICAgICAgICAgLyogbGVuZ3RoIG9mIGRhdGEgaW4gQllURXMgKi8KICAgIERXT1JEICAgIGxhc3Rtb2RpZmllZDsgIC8qIHRpbWUgb2Ygc2Vjb25kcyBzaW5jZSAxLjEuMTk3MCAqLwogICAgTFBCWVRFICAgZGF0YTsgICAgICAgICAgLyogY29udGVudCwgbWF5IGJlIHN0cmluZ3MsIGJpbmFyaWVzLCBldGMuICovCn0gS0VZVkFMVUUsKkxQS0VZVkFMVUU7CgovKiBhIHJlZ2lzdHJ5IGtleSAqLwp0eXBlZGVmIHN0cnVjdCB0YWdLRVlTVFJVQ1QKewogICAgTFBXU1RSICAgICAgICAgICAgICAga2V5bmFtZTsgICAgICAgLyogbmFtZSBvZiBUSElTIGtleSAoVU5JQ09ERSkgKi8KICAgIERXT1JEICAgICAgICAgICAgICAgIGZsYWdzOyAgICAgICAgIC8qIGZsYWdzLiAqLwogICAgTFBXU1RSICAgICAgICAgICAgICAgY2xhc3M7CiAgICAvKiB2YWx1ZXMgKi8KICAgIERXT1JEICAgICAgICAgICAgICAgIG5yb2Z2YWx1ZXM7ICAgIC8qIG5yIG9mIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgTFBLRVlWQUxVRSAgICAgICAgICAgdmFsdWVzOyAgICAgICAgLyogdmFsdWVzIGluIFRISVMga2V5ICovCiAgICAvKiBrZXkgbWFuYWdlbWVudCBwb2ludGVycyAqLwogICAgc3RydWN0IHRhZ0tFWVNUUlVDVAkqbmV4dDsgICAgICAgICAgLyogbmV4dCBrZXkgb24gc2FtZSBoaWVyYXJjaHkgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHRzdWI7ICAgICAgIC8qIGtleXMgdGhhdCBoYW5nIGJlbG93IFRISVMga2V5ICovCn0gS0VZU1RSVUNULCAqTFBLRVlTVFJVQ1Q7CgoKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2NsYXNzZXNfcm9vdD1OVUxMOwkvKiB3aW5kb3dzIDMuMSBnbG9iYWwgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jdXJyZW50X3VzZXI9TlVMTDsJLyogdXNlciBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X2xvY2FsX21hY2hpbmU9TlVMTDsvKiBtYWNoaW5lIHNwZWNpZmljIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfdXNlcnM9TlVMTDsJLyogYWxsIHVzZXJzPyAqLwoKLyogZHluYW1pYywgbm90IHNhdmVkICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9wZXJmb3JtYW5jZV9kYXRhPU5VTEw7CnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jdXJyZW50X2NvbmZpZz1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfZHluX2RhdGE9TlVMTDsKCi8qIHdoYXQgdmFsdWV0eXBlcyBkbyB3ZSBuZWVkIHRvIGNvbnZlcnQ/ICovCiNkZWZpbmUgVU5JQ09OVk1BU0sJKCgxPDxSRUdfU1opfCgxPDxSRUdfTVVMVElfU1opfCgxPDxSRUdfRVhQQU5EX1NaKSkKCmV4dGVybiBMUFdTVFIgX19jZGVjbCBDUlRETExfd2NzY2hyKExQV1NUUiBhLFdDSEFSIGMpOwoKc3RhdGljIExQV1NUUiBzdHJkdXBBMlcoTFBDU1RSIHNyYykKewoJTFBXU1RSIGRlc3Q9eG1hbGxvYygyKnN0cmxlbihzcmMpKzIpOwoJbHN0cmNweUF0b1coZGVzdCxzcmMpOwoJcmV0dXJuIGRlc3Q7Cn0KCnN0YXRpYyBMUFdTVFIgc3RyZHVwVyhMUENXU1RSIGEpIHsKCUxQV1NUUgliOwoJaW50CWxlbjsKCglsZW49c2l6ZW9mKFdDSEFSKSoobHN0cmxlbjMyVyhhKSsxKTsKCWI9KExQV1NUUil4bWFsbG9jKGxlbik7CgltZW1jcHkoYixhLGxlbik7CglyZXR1cm4gYjsKfQoKCnN0YXRpYyBzdHJ1Y3Qgb3BlbmhhbmRsZSB7CglMUEtFWVNUUlVDVAlscGtleTsKCUhLRVkJCWhrZXk7CglSRUdTQU0JCWFjY2Vzc21hc2s7Cn0gICpvcGVuaGFuZGxlcz1OVUxMOwpzdGF0aWMgaW50CW5yb2ZvcGVuaGFuZGxlcz0wOwpzdGF0aWMgaW50CWN1cnJlbnRoYW5kbGU9MTsKCnN0YXRpYyB2b2lkCmFkZF9oYW5kbGUoSEtFWSBoa2V5LExQS0VZU1RSVUNUIGxwa2V5LFJFR1NBTSBhY2Nlc3NtYXNrKSB7CglpbnQJaTsKCglmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspIHsKCQlpZiAob3BlbmhhbmRsZXNbaV0ubHBrZXk9PWxwa2V5KSB7CgkJCVdBUk4ocmVnLCAiVHJpZWQgdG8gYWRkICVwIHR3aWNlIVxuIixscGtleSk7CgkJfQoJCWlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KSB7CgkJCVdBUk4ocmVnLCAiVHJpZWQgdG8gYWRkICVseCB0d2ljZSFcbiIsKExPTkcpaGtleSk7CgkJfQoJfQoJb3BlbmhhbmRsZXM9eHJlYWxsb2MoCW9wZW5oYW5kbGVzLAoJCQkJc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzKzEpCgkJKTsKCW9wZW5oYW5kbGVzW2ldLmxwa2V5CT0gbHBrZXk7CglvcGVuaGFuZGxlc1tpXS5oa2V5CT0gaGtleTsKCW9wZW5oYW5kbGVzW2ldLmFjY2Vzc21hc2s9IGFjY2Vzc21hc2s7Cglucm9mb3BlbmhhbmRsZXMrKzsKfQoKc3RhdGljIExQS0VZU1RSVUNUCmdldF9oYW5kbGUoSEtFWSBoa2V5KSB7CglpbnQJaTsKCglmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspCgkJaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpCgkJCXJldHVybiBvcGVuaGFuZGxlc1tpXS5scGtleTsKCVdBUk4ocmVnLCAiRGlkbid0IGZpbmQgaGFuZGxlICVseD9cbiIsKExPTkcpaGtleSk7CglyZXR1cm4gTlVMTDsKfQoKc3RhdGljIHZvaWQKcmVtb3ZlX2hhbmRsZShIS0VZIGhrZXkpIHsKCWludAlpOwoKCWZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykKCQlpZiAob3BlbmhhbmRsZXNbaV0uaGtleT09aGtleSkKCQkJYnJlYWs7CglpZiAoaT09bnJvZm9wZW5oYW5kbGVzKSB7CgkJV0FSTihyZWcsICJEaWRuJ3QgZmluZCBoYW5kbGUgJTA4eD9cbiIsaGtleSk7CgkJcmV0dXJuOwoJfQoJbWVtY3B5KAlvcGVuaGFuZGxlcytpLAoJCW9wZW5oYW5kbGVzK2krMSwKCQlzaXplb2Yoc3RydWN0IG9wZW5oYW5kbGUpKihucm9mb3BlbmhhbmRsZXMtaS0xKQoJKTsKCW9wZW5oYW5kbGVzPXhyZWFsbG9jKG9wZW5oYW5kbGVzLHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy0xKSk7Cglucm9mb3BlbmhhbmRsZXMtLTsKCXJldHVybjsKfQoKCi8qIGRlYnVnIGZ1bmN0aW9uLCBjb252ZXJ0cyBhIHVuaWNvZGUgaW50byBhIHN0YXRpYyBtZW1vcnkgYXJlYSAKICogKHN1YiBmb3IgdXNpbmcgdHdvIHN0YXRpYyBzdHJpbmdzLCBpbiBjYXNlIHdlIG5lZWQgdGhlbSBpbiBhIHNpbmdsZSBjYWxsKQogKi8KTFBTVFIKVzJDKExQQ1dTVFIgeCxpbnQgc3ViKSB7CglzdGF0aWMJTFBTVFIJdW5pY29kZWRlYnVnWzJdPXtOVUxMLE5VTEx9OwoJaWYgKHg9PU5VTEwpCgkJcmV0dXJuICI8TlVMTD4iOwoJaWYgKHN1YiE9MCAmJiBzdWIhPTEpCgkJcmV0dXJuICI8VzJDOmJhZCBzdWI+IjsKCWlmICh1bmljb2RlZGVidWdbc3ViXSkgSGVhcEZyZWUoIFN5c3RlbUhlYXAsIDAsIHVuaWNvZGVkZWJ1Z1tzdWJdICk7Cgl1bmljb2RlZGVidWdbc3ViXSA9IEhFQVBfc3RyZHVwV3RvQSggU3lzdGVtSGVhcCwgMCwgeCApOwoJcmV0dXJuIHVuaWNvZGVkZWJ1Z1tzdWJdOwp9CgpzdGF0aWMgTFBLRVlTVFJVQ1QKbG9va3VwX2hrZXkoSEtFWSBoa2V5KSB7Cglzd2l0Y2ggKGhrZXkpIHsKCWNhc2UgMHgwMDAwMDAwMDoKCWNhc2UgMHgwMDAwMDAwMToKCWNhc2UgSEtFWV9DTEFTU0VTX1JPT1Q6CgkJcmV0dXJuIGtleV9jbGFzc2VzX3Jvb3Q7CgljYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgoJCXJldHVybiBrZXlfY3VycmVudF91c2VyOwoJY2FzZSBIS0VZX0xPQ0FMX01BQ0hJTkU6CgkJcmV0dXJuIGtleV9sb2NhbF9tYWNoaW5lOwoJY2FzZSBIS0VZX1VTRVJTOgoJCXJldHVybiBrZXlfdXNlcnM7CgljYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKCQlyZXR1cm4ga2V5X3BlcmZvcm1hbmNlX2RhdGE7CgljYXNlIEhLRVlfRFlOX0RBVEE6CgkJcmV0dXJuIGtleV9keW5fZGF0YTsKCWNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKCQlyZXR1cm4ga2V5X2N1cnJlbnRfY29uZmlnOwoJZGVmYXVsdDoKCQlyZXR1cm4gZ2V0X2hhbmRsZShoa2V5KTsKCX0KCS8qTk9UUkVBQ0hFRCovCn0KCi8qIAogKiBzcGxpdHMgdGhlIHVuaWNvZGUgc3RyaW5nICd3cCcgaW50byBhbiBhcnJheSBvZiBzdHJpbmdzLgogKiB0aGUgYXJyYXkgaXMgYWxsb2NhdGVkIGJ5IHRoaXMgZnVuY3Rpb24uIAogKiB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgd2lsbCBiZSBzdG9yZWQgaW4gJ3dwYycKICogRnJlZSB0aGUgYXJyYXkgdXNpbmcgRlJFRV9LRVlfUEFUSAogKi8Kc3RhdGljIHZvaWQKc3BsaXRfa2V5cGF0aChMUENXU1RSIHdwLExQV1NUUiAqKndwdixpbnQgKndwYykgewoJaW50CWksaixsZW47CglMUFdTVFIJd3M7CgoJd3MJPSBIRUFQX3N0cmR1cFcoIFN5c3RlbUhlYXAsIDAsIHdwICk7Cgkqd3BjCT0gMTsKCWZvciAoaT0wO3dzW2ldO2krKykgewoJCWlmICh3c1tpXT09J1xcJykgewoJCQl3c1tpXT0wOwoJCQkoKndwYykrKzsKCQl9Cgl9CglsZW4JPSBpOwoJKndwdgk9IChMUFdTVFIqKUhlYXBBbGxvYyggU3lzdGVtSGVhcCwgMCwgc2l6ZW9mKExQV1NUUikqKCp3cGMrMikpOwoJKCp3cHYpWzBdPSB3czsKCWoJPSAxOwoJZm9yIChpPTE7aTxsZW47aSsrKQoJCWlmICh3c1tpLTFdPT0wKQoJCQkoKndwdilbaisrXT13cytpOwoJKCp3cHYpW2pdPU5VTEw7Cn0KI2RlZmluZSBGUkVFX0tFWV9QQVRIIEhlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHNbMF0pO0hlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHMpOwoKLyoKICogU2hlbGwgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBrZXlzLiAKICovCnZvaWQgU0hFTExfU3RhcnR1cFJlZ2lzdHJ5KCk7CnZvaWQKU0hFTExfSW5pdCgpIHsKCXN0cnVjdAlwYXNzd2QJKnB3ZDsKCglIS0VZCWNsX3JfaGtleSxjX3VfaGtleTsKI2RlZmluZSBBRERfUk9PVF9LRVkoeHgpIFwKCXh4ID0gKExQS0VZU1RSVUNUKXhtYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpO1wKCW1lbXNldCh4eCwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTtcCgl4eC0+a2V5bmFtZT0gc3RyZHVwQTJXKCI8c2hvdWxkX25vdF9hcHBlYXJfYW55d2hlcmU+Iik7CgoJQUREX1JPT1RfS0VZKGtleV9sb2NhbF9tYWNoaW5lKTsKCWlmIChSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlxcU09GVFdBUkVcXENsYXNzZXMiLCZjbF9yX2hrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJRVJSKHJlZywiY291bGRuJ3QgY3JlYXRlIEhLRVlfTE9DQUxfTUFDSElORVxcU09GVFdBUkVcXENsYXNzZXMuIFRoaXMgaXMgaW1wb3NzaWJsZS5cbiIpOwoJCWV4aXQoMSk7Cgl9CglrZXlfY2xhc3Nlc19yb290ID0gbG9va3VwX2hrZXkoY2xfcl9oa2V5KTsKCglBRERfUk9PVF9LRVkoa2V5X3VzZXJzKTsKCiNpZiAwCgkvKiBGSVhNRTogbG9hZCBhbGwgdXNlcnMgYW5kIHRoZWlyIHJlc3AuIHB3ZC0+cHdfZGlyLy53aW5lL3VzZXIucmVnIAoJICoJICAobGF0ZXIsIHdoZW4gYSB3aW4zMiByZWdpc3RyeSBlZGl0aW5nIHRvb2wgYmVjb21lcyBhdmFpbC4pCgkgKi8KCXdoaWxlIChwd2Q9Z2V0cHdlbnQoKSkgewoJCWlmIChwd2QtPnB3X25hbWUgPT0gTlVMTCkKCQkJY29udGludWU7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUyxwd2QtPnB3X25hbWUsJmNfdV9oa2V5KTsKCQlSZWdDbG9zZUtleShjX3VfaGtleSk7Cgl9CiNlbmRpZgoJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCWlmIChwd2QgJiYgcHdkLT5wd19uYW1lKSB7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUyxwd2QtPnB3X25hbWUsJmNfdV9oa2V5KTsKCQlrZXlfY3VycmVudF91c2VyID0gbG9va3VwX2hrZXkoY191X2hrZXkpOwoJfSBlbHNlIHsKCQlBRERfUk9PVF9LRVkoa2V5X2N1cnJlbnRfdXNlcik7Cgl9CglBRERfUk9PVF9LRVkoa2V5X3BlcmZvcm1hbmNlX2RhdGEpOwoJQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X2NvbmZpZyk7CglBRERfUk9PVF9LRVkoa2V5X2R5bl9kYXRhKTsKI3VuZGVmIEFERF9ST09UX0tFWQoJU0hFTExfU3RhcnR1cFJlZ2lzdHJ5KCk7Cn0KCgp2b2lkClNIRUxMX1N0YXJ0dXBSZWdpc3RyeSgpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9EWU5fREFUQSwiXFxQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCglSZWdPcGVuS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJcXEhBUkRXQVJFXFxERVNDUklQVElPTlxcU3lzdGVtIiwmaGtleSk7CglSZWdTZXRWYWx1ZUV4MzJBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgkvKiBcXFNPRlRXQVJFXFxNaWNyb3NvZnRcXFdpbmRvdyBOVFxcQ3VycmVudFZlcnNpb24KCSAqCQkJCQkJQ3VycmVudFZlcnNpb24KCSAqCQkJCQkJQ3VycmVudEJ1aWxkTnVtYmVyCgkgKgkJCQkJCUN1cnJlbnRUeXBlCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPd25lcgoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3JnYW5pemF0aW9uCgkgKgoJICovCgkvKiBTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxTZXJ2aWNlc1xcU05NUFxcUGFyYW1ldGVyc1xcUkZDMTE1NkFnZW50CgkgKiAJCQkJCXN0cmluZwlTeXNDb250YWN0CgkgKiAJCQkJCXN0cmluZwlTeXNMb2NhdGlvbgoJICogCQkJCQkJU3lzU2VydmljZXMKCSAqLwkJCQkJCQoJaWYgKC0xIT1nZXRob3N0bmFtZShidWYsMjAwKSkgewoJCVJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcQ29tcHV0ZXJOYW1lXFxDb21wdXRlck5hbWUiLCZoa2V5KTsKCQlSZWdTZXRWYWx1ZUV4MTYoaGtleSwiQ29tcHV0ZXJOYW1lIiwwLFJFR19TWixidWYsc3RybGVuKGJ1ZikrMSk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKiBTQVZFIFJlZ2lzdHJ5IEZ1bmN0aW9uICoqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIFJFR0lTVFJZX1NBVkVfVkVSU0lPTgkweDAwMDAwMDAxCgovKiBSZWdpc3RyeSBzYXZlZm9ybWF0OgogKiBJZiB5b3UgY2hhbmdlIGl0LCBpbmNyZWFzZSBhYm92ZSBudW1iZXIgYnkgMSwgd2hpY2ggd2lsbCBmbHVzaAogKiBvbGQgcmVnaXN0cnkgZGF0YWJhc2UgZmlsZXMuCiAqIAogKiBHbG9iYWw6CiAqIAkiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIgogKiAJc3Via2V5cy4uLi4KICogU3Via2V5czoKICogCWtleW5hbWUKICoJCXZhbHVlbmFtZT1sYXN0bW9kaWZpZWQsdHlwZSxkYXRhCiAqCQkuLi4KICoJCXN1YmtleXMKICoJLi4uCiAqIGtleW5hbWUsdmFsdWVuYW1lLHN0cmluZ2RhdGE6CiAqCXRoZSB1c3VhbCBhc2NpaSBjaGFyYWN0ZXJzIGZyb20gMHgwMC0weGZmICh3ZWxsLCBub3QgMHgwMCkKICoJYW5kIFx1WFhYWCBhcyBVTklDT0RFIHZhbHVlIFhYWFggd2l0aCBYWFhYPjB4ZmYKICoJKCAiPVxcXHQiIGVzY2FwZWQgaW4gXHVYWFhYIGZvcm0uKQogKiB0eXBlLGxhc3Rtb2RpZmllZDogCiAqCWludAogKiAKICogRklYTUU6IGRvZXNuJ3Qgc2F2ZSAnY2xhc3MnICh3aGF0IGRvZXMgaXQgbWVhbiBhbnl3YXk/KSwgbm9yIGZsYWdzLgogKgogKiBbSEtFWV9DVVJSRU5UX1VTRVJcXFNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeV0KICogU2F2ZU9ubHlVcGRhdGVkS2V5cz15ZXMKICovCnN0YXRpYyBpbnQKX3NhdmVfY2hlY2tfdGFpbnRlZChMUEtFWVNUUlVDVCBscGtleSkgewoJaW50CQl0YWludGVkOwoKCWlmICghbHBrZXkpCgkJcmV0dXJuIDA7CglpZiAobHBrZXktPmZsYWdzICYgUkVHX09QVElPTl9UQUlOVEVEKQoJCXRhaW50ZWQgPSAxOwoJZWxzZQoJCXRhaW50ZWQgPSAwOwoJd2hpbGUgKGxwa2V5KSB7CgkJaWYgKF9zYXZlX2NoZWNrX3RhaW50ZWQobHBrZXktPm5leHRzdWIpKSB7CgkJCWxwa2V5LT5mbGFncyB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJCXRhaW50ZWQgPSAxOwoJCX0KCQlscGtleQk9IGxwa2V5LT5uZXh0OwoJfQoJcmV0dXJuIHRhaW50ZWQ7Cn0KCnN0YXRpYyB2b2lkCl9zYXZlX1VTVFJJTkcoRklMRSAqRixMUFdTVFIgd3N0cixpbnQgZXNjYXBlZXEpIHsKCUxQV1NUUglzOwoJaW50CWRvZXNjYXBlOwoKCWlmICh3c3RyPT1OVUxMKQoJCXJldHVybjsKCXM9d3N0cjsKCXdoaWxlICgqcykgewoJCWRvZXNjYXBlPTA7CgkJaWYgKCpzPjB4ZmYpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoKnM9PSdcbicpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoZXNjYXBlZXEgJiYgKnM9PSc9JykKCQkJZG9lc2NhcGUgPSAxOwoJCWlmICgqcz09J1xcJykKICAgICAgICAgICAgICAgICAgICAgICAgZnB1dGMoKnMsRik7IC8qIGlmIFxcIHRoZW4gcHV0IGl0IHR3aWNlLiAqLwoJCWlmIChkb2VzY2FwZSkKCQkJZnByaW50ZihGLCJcXHUlMDR4IiwqKCh1bnNpZ25lZCBzaG9ydCopcykpOwoJCWVsc2UKCQkJZnB1dGMoKnMsRik7CgkJcysrOwoJfQp9CgpzdGF0aWMgaW50Cl9zYXZlc3Via2V5KEZJTEUgKkYsTFBLRVlTVFJVQ1QgbHBrZXksaW50IGxldmVsLGludCBhbGwpIHsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJaSx0YWJzLGo7CgoJbHB4a2V5CT0gbHBrZXk7Cgl3aGlsZSAobHB4a2V5KSB7CgkJaWYgKAkhKGxweGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1ZPTEFUSUxFKSAmJgoJCQkoYWxsIHx8IChscHhrZXktPmZsYWdzICYgUkVHX09QVElPTl9UQUlOVEVEKSkKCQkpIHsKCQkJZm9yICh0YWJzPWxldmVsO3RhYnMtLTspCgkJCQlmcHV0YygnXHQnLEYpOwoJCQlfc2F2ZV9VU1RSSU5HKEYsbHB4a2V5LT5rZXluYW1lLDEpOwoJCQlmcHV0cygiXG4iLEYpOwoJCQlmb3IgKGk9MDtpPGxweGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQkJCUxQS0VZVkFMVUUJdmFsPWxweGtleS0+dmFsdWVzK2k7CgoJCQkJZm9yICh0YWJzPWxldmVsKzE7dGFicy0tOykKCQkJCQlmcHV0YygnXHQnLEYpOwoJCQkJX3NhdmVfVVNUUklORyhGLHZhbC0+bmFtZSwwKTsKCQkJCWZwdXRjKCc9JyxGKTsKCQkJCWZwcmludGYoRiwiJWxkLCVsZCwiLHZhbC0+dHlwZSx2YWwtPmxhc3Rtb2RpZmllZCk7CgkJCQlpZiAoKDE8PHZhbC0+dHlwZSkgJiBVTklDT05WTUFTSykKCQkJCQlfc2F2ZV9VU1RSSU5HKEYsKExQV1NUUil2YWwtPmRhdGEsMCk7CgkJCQllbHNlCgkJCQkJZm9yIChqPTA7ajx2YWwtPmxlbjtqKyspCgkJCQkJCWZwcmludGYoRiwiJTAyeCIsKigodW5zaWduZWQgY2hhciopdmFsLT5kYXRhK2opKTsKCQkJCWZwdXRzKCJcbiIsRik7CgkJCX0KCQkJLyogZGVzY2VuZCByZWN1cnNpdmVseSAqLwoJCQlpZiAoIV9zYXZlc3Via2V5KEYsbHB4a2V5LT5uZXh0c3ViLGxldmVsKzEsYWxsKSkKCQkJCXJldHVybiAwOwoJCX0KCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQKX3NhdmVzdWJyZWcoRklMRSAqRixMUEtFWVNUUlVDVCBscGtleSxpbnQgYWxsKSB7CglmcHJpbnRmKEYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZFxuIixSRUdJU1RSWV9TQVZFX1ZFUlNJT04pOwoJX3NhdmVfY2hlY2tfdGFpbnRlZChscGtleS0+bmV4dHN1Yik7CglyZXR1cm4gX3NhdmVzdWJrZXkoRixscGtleS0+bmV4dHN1YiwwLGFsbCk7Cn0KCnN0YXRpYyBCT09MMzIKX3NhdmVyZWcoTFBLRVlTVFJVQ1QgbHBrZXksY2hhciAqZm4saW50IGFsbCkgewoJRklMRQkqRjsKCglGPWZvcGVuKGZuLCJ3Iik7CglpZiAoRj09TlVMTCkgewoJCVdBUk4ocmVnLCJDb3VsZG4ndCBvcGVuICVzIGZvciB3cml0aW5nOiAlc1xuIiwKCQkJZm4sc3RyZXJyb3IoZXJybm8pCgkJKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglpZiAoIV9zYXZlc3VicmVnKEYsbHBrZXksYWxsKSkgewoJCWZjbG9zZShGKTsKCQl1bmxpbmsoZm4pOwoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gc2F2ZSBrZXlzLCBwZXJoYXBzIG5vIG1vcmUgZGlza3NwYWNlIGZvciAlcz9cbiIsZm4pOwoJCXJldHVybiBGQUxTRTsKCX0KCWZjbG9zZShGKTsKICAgICAgICByZXR1cm4gVFJVRTsKfQoKdm9pZApTSEVMTF9TYXZlUmVnaXN0cnkoKSB7CgljaGFyCSpmbjsKCXN0cnVjdAlwYXNzd2QJKnB3ZDsKCWNoYXIJYnVmWzRdOwoJSEtFWQloa2V5OwoJaW50CWFsbDsKCglhbGw9MDsKCWlmIChSZWdPcGVuS2V5MTYoSEtFWV9DVVJSRU5UX1VTRVIsS0VZX1JFR0lTVFJZLCZoa2V5KSE9RVJST1JfU1VDQ0VTUykgewoJCXN0cmNweShidWYsInllcyIpOwoJfSBlbHNlIHsKCQlEV09SRCBsZW4sanVuayx0eXBlOwoKCQlsZW49NDsKCQlpZiAoCShFUlJPUl9TVUNDRVNTIT1SZWdRdWVyeVZhbHVlRXgzMkEoCgkJCQloa2V5LAoJCQkJVkFMX1NBVkVVUERBVEVELAoJCQkJJmp1bmssCgkJCQkmdHlwZSwKCQkJCWJ1ZiwKCQkJCSZsZW4KCQkJKSl8fCAodHlwZSE9UkVHX1NaKQoJCSkKCQkJc3RyY3B5KGJ1ZiwieWVzIik7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9CglpZiAobHN0cmNtcGkzMkEoYnVmLCJ5ZXMiKSkKCQlhbGw9MTsKCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CglpZiAocHdkIT1OVUxMICYmIHB3ZC0+cHdfZGlyIT1OVUxMKQogICAgICAgIHsKICAgICAgICAgICAgICAgIGNoYXIgKnRtcDsKCgkJZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihwd2QtPnB3X2RpcikgKyBzdHJsZW4oV0lORV9QUkVGSVgpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJsZW4oU0FWRV9DVVJSRU5UX1VTRVIpICsgMiApOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYKTsKCQkvKiBjcmVhdGUgdGhlIGRpcmVjdG9yeS4gZG9uJ3QgY2FyZSBhYm91dCBlcnJvcmNvZGVzLiAqLwoJCW1rZGlyKGZuLDA3NTUpOyAvKiBkcnd4ci14ci14ICovCgkJc3RyY2F0KGZuLCIvIlNBVkVfQ1VSUkVOVF9VU0VSKTsKCQl0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwoJCXN0cmNweSh0bXAsZm4pO3N0cmNhdCh0bXAsIi50bXAiKTsKCQlpZiAoX3NhdmVyZWcoa2V5X2N1cnJlbnRfdXNlcix0bXAsYWxsKSkgewoJCQlpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CgkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKCQkJCXVubGluayh0bXApOwoJCQl9CgkJfQoJCWZyZWUodG1wKTsKCQlmcmVlKGZuKTsKCQlmbj0oY2hhciopeG1hbGxvYyhzdHJsZW4ocHdkLT5wd19kaXIpK3N0cmxlbihXSU5FX1BSRUZJWCkrc3RybGVuKFNBVkVfTE9DQUxfTUFDSElORSkrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwoJCXRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CgkJc3RyY3B5KHRtcCxmbik7c3RyY2F0KHRtcCwiLnRtcCIpOwoJCWlmIChfc2F2ZXJlZyhrZXlfbG9jYWxfbWFjaGluZSx0bXAsYWxsKSkgewoJCQlpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CgkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKCQkJCXVubGluayh0bXApOwoJCQl9CgkJfQoJCWZyZWUodG1wKTsKCQlmcmVlKGZuKTsKCX0gZWxzZQoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVkLlxuIixnZXR1aWQoKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKiogTE9BRCBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIExQS0VZU1RSVUNUCl9maW5kX29yX2FkZF9rZXkoTFBLRVlTVFJVQ1QgbHBrZXksTFBXU1RSIGtleW5hbWUpIHsKCUxQS0VZU1RSVUNUCWxweGtleSwqbHBscGtleTsKCglpZiAoa2V5bmFtZVswXT09MCkgewoJCWZyZWUoa2V5bmFtZSk7CgkJcmV0dXJuIGxwa2V5OwoJfQoJbHBscGtleT0gJihscGtleS0+bmV4dHN1Yik7CglscHhrZXkJPSAqbHBscGtleTsKCXdoaWxlIChscHhrZXkpIHsKCQlpZiAoIWxzdHJjbXBpMzJXKGxweGtleS0+a2V5bmFtZSxrZXluYW1lKSkKCQkJYnJlYWs7CgkJbHBscGtleQk9ICYobHB4a2V5LT5uZXh0KTsKCQlscHhrZXkJPSAqbHBscGtleTsKCX0KCWlmIChscHhrZXk9PU5VTEwpIHsKCQkqbHBscGtleSA9IChMUEtFWVNUUlVDVCl4bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTsKCQlscHhrZXkJPSAqbHBscGtleTsKCQltZW1zZXQobHB4a2V5LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpOwoJCWxweGtleS0+a2V5bmFtZQk9IGtleW5hbWU7Cgl9IGVsc2UKCQlmcmVlKGtleW5hbWUpOwoJcmV0dXJuIGxweGtleTsKfQoKc3RhdGljIHZvaWQKX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJTFBLRVlTVFJVQ1QgbHBrZXksTFBXU1RSIG5hbWUsRFdPUkQgdHlwZSxMUEJZVEUgZGF0YSxEV09SRCBsZW4sCglEV09SRCBsYXN0bW9kaWZpZWQKKSB7CglMUEtFWVZBTFVFCXZhbD1OVUxMOwoJaW50CQlpOwoKCWlmIChuYW1lICYmICEqbmFtZSkgey8qIGVtcHR5IHN0cmluZyBlcXVhbHMgZGVmYXVsdCAoTlVMTCkgdmFsdWUgKi8KCQlmcmVlKG5hbWUpOwoJCW5hbWUgPSBOVUxMOwoJfQoKCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJdmFsPWxwa2V5LT52YWx1ZXMraTsKCQlpZiAobmFtZT09TlVMTCkgewoJCQlpZiAodmFsLT5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7CgkJfSBlbHNlIHsKCQkJaWYgKAl2YWwtPm5hbWUhPU5VTEwgJiYgCgkJCQkhbHN0cmNtcGkzMlcodmFsLT5uYW1lLG5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJCX0KCX0KCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewoJCWxwa2V5LT52YWx1ZXMgPSB4cmVhbGxvYygKCQkJbHBrZXktPnZhbHVlcywKCQkJKCsrbHBrZXktPm5yb2Z2YWx1ZXMpKnNpemVvZihLRVlWQUxVRSkKCQkpOwoJCXZhbD1scGtleS0+dmFsdWVzK2k7CgkJbWVtc2V0KHZhbCwnXDAnLHNpemVvZihLRVlWQUxVRSkpOwoJCXZhbC0+bmFtZSA9IG5hbWU7Cgl9IGVsc2UgewoJCWlmIChuYW1lKQoJCQlmcmVlKG5hbWUpOwoJfQoJaWYgKHZhbC0+bGFzdG1vZGlmaWVkPGxhc3Rtb2RpZmllZCkgewoJCXZhbC0+bGFzdG1vZGlmaWVkPWxhc3Rtb2RpZmllZDsKCQl2YWwtPnR5cGUgPSB0eXBlOwoJCXZhbC0+bGVuICA9IGxlbjsKCQlpZiAodmFsLT5kYXRhKSAKCQkJZnJlZSh2YWwtPmRhdGEpOwoJCXZhbC0+ZGF0YSA9IGRhdGE7Cgl9IGVsc2UKCQlmcmVlKGRhdGEpOwp9CgoKLyogcmVhZHMgYSBsaW5lIGluY2x1ZGluZyBkeW5hbWljYWxseSBlbmxhcmdpbmcgdGhlIHJlYWRidWZmZXIgYW5kIHRocm93aW5nCiAqIGF3YXkgY29tbWVudHMKICovCnN0YXRpYyBpbnQgCl93aW5lX3JlYWRfbGluZShGSUxFICpGLGNoYXIgKipidWYsaW50ICpsZW4pIHsKCWNoYXIJKnMsKmN1cnJlYWQ7CglpbnQJbXlsZW4sY3Vyb2ZmOwoKCWN1cnJlYWQJPSAqYnVmOwoJbXlsZW4JPSAqbGVuOwoJKipidWYJPSAnXDAnOwoJd2hpbGUgKDEpIHsKCQl3aGlsZSAoMSkgewoJCQlzPWZnZXRzKGN1cnJlYWQsbXlsZW4sRik7CgkJCWlmIChzPT1OVUxMKQoJCQkJcmV0dXJuIDA7IC8qIEVPRiAqLwoJCQlpZiAoTlVMTD09KHM9c3RyY2hyKGN1cnJlYWQsJ1xuJykpKSB7CgkJCQkvKiBidWZmZXIgd2Fzbid0IGxhcmdlIGVub3VnaCAqLwoJCQkJY3Vyb2ZmCT0gc3RybGVuKCpidWYpOwoJCQkJKmJ1Zgk9IHhyZWFsbG9jKCpidWYsKmxlbioyKTsKCQkJCWN1cnJlYWQJPSAqYnVmICsgY3Vyb2ZmOwoJCQkJbXlsZW4JPSAqbGVuOwkvKiB3ZSBmaWxsZWQgdXAgdGhlIGJ1ZmZlciBhbmQgCgkJCQkJCSAqIGdvdCBuZXcgJypsZW4nIGJ5dGVzIHRvIGZpbGwKCQkJCQkJICovCgkJCQkqbGVuCT0gKmxlbiAqIDI7CgkJCX0gZWxzZSB7CgkJCQkqcz0nXDAnOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLyogdGhyb3cgYXdheSBjb21tZW50cyAqLwoJCWlmICgqKmJ1Zj09JyMnIHx8ICoqYnVmPT0nOycpIHsKCQkJY3VycmVhZAk9ICpidWY7CgkJCW15bGVuCT0gKmxlbjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzKSAJLyogZ290IGVuZCBvZiBsaW5lICovCgkJCWJyZWFrOwoJfQoJcmV0dXJuIDE7Cn0KCi8qIGNvbnZlcnRzIGEgY2hhciogaW50byBhIFVOSUNPREUgc3RyaW5nICh1cCB0byBhIHNwZWNpYWwgY2hhcikKICogYW5kIHJldHVybnMgdGhlIHBvc2l0aW9uIGV4YWN0bHkgYWZ0ZXIgdGhhdCBzdHJpbmcKICovCnN0YXRpYyBjaGFyKgpfd2luZV9yZWFkX1VTVFJJTkcoY2hhciAqYnVmLExQV1NUUiAqc3RyKSB7CgljaGFyCSpzOwoJTFBXU1RSCXdzOwoKCS8qIHJlYWQgdXAgdG8gIj0iIG9yICJcMCIgb3IgIlxuIiAqLwoJcwk9IGJ1ZjsKCWlmICgqcyA9PSAnPScpIHsKCQkvKiBlbXB0eSBzdHJpbmcgaXMgdGhlIHdpbjMuMSBkZWZhdWx0IHZhbHVlKE5VTEwpKi8KCQkqc3RyCT0gTlVMTDsKCQlyZXR1cm4gczsKCX0KCSpzdHIJPSAoTFBXU1RSKXhtYWxsb2MoMipzdHJsZW4oYnVmKSsyKTsKCXdzCT0gKnN0cjsKCXdoaWxlICgqcyAmJiAoKnMhPSdcbicpICYmICgqcyE9Jz0nKSkgewoJCWlmICgqcyE9J1xcJykKCQkJKndzKys9KigodW5zaWduZWQgY2hhciopcysrKTsKCQllbHNlIHsKCQkJcysrOwoJCQlpZiAoKnM9PSdcXCcpIHsKCQkJCSp3cysrPSdcXCc7CgkJCQlzKys7CgkJCQljb250aW51ZTsKCQkJfQoJCQlpZiAoKnMhPSd1JykgewoJCQkJV0FSTihyZWcsIk5vbiB1bmljb2RlIGVzY2FwZSBzZXF1ZW5jZSBcXCVjIGZvdW5kIGluIHwlc3xcbiIsKnMsYnVmKTsKCQkJCSp3cysrPSdcXCc7CgkJCQkqd3MrKz0qcysrOwoJCQl9IGVsc2UgewoJCQkJY2hhcgl4YnVmWzVdOwoJCQkJaW50CXdjOwoKCQkJCXMrKzsKCQkJCW1lbWNweSh4YnVmLHMsNCk7eGJ1Zls0XT0nXDAnOwoJCQkJaWYgKCFzc2NhbmYoeGJ1ZiwiJXgiLCZ3YykpCgkJCQkJV0FSTihyZWcsIlN0cmFuZ2UgZXNjYXBlIHNlcXVlbmNlICVzIGZvdW5kIGluIHwlc3xcbiIseGJ1ZixidWYpOwoJCQkJcys9NDsKCQkJCSp3cysrCT0odW5zaWduZWQgc2hvcnQpd2M7CgkJCX0KCQl9Cgl9Cgkqd3MJPSAwOwoJd3MJPSAqc3RyOwoJaWYgKCp3cykKCQkqc3RyCT0gc3RyZHVwVygqc3RyKTsKCWVsc2UKCQkqc3RyCT0gTlVMTDsKCWZyZWUod3MpOwoJcmV0dXJuIHM7Cn0KCnN0YXRpYyBpbnQKX3dpbmVfbG9hZHN1YmtleSgKCUZJTEUgKkYsTFBLRVlTVFJVQ1QgbHBrZXksaW50IGxldmVsLGNoYXIgKipidWYsaW50ICpidWZsZW4saW50IG9wdGZsYWcKKSB7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWk7CgljaGFyCQkqczsKCUxQV1NUUgkJbmFtZTsKCglscGtleS0+ZmxhZ3MgfD0gb3B0ZmxhZzsKCgkvKiBnb29kLiB3ZSBhbHJlYWR5IGdvdCBhIGxpbmUgaGVyZSAuLi4gc28gcGFyc2UgaXQgKi8KCWxweGtleQk9IE5VTEw7Cgl3aGlsZSAoMSkgewoJCWk9MDtzPSpidWY7CgkJd2hpbGUgKCpzPT0nXHQnKSB7CgkJCXMrKzsKCQkJaSsrOwoJCX0KCQlpZiAoaT5sZXZlbCkgewoJCQlpZiAobHB4a2V5PT1OVUxMKSB7CgkJCQlXQVJOKHJlZywiR290IGEgc3ViaGllcmFyY2h5IHdpdGhvdXQgcmVzcC4ga2V5P1xuIik7CgkJCQlyZXR1cm4gMDsKCQkJfQoJCQlfd2luZV9sb2Fkc3Via2V5KEYsbHB4a2V5LGxldmVsKzEsYnVmLGJ1ZmxlbixvcHRmbGFnKTsKCQkJY29udGludWU7CgkJfQoJCS8qIGxldCB0aGUgY2FsbGVyIGhhbmRsZSB0aGlzIGxpbmUgKi8KCQlpZiAoaTxsZXZlbCB8fCAqKmJ1Zj09J1wwJykKCQkJcmV0dXJuIDE7CgoJCS8qIGl0IGNhbiBiZTogYSB2YWx1ZSBvciBhIGtleW5hbWUuIFBhcnNlIHRoZSBuYW1lIGZpcnN0ICovCgkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywmbmFtZSk7CgoJCS8qIHN3aXRjaCgpIGRlZmF1bHQ6IGhhY2sgdG8gYXZvaWQgZ290b3MgKi8KCQlzd2l0Y2ggKDApIHsKCQlkZWZhdWx0OgoJCQlpZiAoKnM9PSdcMCcpIHsKCQkJCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoJCQl9IGVsc2UgewoJCQkJTFBCWVRFCQlkYXRhOwoJCQkJaW50CQlsZW4sbGFzdG1vZGlmaWVkLHR5cGU7CgoJCQkJaWYgKCpzIT0nPScpIHsKCQkJCQlXQVJOKHJlZywiVW5leHBlY3RlZCBjaGFyYWN0ZXI6ICVjXG4iLCpzKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCXMrKzsKCQkJCWlmICgyIT1zc2NhbmYocywiJWQsJWQsIiwmdHlwZSwmbGFzdG1vZGlmaWVkKSkgewoJCQkJCVdBUk4ocmVnLCJIYXZlbid0IHVuZGVyc3Rvb2QgcG9zc2libGUgdmFsdWUgaW4gfCVzfCwgc2tpcHBpbmcuXG4iLCpidWYpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJLyogc2tpcCB0aGUgMiAsICovCgkJCQlzPXN0cmNocihzLCcsJyk7cysrOwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCWlmICgoMTw8dHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsKExQV1NUUiopJmRhdGEpOwoJCQkJCWlmIChkYXRhKQoJCQkJCQlsZW4gPSBsc3RybGVuMzJXKChMUFdTVFIpZGF0YSkqMisyOwoJCQkJCWVsc2UJCgkJCQkJCWxlbiA9IDA7CgkJCQl9IGVsc2UgewoJCQkJCWxlbj1zdHJsZW4ocykvMjsKCQkJCQlkYXRhID0gKExQQllURSl4bWFsbG9jKGxlbisxKTsKCQkJCQlmb3IgKGk9MDtpPGxlbjtpKyspIHsKCQkJCQkJZGF0YVtpXT0wOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXT0oKnMtJzAnKTw8NDsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV09KCpzLSdhJysnXHhhJyk8PDQ7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nQScrJ1x4YScpPDw0OwoJCQkJCQlzKys7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldfD0qcy0nMCc7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nYScrJ1x4YSc7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nQScrJ1x4YSc7CgkJCQkJCXMrKzsKCQkJCQl9CgkJCQl9CgkJCQlfZmluZF9vcl9hZGRfdmFsdWUobHBrZXksbmFtZSx0eXBlLGRhdGEsbGVuLGxhc3Rtb2RpZmllZCk7CgkJCX0KCQl9CgkJLyogcmVhZCB0aGUgbmV4dCBsaW5lICovCgkJaWYgKCFfd2luZV9yZWFkX2xpbmUoRixidWYsYnVmbGVuKSkKCQkJcmV0dXJuIDE7Cgl9CglyZXR1cm4gMTsKfQoKc3RhdGljIGludApfd2luZV9sb2Fkc3VicmVnKEZJTEUgKkYsTFBLRVlTVFJVQ1QgbHBrZXksaW50IG9wdGZsYWcpIHsKCWludAl2ZXI7CgljaGFyCSpidWY7CglpbnQJYnVmbGVuOwoKCWJ1Zj14bWFsbG9jKDEwKTtidWZsZW49MTA7CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXNzY2FuZihidWYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAodmVyIT1SRUdJU1RSWV9TQVZFX1ZFUlNJT04pIHsKCQlUUkFDRShyZWcsIk9sZCBmb3JtYXQgKCVkKSByZWdpc3RyeSBmb3VuZCwgaWdub3JpbmcgaXQuIChidWYgd2FzICVzKS5cbiIsdmVyLGJ1Zik7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9sb2Fkc3Via2V5KEYsbHBrZXksMCwmYnVmLCZidWZsZW4sb3B0ZmxhZykpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglmcmVlKGJ1Zik7CglyZXR1cm4gMTsKfQoKc3RhdGljIHZvaWQKX3dpbmVfbG9hZHJlZyhMUEtFWVNUUlVDVCBscGtleSxjaGFyICpmbixpbnQgb3B0ZmxhZykgewoJRklMRQkqRjsKCglGPWZvcGVuKGZuLCJyYiIpOwoJaWYgKEY9PU5VTEwpIHsKCQlXQVJOKHJlZywiQ291bGRuJ3Qgb3BlbiAlcyBmb3IgcmVhZGluZzogJXNcbiIsCgkJICAgICAgIGZuLHN0cmVycm9yKGVycm5vKQoJCSk7CgkJcmV0dXJuOwoJfQoJaWYgKCFfd2luZV9sb2Fkc3VicmVnKEYsbHBrZXksb3B0ZmxhZykpIHsKCQlmY2xvc2UoRik7CgkJdW5saW5rKGZuKTsKCQlyZXR1cm47Cgl9CglmY2xvc2UoRik7Cn0KCnN0YXRpYyB2b2lkCl9jb3B5X3JlZ2lzdHJ5KExQS0VZU1RSVUNUIGZyb20sTFBLRVlTVFJVQ1QgdG8pIHsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJajsKCUxQS0VZVkFMVUUJdmFsZnJvbTsKCglmcm9tPWZyb20tPm5leHRzdWI7Cgl3aGlsZSAoZnJvbSkgewoJCWxweGtleSA9IF9maW5kX29yX2FkZF9rZXkodG8sc3RyZHVwVyhmcm9tLT5rZXluYW1lKSk7CgoJCWZvciAoaj0wO2o8ZnJvbS0+bnJvZnZhbHVlcztqKyspIHsKCQkJTFBXU1RSCW5hbWU7CgkJCUxQQllURQlkYXRhOwoKCQkJdmFsZnJvbSA9IGZyb20tPnZhbHVlcytqOwoJCQluYW1lPXZhbGZyb20tPm5hbWU7CgkJCWlmIChuYW1lKSBuYW1lPXN0cmR1cFcobmFtZSk7CgkJCWRhdGE9KExQQllURSl4bWFsbG9jKHZhbGZyb20tPmxlbik7CgkJCW1lbWNweShkYXRhLHZhbGZyb20tPmRhdGEsdmFsZnJvbS0+bGVuKTsKCgkJCV9maW5kX29yX2FkZF92YWx1ZSgKCQkJCWxweGtleSwKCQkJCW5hbWUsCgkJCQl2YWxmcm9tLT50eXBlLAoJCQkJZGF0YSwKCQkJCXZhbGZyb20tPmxlbiwKCQkJCXZhbGZyb20tPmxhc3Rtb2RpZmllZAoJCQkpOwoJCX0KCQlfY29weV9yZWdpc3RyeShmcm9tLGxweGtleSk7CgkJZnJvbSA9IGZyb20tPm5leHQ7Cgl9Cn0KCi8qIFdJTkRPV1MgOTUgUkVHSVNUUlkgTE9BREVSICovCi8qIAogKiBTdHJ1Y3R1cmUgb2YgYSB3aW45NSByZWdpc3RyeSBkYXRhYmFzZS4KICogbWFpbiBoZWFkZXI6CiAqIDAgOgkiQ1JFRyIJLSBtYWdpYwogKiA0IDoJRFdPUkQgdmVyc2lvbgogKiA4IDoJRFdPUkQgb2Zmc2V0X29mX1JHREJfcGFydAogKiAwQy4uMEY6CT8gKHNvbWVvbmUgZmlsbCBpbiBwbGVhc2UpCiAqIDEwOiAgV09SRAludW1iZXIgb2YgUkdEQiBibG9ja3MKICogMTI6ICBXT1JECT8KICogMTQ6ICBXT1JECWFsd2F5cyAwMDAwPwogKiAxNjogIFdPUkQJYWx3YXlzIDAwMDE/CiAqIDE4Li4xRjoJPyAoc29tZW9uZSBmaWxsIGluIHBsZWFzZSkKICoKICogMjA6IFJHS05fc2VjdGlvbjoKICogICBoZWFkZXI6CiAqIAkwIDoJCSJSR0tOIgktIG1hZ2ljCiAqICAgICAgNCA6IERXT1JECW9mZnNldCB0byBmaXJzdCBSR0RCIHNlY3Rpb24KICogICAgICA4IDogRFdPUkQJb2Zmc2V0IHRvID8KICogCUMuLjB4MUI6IAk/IChmaWxsIGluKQogKiAgICAgIDB4MjAgLi4uIG9mZnNldF9vZl9SR0RCX3BhcnQ6IERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZXMKICoKICogICBEaXNrIEtleSBFbnRyeSBTdHJ1Y3R1cmU6CiAqCTAwOiBEV09SRAktIEZyZWUgZW50cnkgaW5kaWNhdG9yKD8pCiAqCTA0OiBEV09SRAktIEhhc2ggPSBzdW0gb2YgYnl0ZXMgb2Yga2V5bmFtZQogKgkwODogRFdPUkQJLSBSb290IGtleSBpbmRpY2F0b3I/IHVua25vd24sIGJ1dCB1c3VhbGx5IDB4RkZGRkZGRkYgb24gd2luOTUgc3lzdGVtcwogKgkwQzogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgUHJldmlvdXNMZXZlbCBLZXkuCiAqCTEwOiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBOZXh0IFN1YmxldmVsIEtleS4KICoJMTQ6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIE5leHQgS2V5IChvbiBzYW1lIGxldmVsKS4KICogREtFUD4xODogV09SRAktIE5yLCBMb3cgU2lnbmlmaWNhbnQgcGFydC4KICoJMUE6IFdPUkQJLSBOciwgSGlnaCBTaWduaWZpY2FudCBwYXJ0LgogKgogKiBUaGUgZGlzayBhZGRyZXNzIGFsd2F5cyBwb2ludHMgdG8gdGhlIG5yIHBhcnQgb2YgdGhlIHByZXZpb3VzIGtleSBlbnRyeSAKICogb2YgdGhlIHJlZmVyZW5jZWQga2V5LiBEb24ndCBhc2sgbWUgd2h5LCBvciBldmVuIGlmIEkgZ290IHRoaXMgY29ycmVjdAogKiBmcm9tIHN0YXJpbmcgYXQgMWtnIG9mIGhleGR1bXBzLiAoREtFUCkKICoKICogVGhlIEhpZ2ggc2lnbmlmaWNhbnQgcGFydCBvZiB0aGUgc3RydWN0dXJlIHNlZW1zIHRvIGVxdWFsIHRoZSBudW1iZXIKICogb2YgdGhlIFJHREIgc2VjdGlvbi4gVGhlIGxvdyBzaWduaWZpY2FudCBwYXJ0IGlzIGEgdW5pcXVlIElEIHdpdGhpbgogKiB0aGF0IFJHREIgc2VjdGlvbgogKgogKiBUaGVyZSBhcmUgdHdvIG1pbm9yIGNvcnJlY3Rpb25zIHRvIHRoZSBwb3NpdGlvbiBvZiB0aGF0IHN0cnVjdHVyZS4KICogMS4gSWYgdGhlIGFkZHJlc3MgaXMgeHh4MDE0IG9yIHh4eDAxOCBpdCB3aWxsIGJlIGFsaWduZWQgdG8geHh4MDFjIEFORCAKICogICAgdGhlIERLRSByZXJlYWQgZnJvbSB0aGVyZS4KICogMi4gSWYgdGhlIGFkZHJlc3MgaXMgeHh4RkZ4IGl0IHdpbGwgYmUgYWxpZ25lZCB0byAoeHh4KzEpMDAwLgogKiBDUFMgLSBJIGhhdmUgbm90IGV4cGVyaWVuY2VkIHRoZSBhYm92ZSBwaGVub21lbm9uIGluIG15IHJlZ2lzdHJ5IGZpbGVzCiAqCiAqIFJHREJfc2VjdGlvbjoKICogCTAwOgkJIlJHREIiCS0gbWFnaWMKICoJMDQ6IERXT1JECW9mZnNldCB0byBuZXh0IFJHREIgc2VjdGlvbgogKgkwODogRFdPUkQJPwogKgkwQzogV09SRAlhbHdheXMgMDAwZD8KICoJMEU6IFdPUkQJUkdEQiBibG9jayBudW1iZXIKICoJMTA6CURXT1JECT8gKGVxdWFscyB2YWx1ZSBhdCBvZmZzZXQgNCAtIHZhbHVlIGF0IG9mZnNldCA4KQogKgkxNC4uMUY6CQk/CiAqCTIwLi4uLi46CWRpc2sga2V5cwogKgogKiBkaXNrIGtleToKICogCTAwOiAJRFdPUkQJbmV4dGtleW9mZnNldAktIG9mZnNldCB0byB0aGUgbmV4dCBkaXNrIGtleSBzdHJ1Y3R1cmUKICoJMDg6IAlXT1JECW5yTFMJCS0gbG93IHNpZ25pZmljYW50IHBhcnQgb2YgTlIKICoJMEE6IAlXT1JECW5ySFMJCS0gaGlnaCBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBDOiAJRFdPUkQJYnl0ZXN1c2VkCS0gYnl0ZXMgdXNlZCBpbiB0aGlzIHN0cnVjdHVyZS4KICoJMTA6IAlXT1JECW5hbWVfbGVuCS0gbGVuZ3RoIG9mIG5hbWUgaW4gYnl0ZXMuIHdpdGhvdXQgXDAKICoJMTI6IAlXT1JECW5yX29mX3ZhbHVlcwktIG51bWJlciBvZiB2YWx1ZXMuCiAqCTE0OiAJY2hhcgluYW1lW25hbWVfbGVuXQktIG5hbWUgc3RyaW5nLiBObyBcMC4KICoJMTQrbmFtZV9sZW46IGRpc2sgdmFsdWVzCiAqCW5leHRrZXlvZmZzZXQ6IC4uLiBuZXh0IGRpc2sga2V5CiAqCiAqIGRpc2sgdmFsdWU6CiAqCTAwOglEV09SRAl0eXBlCQktIHZhbHVlIHR5cGUgKGhtbSwgY291bGQgYmUgV09SRCB0b28pCiAqCTA0OglEV09SRAkJCS0gdW5rbm93biwgdXN1YWxseSAwCiAqCTA4OglXT1JECW5hbWVsZW4JCS0gbGVuZ3RoIG9mIE5hbWUuIDAgbWVhbnMgbmFtZT1OVUxMCiAqCTBDOglXT1JECWRhdGFsZW4JCS0gbGVuZ3RoIG9mIERhdGEuCiAqCTEwOgljaGFyCW5hbWVbbmFtZWxlbl0JLSBuYW1lLCBubyBcMAogKgkxMCtuYW1lbGVuOiBCWVRFCWRhdGFbZGF0YWxlbl0gLSBkYXRhLCB3aXRob3V0IFwwIGlmIHN0cmluZwogKgkxMCtuYW1lbGVuK2RhdGFsZW46IG5leHQgdmFsdWVzIG9yIGRpc2sga2V5CiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuckhTIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKiByZXBlYXQgdW50aWwgZW5kIG9mIGZpbGUuCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgdmFsdWUgYXQgb2Zmc2V0CiAqIDEwIGVxdWFscyB0aGUgdmFsdWUgYXQgb2Zmc2V0IDQgbWludXMgdGhlIHZhbHVlIGF0IG9mZnNldCA4LiBJIGhhdmUgbm8KICogaWRlYSBhdCB0aGUgbW9tZW50IHdoYXQgdGhpcyBtZWFucy4gIChLZXZpbiBDb3plbnMpCiAqCiAqIEZJWE1FOiB0aGlzIGRlc2NyaXB0aW9uIG5lZWRzIHNvbWUgc2VyaW91cyBoZWxwLCB5ZXMuCiAqLwoKc3RydWN0CV93OTVrZXl2YWx1ZSB7Cgl1bnNpZ25lZCBsb25nCQl0eXBlOwoJdW5zaWduZWQgc2hvcnQJCWRhdGFsZW47CgljaGFyCQkJKm5hbWU7Cgl1bnNpZ25lZCBjaGFyCQkqZGF0YTsKCXVuc2lnbmVkIGxvbmcJCXgxOwoJaW50CQkJbGFzdG1vZGlmaWVkOwp9OwoKc3RydWN0IAlfdzk1a2V5IHsKCWNoYXIJCQkqbmFtZTsKCWludAkJCW5yb2Z2YWxzOwoJc3RydWN0CV93OTVrZXl2YWx1ZQkqdmFsdWVzOwoJc3RydWN0IF93OTVrZXkJCSpwcmV2bHZsOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0c3ViOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0Owp9OwoKCnN0cnVjdCBfdzk1X2luZm8gewogIGNoYXIgKnJna25idWZmZXI7CiAgaW50ICByZ2tuc2l6ZTsKICBjaGFyICpyZ2RiYnVmZmVyOwogIGludCAgcmdkYnNpemU7CiAgaW50ICBkZXB0aDsKICBpbnQgIGxhc3Rtb2RpZmllZDsKfTsKCkxQV1NUUiBzdHJjdnRBMlcoTFBDU1RSIHNyYywgaW50IG5jaGFycykKCnsKICAgTFBXU1RSIGRlc3QgPSB4bWFsbG9jICgyICogbmNoYXJzICsgMik7CgogICBsc3RyY3B5bkF0b1coZGVzdCxzcmMsbmNoYXJzKzEpOwogICBkZXN0W25jaGFyc10gPSAwOwogICByZXR1cm4gZGVzdDsKfQoKc3RhdGljIExQS0VZU1RSVUNUIF93OTVfcHJvY2Vzc0tleSAoIExQS0VZU1RSVUNUIGxwa2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnJMUywgaW50IG5yTVMsIHN0cnVjdCBfdzk1X2luZm8gKmluZm8gKQoKewogIC8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCkgKi8KCXN0cnVjdAlka2ggewogICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZwkJbmV4dGtleW9mZjsgCgkJdW5zaWduZWQgc2hvcnQJCW5yTFM7CgkJdW5zaWduZWQgc2hvcnQJCW5yTVM7CgkJdW5zaWduZWQgbG9uZwkJYnl0ZXN1c2VkOwoJCXVuc2lnbmVkIHNob3J0CQlrZXluYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWx1ZXM7CgkJdW5zaWduZWQgbG9uZwkJeHgxOwoJCS8qIGtleW5hbWUgKi8KCQkvKiBkaXNrIGtleSB2YWx1ZXMgb3Igbm90aGluZyAqLwoJfTsKCS8qIERpc2sgS2V5IFZhbHVlIHN0cnVjdHVyZSAqLwoJc3RydWN0CWRrdiB7CgkJdW5zaWduZWQgbG9uZwkJdHlwZTsKCQl1bnNpZ25lZCBsb25nCQl4MTsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsbmFtZWxlbjsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsZGF0YWxlbjsKCQkvKiB2YWxuYW1lLCB2YWxkYXRhICovCgl9OwoKCQoJc3RydWN0CWRraCBka2g7CglpbnQJYnl0ZXNyZWFkID0gMDsKCWNoYXIgICAgKnJnZGJkYXRhID0gaW5mby0+cmdkYmJ1ZmZlcjsKCWludCAgICAgbmJ5dGVzID0gaW5mby0+cmdkYnNpemU7CgljaGFyICAgICpjdXJkYXRhID0gcmdkYmRhdGE7CgljaGFyICAgICplbmQgPSByZ2RiZGF0YSArIG5ieXRlczsKCWludCAgICAgb2ZmX25leHRfcmdkYjsKCWNoYXIgICAgKm5leHQgPSByZ2RiZGF0YTsKCWludCAgICAgbnJnZGIsIGk7CglMUEtFWVNUUlVDVAlscHhrZXk7CgkKCWRvIHsKCSAgY3VyZGF0YSA9IG5leHQ7CgkgIGlmIChzdHJuY21wKGN1cmRhdGEsICJSR0RCIiwgNCkpIHJldHVybiAoTlVMTCk7CgkgICAgCgkgIG1lbWNweSgmb2ZmX25leHRfcmdkYixjdXJkYXRhKzQsNCk7CgkgIG5leHQgPSBjdXJkYXRhICsgb2ZmX25leHRfcmdkYjsKCSAgbnJnZGIgPSAoaW50KSAqKChzaG9ydCAqKWN1cmRhdGEgKyA3KTsKCgl9IHdoaWxlIChucmdkYiAhPSBuck1TICYmIChuZXh0IDwgZW5kKSk7CgoJLyogY3VyZGF0YSBub3cgcG9pbnRzIHRvIHRoZSBzdGFydCBvZiB0aGUgcmlnaHQgUkdEQiBzZWN0aW9uICovCgljdXJkYXRhICs9IDB4MjA7CgojZGVmaW5lIFhSRUFEKHdoZXJldG8sbGVuKSBcCglpZiAoKGN1cmRhdGEgKyBsZW4pIDxlbmQpIHtcCgkJbWVtY3B5KHdoZXJldG8sY3VyZGF0YSxsZW4pO1wKCQljdXJkYXRhKz1sZW47XAoJCWJ5dGVzcmVhZCs9bGVuO1wKCX0KCglkbyB7CgkgIFhSRUFEKCZka2gsIHNpemVvZiAoZGtoKSk7CgkgIGlmIChka2gubnJMUyA9PSBuckxTKSBicmVhazsKCgkgIGN1cmRhdGEgKz0gZGtoLm5leHRrZXlvZmYgLSBzaXplb2YoZGtoKTsKCX0gd2hpbGUgKGN1cmRhdGEgPCBuZXh0KTsKCglpZiAoZGtoLm5yTFMgIT0gbnJMUykgcmV0dXJuIChOVUxMKTsKCglpZiAobnJnZGIgIT0gZGtoLm5yTVMpIHsKCSAgcmV0dXJuIChOVUxMKTsKCX0KCiAgICAgICAgYXNzZXJ0KChka2gua2V5bmFtZWxlbjwyKSB8fCBjdXJkYXRhWzBdKTsKCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LHN0cmN2dEEyVyhjdXJkYXRhLCBka2gua2V5bmFtZWxlbikpOwoJY3VyZGF0YSArPSBka2gua2V5bmFtZWxlbjsKCglmb3IgKGk9MDtpPCBka2gudmFsdWVzOyBpKyspIHsKCSAgc3RydWN0IGRrdiBka3Y7CgkgIExQQllURSBkYXRhOwoJICBpbnQgbGVuOwoJICBMUFdTVFIgbmFtZTsKCgkgIFhSRUFEKCZka3Ysc2l6ZW9mKGRrdikpOwoKCSAgbmFtZSA9IHN0cmN2dEEyVyhjdXJkYXRhLCBka3YudmFsbmFtZWxlbik7CgkgIGN1cmRhdGEgKz0gZGt2LnZhbG5hbWVsZW47CgoJICBpZiAoKDEgPDwgZGt2LnR5cGUpICYgVU5JQ09OVk1BU0spIHsKCSAgICBkYXRhID0gKExQQllURSkgc3RyY3Z0QTJXKGN1cmRhdGEsIGRrdi52YWxkYXRhbGVuKTsKCSAgICBsZW4gPSAyKihka3YudmFsZGF0YWxlbiArIDEpOwoJICB9IGVsc2UgewoJICAgIC8qIEkgZG9uJ3QgdGhpbmsgd2Ugd2FudCB0byBOVUxMIHRlcm1pbmF0ZSBhbGwgZGF0YSAqLwoJICAgIGRhdGEgPSB4bWFsbG9jKGRrdi52YWxkYXRhbGVuKTsKCSAgICBtZW1jcHkgKGRhdGEsIGN1cmRhdGEsIGRrdi52YWxkYXRhbGVuKTsKCSAgICBsZW4gPSBka3YudmFsZGF0YWxlbjsKCSAgfQoKCSAgY3VyZGF0YSArPSBka3YudmFsZGF0YWxlbjsKCSAgCgkgIF9maW5kX29yX2FkZF92YWx1ZSgKCQkJICAgICBscHhrZXksCgkJCSAgICAgbmFtZSwKCQkJICAgICBka3YudHlwZSwKCQkJICAgICBkYXRhLAoJCQkgICAgIGxlbiwKCQkJICAgICBpbmZvLT5sYXN0bW9kaWZpZWQKCQkJICAgICApOwoKCX0KCglyZXR1cm4gKGxweGtleSk7Cn0KCnN0YXRpYyB2b2lkCl93OTVfd2Fsa3Jna24oTFBLRVlTVFJVQ1QgcHJldmtleSwgY2hhciAqb2ZmLCBzdHJ1Y3QgX3c5NV9pbmZvICppbmZvKQoKewogIC8qIERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZSAoUkdLTiBwYXJ0KSAqLwogIHN0cnVjdAlka2UgewogICAgdW5zaWduZWQgbG9uZwkJeDE7CiAgICB1bnNpZ25lZCBsb25nCQl4MjsKICAgIHVuc2lnbmVkIGxvbmcJCXgzOy8qdXN1YWxseSAweEZGRkZGRkZGICovCiAgICB1bnNpZ25lZCBsb25nCQlwcmV2bHZsOwogICAgdW5zaWduZWQgbG9uZwkJbmV4dHN1YjsKICAgIHVuc2lnbmVkIGxvbmcJCW5leHQ7CiAgICB1bnNpZ25lZCBzaG9ydAkJbnJMUzsKICAgIHVuc2lnbmVkIHNob3J0CQluck1TOwogIH0gKmRrZSA9IChzdHJ1Y3QgZGtlICopb2ZmOwogIExQS0VZU1RSVUNUICBscHhrZXk7CgogIGlmIChka2UgPT0gTlVMTCkgewogICAgZGtlID0gKHN0cnVjdCBka2UgKikgKChjaGFyICopaW5mby0+cmdrbmJ1ZmZlcik7CiAgfQoKICBscHhrZXkgPSBfdzk1X3Byb2Nlc3NLZXkocHJldmtleSwgZGtlLT5uckxTLCBka2UtPm5yTVMsIGluZm8pOwogIC8qIFhYWCA8LS0gVGhpcyBpcyBhIGhhY2sqLwogIGlmICghbHB4a2V5KSB7CiAgICBscHhrZXkgPSBwcmV2a2V5OwogIH0KCiAgaWYgKGRrZS0+bmV4dHN1YiAhPSAtMSAmJiAKICAgICAgKChka2UtPm5leHRzdWIgLSAweDIwKSA8IGluZm8tPnJna25zaXplKSAKICAgICAgJiYgKGRrZS0+bmV4dHN1YiA+IDB4MjApKSB7CiAgICAKICAgIF93OTVfd2Fsa3Jna24obHB4a2V5LCAKCQkgIGluZm8tPnJna25idWZmZXIgKyBka2UtPm5leHRzdWIgLSAweDIwLCAKCQkgIGluZm8pOwogIH0KICAKICBpZiAoZGtlLT5uZXh0ICE9IC0xICYmIAogICAgICAoKGRrZS0+bmV4dCAtIDB4MjApIDwgaW5mby0+cmdrbnNpemUpICYmIAogICAgICAoZGtlLT5uZXh0ID4gMHgyMCkpIHsKICAgIF93OTVfd2Fsa3Jna24ocHJldmtleSwgIAoJCSAgaW5mby0+cmdrbmJ1ZmZlciArIGRrZS0+bmV4dCAtIDB4MjAsCgkJICBpbmZvKTsKICB9CgogIHJldHVybjsKfQoKc3RhdGljIHZvaWQKX3c5NV9sb2FkcmVnKGNoYXIqIGZuLExQS0VZU1RSVUNUIGxwa2V5KSB7CglIRklMRTMyCQloZmQ7CgljaGFyCQltYWdpY1s1XTsKCXVuc2lnbmVkIGxvbmcJd2hlcmUsdmVyc2lvbixyZ2Ric2VjdGlvbixlbmQ7CglzdHJ1Y3QgICAgICAgICAgX3c5NV9pbmZvIGluZm87CglPRlNUUlVDVAlvZnM7CglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmRpbmZvOwoKCVRSQUNFKHJlZywiTG9hZGluZyBXaW45NSByZWdpc3RyeSBkYXRhYmFzZSAnJXMnXG4iLGZuKTsKCWhmZD1PcGVuRmlsZTMyKGZuLCZvZnMsT0ZfUkVBRCk7CglpZiAoaGZkPT1IRklMRV9FUlJPUjMyKQoJCXJldHVybjsKCW1hZ2ljWzRdPTA7CglpZiAoNCE9X2xyZWFkMzIoaGZkLG1hZ2ljLDQpKQoJCXJldHVybjsKCWlmIChzdHJjbXAobWFnaWMsIkNSRUciKSkgewoJCVdBUk4ocmVnLCIlcyBpcyBub3QgYSB3OTUgcmVnaXN0cnkuXG4iLGZuKTsKCQlyZXR1cm47Cgl9CglpZiAoNCE9X2xyZWFkMzIoaGZkLCZ2ZXJzaW9uLDQpKQoJCXJldHVybjsKCWlmICg0IT1fbHJlYWQzMihoZmQsJnJnZGJzZWN0aW9uLDQpKQoJCXJldHVybjsKCWlmICgtMT09X2xsc2VlazMyKGhmZCwweDIwLFNFRUtfU0VUKSkKCQlyZXR1cm47CglpZiAoNCE9X2xyZWFkMzIoaGZkLG1hZ2ljLDQpKQoJCXJldHVybjsKCWlmIChzdHJjbXAobWFnaWMsIlJHS04iKSkgewoJCVdBUk4ocmVnLCAic2Vjb25kIElGRiBoZWFkZXIgbm90IFJHS04sIGJ1dCAlc1xuIiwgbWFnaWMpOwoJCXJldHVybjsKCX0KCgkvKiBTVEVQIDE6IEtleWxpbmsgc3RydWN0dXJlcyAqLwoJaWYgKC0xPT1fbGxzZWVrMzIoaGZkLDB4NDAsU0VFS19TRVQpKQoJCXJldHVybjsKCXdoZXJlCT0gMHg0MDsKCWVuZAk9IHJnZGJzZWN0aW9uOwoKCWluZm8ucmdrbnNpemUgPSBlbmQgLSB3aGVyZTsKCWluZm8ucmdrbmJ1ZmZlciA9IChjaGFyKil4bWFsbG9jKGluZm8ucmdrbnNpemUpOwoJaWYgKGluZm8ucmdrbnNpemUgIT0gX2xyZWFkMzIoaGZkLGluZm8ucmdrbmJ1ZmZlcixpbmZvLnJna25zaXplKSkKCQlyZXR1cm47CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZmQsJmhmZGluZm8pKQoJCXJldHVybjsKCgllbmQgPSBoZmRpbmZvLm5GaWxlU2l6ZUxvdzsKCWluZm8ubGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmRpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCglpZiAoLTE9PV9sbHNlZWszMihoZmQscmdkYnNlY3Rpb24sU0VFS19TRVQpKQoJCXJldHVybjsKCglpbmZvLnJnZGJidWZmZXIgPSAoY2hhciopeG1hbGxvYyhlbmQtcmdkYnNlY3Rpb24pOwoJaW5mby5yZ2Ric2l6ZSA9IGVuZCAtIHJnZGJzZWN0aW9uOwoKCWlmIChpbmZvLnJnZGJzaXplICE9X2xyZWFkMzIoaGZkLGluZm8ucmdkYmJ1ZmZlcixpbmZvLnJnZGJzaXplKSkKCQlyZXR1cm47CglfbGNsb3NlMzIoaGZkKTsKCglfdzk1X3dhbGtyZ2tuKGxwa2V5LCBOVUxMLCAmaW5mbyk7CgoJZnJlZSAoaW5mby5yZ2RiYnVmZmVyKTsKCWZyZWUgKGluZm8ucmdrbmJ1ZmZlcik7Cn0KCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCgovKgogICAgcmVnaGFjayAtIHdpbmRvd3MgMy4xMSByZWdpc3RyeSBkYXRhIGZvcm1hdCBkZW1vIHByb2dyYW0uCgogICAgVGhlIHJlZy5kYXQgZmlsZSBoYXMgMyBwYXJ0cywgYSBoZWFkZXIsIGEgdGFibGUgb2YgOC1ieXRlIGVudHJpZXMgdGhhdCBpcwogICAgYSBjb21iaW5lZCBoYXNoIHRhYmxlIGFuZCB0cmVlIGRlc2NyaXB0aW9uLCBhbmQgZmluYWxseSBhIHRleHQgdGFibGUuCgogICAgVGhlIGhlYWRlciBpcyBvYnZpb3VzIGZyb20gdGhlIHN0cnVjdCBoZWFkZXIuIFRoZSB0YWJvZmYxIGFuZCB0YWJvZmYyCiAgICBmaWVsZHMgYXJlIGFsd2F5cyAweDIwLCBhbmQgdGhlaXIgdXNhZ2UgaXMgdW5rbm93bi4KCiAgICBUaGUgOC1ieXRlIGVudHJ5IHRhYmxlIGhhcyB2YXJpb3VzIGVudHJ5IHR5cGVzLgoKICAgIHRhYmVudFswXSBpcyBhIHJvb3QgaW5kZXguIFRoZSBzZWNvbmQgd29yZCBoYXMgdGhlIGluZGV4IG9mIHRoZSByb290IG9mCiAgICAgICAgICAgIHRoZSBkaXJlY3RvcnkuCiAgICB0YWJlbnRbMS4uaGFzaHNpemVdIGlzIGEgaGFzaCB0YWJsZS4gVGhlIGZpcnN0IHdvcmQgaW4gdGhlIGhhc2ggZW50cnkgaXMKICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBrZXkvdmFsdWUgdGhhdCBoYXMgdGhhdCBoYXNoLiBEYXRhIHdpdGggdGhlIHNhbWUKICAgICAgICAgICAgaGFzaCB2YWx1ZSBhcmUgb24gYSBjaXJjdWxhciBsaXN0LiBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlCiAgICAgICAgICAgIGhhc2ggZW50cnkgYXJlIGFsd2F5cyB6ZXJvLgogICAgdGFiZW50W2hhc2hzaXplLi50YWJjbnRdIGlzIHRoZSB0cmVlIHN0cnVjdHVyZS4gVGhlcmUgYXJlIHR3byBraW5kcyBvZgogICAgICAgICAgICBlbnRyeTogZGlyZW50IGFuZCBrZXllbnQvdmFsZW50LiBUaGV5IGFyZSBpZGVudGlmaWVkIGJ5IGNvbnRleHQuCiAgICB0YWJlbnRbZnJlZWlkeF0gaXMgdGhlIGZpcnN0IGZyZWUgZW50cnkuIFRoZSBmaXJzdCB3b3JkIGluIGEgZnJlZSBlbnRyeQogICAgICAgICAgICBpcyB0aGUgaW5kZXggb2YgdGhlIG5leHQgZnJlZSBlbnRyeS4gVGhlIGxhc3QgaGFzIDAgYXMgYSBsaW5rLgogICAgICAgICAgICBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlIGZyZWUgbGlzdCBhcmUgcHJvYmFibHkgaXJyZWxldmFudC4KCiAgICBFbnRyaWVzIGluIHRleHQgdGFibGUgYXJlIHByZWNlZWRlZCBieSBhIHdvcmQgYXQgb2Zmc2V0LTIuIFRoaXMgd29yZAogICAgaGFzIHRoZSB2YWx1ZSAoMippbmRleCkrMSwgd2hlcmUgaW5kZXggaXMgdGhlIHJlZmVycmluZyBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBpbiB0aGUgdGFibGUuIEkgaGF2ZSBubyBzdWdnZXN0aW9uIGZvciB0aGUgMiogYW5kIHRoZSArMS4KICAgIEZvbGxvd2luZyB0aGUgd29yZCwgdGhlcmUgYXJlIE4gYnl0ZXMgb2YgZGF0YSwgYXMgcGVyIHRoZSBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBsZW5ndGguIFRoZSBvZmZzZXQgb2YgdGhlIGtleWVudC92YWxlbnQgZW50cnkgaXMgZnJvbSB0aGUgc3RhcnQKICAgIG9mIHRoZSB0ZXh0IHRhYmxlIHRvIHRoZSBmaXJzdCBkYXRhIGJ5dGUuCgogICAgVGhpcyBpbmZvcm1hdGlvbiBpcyBub3QgYXZhaWxhYmxlIGZyb20gTWljcm9zb2Z0LiBUaGUgZGF0YSBmb3JtYXQgaXMKICAgIGRlZHVjZWQgZnJvbSB0aGUgcmVnLmRhdCBmaWxlIGJ5IG1lLiBNaXN0YWtlcyBtYXkKICAgIGhhdmUgYmVlbiBtYWRlLiBJIGNsYWltIG5vIHJpZ2h0cyBhbmQgZ2l2ZSBubyBndWFyYW50ZWVzIGZvciB0aGlzIHByb2dyYW0uCgogICAgVG9yIFNq+HdhbGwsIHRvckBzbi5ubwoqLwoKLyogcmVnLmRhdCBoZWFkZXIgZm9ybWF0ICovCnN0cnVjdCBfdzMxX2hlYWRlciB7CgljaGFyCQljb29raWVbOF07CS8qICdTSENDMy4xMCcgKi8KCXVuc2lnbmVkIGxvbmcJdGFib2ZmMTsJLyogb2Zmc2V0IG9mIGhhc2ggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFib2ZmMjsJLyogb2Zmc2V0IG9mIGluZGV4IHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYmNudDsJCS8qIG51bWJlciBvZiBlbnRyaWVzIGluIGluZGV4IHRhYmxlICovCgl1bnNpZ25lZCBsb25nCXRleHRvZmY7CS8qIG9mZnNldCBvZiB0ZXh0IHBhcnQgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dHNpemU7CS8qIGJ5dGUgc2l6ZSBvZiB0ZXh0IHBhcnQgKi8KCXVuc2lnbmVkIHNob3J0CWhhc2hzaXplOwkvKiBoYXNoIHNpemUgKi8KCXVuc2lnbmVkIHNob3J0CWZyZWVpZHg7CS8qIGZyZWUgaW5kZXggKi8KfTsKCi8qIGdlbmVyaWMgZm9ybWF0IG9mIHRhYmxlIGVudHJpZXMgKi8Kc3RydWN0IF93MzFfdGFiZW50IHsKCXVuc2lnbmVkIHNob3J0IHcwLCB3MSwgdzIsIHczOwp9OwoKLyogZGlyZWN0b3J5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfZGlyZW50IHsKCXVuc2lnbmVkIHNob3J0CXNpYmxpbmdfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBzaWJsaW5nIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJY2hpbGRfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBjaGlsZCBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWtleV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGtleSBrZXllbnQgKi8KCXVuc2lnbmVkIHNob3J0CXZhbHVlX2lkeDsJLyogdGFibGUgaW5kZXggb2YgdmFsdWUgdmFsZW50ICovCn07CgovKiBrZXkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9rZXllbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHZhbHVlIHRhYmVudDogKi8Kc3RydWN0IF93MzFfdmFsZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiByZWN1cnNpdmUgaGVscGVyIGZ1bmN0aW9uIHRvIGRpc3BsYXkgYSBkaXJlY3RvcnkgdHJlZSAqLwp2b2lkCl9fdzMxX2R1bXB0cmVlKAl1bnNpZ25lZCBzaG9ydCBpZHgsCgkJdW5zaWduZWQgY2hhciAqdHh0LAoJCXN0cnVjdCBfdzMxX3RhYmVudCAqdGFiLAoJCXN0cnVjdCBfdzMxX2hlYWRlciAqaGVhZCwKCQlMUEtFWVNUUlVDVAlscGtleSwKCQl0aW1lX3QJCWxhc3Rtb2RpZmllZCwKCQlpbnQJCWxldmVsCikgewoJc3RydWN0IF93MzFfZGlyZW50CSpkaXI7CglzdHJ1Y3QgX3czMV9rZXllbnQJKmtleTsKCXN0cnVjdCBfdzMxX3ZhbGVudAkqdmFsOwoJTFBLRVlTVFJVQ1QJCXhscGtleSA9IE5VTEw7CglMUFdTVFIJCQluYW1lLHZhbHVlOwoJc3RhdGljIGNoYXIJCXRhaWxbNDAwXTsKCgl3aGlsZSAoaWR4IT0wKSB7CgkJZGlyPShzdHJ1Y3QgX3czMV9kaXJlbnQqKSZ0YWJbaWR4XTsKCgkJaWYgKGRpci0+a2V5X2lkeCkgewoJCQlrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgoJCQltZW1jcHkodGFpbCwmdHh0W2tleS0+c3RyaW5nX29mZl0sa2V5LT5sZW5ndGgpOwoJCQl0YWlsW2tleS0+bGVuZ3RoXT0nXDAnOwoJCQkvKiBhbGwgdG9wbGV2ZWwgZW50cmllcyBBTkQgdGhlIGVudHJpZXMgaW4gdGhlIAoJCQkgKiB0b3BsZXZlbCBzdWJkaXJlY3RvcnkgYmVsb25nIHRvIFxTT0ZUV0FSRVxDbGFzc2VzCgkJCSAqLwoJCQlpZiAoIWxldmVsICYmICFsc3RyY21wMzJBKHRhaWwsIi5jbGFzc2VzIikpIHsKCQkJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxscGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJCQlpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCW5hbWU9c3RyZHVwQTJXKHRhaWwpOwoKCQkJeGxwa2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksbmFtZSk7CgoJCQkvKiBvbmx5IGFkZCBpZiBsZWFmIG5vZGUgb3IgdmFsdWVkIG5vZGUgKi8KCQkJaWYgKGRpci0+dmFsdWVfaWR4IT0wfHxkaXItPmNoaWxkX2lkeD09MCkgewoJCQkJaWYgKGRpci0+dmFsdWVfaWR4KSB7CgkJCQkJdmFsPShzdHJ1Y3QgX3czMV92YWxlbnQqKSZ0YWJbZGlyLT52YWx1ZV9pZHhdOwoJCQkJCW1lbWNweSh0YWlsLCZ0eHRbdmFsLT5zdHJpbmdfb2ZmXSx2YWwtPmxlbmd0aCk7CgkJCQkJdGFpbFt2YWwtPmxlbmd0aF09J1wwJzsKCQkJCQl2YWx1ZT1zdHJkdXBBMlcodGFpbCk7CgkJCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKHhscGtleSxOVUxMLFJFR19TWiwoTFBCWVRFKXZhbHVlLGxzdHJsZW4zMlcodmFsdWUpKjIrMixsYXN0bW9kaWZpZWQpOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJVFJBQ0UocmVnLCJzdHJhbmdlOiBubyBkaXJlY3Rvcnkga2V5IG5hbWUsIGlkeD0lMDR4XG4iLCBpZHgpOwoJCX0KCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQseGxwa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQlpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKCX0KfQoKdm9pZApfdzMxX2xvYWRyZWcoKSB7CglIRklMRTMyCQkJaGY7CglzdHJ1Y3QgX3czMV9oZWFkZXIJaGVhZDsKCXN0cnVjdCBfdzMxX3RhYmVudAkqdGFiOwoJdW5zaWduZWQgY2hhcgkJKnR4dDsKCWludAkJCWxlbjsKCU9GU1RSVUNUCQlvZnM7CglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmluZm87Cgl0aW1lX3QJCQlsYXN0bW9kaWZpZWQ7CglIS0VZCQkJaGtleTsKCUxQS0VZU1RSVUNUCQlscGtleTsKCgloZiA9IE9wZW5GaWxlMzIoInJlZy5kYXQiLCZvZnMsT0ZfUkVBRCk7CglpZiAoaGY9PUhGSUxFX0VSUk9SMzIpCgkJcmV0dXJuOwoKCS8qIHJlYWQgJiBkdW1wIGhlYWRlciAqLwoJaWYgKHNpemVvZihoZWFkKSE9X2xyZWFkMzIoaGYsJmhlYWQsc2l6ZW9mKGhlYWQpKSkgewoJCUVSUihyZWcsICJyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoJaWYgKG1lbWNtcChoZWFkLmNvb2tpZSwgIlNIQ0MzLjEwIiwgc2l6ZW9mKGhlYWQuY29va2llKSkhPTApIHsKCQlFUlIocmVnLCAicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoKCWxlbiA9IGhlYWQudGFiY250ICogc2l6ZW9mKHN0cnVjdCBfdzMxX3RhYmVudCk7CgkvKiByZWFkIGFuZCBkdW1wIGluZGV4IHRhYmxlICovCgl0YWIgPSB4bWFsbG9jKGxlbik7CglpZiAobGVuIT1fbHJlYWQzMihoZix0YWIsbGVuKSkgewoJCUVSUihyZWcsImNvdWxkbid0IHJlYWQgJWQgYnl0ZXMuXG4iLGxlbik7IAoJCWZyZWUodGFiKTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCgkvKiByZWFkIHRleHQgKi8KCXR4dCA9IHhtYWxsb2MoaGVhZC50ZXh0c2l6ZSk7CglpZiAoLTE9PV9sbHNlZWszMihoZixoZWFkLnRleHRvZmYsU0VFS19TRVQpKSB7CgkJRVJSKHJlZywiY291bGRuJ3Qgc2VlayB0byB0ZXh0YmxvY2suXG4iKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCWlmIChoZWFkLnRleHRzaXplIT1fbHJlYWQzMihoZix0eHQsaGVhZC50ZXh0c2l6ZSkpIHsKCQlFUlIocmVnLCJ0ZXh0YmxvY2sgdG9vIHNob3J0ICglZCBpbnN0ZWFkIG9mICVsZCkuXG4iLGxlbixoZWFkLnRleHRzaXplKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCglpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmLCZoZmluZm8pKSB7CgkJRVJSKHJlZywiR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUgZmFpbGVkPy5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoJbGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoKCWlmIChSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlxcU09GVFdBUkVcXENsYXNzZXMiLCZoa2V5KSE9RVJST1JfU1VDQ0VTUykKCQlyZXR1cm47CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwoJX193MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLDApOwoJZnJlZSh0YWIpOwoJZnJlZSh0eHQpOwoJX2xjbG9zZTMyKGhmKTsKCXJldHVybjsKfQoKdm9pZApTSEVMTF9Mb2FkUmVnaXN0cnkoKSB7CgljaGFyCSpmbjsKCXN0cnVjdAlwYXNzd2QJKnB3ZDsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCgoJaWYgKGtleV9jbGFzc2VzX3Jvb3Q9PU5VTEwpCgkJU0hFTExfSW5pdCgpOwoKCS8qIExvYWQgd2luZG93cyAzLjEgZW50cmllcyAqLwoJX3czMV9sb2FkcmVnKCk7CgkvKiBMb2FkIHdpbmRvd3MgOTUgZW50cmllcyAqLwoJX3c5NV9sb2FkcmVnKCJDOlxcc3lzdGVtLjFzdCIsCWtleV9sb2NhbF9tYWNoaW5lKTsKCV93OTVfbG9hZHJlZygic3lzdGVtLmRhdCIsCWtleV9sb2NhbF9tYWNoaW5lKTsKCV93OTVfbG9hZHJlZygidXNlci5kYXQiLAlrZXlfdXNlcnMpOwoKCS8qIHRoZSBnbG9iYWwgdXNlciBkZWZhdWx0IGlzIGxvYWRlZCB1bmRlciBIS0VZX1VTRVJTXFwuRGVmYXVsdCAqLwoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUywiLkRlZmF1bHQiLCZoa2V5KTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7Cglfd2luZV9sb2FkcmVnKGxwa2V5LFNBVkVfVVNFUlNfREVGQVVMVCwwKTsKCgkvKiBIS0VZX1VTRVJTXFwuRGVmYXVsdCBpcyBjb3BpZWQgdG8gSEtFWV9DVVJSRU5UX1VTRVIgKi8KCV9jb3B5X3JlZ2lzdHJ5KGxwa2V5LGtleV9jdXJyZW50X3VzZXIpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogdGhlIGdsb2JhbCBtYWNoaW5lIGRlZmF1bHRzICovCglfd2luZV9sb2FkcmVnKGtleV9sb2NhbF9tYWNoaW5lLFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxULDApOwoKCS8qIGxvYWQgdGhlIHVzZXIgc2F2ZWQgcmVnaXN0cmllcyAqLwoKCS8qIEZJWE1FOiB1c2UgZ2V0ZW52KCJIT01FIikgb3IgZ2V0cHd1aWQoZ2V0dWlkKCkpLT5wd19kaXIgPz8gKi8KCglwd2Q9Z2V0cHd1aWQoZ2V0dWlkKCkpOwoJaWYgKHB3ZCE9TlVMTCAmJiBwd2QtPnB3X2RpciE9TlVMTCkgewoJCWZuPShjaGFyKil4bWFsbG9jKHN0cmxlbihwd2QtPnB3X2Rpcikrc3RybGVuKFdJTkVfUFJFRklYKStzdHJsZW4oU0FWRV9DVVJSRU5UX1VTRVIpKzIpOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwoJCV93aW5lX2xvYWRyZWcoa2V5X2N1cnJlbnRfdXNlcixmbixSRUdfT1BUSU9OX1RBSU5URUQpOwoJCWZyZWUoZm4pOwoJCWZuPShjaGFyKil4bWFsbG9jKHN0cmxlbihwd2QtPnB3X2Rpcikrc3RybGVuKFdJTkVfUFJFRklYKStzdHJsZW4oU0FWRV9MT0NBTF9NQUNISU5FKSsyKTsKCQlzdHJjcHkoZm4scHdkLT5wd19kaXIpOwoJCXN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfTUFDSElORSk7CgkJX3dpbmVfbG9hZHJlZyhrZXlfbG9jYWxfbWFjaGluZSxmbixSRUdfT1BUSU9OX1RBSU5URUQpOwoJCWZyZWUoZm4pOwoJfSBlbHNlCgkJV0FSTihyZWcsIkZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWQuXG4iLGdldHVpZCgpKTsKCWlmIChFUlJPUl9TVUNDRVNTPT1SZWdDcmVhdGVLZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpKSB7CgkJRFdPUkQJanVuayx0eXBlLGxlbjsKCQljaGFyCWRhdGFbNV07CgoJCWxlbj00OwoJCWlmICgoCVJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQkJCWhrZXksCgkJCQlWQUxfU0FWRVVQREFURUQsCgkJCQkmanVuaywKCQkJCSZ0eXBlLAoJCQkJZGF0YSwKCQkJCSZsZW4KCQkJKSE9RVJST1JfU1VDQ0VTUykgfHwKCQkJdHlwZSAhPSBSRUdfU1oKCQkpCgkJCVJlZ1NldFZhbHVlRXgzMkEoaGtleSxWQUxfU0FWRVVQREFURUQsMCxSRUdfU1osInllcyIsNCk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIEFQSSBGVU5DVElPTlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKgogKiBPcGVuIEtleXMuCiAqCiAqIEFsbCBmdW5jdGlvbnMgYXJlIHN0dWJzIHRvIFJlZ09wZW5LZXlFeDMyVyB3aGVyZSBhbGwgdGhlCiAqIG1hZ2ljIGhhcHBlbnMuIAogKgogKiBGSVhNRTogc2VjdXJpdHksb3B0aW9ucyxkZXNpcmVkYWNjZXNzLC4uLgogKgogKiBDYWxscGF0aDoKICogUmVnT3BlbktleTE2IC0+IFJlZ09wZW5LZXkzMkEgLT4gUmVnT3BlbktleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnT3BlbktleTMyVyAgIC0+IFJlZ09wZW5LZXlFeDMyVyAKICovCgovKiBSZWdPcGVuS2V5RXhXCQlbQURWQVBJMzIuMTUwXSAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleUV4MzJXKAoJSEtFWQloa2V5LAoJTFBDV1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdSZXNlcnZlZCwKCVJFR1NBTQlzYW1EZXNpcmVkLAoJTFBIS0VZCXJldGtleQopIHsKCUxQS0VZU1RSVUNUCWxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoJVFJBQ0UocmVnLCIoJWx4LCVzLCVsZCwlbHgsJXApXG4iLAoJCShMT05HKWhrZXksVzJDKGxwc3pTdWJLZXksMCksZHdSZXNlcnZlZCxzYW1EZXNpcmVkLHJldGtleQoJKTsKCglscE5leHRLZXkJPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBOZXh0S2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CglpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KSB7CgkJYWRkX2hhbmRsZSgrK2N1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwoJCSpyZXRrZXk9Y3VycmVudGhhbmRsZTsKCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCX0KCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleQk9IGxwTmV4dEtleTsKCXdoaWxlICh3cHNbaV0pIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21waTMyVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJCWJyZWFrOwoJCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJCX0KCQlpZiAoIWxweGtleSkgewoJCQlGUkVFX0tFWV9QQVRIOwoJCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJCX0KCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJYWRkX2hhbmRsZSgrK2N1cnJlbnRoYW5kbGUsbHB4a2V5LHNhbURlc2lyZWQpOwoJKnJldGtleQk9IGN1cnJlbnRoYW5kbGU7CglGUkVFX0tFWV9QQVRIOwoJcmV0dXJuCVNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ09wZW5LZXlXCQkJW0FEVkFQSTMyLjE1MV0gKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkzMlcoCglIS0VZCWhrZXksCglMUENXU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJVFJBQ0UocmVnLCIoJWx4LCVzLCVwKVxuIiwKCQkoTE9ORyloa2V5LFcyQyhscHN6U3ViS2V5LDApLHJldGtleQoJKTsKCXJldHVybiBSZWdPcGVuS2V5RXgzMlcoaGtleSxscHN6U3ViS2V5LDAsS0VZX0FMTF9BQ0NFU1MscmV0a2V5KTsKfQoKCi8qIFJlZ09wZW5LZXlFeEEJCVtBRFZBUEkzMi4xNDldICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5RXgzMkEoCglIS0VZCWhrZXksCglMUENTVFIJbHBzelN1YktleSwKCURXT1JECWR3UmVzZXJ2ZWQsCglSRUdTQU0Jc2FtRGVzaXJlZCwKCUxQSEtFWQlyZXRrZXkKKSB7CglMUFdTVFIJbHBzelN1YktleVc7CglEV09SRAlyZXQ7CgoJVFJBQ0UocmVnLCIoJWx4LCVzLCVsZCwlbHgsJXApXG4iLAoJCShMT05HKWhrZXksbHBzelN1YktleSxkd1Jlc2VydmVkLHNhbURlc2lyZWQscmV0a2V5CgkpOwoJaWYgKGxwc3pTdWJLZXkpCgkJbHBzelN1YktleVc9c3RyZHVwQTJXKGxwc3pTdWJLZXkpOwoJZWxzZQoJCWxwc3pTdWJLZXlXPU5VTEw7CglyZXQ9UmVnT3BlbktleUV4MzJXKGhrZXksbHBzelN1YktleVcsZHdSZXNlcnZlZCxzYW1EZXNpcmVkLHJldGtleSk7CglpZiAobHBzelN1YktleVcpCgkJZnJlZShscHN6U3ViS2V5Vyk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdPcGVuS2V5QQkJCVtBRFZBUEkzMi4xNDhdICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MzJBKAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJVFJBQ0UocmVnLCIoJWx4LCVzLCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXkscmV0a2V5CgkpOwoJcmV0dXJuCVJlZ09wZW5LZXlFeDMyQShoa2V5LGxwc3pTdWJLZXksMCxLRVlfQUxMX0FDQ0VTUyxyZXRrZXkpOwp9CgovKiBSZWdPcGVuS2V5CQkJW1NIRUxMLjFdIFtLRVJORUwuMjE3XSAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTE2KAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJVFJBQ0UocmVnLCIoJWx4LCVzLCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXkscmV0a2V5CgkpOwoJcmV0dXJuIFJlZ09wZW5LZXkzMkEoaGtleSxscHN6U3ViS2V5LHJldGtleSk7Cn0KCi8qIAogKiBDcmVhdGUga2V5cwogKiAKICogQWxsIHRob3NlIGZ1bmN0aW9ucyBjb252ZXJ0IHRoZWlyIHJlc3BlY3RpdmUgCiAqIGFyZ3VtZW50cyBhbmQgY2FsbCBSZWdDcmVhdGVLZXlFeFcgYXQgdGhlIGVuZC4KICoKICogRklYTUU6IG5vIHNlY3VyaXR5LG5vIGFjY2VzcyBhdHRyaWIsbm8gb3B0aW9uaGFuZGxpbmcgeWV0LgogKgogKiBDYWxscGF0aDoKICogUmVnQ3JlYXRlS2V5MTYgLT4gUmVnQ3JlYXRlS2V5MzJBIC0+IFJlZ0NyZWF0ZUtleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ0NyZWF0ZUtleTMyVyAgIC0+IFJlZ0NyZWF0ZUtleUV4MzJXCiAqLwoKLyogUmVnQ3JlYXRlS2V5RXhXCQlbQURWQVBJMzIuMTMxXSAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5RXgzMlcoCglIS0VZCWhrZXksCglMUENXU1RSCWxwc3pTdWJLZXksCglEV09SRAlkd1Jlc2VydmVkLAoJTFBXU1RSCWxwc3pDbGFzcywKCURXT1JECWZkd09wdGlvbnMsCglSRUdTQU0Jc2FtRGVzaXJlZCwKCUxQU0VDVVJJVFlfQVRUUklCVVRFUyBscFNlY0F0dHJpYnMsCglMUEhLRVkJcmV0a2V5LAoJTFBEV09SRAlscERpc3BvcwopIHsKCUxQS0VZU1RSVUNUCSpscGxwUHJldktleSxscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCi8qRklYTUU6IGhhbmRsZSBzZWN1cml0eS9hY2Nlc3Mvd2hhdGV2ZXIgKi8KCVRSQUNFKHJlZywiKCVseCwlcywlbGQsJXMsJWx4LCVseCwlcCwlcCwlcClcbiIsCgkJKExPTkcpaGtleSwKCQlXMkMobHBzelN1YktleSwwKSwKCQlkd1Jlc2VydmVkLAoJCVcyQyhscHN6Q2xhc3MsMSksCgkJZmR3T3B0aW9ucywKCQlzYW1EZXNpcmVkLAoJCWxwU2VjQXR0cmlicywKCQlyZXRrZXksCgkJbHBEaXNwb3MKCSk7CgoJbHBOZXh0S2V5CT0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwTmV4dEtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkgewoJCWFkZF9oYW5kbGUoKytjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKCQkqcmV0a2V5PWN1cnJlbnRoYW5kbGU7CgkJbHBOZXh0S2V5LT5mbGFnc3w9UkVHX09QVElPTl9UQUlOVEVEOwoJCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwoJfQoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7Cgl3aGlsZSAoKGk8d3BjKSAmJiAod3BzW2ldWzBdPT0nXDAnKSkgaSsrOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKHdwc1tpXSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KQoJCQlicmVhazsKCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJaWYgKGxweGtleSkgewoJCWFkZF9oYW5kbGUoKytjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKCQlscHhrZXktPmZsYWdzICB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwoJCWlmIChscERpc3BvcykKCQkJKmxwRGlzcG9zCT0gUkVHX09QRU5FRF9FWElTVElOR19LRVk7CgkJRlJFRV9LRVlfUEFUSDsKCQlyZXR1cm4JU0hFTExfRVJST1JfU1VDQ0VTUzsKCX0KCS8qIGdvb2QuIG5vdyB0aGUgaGFyZCBwYXJ0ICovCgl3aGlsZSAod3BzW2ldKSB7CgkJbHBscFByZXZLZXkJPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7CgkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCQlscHhrZXkJCT0gKmxwbHBQcmV2S2V5OwoJCX0KCQkqbHBscFByZXZLZXk9bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTsKCQlpZiAoISpscGxwUHJldktleSkgewoJCQlGUkVFX0tFWV9QQVRIOwoJCQlyZXR1cm4gU0hFTExfRVJST1JfT1VUT0ZNRU1PUlk7CgkJfQoJCW1lbXNldCgqbHBscFByZXZLZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CgkJKCpscGxwUHJldktleSktPmtleW5hbWUJPSBzdHJkdXBXKHdwc1tpXSk7CgkJKCpscGxwUHJldktleSktPm5leHQJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5uZXh0c3ViCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+dmFsdWVzCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+bnJvZnZhbHVlcyA9IDA7CgkJKCpscGxwUHJldktleSktPmZsYWdzIAk9IFJFR19PUFRJT05fVEFJTlRFRDsKCQlpZiAobHBzekNsYXNzKQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBzdHJkdXBXKGxwc3pDbGFzcyk7CgkJZWxzZQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBOVUxMOwoJCWxwTmV4dEtleQk9ICpscGxwUHJldktleTsKCQlpKys7Cgl9CglhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgoJLypGSVhNRTogZmxhZyBoYW5kbGluZyBjb3JyZWN0PyAqLwoJbHBOZXh0S2V5LT5mbGFncz0gZmR3T3B0aW9ucyB8UkVHX09QVElPTl9UQUlOVEVEOwoJaWYgKGxwc3pDbGFzcykKCQlscE5leHRLZXktPmNsYXNzID0gc3RyZHVwVyhscHN6Q2xhc3MpOwoJZWxzZQoJCWxwTmV4dEtleS0+Y2xhc3MgPSBOVUxMOwoJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwoJaWYgKGxwRGlzcG9zKQoJCSpscERpc3Bvcwk9IFJFR19DUkVBVEVEX05FV19LRVk7CglGUkVFX0tFWV9QQVRIOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ0NyZWF0ZUtleVcJCVtBRFZBUEkzMi4xMzJdICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkzMlcoCglIS0VZCWhrZXksCglMUENXU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJRFdPUkQJanVuayxyZXQ7CgoJVFJBQ0UocmVnLCIoJWx4LCVzLCVwKVxuIiwKCQkoTE9ORyloa2V5LFcyQyhscHN6U3ViS2V5LDApLHJldGtleQoJKTsKCXJldD1SZWdDcmVhdGVLZXlFeDMyVygKCQloa2V5LAkJLyoga2V5IGhhbmRsZSAqLwoJCWxwc3pTdWJLZXksCS8qIHN1YmtleSBuYW1lICovCgkJMCwJCS8qIHJlc2VydmVkID0gMCAqLwoJCU5VTEwsCQkvKiBscHN6Q2xhc3M/IEZJWE1FOiA/ICovCgkJUkVHX09QVElPTl9OT05fVk9MQVRJTEUsCS8qIG9wdGlvbnMgKi8KCQlLRVlfQUxMX0FDQ0VTUywJLyogZGVzaXJlZCBhY2Nlc3MgYXR0cmlicyAqLwoJCU5VTEwsCQkvKiBscHNlY3VyaXR5IGF0dHJpYnV0ZXMgKi8KCQlyZXRrZXksCQkvKiBscHJldGtleSAqLwoJCSZqdW5rCQkvKiBkaXNwb3NpdGlvbiB2YWx1ZSAqLwoJKTsKCXJldHVybglyZXQ7Cn0KCi8qIFJlZ0NyZWF0ZUtleUV4QQkJW0FEVkFQSTMyLjEzMF0gKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleUV4MzJBKAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglEV09SRAlkd1Jlc2VydmVkLAoJTFBTVFIJbHBzekNsYXNzLAoJRFdPUkQJZmR3T3B0aW9ucywKCVJFR1NBTQlzYW1EZXNpcmVkLAoJTFBTRUNVUklUWV9BVFRSSUJVVEVTIGxwU2VjQXR0cmlicywKCUxQSEtFWQlyZXRrZXksCglMUERXT1JECWxwRGlzcG9zCikgewoJTFBXU1RSCWxwc3pTdWJLZXlXLGxwc3pDbGFzc1c7CglEV09SRAlyZXQ7CgoJVFJBQ0UocmVnLCIoJWx4LCVzLCVsZCwlcywlbHgsJWx4LCVwLCVwLCVwKVxuIiwKCQkoTE9ORyloa2V5LAoJCWxwc3pTdWJLZXksCgkJZHdSZXNlcnZlZCwKCQlscHN6Q2xhc3MsCgkJZmR3T3B0aW9ucywKCQlzYW1EZXNpcmVkLAoJCWxwU2VjQXR0cmlicywKCQlyZXRrZXksCgkJbHBEaXNwb3MKCSk7CglpZiAobHBzelN1YktleSkKCQlscHN6U3ViS2V5Vz1zdHJkdXBBMlcobHBzelN1YktleSk7CgllbHNlCgkJbHBzelN1YktleVc9TlVMTDsKCWlmIChscHN6Q2xhc3MpCgkJbHBzekNsYXNzVz1zdHJkdXBBMlcobHBzekNsYXNzKTsKCWVsc2UKCQlscHN6Q2xhc3NXPU5VTEw7CglyZXQ9UmVnQ3JlYXRlS2V5RXgzMlcoCgkJaGtleSwKCQlscHN6U3ViS2V5VywKCQlkd1Jlc2VydmVkLAoJCWxwc3pDbGFzc1csCgkJZmR3T3B0aW9ucywKCQlzYW1EZXNpcmVkLAoJCWxwU2VjQXR0cmlicywKCQlyZXRrZXksCgkJbHBEaXNwb3MKCSk7CglpZiAobHBzelN1YktleVcpCgkJZnJlZShscHN6U3ViS2V5Vyk7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnQ3JlYXRlS2V5QQkJW0FEVkFQSTMyLjEyOV0gKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTMyQSgKCUhLRVkJaGtleSwKCUxQQ1NUUglscHN6U3ViS2V5LAoJTFBIS0VZCXJldGtleQopIHsKCURXT1JECWp1bms7CgoJVFJBQ0UocmVnLCIoJWx4LCVzLCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXkscmV0a2V5CgkpOwoJcmV0dXJuCVJlZ0NyZWF0ZUtleUV4MzJBKAoJCWhrZXksCQkvKiBrZXkgaGFuZGxlICovCgkJbHBzelN1YktleSwJLyogc3Via2V5IG5hbWUgKi8KCQkwLAkJLyogcmVzZXJ2ZWQgPSAwICovCgkJTlVMTCwJCS8qIGxwc3pDbGFzcz8gRklYTUU6ID8gKi8KCQlSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwvKiBvcHRpb25zICovCgkJS0VZX0FMTF9BQ0NFU1MsCS8qIGRlc2lyZWQgYWNjZXNzIGF0dHJpYnMgKi8KCQlOVUxMLAkJLyogbHBzZWN1cml0eSBhdHRyaWJ1dGVzICovCgkJcmV0a2V5LAkJLyogbHByZXRrZXkgKi8KCQkmanVuawkJLyogZGlzcG9zaXRpb24gdmFsdWUgKi8KCSk7Cn0KCi8qIFJlZ0NyZWF0ZUtleQkJCVtTSEVMTC4yXSBbS0VSTkVMLjIxOF0gKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTE2KAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJVFJBQ0UocmVnLCIoJWx4LCVzLCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXkscmV0a2V5CgkpOwoJcmV0dXJuIFJlZ0NyZWF0ZUtleTMyQShoa2V5LGxwc3pTdWJLZXkscmV0a2V5KTsKfQoKLyogCiAqIFF1ZXJ5IFZhbHVlIEZ1bmN0aW9ucwogKiBXaW4zMiBkaWZmZXJzIGJldHdlZW4ga2V5bmFtZXMgYW5kIHZhbHVlbmFtZXMuIAogKiBtdWx0aXBsZSB2YWx1ZXMgbWF5IGJlbG9uZyB0byBvbmUga2V5LCB0aGUgc3BlY2lhbCB2YWx1ZQogKiB3aXRoIG5hbWUgTlVMTCBpcyB0aGUgZGVmYXVsdCB2YWx1ZSB1c2VkIGJ5IHRoZSB3aW4zMQogKiBjb21wYXQgZnVuY3Rpb25zLgogKgogKiBDYWxscGF0aDoKICogUmVnUXVlcnlWYWx1ZTE2IC0+IFJlZ1F1ZXJ5VmFsdWUzMkEgLT4gUmVnUXVlcnlWYWx1ZUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdRdWVyeVZhbHVlMzJXIC0+IFJlZ1F1ZXJ5VmFsdWVFeDMyVwogKi8KCi8qIFJlZ1F1ZXJ5VmFsdWVFeFcJCVtBRFZBUEkzMi4xNThdICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXgzMlcoCglIS0VZCWhrZXksCglMUFdTVFIJbHBzelZhbHVlTmFtZSwKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJaW50CQlpOwoKCVRSQUNFKHJlZywiKCV4LCVzLCVwLCVwLCVwLCVsZClcbiIsCgkJICAgICBoa2V5LFcyQyhscHN6VmFsdWVOYW1lLDApLGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLAoJCSAgICAgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKCWxwa2V5CT0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CglpZiAobHBzelZhbHVlTmFtZSAmJiAhKmxwc3pWYWx1ZU5hbWUpCgkJbHBzelZhbHVlTmFtZSA9IE5VTEw7CglpZiAobHBzelZhbHVlTmFtZT09TlVMTCkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXBpMzJXKGxwc3pWYWx1ZU5hbWUsbHBrZXktPnZhbHVlc1tpXS5uYW1lKQoJCQkpCgkJCQlicmVhazsKCX0KCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewoJCWlmIChscHN6VmFsdWVOYW1lPT1OVUxMKSB7CgkJCWlmIChscGJEYXRhKSB7CgkJCQkqKFdDSEFSKilscGJEYXRhID0gMDsKCQkJCSpscGNiRGF0YQk9IDI7CgkJCX0KCQkJaWYgKGxwZHdUeXBlKQoJCQkJKmxwZHdUeXBlCT0gUkVHX1NaOwoJCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCQl9CgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsvKkZJWE1FOiBjb3JyZWN0IHJldHVybj8gKi8KCX0KCWlmIChscGR3VHlwZSkKCQkqbHBkd1R5cGUJPSBscGtleS0+dmFsdWVzW2ldLnR5cGU7CglpZiAobHBiRGF0YT09TlVMTCkgewoJCWlmIChscGNiRGF0YT09TlVMTCkKCQkJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7CgkJKmxwY2JEYXRhCT0gbHBrZXktPnZhbHVlc1tpXS5sZW47CgkJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cgl9CglpZiAoKmxwY2JEYXRhPGxwa2V5LT52YWx1ZXNbaV0ubGVuKSB7CgkJKihXQ0hBUiopbHBiRGF0YT0gMDsKCQkqbHBjYkRhdGEJPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJfQoJbWVtY3B5KGxwYkRhdGEsbHBrZXktPnZhbHVlc1tpXS5kYXRhLGxwa2V5LT52YWx1ZXNbaV0ubGVuKTsKCSpscGNiRGF0YQk9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ1F1ZXJ5VmFsdWVXCQlbQURWQVBJMzIuMTU5XSAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZTMyVygKCUhLRVkJaGtleSwKCUxQV1NUUglscHN6U3ViS2V5LAoJTFBXU1RSCWxwc3pEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQsbHBkd1R5cGU7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJXAsJWxkKVxuIiwKCQkgICAgIGhrZXksVzJDKGxwc3pTdWJLZXksMCksbHBzekRhdGEsCgkJICAgICBscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgoJLyogb25seSBvcGVuIHN1YmtleSwgaWYgd2UgcmVhbGx5IGRvIGRlc2NlbmQgKi8KCWlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CgkJcmV0CT0gUmVnT3BlbktleTMyVyhoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXkJPSBoa2V5OwoKCWxwZHdUeXBlCT0gUkVHX1NaOwoJcmV0CT0gUmVnUXVlcnlWYWx1ZUV4MzJXKAoJCXhoa2V5LAoJCU5VTEwsCQkvKiB2YXJuYW1lIE5VTEwgLT4gY29tcGF0ICovCgkJTlVMTCwJCS8qIGxwZHdSZXNlcnZlZCwgbXVzdCBiZSBOVUxMICovCgkJJmxwZHdUeXBlLAoJCShMUEJZVEUpbHBzekRhdGEsCgkJbHBjYkRhdGEKCSk7CglpZiAoeGhrZXkhPWhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnUXVlcnlWYWx1ZUV4QQkJW0FEVkFQSTMyLjE1N10gKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCUhLRVkJaGtleSwKCUxQU1RSCWxwc3pWYWx1ZU5hbWUsCglMUERXT1JECWxwZHdSZXNlcnZlZCwKCUxQRFdPUkQJbHBkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglMUFdTVFIJbHBzelZhbHVlTmFtZVc7CglMUEJZVEUJYnVmOwoJRFdPUkQJcmV0LG15eGxlbjsKCURXT1JECSpteWxlbjsKCURXT1JECXR5cGU7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIiwKCQkgICAgIGhrZXksbHBzelZhbHVlTmFtZSxscGR3UmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSwKCQkgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCglpZiAobHBzelZhbHVlTmFtZSkKCQlscHN6VmFsdWVOYW1lVz1zdHJkdXBBMlcobHBzelZhbHVlTmFtZSk7CgllbHNlIAoJCWxwc3pWYWx1ZU5hbWVXPU5VTEw7CgoJaWYgKGxwZHdUeXBlKQoJCXR5cGU9KmxwZHdUeXBlOwoKCWlmIChscGJEYXRhKSB7CgkJbXl4bGVuICA9IDA7CgkJbXlsZW4JPSAmbXl4bGVuOwoJCWJ1Zgk9IHhtYWxsb2MoNCk7CgkJcmV0PVJlZ1F1ZXJ5VmFsdWVFeDMyVygKCQkJaGtleSwKCQkJbHBzelZhbHVlTmFtZVcsCgkJCWxwZHdSZXNlcnZlZCwKCQkJJnR5cGUsCgkJCWJ1ZiwKCQkJbXlsZW4KCQkpOwoJCWZyZWUoYnVmKTsKCQlpZiAocmV0PT1FUlJPUl9NT1JFX0RBVEEpIHsKCQkJYnVmCT0gKExQQllURSl4bWFsbG9jKCpteWxlbik7CgkJfSBlbHNlIHsKCQkJYnVmCT0gKExQQllURSl4bWFsbG9jKDIqKCpscGNiRGF0YSkpOwoJCQlteXhsZW4gID0gMiooKmxwY2JEYXRhKTsKCQl9Cgl9IGVsc2UgewoJCWJ1Zj1OVUxMOwoJCWlmIChscGNiRGF0YSkgewoJCQlteXhsZW4JPSAqbHBjYkRhdGEqMjsKCQkJbXlsZW4JPSAmbXl4bGVuOwoJCX0gZWxzZQoJCQlteWxlbgk9IE5VTEw7Cgl9CglyZXQ9UmVnUXVlcnlWYWx1ZUV4MzJXKAoJCWhrZXksCgkJbHBzelZhbHVlTmFtZVcsCgkJbHBkd1Jlc2VydmVkLAoJCSZ0eXBlLAoJCWJ1ZiwKCQlteWxlbgoJKTsKCWlmIChscGR3VHlwZSkgCgkJKmxwZHdUeXBlPXR5cGU7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJaWYgKGJ1ZikgewoJCQlpZiAoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgewoJCQkJLyogY29udmVydCBVTklDT0RFIHRvIEFTQ0lJICovCgkJCQlsc3RyY3B5V3RvQShscGJEYXRhLChMUFdTVFIpYnVmKTsKCQkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJCQl9IGVsc2UgewoJCQkJaWYgKG15eGxlbj4qbHBjYkRhdGEpCgkJCQkJcmV0CT0gRVJST1JfTU9SRV9EQVRBOwoJCQkJZWxzZQoJCQkJCW1lbWNweShscGJEYXRhLGJ1ZixteXhsZW4pOwoKCQkJCSpscGNiRGF0YQk9IG15eGxlbjsKCQkJfQoJCX0gZWxzZSB7CgkJCWlmICgoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgJiYgbHBjYkRhdGEpCgkJCQkqbHBjYkRhdGEJPSBteXhsZW4vMjsKCQl9Cgl9IGVsc2UgewoJCWlmICgoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgJiYgbHBjYkRhdGEpCgkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJfQoJaWYgKGJ1ZikKCQlmcmVlKGJ1Zik7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdRdWVyeVZhbHVlRXgJCVtLRVJORUwuMjI1XSAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MTYoCglIS0VZCWhrZXksCglMUFNUUglscHN6VmFsdWVOYW1lLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUERXT1JECWxwZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJVFJBQ0UocmVnLCIoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIiwKCQkgICAgIGhrZXksbHBzelZhbHVlTmFtZSxscGR3UmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSwKCQkgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCglyZXR1cm4gUmVnUXVlcnlWYWx1ZUV4MzJBKAoJCWhrZXksCgkJbHBzelZhbHVlTmFtZSwKCQlscGR3UmVzZXJ2ZWQsCgkJbHBkd1R5cGUsCgkJbHBiRGF0YSwKCQlscGNiRGF0YQoJKTsKfQoKLyogUmVnUXVlcnlWYWx1ZUEJCVtBRFZBUEkzMi4xNTZdICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMzJBKAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelN1YktleSwKCUxQU1RSCWxwc3pEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQsbHBkd1R5cGU7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJXAsJWxkKVxuIiwKCQkgICAgIGhrZXksbHBzelN1YktleSxscHN6RGF0YSwKCQkgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCgkvKiBvbmx5IG9wZW4gc3Via2V5LCBpZiB3ZSByZWFsbHkgZG8gZGVzY2VuZCAqLwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQJPSBSZWdPcGVuS2V5MTYoaGtleSxscHN6U3ViS2V5LCZ4aGtleSk7CgkJaWYgKHJldCE9RVJST1JfU1VDQ0VTUykKCQkJcmV0dXJuIHJldDsKCX0gZWxzZQoJCXhoa2V5CT0gaGtleTsKCglscGR3VHlwZQk9IFJFR19TWjsKCXJldAk9IFJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQl4aGtleSwKCQlOVUxMLAkJLyogbHBzelZhbHVlTmFtZSBOVUxMIC0+IGNvbXBhdCAqLwoJCU5VTEwsCQkvKiBscGR3UmVzZXJ2ZWQsIG11c3QgYmUgTlVMTCAqLwoJCSZscGR3VHlwZSwKCQkoTFBCWVRFKWxwc3pEYXRhLAoJCWxwY2JEYXRhCgkpOwoJaWYgKHhoa2V5IT1oa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCi8qIFJlZ1F1ZXJ5VmFsdWUJCVtTSEVMTC42XSBbS0VSTkVMLjIyNF0gKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUxNigKCUhLRVkJaGtleSwKCUxQU1RSCWxwc3pTdWJLZXksCglMUFNUUglscHN6RGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglUUkFDRShyZWcsIigleCwlcywlcCwlbGQpXG4iLAoJCSAgICAgaGtleSxscHN6U3ViS2V5LGxwc3pEYXRhLGxwY2JEYXRhPypscGNiRGF0YTowKTsKCgkvKiBIQUNLOiB0aGUgMTZiaXQgUmVnUXVlcnlWYWx1ZSBkb2Vzbid0IGhhbmRsZSBzZWxlY3RvcmJsb2NrcwoJICogICAgICAgYW55d2F5LCBzbyB3ZSBqdXN0IG1hc2sgb3V0IHRoZSBoaWdoIDE2IGJpdC4KCSAqICAgICAgICh0aGlzIChub3Qgc28gbXVjaCBpbmNpZGVudGx5OykgaG9wZWZ1bGx5IGZpeGVzIEFsZHVzIEZINCkKCSAqLwoJaWYgKGxwY2JEYXRhKQoJCSpscGNiRGF0YSAmPSAweEZGRkY7CglyZXR1cm4gUmVnUXVlcnlWYWx1ZTMyQShoa2V5LGxwc3pTdWJLZXksbHBzekRhdGEsbHBjYkRhdGEpOwp9CgovKgogKiBTZXR0aW5nIHZhbHVlcyBvZiBSZWdpc3RyeSBrZXlzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdTZXRWYWx1ZTE2IC0+IFJlZ1NldFZhbHVlMzJBIC0+IFJlZ1NldFZhbHVlRXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1NldFZhbHVlMzJXICAgLT4gUmVnU2V0VmFsdWVFeDMyVwogKi8KCi8qIFJlZ1NldFZhbHVlRXhXCQlbQURWQVBJMzIuMTcwXSAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDMyVygKCUhLRVkJaGtleSwKCUxQV1NUUglscHN6VmFsdWVOYW1lLAoJRFdPUkQJZHdSZXNlcnZlZCwKCURXT1JECWR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJRFdPUkQJY2JEYXRhCikgewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglpbnQJCWk7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLAoJCWhrZXksVzJDKGxwc3pWYWx1ZU5hbWUsMCksZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEKCSk7CgkvKiB3ZSBubyBsb25nZXIgY2FyZSBhYm91dCB0aGUgbHBiRGF0YSB0eXBlIGhlcmUuLi4gKi8KCWxwa2V5CT0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CgoJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCglpZiAobHBzelZhbHVlTmFtZT09TlVMTCkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXBpMzJXKGxwc3pWYWx1ZU5hbWUsbHBrZXktPnZhbHVlc1tpXS5uYW1lKQoJCQkpCgkJCQlicmVhazsKCX0KCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewoJCWxwa2V5LT52YWx1ZXMgPSAoTFBLRVlWQUxVRSl4cmVhbGxvYygKCQkJCQlscGtleS0+dmFsdWVzLAoJCQkJCShscGtleS0+bnJvZnZhbHVlcysxKSpzaXplb2YoS0VZVkFMVUUpCgkJCQkpOwoJCWxwa2V5LT5ucm9mdmFsdWVzKys7CgkJbWVtc2V0KGxwa2V5LT52YWx1ZXMraSwnXDAnLHNpemVvZihLRVlWQUxVRSkpOwoJfQoJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQlpZiAobHBzelZhbHVlTmFtZSkKCQkJbHBrZXktPnZhbHVlc1tpXS5uYW1lID0gc3RyZHVwVyhscHN6VmFsdWVOYW1lKTsKCQllbHNlCgkJCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSA9IE5VTEw7CglscGtleS0+dmFsdWVzW2ldLmxlbgk9IGNiRGF0YTsKCWxwa2V5LT52YWx1ZXNbaV0udHlwZQk9IGR3VHlwZTsKCWlmIChscGtleS0+dmFsdWVzW2ldLmRhdGEgIT1OVUxMKQoJCWZyZWUobHBrZXktPnZhbHVlc1tpXS5kYXRhKTsKCWxwa2V5LT52YWx1ZXNbaV0uZGF0YQk9IChMUEJZVEUpeG1hbGxvYyhjYkRhdGEpOwoJbHBrZXktPnZhbHVlc1tpXS5sYXN0bW9kaWZpZWQgPSB0aW1lKE5VTEwpOwoJbWVtY3B5KGxwa2V5LT52YWx1ZXNbaV0uZGF0YSxscGJEYXRhLGNiRGF0YSk7CglyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKfQoKLyogUmVnU2V0VmFsdWVFeEEJCVtBRFZBUEkzMi4xNjldICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MzJBKAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelZhbHVlTmFtZSwKCURXT1JECWR3UmVzZXJ2ZWQsCglEV09SRAlkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCURXT1JECWNiRGF0YQopIHsKCUxQQllURQlidWY7CglMUFdTVFIJbHBzelZhbHVlTmFtZVc7CglEV09SRAlyZXQ7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLAoJCWhrZXksbHBzelZhbHVlTmFtZSxkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YQoJKTsKCWlmICgoMTw8ZHdUeXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJYnVmPShMUEJZVEUpc3RyZHVwQTJXKGxwYkRhdGEpOwoJCWNiRGF0YT0yKnN0cmxlbihscGJEYXRhKSsyOwoJfSBlbHNlCgkJYnVmPWxwYkRhdGE7CglpZiAobHBzelZhbHVlTmFtZSkKCQlscHN6VmFsdWVOYW1lVyA9IHN0cmR1cEEyVyhscHN6VmFsdWVOYW1lKTsKCWVsc2UKCQlscHN6VmFsdWVOYW1lVyA9IE5VTEw7CglyZXQ9UmVnU2V0VmFsdWVFeDMyVyhoa2V5LGxwc3pWYWx1ZU5hbWVXLGR3UmVzZXJ2ZWQsZHdUeXBlLGJ1ZixjYkRhdGEpOwoJaWYgKGxwc3pWYWx1ZU5hbWVXKQoJCWZyZWUobHBzelZhbHVlTmFtZVcpOwoJaWYgKGJ1ZiE9bHBiRGF0YSkKCQlmcmVlKGJ1Zik7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdTZXRWYWx1ZUV4CQlbS0VSTkVMLjIyNl0gKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXgxNigKCUhLRVkJaGtleSwKCUxQU1RSCWxwc3pWYWx1ZU5hbWUsCglEV09SRAlkd1Jlc2VydmVkLAoJRFdPUkQJZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglEV09SRAljYkRhdGEKKSB7CglUUkFDRShyZWcsIigleCwlcywlbGQsJWxkLCVwLCVsZClcbiIsCgkJaGtleSxscHN6VmFsdWVOYW1lLGR3UmVzZXJ2ZWQsZHdUeXBlLGxwYkRhdGEsY2JEYXRhCgkpOwoJcmV0dXJuIFJlZ1NldFZhbHVlRXgzMkEoaGtleSxscHN6VmFsdWVOYW1lLGR3UmVzZXJ2ZWQsZHdUeXBlLGxwYkRhdGEsY2JEYXRhKTsKfQoKLyogUmVnU2V0VmFsdWVXCQkJW0FEVkFQSTMyLjE3MV0gKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMzJXKAoJSEtFWQloa2V5LAoJTFBDV1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdUeXBlLAoJTFBDV1NUUglscHN6RGF0YSwKCURXT1JECWNiRGF0YQopIHsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQ7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsCgkJaGtleSxXMkMobHBzelN1YktleSwwKSxkd1R5cGUsVzJDKGxwc3pEYXRhLDApLGNiRGF0YQoJKTsKCWlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CgkJcmV0PVJlZ0NyZWF0ZUtleTMyVyhoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXk9aGtleTsKCWlmIChkd1R5cGUhPVJFR19TWikgewoJCVRSQUNFKHJlZywiUmVnU2V0VmFsdWVYIGNhbGxlZCB3aXRoIGR3VHlwZT0lbGQhXG4iLGR3VHlwZSk7CgkJZHdUeXBlPVJFR19TWjsKCX0KCWlmIChjYkRhdGEhPTIqbHN0cmxlbjMyVyhscHN6RGF0YSkrMikgewoJCVRSQUNFKHJlZywiUmVnU2V0VmFsdWVYIGNhbGxlZCB3aXRoIGxlbj0lbGQgIT0gc3RybGVuKCVzKSsxPSVkIVxuIiwKCQkJY2JEYXRhLFcyQyhscHN6RGF0YSwwKSwyKmxzdHJsZW4zMlcobHBzekRhdGEpKzIKCQkpOwoJCWNiRGF0YT0yKmxzdHJsZW4zMlcobHBzekRhdGEpKzI7Cgl9CglyZXQ9UmVnU2V0VmFsdWVFeDMyVyh4aGtleSxOVUxMLDAsZHdUeXBlLChMUEJZVEUpbHBzekRhdGEsY2JEYXRhKTsKCWlmIChoa2V5IT14aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0OwoKfQovKiBSZWdTZXRWYWx1ZUEJCQlbQURWQVBJMzIuMTY4XSAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUzMkEoCglIS0VZCWhrZXksCglMUENTVFIJbHBzelN1YktleSwKCURXT1JECWR3VHlwZSwKCUxQQ1NUUglscHN6RGF0YSwKCURXT1JECWNiRGF0YQopIHsKCURXT1JECXJldDsKCUhLRVkJeGhrZXk7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsCgkJaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEKCSk7CglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldD1SZWdDcmVhdGVLZXkxNihoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXk9aGtleTsKCglpZiAoZHdUeXBlIT1SRUdfU1opIHsKCQlUUkFDRShyZWcsIlJlZ1NldFZhbHVlQSBjYWxsZWQgd2l0aCBkd1R5cGU9JWxkIVxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT1zdHJsZW4obHBzekRhdGEpKzEpCgkJY2JEYXRhPXN0cmxlbihscHN6RGF0YSkrMTsKCXJldD1SZWdTZXRWYWx1ZUV4MzJBKHhoa2V5LE5VTEwsMCxkd1R5cGUsKExQQllURSlscHN6RGF0YSxjYkRhdGEpOwoJaWYgKHhoa2V5IT1oa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCi8qIFJlZ1NldFZhbHVlCQkJW0tFUk5FTC4yMjFdIFtTSEVMTC41XSAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUxNigKCUhLRVkJaGtleSwKCUxQQ1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdUeXBlLAoJTFBDU1RSCWxwc3pEYXRhLAoJRFdPUkQJY2JEYXRhCikgewoJRFdPUkQJcmV0OwoJVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsCgkJaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEKCSk7CglyZXQ9UmVnU2V0VmFsdWUzMkEoaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEpOwoJcmV0dXJuIHJldDsKfQoKLyogCiAqIEtleSBFbnVtZXJhdGlvbgogKgogKiBDYWxscGF0aDoKICogUmVnRW51bUtleTE2IC0+IFJlZ0VudW1LZXkzMkEgLT4gUmVnRW51bUtleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdFbnVtS2V5MzJXICAgLT4gUmVnRW51bUtleUV4MzJXCiAqLwoKLyogUmVnRW51bUtleUV4VwkJW0FEVkFQSTMyLjEzOV0gKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlFeDMyVygKCUhLRVkJaGtleSwKCURXT1JECWlTdWJrZXksCglMUFdTVFIJbHBzek5hbWUsCglMUERXT1JECWxwY2NoTmFtZSwKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBXU1RSCWxwc3pDbGFzcywKCUxQRFdPUkQJbHBjY2hDbGFzcywKCUZJTEVUSU1FCSpmdAopIHsKCUxQS0VZU1RSVUNUCWxwa2V5LGxweGtleTsKCglUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlTdWJrZXksbHBzek5hbWUsKmxwY2NoTmFtZSxscGR3UmVzZXJ2ZWQsbHBzekNsYXNzLGxwY2NoQ2xhc3MsZnQKCSk7CglscGtleT1sb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCWlmICghbHBrZXktPm5leHRzdWIpCgkJcmV0dXJuIEVSUk9SX05PX01PUkVfSVRFTVM7CglscHhrZXk9bHBrZXktPm5leHRzdWI7Cgl3aGlsZSAoaVN1YmtleSAmJiBscHhrZXkpIHsKCQlpU3Via2V5LS07CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCWlmIChpU3Via2V5IHx8ICFscHhrZXkpCgkJcmV0dXJuIEVSUk9SX05PX01PUkVfSVRFTVM7CglpZiAoMipsc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSkrMj4qbHBjY2hOYW1lKQoJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgltZW1jcHkobHBzek5hbWUsbHB4a2V5LT5rZXluYW1lLGxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKSoyKzIpOwoJaWYgKGxwc3pDbGFzcykgewoJCS8qIHdoYXQgc2hvdWxkIHdlIHdyaXRlIGludG8gaXQ/ICovCgkJKmxwc3pDbGFzcwk9IDA7CgkJKmxwY2NoQ2xhc3MJPSAyOwoJfQoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgp9CgovKiBSZWdFbnVtS2V5VwkJCVtBRFZBUEkzMi4xNDBdICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MzJXKAoJSEtFWQloa2V5LAoJRFdPUkQJaVN1YmtleSwKCUxQV1NUUglscHN6TmFtZSwKCURXT1JECWxwY2NoTmFtZQopIHsKCUZJTEVUSU1FCWZ0OwoKCVRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLAoJCWhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUKCSk7CglyZXR1cm4gUmVnRW51bUtleUV4MzJXKGhrZXksaVN1YmtleSxscHN6TmFtZSwmbHBjY2hOYW1lLE5VTEwsTlVMTCxOVUxMLCZmdCk7Cn0KLyogUmVnRW51bUtleUV4QQkJW0FEVkFQSTMyLjEzOF0gKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlFeDMyQSgKCUhLRVkJaGtleSwKCURXT1JECWlTdWJrZXksCglMUFNUUglscHN6TmFtZSwKCUxQRFdPUkQJbHBjY2hOYW1lLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUFNUUglscHN6Q2xhc3MsCglMUERXT1JECWxwY2NoQ2xhc3MsCglGSUxFVElNRQkqZnQKKSB7CglEV09SRAlyZXQsbHBjY2hOYW1lVyxscGNjaENsYXNzVzsKCUxQV1NUUglscHN6TmFtZVcsbHBzekNsYXNzVzsKCgoJVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZCwlcCwlcCwlcCwlcClcbiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLCpscGNjaE5hbWUsbHBkd1Jlc2VydmVkLGxwc3pDbGFzcyxscGNjaENsYXNzLGZ0CgkpOwoJaWYgKGxwc3pOYW1lKSB7CgkJbHBzek5hbWVXCT0gKExQV1NUUil4bWFsbG9jKCpscGNjaE5hbWUqMik7CgkJbHBjY2hOYW1lVwk9ICpscGNjaE5hbWUqMjsKCX0gZWxzZSB7CgkJbHBzek5hbWVXCT0gTlVMTDsKCQlscGNjaE5hbWVXIAk9IDA7Cgl9CglpZiAobHBzekNsYXNzKSB7CgkJbHBzekNsYXNzVwkJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoQ2xhc3MqMik7CgkJbHBjY2hDbGFzc1cJPSAqbHBjY2hDbGFzcyoyOwoJfSBlbHNlIHsKCQlscHN6Q2xhc3NXCT0wOwoJCWxwY2NoQ2xhc3NXPTA7Cgl9CglyZXQ9UmVnRW51bUtleUV4MzJXKAoJCWhrZXksCgkJaVN1YmtleSwKCQlscHN6TmFtZVcsCgkJJmxwY2NoTmFtZVcsCgkJbHBkd1Jlc2VydmVkLAoJCWxwc3pDbGFzc1csCgkJJmxwY2NoQ2xhc3NXLAoJCWZ0CgkpOwoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCWxzdHJjcHlXdG9BKGxwc3pOYW1lLGxwc3pOYW1lVyk7CgkJKmxwY2NoTmFtZT1zdHJsZW4obHBzek5hbWUpOwoJCWlmIChscHN6Q2xhc3NXKSB7CgkJCWxzdHJjcHlXdG9BKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCQkJKmxwY2NoQ2xhc3M9c3RybGVuKGxwc3pDbGFzcyk7CgkJfQoJfQoJaWYgKGxwc3pOYW1lVykKCQlmcmVlKGxwc3pOYW1lVyk7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnRW51bUtleUEJCQlbQURWQVBJMzIuMTM3XSAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTMyQSgKCUhLRVkJaGtleSwKCURXT1JECWlTdWJrZXksCglMUFNUUglscHN6TmFtZSwKCURXT1JECWxwY2NoTmFtZQopIHsKCUZJTEVUSU1FCWZ0OwoKCVRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLAoJCWhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUKCSk7CglyZXR1cm4JUmVnRW51bUtleUV4MzJBKAoJCWhrZXksCgkJaVN1YmtleSwKCQlscHN6TmFtZSwKCQkmbHBjY2hOYW1lLAoJCU5VTEwsCgkJTlVMTCwKCQlOVUxMLAoJCSZmdAoJKTsKfQoKLyogUmVnRW51bUtleQkJCVtTSEVMTC43XSBbS0VSTkVMLjIxNl0gKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXkxNigKCUhLRVkJaGtleSwKCURXT1JECWlTdWJrZXksCglMUFNUUglscHN6TmFtZSwKCURXT1JECWxwY2NoTmFtZQopIHsKCVRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLAoJCWhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUKCSk7CglyZXR1cm4gUmVnRW51bUtleTMyQShoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKfQoKLyogCiAqIEVudW1lcmF0ZSBSZWdpc3RyeSBWYWx1ZXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0VudW1WYWx1ZTE2IC0+IFJlZ0VudW1WYWx1ZTMyQSAtPiBSZWdFbnVtVmFsdWUzMlcKICovCgovKiBSZWdFbnVtVmFsdWVXCQlbQURWQVBJMzIuMTQyXSAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMzJXKAoJSEtFWQloa2V5LAoJRFdPUkQJaVZhbHVlLAoJTFBXU1RSCWxwc3pWYWx1ZSwKCUxQRFdPUkQJbHBjY2hWYWx1ZSwKCUxQRFdPUkQJbHBkUmVzZXJ2ZWQsCglMUERXT1JECWxwZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglMUEtFWVZBTFVFCXZhbDsKCglUUkFDRShyZWcsIigleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksaVZhbHVlLGxwc3pWYWx1ZSxscGNjaFZhbHVlLGxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEKCSk7CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscGtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJaWYgKGxwa2V5LT5ucm9mdmFsdWVzPD1pVmFsdWUpCgkJcmV0dXJuIEVSUk9SX05PX01PUkVfSVRFTVM7Cgl2YWwJPSBscGtleS0+dmFsdWVzK2lWYWx1ZTsKCglpZiAodmFsLT5uYW1lKSB7CgkJaWYgKGxzdHJsZW4zMlcodmFsLT5uYW1lKSoyKzI+KmxwY2NoVmFsdWUpIHsKCQkJKmxwY2NoVmFsdWUgPSBsc3RybGVuMzJXKHZhbC0+bmFtZSkqMisyOwoJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCX0KCQltZW1jcHkobHBzelZhbHVlLHZhbC0+bmFtZSwyKmxzdHJsZW4zMlcodmFsLT5uYW1lKSsyKTsKCQkqbHBjY2hWYWx1ZT1sc3RybGVuMzJXKHZhbC0+bmFtZSkqMisyOwoJfSBlbHNlIHsKCQkqbHBzelZhbHVlCT0gMDsKCQkqbHBjY2hWYWx1ZQk9IDA7Cgl9CglpZiAobHBkd1R5cGUpCgkJKmxwZHdUeXBlPXZhbC0+dHlwZTsKCWlmIChscGJEYXRhKSB7CgkJaWYgKHZhbC0+bGVuPipscGNiRGF0YSkKCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQltZW1jcHkobHBiRGF0YSx2YWwtPmRhdGEsdmFsLT5sZW4pOwoJCSpscGNiRGF0YSA9IHZhbC0+bGVuOwoJfQoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ0VudW1WYWx1ZUEJCVtBRFZBUEkzMi4xNDFdICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUzMkEoCglIS0VZCWhrZXksCglEV09SRAlpVmFsdWUsCglMUFNUUglscHN6VmFsdWUsCglMUERXT1JECWxwY2NoVmFsdWUsCglMUERXT1JECWxwZFJlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUxQV1NUUglscHN6VmFsdWVXOwoJTFBCWVRFCWxwYkRhdGFXOwoJRFdPUkQJcmV0LGxwY2JEYXRhVzsKCglUUkFDRShyZWcsIigleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksaVZhbHVlLGxwc3pWYWx1ZSxscGNjaFZhbHVlLGxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEKCSk7CgoJbHBzelZhbHVlVyA9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hWYWx1ZSoyKTsKCWlmIChscGJEYXRhKSB7CgkJbHBiRGF0YVcgPSAoTFBCWVRFKXhtYWxsb2MoKmxwY2JEYXRhKjIpOwoJCWxwY2JEYXRhVyA9ICpscGNiRGF0YSoyOwoJfSBlbHNlCgkJbHBiRGF0YVcgPSBOVUxMOwoJcmV0PVJlZ0VudW1WYWx1ZTMyVygKCQloa2V5LAoJCWlWYWx1ZSwKCQlscHN6VmFsdWVXLAoJCWxwY2NoVmFsdWUsCgkJbHBkUmVzZXJ2ZWQsCgkJbHBkd1R5cGUsCgkJbHBiRGF0YVcsCgkJJmxwY2JEYXRhVwoJKTsKCglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJbHN0cmNweVd0b0EobHBzelZhbHVlLGxwc3pWYWx1ZVcpOwoJCWlmIChscGJEYXRhKSB7CgkJCWlmICgoMTw8KmxwZHdUeXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJCQlsc3RyY3B5V3RvQShscGJEYXRhLChMUFdTVFIpbHBiRGF0YVcpOwoJCQl9IGVsc2UgewoJCQkJaWYgKGxwY2JEYXRhVyA+ICpscGNiRGF0YSkKCQkJCQlyZXQJPSBFUlJPUl9NT1JFX0RBVEE7CgkJCQllbHNlCgkJCQkJbWVtY3B5KGxwYkRhdGEsbHBiRGF0YVcsbHBjYkRhdGFXKTsKCQkJfQoJCQkqbHBjYkRhdGEgPSBscGNiRGF0YVc7CgkJfQoJfQoJaWYgKGxwYkRhdGFXKQoJCWZyZWUobHBiRGF0YVcpOwoJaWYgKGxwc3pWYWx1ZVcpCgkJZnJlZShscHN6VmFsdWVXKTsKCXJldHVybiByZXQ7Cn0KCi8qIFJlZ0VudW1WYWx1ZQkJCVtLRVJORUwuMjIzXSAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMTYoCglIS0VZCWhrZXksCglEV09SRAlpVmFsdWUsCglMUFNUUglscHN6VmFsdWUsCglMUERXT1JECWxwY2NoVmFsdWUsCglMUERXT1JECWxwZFJlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCVRSQUNFKHJlZywiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsCgkJaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YQoJKTsKCXJldHVybiBSZWdFbnVtVmFsdWUzMkEoCgkJaGtleSwKCQlpVmFsdWUsCgkJbHBzelZhbHVlLAoJCWxwY2NoVmFsdWUsCgkJbHBkUmVzZXJ2ZWQsCgkJbHBkd1R5cGUsCgkJbHBiRGF0YSwKCQlscGNiRGF0YQoJKTsKfQoKLyogCiAqICBDbG9zZSByZWdpc3RyeSBrZXkKICovCi8qIFJlZ0Nsb3NlS2V5CQkJW1NIRUxMLjNdIFtLRVJORUwuMjIwXSBbQURWQVBJMzIuMTI2XSAqLwpEV09SRCBXSU5BUEkgUmVnQ2xvc2VLZXkoSEtFWSBoa2V5KSB7CglUUkFDRShyZWcsIigleClcbiIsaGtleSk7CglyZW1vdmVfaGFuZGxlKGhrZXkpOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KLyogCiAqIERlbGV0ZSByZWdpc3RyeSBrZXkKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZUtleTE2IC0+IFJlZ0RlbGV0ZUtleTMyQSAtPiBSZWdEZWxldGVLZXkzMlcKICovCi8qIFJlZ0RlbGV0ZUtleVcJCVtBRFZBUEkzMi4xMzRdICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkzMlcoSEtFWSBoa2V5LExQV1NUUiBscHN6U3ViS2V5KSB7CglMUEtFWVNUUlVDVAkqbHBscFByZXZLZXksbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgoJVFJBQ0UocmVnLCIoJXgsJXMpXG4iLAoJCWhrZXksVzJDKGxwc3pTdWJLZXksMCkKCSk7CglscE5leHRLZXkJPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBOZXh0S2V5KSB7CgkJVFJBQ0UocmVnLCAiICBCYWRrZXlbMV0uXG4iKTsKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJfQoJLyogd2UgbmVlZCB0byBrbm93IHRoZSBwcmV2aW91cyBrZXkgaW4gdGhlIGhpZXIuICovCglpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KSB7CgkJVFJBQ0UocmVnLCAiICBCYWRrZXlbMl0uXG4iKTsKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJfQoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7CglscHhrZXkJPSBscE5leHRLZXk7Cgl3aGlsZSAoaTx3cGMtMSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlUUkFDRShyZWcsICIgIFNjYW5uaW5nIFslc11cbiIsCgkJCQkgICAgIFcyQyAobHB4a2V5LT5rZXluYW1lLCAwKSk7CgkJCWlmICghbHN0cmNtcGkzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCQlicmVhazsKCQkJbHB4a2V5PWxweGtleS0+bmV4dDsKCQl9CgkJaWYgKCFscHhrZXkpIHsKCQkJRlJFRV9LRVlfUEFUSDsKCQkJVFJBQ0UocmVnLCAiICBOb3QgZm91bmQuXG4iKTsKCQkJLyogbm90IGZvdW5kIGlzIHN1Y2Nlc3MgKi8KCQkJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7CgkJfQoJCWkrKzsKCQlscE5leHRLZXkJPSBscHhrZXk7Cgl9CglscHhrZXkJPSBscE5leHRLZXktPm5leHRzdWI7CglscGxwUHJldktleSA9ICYobHBOZXh0S2V5LT5uZXh0c3ViKTsKCXdoaWxlIChscHhrZXkpIHsKCQlUUkFDRShyZWcsICIgIFNjYW5uaW5nIFslc11cbiIsCgkJCSAgICAgVzJDIChscHhrZXktPmtleW5hbWUsIDApKTsKCQlpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQlicmVhazsKCQlscGxwUHJldktleQk9ICYobHB4a2V5LT5uZXh0KTsKCQlscHhrZXkJCT0gbHB4a2V5LT5uZXh0OwoJfQoJaWYgKCFscHhrZXkpIHsKCQlGUkVFX0tFWV9QQVRIOwoJCVdBUk4ocmVnICwgIiAgTm90IGZvdW5kLlxuIik7CgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCX0KCWlmIChscHhrZXktPm5leHRzdWIpIHsKCQlGUkVFX0tFWV9QQVRIOwoJCVdBUk4ocmVnICwgIiAgTm90IGVtcHR5LlxuIik7CgkJcmV0dXJuIFNIRUxMX0VSUk9SX0NBTlRXUklURTsKCX0KCSpscGxwUHJldktleQk9IGxweGtleS0+bmV4dDsKCWZyZWUobHB4a2V5LT5rZXluYW1lKTsKCWlmIChscHhrZXktPmNsYXNzKQoJCWZyZWUobHB4a2V5LT5jbGFzcyk7CglpZiAobHB4a2V5LT52YWx1ZXMpCgkJZnJlZShscHhrZXktPnZhbHVlcyk7CglmcmVlKGxweGtleSk7CglGUkVFX0tFWV9QQVRIOwoJVFJBQ0UocmVnLCAiICBEb25lLlxuIik7CglyZXR1cm4JU0hFTExfRVJST1JfU1VDQ0VTUzsKfQoKLyogUmVnRGVsZXRlS2V5QQkJW0FEVkFQSTMyLjEzM10gKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTMyQShIS0VZIGhrZXksTFBDU1RSIGxwc3pTdWJLZXkpIHsKCUxQV1NUUglscHN6U3ViS2V5VzsKCURXT1JECXJldDsKCglUUkFDRShyZWcsIigleCwlcylcbiIsCgkJaGtleSxscHN6U3ViS2V5CgkpOwoJbHBzelN1YktleVc9SEVBUF9zdHJkdXBBdG9XKEdldFByb2Nlc3NIZWFwKCksMCxscHN6U3ViS2V5KTsKCXJldD1SZWdEZWxldGVLZXkzMlcoaGtleSxscHN6U3ViS2V5Vyk7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsbHBzelN1YktleVcpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnRGVsZXRlS2V5CQkJW1NIRUxMLjRdIFtLRVJORUwuMjE5XSAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5MTYoSEtFWSBoa2V5LExQQ1NUUiBscHN6U3ViS2V5KSB7CglUUkFDRShyZWcsIigleCwlcylcbiIsCgkJaGtleSxscHN6U3ViS2V5CgkpOwoJcmV0dXJuIFJlZ0RlbGV0ZUtleTMyQShoa2V5LGxwc3pTdWJLZXkpOwp9CgovKiAKICogRGVsZXRlIHJlZ2lzdHJ5IHZhbHVlCiAqCiAqIENhbGxwYXRoOgogKiBSZWdEZWxldGVWYWx1ZTE2IC0+IFJlZ0RlbGV0ZVZhbHVlMzJBIC0+IFJlZ0RlbGV0ZVZhbHVlMzJXCiAqLwovKiBSZWdEZWxldGVWYWx1ZVcJCVtBRFZBUEkzMi4xMzZdICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTMyVyhIS0VZIGhrZXksTFBXU1RSIGxwc3pWYWx1ZSkKewoJRFdPUkQJCWk7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKCVRSQUNFKHJlZywiKCV4LCVzKVxuIiwKCQloa2V5LFcyQyhscHN6VmFsdWUsMCkKCSk7CglscGtleT1sb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCWlmIChscHN6VmFsdWUpIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKAlscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYKCQkJCSFsc3RyY21waTMyVyhscGtleS0+dmFsdWVzW2ldLm5hbWUsbHBzelZhbHVlKQoJCQkpCgkJCQlicmVhazsKCX0gZWxzZSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCX0KCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOy8qRklYTUU6IGNvcnJlY3QgZXJyb3Jjb2RlPyAqLwoJdmFsCT0gbHBrZXktPnZhbHVlcytpOwoJaWYgKHZhbC0+bmFtZSkgZnJlZSh2YWwtPm5hbWUpOwoJaWYgKHZhbC0+ZGF0YSkgZnJlZSh2YWwtPmRhdGEpOwoJbWVtY3B5KAkKCQlscGtleS0+dmFsdWVzK2ksCgkJbHBrZXktPnZhbHVlcytpKzEsCgkJc2l6ZW9mKEtFWVZBTFVFKSoobHBrZXktPm5yb2Z2YWx1ZXMtaS0xKQoJKTsKCWxwa2V5LT52YWx1ZXMJPSAoTFBLRVlWQUxVRSl4cmVhbGxvYygKCQkJCWxwa2V5LT52YWx1ZXMsCgkJCQkobHBrZXktPm5yb2Z2YWx1ZXMtMSkqc2l6ZW9mKEtFWVZBTFVFKQoJCQkpOwoJbHBrZXktPm5yb2Z2YWx1ZXMtLTsKCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdEZWxldGVWYWx1ZUEJCVtBRFZBUEkzMi4xMzVdICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTMyQShIS0VZIGhrZXksTFBTVFIgbHBzelZhbHVlKQp7CglMUFdTVFIJbHBzelZhbHVlVzsKCURXT1JECXJldDsKCglUUkFDRShyZWcsICIoJXgsJXMpXG4iLCBoa2V5LGxwc3pWYWx1ZSApOwogICAgICAgIGxwc3pWYWx1ZVc9SEVBUF9zdHJkdXBBdG9XKEdldFByb2Nlc3NIZWFwKCksMCxscHN6VmFsdWUpOwoJcmV0PVJlZ0RlbGV0ZVZhbHVlMzJXKGhrZXksbHBzelZhbHVlVyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLGxwc3pWYWx1ZVcpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnRGVsZXRlVmFsdWUJCVtLRVJORUwuMjIyXSAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUxNihIS0VZIGhrZXksTFBTVFIgbHBzelZhbHVlKQp7CglUUkFDRShyZWcsIigleCwlcylcbiIsIGhrZXksbHBzelZhbHVlICk7CglyZXR1cm4gUmVnRGVsZXRlVmFsdWUzMkEoaGtleSxscHN6VmFsdWUpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdGbHVzaEtleSBbS0VSTkVMLjIyN10gW0FEVkFQSTMyLjE0M10KICogV3JpdGVzIGtleSB0byByZWdpc3RyeQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byB3cml0ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0ZsdXNoS2V5KCBIS0VZIGhrZXkgKQp7CiAgICBGSVhNRShyZWcsICIoJXgpOiBzdHViXG4iLCBoa2V5KTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyogRklYTUU6IGxwY2NoWFhYWCAuLi4gaXMgdGhpcyBjb3VudGluZyBpbiBXQ0hBUlMgb3IgaW4gQllURXMgPz8gKi8KCi8qIFJlZ1F1ZXJ5SW5mb0tleVcJCVtBRFZBUEkzMi4xNTNdICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeUluZm9LZXkzMlcoCglIS0VZCWhrZXksCglMUFdTVFIJbHBzekNsYXNzLAoJTFBEV09SRAlscGNjaENsYXNzLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUERXT1JECWxwY1N1YktleXMsCglMUERXT1JECWxwY2NoTWF4U3Via2V5LAoJTFBEV09SRAlscGNjaE1heENsYXNzLAoJTFBEV09SRAlscGNWYWx1ZXMsCglMUERXT1JECWxwY2NoTWF4VmFsdWVOYW1lLAoJTFBEV09SRAlscGNjYk1heFZhbHVlRGF0YSwKCUxQRFdPUkQJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCUZJTEVUSU1FCSpmdAopIHsKCUxQS0VZU1RSVUNUCWxwa2V5LGxweGtleTsKCWludAkJbnJvZmtleXMsbWF4c3Via2V5LG1heGNsYXNzLG1heHZhbHVlcyxtYXh2bmFtZSxtYXh2ZGF0YTsKCWludAkJaTsKCglUUkFDRShyZWcsIigleCwuLi4uLi4pXG4iLGhrZXkpOwoJbHBrZXk9bG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CglpZiAobHBzekNsYXNzKSB7CgkJaWYgKGxwa2V5LT5jbGFzcykgewoJCQlpZiAobHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjIrMj4qbHBjY2hDbGFzcykgewoJCQkJKmxwY2NoQ2xhc3M9bHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjI7CgkJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCQl9CgkJCSpscGNjaENsYXNzPWxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyOwoJCQltZW1jcHkobHBzekNsYXNzLGxwa2V5LT5jbGFzcyxsc3RybGVuMzJXKGxwa2V5LT5jbGFzcykpOwoJCX0gZWxzZSB7CgkJCSpscHN6Q2xhc3MJPSAwOwoJCQkqbHBjY2hDbGFzcwk9IDA7CgkJfQoJfSBlbHNlIHsKCQlpZiAobHBjY2hDbGFzcykKCQkJKmxwY2NoQ2xhc3MJPSBsc3RybGVuMzJXKGxwa2V5LT5jbGFzcykqMjsKCX0KCWxweGtleT1scGtleS0+bmV4dHN1YjsKCW5yb2ZrZXlzPW1heHN1YmtleT1tYXhjbGFzcz1tYXh2YWx1ZXM9bWF4dm5hbWU9bWF4dmRhdGE9MDsKCXdoaWxlIChscHhrZXkpIHsKCQlucm9ma2V5cysrOwoJCWlmIChsc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSk+bWF4c3Via2V5KQoJCQltYXhzdWJrZXk9bHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpOwoJCWlmIChscHhrZXktPmNsYXNzICYmIGxzdHJsZW4zMlcobHB4a2V5LT5jbGFzcyk+bWF4Y2xhc3MpCgkJCW1heGNsYXNzPWxzdHJsZW4zMlcobHB4a2V5LT5jbGFzcyk7CgkJaWYgKGxweGtleS0+bnJvZnZhbHVlcz5tYXh2YWx1ZXMpCgkJCW1heHZhbHVlcz1scHhrZXktPm5yb2Z2YWx1ZXM7CgkJZm9yIChpPTA7aTxscHhrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJCUxQS0VZVkFMVUUJdmFsPWxweGtleS0+dmFsdWVzK2k7CgoJCQlpZiAodmFsLT5uYW1lICYmIGxzdHJsZW4zMlcodmFsLT5uYW1lKT5tYXh2bmFtZSkKCQkJCW1heHZuYW1lPWxzdHJsZW4zMlcodmFsLT5uYW1lKTsKCQkJaWYgKHZhbC0+bGVuPm1heHZkYXRhKQoJCQkJbWF4dmRhdGE9dmFsLT5sZW47CgkJfQoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9CglpZiAoIW1heGNsYXNzKSBtYXhjbGFzcwk9IDE7CglpZiAoIW1heHZuYW1lKSBtYXh2bmFtZQk9IDE7CglpZiAobHBjU3ViS2V5cykKCQkqbHBjU3ViS2V5cwk9IG5yb2ZrZXlzOwoJaWYgKGxwY2NoTWF4U3Via2V5KQoJCSpscGNjaE1heFN1YmtleQk9IG1heHN1YmtleSoyOwoJaWYgKGxwY2NoTWF4Q2xhc3MpCgkJKmxwY2NoTWF4Q2xhc3MJPSBtYXhjbGFzcyoyOwoJaWYgKGxwY1ZhbHVlcykKCQkqbHBjVmFsdWVzCT0gbWF4dmFsdWVzOwoJaWYgKGxwY2NoTWF4VmFsdWVOYW1lKQoJCSpscGNjaE1heFZhbHVlTmFtZT0gbWF4dm5hbWU7CglpZiAobHBjY2JNYXhWYWx1ZURhdGEpCgkJKmxwY2NiTWF4VmFsdWVEYXRhPSBtYXh2ZGF0YTsKCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdRdWVyeUluZm9LZXlBCQlbQURWQVBJMzIuMTUyXSAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlJbmZvS2V5MzJBKAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzekNsYXNzLAoJTFBEV09SRAlscGNjaENsYXNzLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUERXT1JECWxwY1N1YktleXMsCglMUERXT1JECWxwY2NoTWF4U3Via2V5LAoJTFBEV09SRAlscGNjaE1heENsYXNzLAoJTFBEV09SRAlscGNWYWx1ZXMsCglMUERXT1JECWxwY2NoTWF4VmFsdWVOYW1lLAoJTFBEV09SRAlscGNjYk1heFZhbHVlRGF0YSwKCUxQRFdPUkQJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCUZJTEVUSU1FCSpmdAopIHsKCUxQV1NUUgkJbHBzekNsYXNzVzsKCURXT1JECQlyZXQ7CgoJVFJBQ0UocmVnLCIoJXgsLi4uLi4uKVxuIixoa2V5KTsKCWlmIChscHN6Q2xhc3MpIHsKCQkqbHBjY2hDbGFzcyo9IDI7CgkJbHBzekNsYXNzVyAgPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoQ2xhc3MpOwoKCX0gZWxzZQoJCWxwc3pDbGFzc1cgID0gTlVMTDsKCXJldD1SZWdRdWVyeUluZm9LZXkzMlcoCgkJaGtleSwKCQlscHN6Q2xhc3NXLAoJCWxwY2NoQ2xhc3MsCgkJbHBkd1Jlc2VydmVkLAoJCWxwY1N1YktleXMsCgkJbHBjY2hNYXhTdWJrZXksCgkJbHBjY2hNYXhDbGFzcywKCQlscGNWYWx1ZXMsCgkJbHBjY2hNYXhWYWx1ZU5hbWUsCgkJbHBjY2JNYXhWYWx1ZURhdGEsCgkJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCQlmdAoJKTsKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MgJiYgbHBzekNsYXNzKQoJCWxzdHJjcHlXdG9BKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCWlmIChscGNjaENsYXNzKQoJCSpscGNjaENsYXNzLz0yOwoJaWYgKGxwY2NoTWF4U3Via2V5KQoJCSpscGNjaE1heFN1YmtleS89MjsKCWlmIChscGNjaE1heENsYXNzKQoJCSpscGNjaE1heENsYXNzLz0yOwoJaWYgKGxwY2NoTWF4VmFsdWVOYW1lKQoJCSpscGNjaE1heFZhbHVlTmFtZS89MjsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9Ci8qIFJlZ0Nvbm5lY3RSZWdpc3RyeUEJCVtBRFZBUEkzMi4xMjddICovCkRXT1JEIFdJTkFQSSBSZWdDb25uZWN0UmVnaXN0cnkzMkEoTFBDU1RSIG1hY2hpbmUsSEtFWSBoa2V5LExQSEtFWSByZXNrZXkpCnsKCUZJWE1FKHJlZywiKCVzLCUwOHgsJXApOnN0dWIuXG4iLG1hY2hpbmUsaGtleSxyZXNrZXkpOwoJcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOyAvKiBGSVhNRSAqLwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdHZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTQ0XQogKiBSZXRyaWV2ZXMgYSBjb3B5IG9mIHNlY3VyaXR5IGRlc2NyaXB0b3IgcHJvdGVjdGluZyB0aGUgcmVnaXN0cnkga2V5CiAqCiAqIE5PVEVTCiAqICAgIHBTZWN1cml0eURlc2NyaXB0b3Igc2hvdWxkIGJlIFBTRUNVUklUWV9ERVNDUklQVE9SCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpMT05HIFdJTkFQSSBSZWdHZXRLZXlTZWN1cml0eSggSEtFWSBoS2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFQ1VSSVRZX0lORk9STUFUSU9OIFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgcFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciApCnsKICAgIEZJWE1FKHJlZywgIiglZCwlbGQsJXAsJXApOiBzdHViXG4iLCBoS2V5LCBTZWN1cml0eUluZm9ybWF0aW9uLAogICAgICAgICAgcFNlY3VyaXR5RGVzY3JpcHRvciwgbHBjYlNlY3VyaXR5RGVzY3JpcHRvcik7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoK