LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICoKICogRGVjZW1iZXIgMjEsIDE5OTcgLSBLZXZpbiBDb3plbnMKICogRml4ZWQgYnVncyBpbiB0aGUgX3c5NV9sb2FkcmVnKCkgZnVuY3Rpb24uIEFkZGVkIGV4dHJhIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyB0aGUgZm9ybWF0IG9mIHRoZSBXaW5kb3dzICc5NSByZWdpc3RyeSBmaWxlcy4KICoKICogTWF5IDUsIDE5OTggLSBNYXR0aGV3IEJlY2tlcgogKiBDaGFuZ2VkIG9wdGlvbmZsYWdzIHRvIERXT1JEIGluc3RlYWQgb2YgaW50IGJlY2F1c2UgaXQgY291bGQgYmUgMHg4MDAwMDAwCiAqIEFsbCBlcnJvciByZXR1cm4gdmFsdWVzIG11c3QgY29tZSBmcm9tIHdpbmVycm9yLmgKICoKICogTk9URVMKICogICAgV2hlbiBjaGFuZ2luZyB0aGlzIGZpbGUsIHBsZWFzZSByZS1ydW4gdGhlIHJlZ3Rlc3QgcHJvZ3JhbSB0byBlbnN1cmUKICogICAgdGhlIGNvbmRpdGlvbnMgYXJlIGhhbmRsZWQgcHJvcGVybHkuCiAqCiAqIFRPRE8KICogICAgU2VjdXJpdHkgYWNjZXNzCiAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL2ZjbnRsLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8cHdkLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJ4bWFsbG9jLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCnZvaWQgU0hFTExfU3RhcnR1cFJlZ2lzdHJ5KCk7CgovKiBUaGlzIGlzIG5vdCB1c2VkIGFueXdoZXJlICovCiNkZWZpbmUJREVCVUdfVzk1X0xPQURSRUcJMAoKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCi8qIE5PVEU6IGRvIG5vdCBhcHBlbmQgYSAvLiBsaW51eCcgbWtkaXIoKSBXSUxMIEZBSUwgaWYgeW91IGRvIHRoYXQgKi8KI2RlZmluZSBXSU5FX1BSRUZJWAkJCSIvLndpbmUiCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUCQkiL3Vzci9sb2NhbC9ldGMvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUCSIvdXNyL2xvY2FsL2V0Yy93aW5lLnN5c3RlbXJlZyIKCi8qIHJlbGF0aXZlIGluIH51c2VyLy53aW5lLyA6ICovCiNkZWZpbmUgU0FWRV9DVVJSRU5UX1VTRVIJCSJ1c2VyLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX01BQ0hJTkUJCSJzeXN0ZW0ucmVnIgoKI2RlZmluZSBLRVlfUkVHSVNUUlkJIlNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeSIKI2RlZmluZSBWQUxfU0FWRVVQREFURUQJIlNhdmVPbmx5VXBkYXRlZEtleXMiCgovKiBvbmUgdmFsdWUgb2YgYSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZVkFMVUUKewogICAgTFBXU1RSICAgbmFtZTsgICAgICAgICAgLyogbmFtZSBvZiB2YWx1ZSAoVU5JQ09ERSkgb3IgTlVMTCBmb3Igd2luMzEgKi8KICAgIERXT1JEICAgIHR5cGU7ICAgICAgICAgIC8qIHR5cGUgb2YgdmFsdWUgKi8KICAgIERXT1JEICAgIGxlbjsgICAgICAgICAgIC8qIGxlbmd0aCBvZiBkYXRhIGluIEJZVEVzICovCiAgICBEV09SRCAgICBsYXN0bW9kaWZpZWQ7ICAvKiB0aW1lIG9mIHNlY29uZHMgc2luY2UgMS4xLjE5NzAgKi8KICAgIExQQllURSAgIGRhdGE7ICAgICAgICAgIC8qIGNvbnRlbnQsIG1heSBiZSBzdHJpbmdzLCBiaW5hcmllcywgZXRjLiAqLwp9IEtFWVZBTFVFLCpMUEtFWVZBTFVFOwoKLyogYSByZWdpc3RyeSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZU1RSVUNUCnsKICAgIExQV1NUUiAgICAgICAgICAgICAgIGtleW5hbWU7ICAgICAgIC8qIG5hbWUgb2YgVEhJUyBrZXkgKFVOSUNPREUpICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBmbGFnczsgICAgICAgICAvKiBmbGFncy4gKi8KICAgIExQV1NUUiAgICAgICAgICAgICAgIGNsYXNzOwogICAgLyogdmFsdWVzICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBucm9mdmFsdWVzOyAgICAvKiBuciBvZiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIExQS0VZVkFMVUUgICAgICAgICAgIHZhbHVlczsgICAgICAgIC8qIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgLyoga2V5IG1hbmFnZW1lbnQgcG9pbnRlcnMgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHQ7ICAgICAgICAgIC8qIG5leHQga2V5IG9uIHNhbWUgaGllcmFyY2h5ICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0c3ViOyAgICAgICAvKiBrZXlzIHRoYXQgaGFuZyBiZWxvdyBUSElTIGtleSAqLwp9IEtFWVNUUlVDVCwgKkxQS0VZU1RSVUNUOwoKCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jbGFzc2VzX3Jvb3Q9TlVMTDsJLyogd2luZG93cyAzLjEgZ2xvYmFsIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF91c2VyPU5VTEw7CS8qIHVzZXIgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9sb2NhbF9tYWNoaW5lPU5VTEw7LyogbWFjaGluZSBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3VzZXJzPU5VTEw7CS8qIGFsbCB1c2Vycz8gKi8KCi8qIGR5bmFtaWMsIG5vdCBzYXZlZCAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfcGVyZm9ybWFuY2VfZGF0YT1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF9jb25maWc9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2R5bl9kYXRhPU5VTEw7CgovKiB3aGF0IHZhbHVldHlwZXMgZG8gd2UgbmVlZCB0byBjb252ZXJ0PyAqLwojZGVmaW5lIFVOSUNPTlZNQVNLCSgoMTw8UkVHX1NaKXwoMTw8UkVHX01VTFRJX1NaKXwoMTw8UkVHX0VYUEFORF9TWikpCgoKLyoKICogRklYTUUKICogICBBcmUgdGhlc2UgZG9pbmcgdGhlIHNhbWUgYXMgSEVBUF9zdHJkdXBBdG9XIGFuZCBIRUFQX3N0cmR1cFd0b0E/CiAqICAgSWYgc28sIGNhbiB3ZSByZW1vdmUgdGhlbT8KICovCnN0YXRpYyBMUFdTVFIgc3RyZHVwQTJXKExQQ1NUUiBzcmMpCnsKCUxQV1NUUiBkZXN0PXhtYWxsb2MoMipzdHJsZW4oc3JjKSsyKTsKCWxzdHJjcHlBdG9XKGRlc3Qsc3JjKTsKCXJldHVybiBkZXN0Owp9CgpzdGF0aWMgTFBXU1RSIHN0cmR1cFcoTFBDV1NUUiBhKSB7CglMUFdTVFIJYjsKCWludAlsZW47CgoJbGVuPXNpemVvZihXQ0hBUikqKGxzdHJsZW4zMlcoYSkrMSk7CgliPShMUFdTVFIpeG1hbGxvYyhsZW4pOwoJbWVtY3B5KGIsYSxsZW4pOwoJcmV0dXJuIGI7Cn0KCgpzdGF0aWMgc3RydWN0IG9wZW5oYW5kbGUgewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglIS0VZCQloa2V5OwoJUkVHU0FNCQlhY2Nlc3NtYXNrOwp9ICAqb3BlbmhhbmRsZXM9TlVMTDsKc3RhdGljIGludAlucm9mb3BlbmhhbmRsZXM9MDsKc3RhdGljIGludAljdXJyZW50aGFuZGxlPTE7CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBhZGRfaGFuZGxlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIGFkZF9oYW5kbGUoIEhLRVkgaGtleSwgTFBLRVlTVFJVQ1QgbHBrZXksIFJFR1NBTSBhY2Nlc3NtYXNrICkKewogICAgaW50IGk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXAsJWx4KVxuIixoa2V5LGxwa2V5LGFjY2Vzc21hc2spOwogICAgaWYgKGxwa2V5KQogICAgICAgIFRSQUNFKHJlZywiICglcylcbiIsZGVidWdzdHJfdyhscGtleS0+a2V5bmFtZSkpOwoKICAgIC8qIENoZWNrIGZvciBkdXBsaWNhdGVzICovCiAgICBmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspIHsKICAgICAgICBpZiAob3BlbmhhbmRsZXNbaV0ubHBrZXk9PWxwa2V5KSB7CiAgICAgICAgICAgIC8qIFRoaXMgaXMgbm90IHJlYWxseSBhbiBlcnJvciAtIHRoZSB1c2VyIGlzIGFsbG93ZWQgdG8gY3JlYXRlCiAgICAgICAgICAgICAgIHR3byAob3IgbW9yZSkgaGFuZGxlcyB0byB0aGUgc2FtZSBrZXkgKi8KICAgICAgICAgICAgLypXQVJOKHJlZywgIkFkZGluZyBrZXkgJXAgdHdpY2VcbiIsbHBrZXkpOyovCiAgICAgICAgfQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KSB7CiAgICAgICAgICAgIFdBUk4ocmVnLCAiQWRkaW5nIGhhbmRsZSAleCB0d2ljZVxuIixoa2V5KTsKICAgICAgICB9CiAgICB9CiAgICBvcGVuaGFuZGxlcz14cmVhbGxvYyggb3BlbmhhbmRsZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcysxKSk7CgogICAgb3BlbmhhbmRsZXNbaV0ubHBrZXkgPSBscGtleTsKICAgIG9wZW5oYW5kbGVzW2ldLmhrZXkgPSBoa2V5OwogICAgb3BlbmhhbmRsZXNbaV0uYWNjZXNzbWFzayA9IGFjY2Vzc21hc2s7CiAgICBucm9mb3BlbmhhbmRsZXMrKzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZ2V0X2hhbmRsZSBbSW50ZXJuYWxdCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogUG9pbnRlciB0byBrZXkKICogICAgRmFpbHVyZTogTlVMTAogKi8Kc3RhdGljIExQS0VZU1RSVUNUIGdldF9oYW5kbGUoIEhLRVkgaGtleSApCnsKICAgIGludCBpOwoKICAgIGZvciAoaT0wOyBpPG5yb2ZvcGVuaGFuZGxlczsgaSsrKQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5ID09IGhrZXkpCiAgICAgICAgICAgIHJldHVybiBvcGVuaGFuZGxlc1tpXS5scGtleTsKICAgIFdBUk4ocmVnLCAiQ291bGQgbm90IGZpbmQgaGFuZGxlICV4XG4iLGhrZXkpOwogICAgcmV0dXJuIE5VTEw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIHJlbW92ZV9oYW5kbGUgW0ludGVybmFsXQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byByZW1vdmUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVSUk9SX0lOVkFMSURfSEFORExFCiAqLwpzdGF0aWMgRFdPUkQgcmVtb3ZlX2hhbmRsZSggSEtFWSBoa2V5ICkKewogICAgaW50IGk7CgogICAgZm9yIChpPTA7aTxucm9mb3BlbmhhbmRsZXM7aSsrKQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KQogICAgICAgICAgICBicmVhazsKCiAgICBpZiAoaSA9PSBucm9mb3BlbmhhbmRsZXMpIHsKICAgICAgICBXQVJOKHJlZywgIkNvdWxkIG5vdCBmaW5kIGhhbmRsZSAleFxuIixoa2V5KTsKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CiAgICB9CgogICAgbWVtY3B5KCBvcGVuaGFuZGxlcytpLAogICAgICAgICAgICBvcGVuaGFuZGxlcytpKzEsCiAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy1pLTEpCiAgICApOwogICAgb3BlbmhhbmRsZXM9eHJlYWxsb2Mob3BlbmhhbmRsZXMsc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLTEpKTsKICAgIG5yb2ZvcGVuaGFuZGxlcy0tOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKiBkZWJ1ZyBmdW5jdGlvbiwgY29udmVydHMgYSB1bmljb2RlIGludG8gYSBzdGF0aWMgbWVtb3J5IGFyZWEgCiAqIChzdWIgZm9yIHVzaW5nIHR3byBzdGF0aWMgc3RyaW5ncywgaW4gY2FzZSB3ZSBuZWVkIHRoZW0gaW4gYSBzaW5nbGUgY2FsbCkKICoKICogRklYTUUKICogICAgVGhpcyBzZWVtcyB0byBiZSB1c2VkIHRoZSBzYW1lIGFzIGRlYnVnc3RyX3cuCiAqICAgIElmIHNvLCBjYW4gdGhpcyBvbmUgZ28gYXdheT8KICovCkxQU1RSClcyQyhMUENXU1RSIHgsaW50IHN1YikgewoJc3RhdGljCUxQU1RSCXVuaWNvZGVkZWJ1Z1syXT17TlVMTCxOVUxMfTsKCWlmICh4PT1OVUxMKQoJCXJldHVybiAiPE5VTEw+IjsKCWlmIChzdWIhPTAgJiYgc3ViIT0xKQoJCXJldHVybiAiPFcyQzpiYWQgc3ViPiI7CglpZiAodW5pY29kZWRlYnVnW3N1Yl0pIEhlYXBGcmVlKCBTeXN0ZW1IZWFwLCAwLCB1bmljb2RlZGVidWdbc3ViXSApOwoJdW5pY29kZWRlYnVnW3N1Yl0gPSBIRUFQX3N0cmR1cFd0b0EoIFN5c3RlbUhlYXAsIDAsIHggKTsKCXJldHVybiB1bmljb2RlZGVidWdbc3ViXTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogbG9va3VwX2hrZXkgW0ludGVybmFsXQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFBvaW50ZXIgdG8ga2V5IHN0cnVjdHVyZQogKiAgICBGYWlsdXJlOiBOVUxMCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgbG9va3VwX2hrZXkoIEhLRVkgaGtleSApCnsKCXN3aXRjaCAoaGtleSkgewogICAgLyogVGhlc2Ugc2VlbSBlcnJvbmVvdXMgKi8KICAgIC8qCWNhc2UgMHgwMDAwMDAwMDogKi8KICAgIC8qCWNhc2UgMHgwMDAwMDAwMTogKi8KCWNhc2UgSEtFWV9DTEFTU0VTX1JPT1Q6CgkJcmV0dXJuIGtleV9jbGFzc2VzX3Jvb3Q7CgljYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgoJCXJldHVybiBrZXlfY3VycmVudF91c2VyOwoJY2FzZSBIS0VZX0xPQ0FMX01BQ0hJTkU6CgkJcmV0dXJuIGtleV9sb2NhbF9tYWNoaW5lOwoJY2FzZSBIS0VZX1VTRVJTOgoJCXJldHVybiBrZXlfdXNlcnM7CgljYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKCQlyZXR1cm4ga2V5X3BlcmZvcm1hbmNlX2RhdGE7CgljYXNlIEhLRVlfRFlOX0RBVEE6CgkJcmV0dXJuIGtleV9keW5fZGF0YTsKCWNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKCQlyZXR1cm4ga2V5X2N1cnJlbnRfY29uZmlnOwoJZGVmYXVsdDoKCQlyZXR1cm4gZ2V0X2hhbmRsZShoa2V5KTsKCX0KCS8qTk9UUkVBQ0hFRCovCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIHNwbGl0X2tleXBhdGggW0ludGVybmFsXQogKiBzcGxpdHMgdGhlIHVuaWNvZGUgc3RyaW5nICd3cCcgaW50byBhbiBhcnJheSBvZiBzdHJpbmdzLgogKiB0aGUgYXJyYXkgaXMgYWxsb2NhdGVkIGJ5IHRoaXMgZnVuY3Rpb24uIAogKiBGcmVlIHRoZSBhcnJheSB1c2luZyBGUkVFX0tFWV9QQVRICiAqCiAqIFBBUkFNUwogKiAgICB3cCAgW0ldIFN0cmluZyB0byBzcGxpdCB1cAogKiAgICB3cHYgW09dIEFycmF5IG9mIHBvaW50ZXJzIHRvIHN0cmluZ3MKICogICAgd3BjIFtPXSBOdW1iZXIgb2YgY29tcG9uZW50cwogKi8Kc3RhdGljIHZvaWQgc3BsaXRfa2V5cGF0aCggTFBDV1NUUiB3cCwgTFBXU1RSICoqd3B2LCBpbnQgKndwYykKewogICAgaW50CWksaixsZW47CiAgICBMUFdTVFIgd3M7CgogICAgVFJBQ0UocmVnLCIoJXMsJXAsJXApXG4iLGRlYnVnc3RyX3cod3ApLHdwdix3cGMpOwoKICAgIHdzCT0gSEVBUF9zdHJkdXBXKCBTeXN0ZW1IZWFwLCAwLCB3cCApOwoKICAgIC8qIFdlIGtub3cgd2UgaGF2ZSBhdCBsZWFzdCBvbmUgc3Vic3RyaW5nICovCiAgICAqd3BjID0gMTsKCiAgICAvKiBSZXBsYWNlIGVhY2ggYmFja3NsYXNoIHdpdGggTlVMTCwgYW5kIGluY3JlbWVudCB0aGUgY291bnQgKi8KICAgIGZvciAoaT0wO3dzW2ldO2krKykgewogICAgICAgIGlmICh3c1tpXT09J1xcJykgewogICAgICAgICAgICB3c1tpXT0wOwogICAgICAgICAgICAoKndwYykrKzsKICAgICAgICB9CiAgICB9CgogICAgbGVuID0gaTsKCiAgICAvKiBBbGxvY2F0ZSB0aGUgc3BhY2UgZm9yIHRoZSBhcnJheSBvZiBwb2ludGVycywgbGVhdmluZyByb29tIGZvciB0aGUKICAgICAgIE5VTEwgYXQgdGhlIGVuZCAqLwogICAgKndwdiA9IChMUFdTVFIqKUhlYXBBbGxvYyggU3lzdGVtSGVhcCwgMCwgc2l6ZW9mKExQV1NUUikqKCp3cGMrMikpOwogICAgKCp3cHYpWzBdPSB3czsKCiAgICAvKiBBc3NpZ24gZWFjaCBwb2ludGVyIHRvIHRoZSBhcHByb3ByaWF0ZSBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZyAqLwogICAgaiA9IDE7CiAgICBmb3IgKGk9MTtpPGxlbjtpKyspCiAgICAgICAgaWYgKHdzW2ktMV09PTApIHsKICAgICAgICAgICAgKCp3cHYpW2orK109d3MraTsKICAgICAgICAgICAgLyogVFJBQ0UocmVnLCAiIFN1Yml0ZW0gJWQgPSAlc1xuIixqLTEsZGVidWdzdHJfdygoKndwdilbai0xXSkpOyAqLwogICAgICAgIH0KCiAgICAoKndwdilbal09TlVMTDsKfQojZGVmaW5lIEZSRUVfS0VZX1BBVEggSGVhcEZyZWUoU3lzdGVtSGVhcCwwLHdwc1swXSk7SGVhcEZyZWUoU3lzdGVtSGVhcCwwLHdwcyk7CgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX0luaXQgW0ludGVybmFsXQogKiBTaGVsbCBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIGtleXMuIAogKi8Kdm9pZCBTSEVMTF9Jbml0KCkgewoJc3RydWN0CXBhc3N3ZAkqcHdkOwoKCUhLRVkJY2xfcl9oa2V5LGNfdV9oa2V5OwojZGVmaW5lIEFERF9ST09UX0tFWSh4eCkgXAoJeHggPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7XAoJbWVtc2V0KHh4LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpO1wKCXh4LT5rZXluYW1lPSBzdHJkdXBBMlcoIjxzaG91bGRfbm90X2FwcGVhcl9hbnl3aGVyZT4iKTsKCglBRERfUk9PVF9LRVkoa2V5X2xvY2FsX21hY2hpbmUpOwoJaWYgKFJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiU09GVFdBUkVcXENsYXNzZXMiLCZjbF9yX2hrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJRVJSKHJlZywiQ291bGQgbm90IGNyZWF0ZSBIS0xNXFxTT0ZUV0FSRVxcQ2xhc3Nlcy4gVGhpcyBpcyBpbXBvc3NpYmxlLlxuIik7CgkJZXhpdCgxKTsKCX0KCWtleV9jbGFzc2VzX3Jvb3QgPSBsb29rdXBfaGtleShjbF9yX2hrZXkpOwoKCUFERF9ST09UX0tFWShrZXlfdXNlcnMpOwoKI2lmIDAKCS8qIEZJWE1FOiBsb2FkIGFsbCB1c2VycyBhbmQgdGhlaXIgcmVzcC4gcHdkLT5wd19kaXIvLndpbmUvdXNlci5yZWcgCgkgKgkgIChsYXRlciwgd2hlbiBhIHdpbjMyIHJlZ2lzdHJ5IGVkaXRpbmcgdG9vbCBiZWNvbWVzIGF2YWlsLikKCSAqLwoJd2hpbGUgKHB3ZD1nZXRwd2VudCgpKSB7CgkJaWYgKHB3ZC0+cHdfbmFtZSA9PSBOVUxMKQoJCQljb250aW51ZTsKCQlSZWdDcmVhdGVLZXkxNihIS0VZX1VTRVJTLHB3ZC0+cHdfbmFtZSwmY191X2hrZXkpOwoJCVJlZ0Nsb3NlS2V5KGNfdV9oa2V5KTsKCX0KI2VuZGlmCglwd2Q9Z2V0cHd1aWQoZ2V0dWlkKCkpOwoJaWYgKHB3ZCAmJiBwd2QtPnB3X25hbWUpIHsKCQlSZWdDcmVhdGVLZXkxNihIS0VZX1VTRVJTLHB3ZC0+cHdfbmFtZSwmY191X2hrZXkpOwoJCWtleV9jdXJyZW50X3VzZXIgPSBsb29rdXBfaGtleShjX3VfaGtleSk7Cgl9IGVsc2UgewoJCUFERF9ST09UX0tFWShrZXlfY3VycmVudF91c2VyKTsKCX0KCUFERF9ST09UX0tFWShrZXlfcGVyZm9ybWFuY2VfZGF0YSk7CglBRERfUk9PVF9LRVkoa2V5X2N1cnJlbnRfY29uZmlnKTsKCUFERF9ST09UX0tFWShrZXlfZHluX2RhdGEpOwojdW5kZWYgQUREX1JPT1RfS0VZCglTSEVMTF9TdGFydHVwUmVnaXN0cnkoKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfU3RhcnR1cFJlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnZvaWQgU0hFTExfU3RhcnR1cFJlZ2lzdHJ5KCB2b2lkICkKewoJSEtFWQloa2V5OwoJY2hhcglidWZbMjAwXTsKCiAgICBUUkFDRShyZWcsIih2b2lkKVxuIik7CgoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9EWU5fREFUQSwiUGVyZlN0YXRzXFxTdGF0RGF0YSIsJmhrZXkpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgogICAgICAgIC8qIFRoaXMgd2FzIGFuIE9wZW4sIGJ1dCBzaW5jZSBpdCBpcyBjYWxsZWQgYmVmb3JlIHRoZSByZWFsIHJlZ2lzdHJpZXMKICAgICAgICAgICBhcmUgbG9hZGVkLCBpdCB3YXMgY2hhbmdlZCB0byBhIENyZWF0ZSAtIE1UQiA5ODA1MDcqLwoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJIQVJEV0FSRVxcREVTQ1JJUFRJT05cXFN5c3RlbSIsJmhrZXkpOwoJUmVnU2V0VmFsdWVFeDMyQShoa2V5LCJJZGVudGlmaWVyIiwwLFJFR19TWiwiU3lzdGVtVHlwZSBXSU5FIixzdHJsZW4oIlN5c3RlbVR5cGUgV0lORSIpKTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKCS8qIFxcU09GVFdBUkVcXE1pY3Jvc29mdFxcV2luZG93IE5UXFxDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50QnVpbGROdW1iZXIKCSAqCQkJCQkJQ3VycmVudFR5cGUKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE93bmVyCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPcmdhbml6YXRpb24KCSAqCgkgKi8KCS8qIFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTTk1QXFxQYXJhbWV0ZXJzXFxSRkMxMTU2QWdlbnQKCSAqIAkJCQkJc3RyaW5nCVN5c0NvbnRhY3QKCSAqIAkJCQkJc3RyaW5nCVN5c0xvY2F0aW9uCgkgKiAJCQkJCQlTeXNTZXJ2aWNlcwoJICovCQkJCQkJCglpZiAoLTEhPWdldGhvc3RuYW1lKGJ1ZiwyMDApKSB7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxDb250cm9sXFxDb21wdXRlck5hbWVcXENvbXB1dGVyTmFtZSIsJmhrZXkpOwoJCVJlZ1NldFZhbHVlRXgxNihoa2V5LCJDb21wdXRlck5hbWUiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSsxKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKiogU0FWRSBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBSRUdJU1RSWV9TQVZFX1ZFUlNJT04JMHgwMDAwMDAwMQoKLyogUmVnaXN0cnkgc2F2ZWZvcm1hdDoKICogSWYgeW91IGNoYW5nZSBpdCwgaW5jcmVhc2UgYWJvdmUgbnVtYmVyIGJ5IDEsIHdoaWNoIHdpbGwgZmx1c2gKICogb2xkIHJlZ2lzdHJ5IGRhdGFiYXNlIGZpbGVzLgogKiAKICogR2xvYmFsOgogKiAJIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIKICogCXN1YmtleXMuLi4uCiAqIFN1YmtleXM6CiAqIAlrZXluYW1lCiAqCQl2YWx1ZW5hbWU9bGFzdG1vZGlmaWVkLHR5cGUsZGF0YQogKgkJLi4uCiAqCQlzdWJrZXlzCiAqCS4uLgogKiBrZXluYW1lLHZhbHVlbmFtZSxzdHJpbmdkYXRhOgogKgl0aGUgdXN1YWwgYXNjaWkgY2hhcmFjdGVycyBmcm9tIDB4MDAtMHhmZiAod2VsbCwgbm90IDB4MDApCiAqCWFuZCBcdVhYWFggYXMgVU5JQ09ERSB2YWx1ZSBYWFhYIHdpdGggWFhYWD4weGZmCiAqCSggIj1cXFx0IiBlc2NhcGVkIGluIFx1WFhYWCBmb3JtLikKICogdHlwZSxsYXN0bW9kaWZpZWQ6IAogKglpbnQKICogCiAqIEZJWE1FOiBkb2Vzbid0IHNhdmUgJ2NsYXNzJyAod2hhdCBkb2VzIGl0IG1lYW4gYW55d2F5PyksIG5vciBmbGFncy4KICoKICogW0hLRVlfQ1VSUkVOVF9VU0VSXFxTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnldCiAqIFNhdmVPbmx5VXBkYXRlZEtleXM9eWVzCiAqLwpzdGF0aWMgaW50Cl9zYXZlX2NoZWNrX3RhaW50ZWQoTFBLRVlTVFJVQ1QgbHBrZXkpIHsKCWludAkJdGFpbnRlZDsKCglpZiAoIWxwa2V5KQoJCXJldHVybiAwOwoJaWYgKGxwa2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkKCQl0YWludGVkID0gMTsKCWVsc2UKCQl0YWludGVkID0gMDsKCXdoaWxlIChscGtleSkgewoJCWlmIChfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKSkgewoJCQlscGtleS0+ZmxhZ3MgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoJCQl0YWludGVkID0gMTsKCQl9CgkJbHBrZXkJPSBscGtleS0+bmV4dDsKCX0KCXJldHVybiB0YWludGVkOwp9CgpzdGF0aWMgdm9pZApfc2F2ZV9VU1RSSU5HKEZJTEUgKkYsTFBXU1RSIHdzdHIsaW50IGVzY2FwZWVxKSB7CglMUFdTVFIJczsKCWludAlkb2VzY2FwZTsKCglpZiAod3N0cj09TlVMTCkKCQlyZXR1cm47CglzPXdzdHI7Cgl3aGlsZSAoKnMpIHsKCQlkb2VzY2FwZT0wOwoJCWlmICgqcz4weGZmKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKCpzPT0nXG4nKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKGVzY2FwZWVxICYmICpzPT0nPScpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoKnM9PSdcXCcpCiAgICAgICAgICAgICAgICAgICAgICAgIGZwdXRjKCpzLEYpOyAvKiBpZiBcXCB0aGVuIHB1dCBpdCB0d2ljZS4gKi8KCQlpZiAoZG9lc2NhcGUpCgkJCWZwcmludGYoRiwiXFx1JTA0eCIsKigodW5zaWduZWQgc2hvcnQqKXMpKTsKCQllbHNlCgkJCWZwdXRjKCpzLEYpOwoJCXMrKzsKCX0KfQoKc3RhdGljIGludApfc2F2ZXN1YmtleShGSUxFICpGLExQS0VZU1RSVUNUIGxwa2V5LGludCBsZXZlbCxpbnQgYWxsKSB7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWksdGFicyxqOwoKCWxweGtleQk9IGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJIShscHhrZXktPmZsYWdzICYgUkVHX09QVElPTl9WT0xBVElMRSkgJiYKCQkJKGFsbCB8fCAobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkpCgkJKSB7CgkJCWZvciAodGFicz1sZXZlbDt0YWJzLS07KQoJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJX3NhdmVfVVNUUklORyhGLGxweGtleS0+a2V5bmFtZSwxKTsKCQkJZnB1dHMoIlxuIixGKTsKCQkJZm9yIChpPTA7aTxscHhrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJCQlMUEtFWVZBTFVFCXZhbD1scHhrZXktPnZhbHVlcytpOwoKCQkJCWZvciAodGFicz1sZXZlbCsxO3RhYnMtLTspCgkJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJCV9zYXZlX1VTVFJJTkcoRix2YWwtPm5hbWUsMCk7CgkJCQlmcHV0YygnPScsRik7CgkJCQlmcHJpbnRmKEYsIiVsZCwlbGQsIix2YWwtPnR5cGUsdmFsLT5sYXN0bW9kaWZpZWQpOwoJCQkJaWYgKCgxPDx2YWwtPnR5cGUpICYgVU5JQ09OVk1BU0spCgkJCQkJX3NhdmVfVVNUUklORyhGLChMUFdTVFIpdmFsLT5kYXRhLDApOwoJCQkJZWxzZQoJCQkJCWZvciAoaj0wO2o8dmFsLT5sZW47aisrKQoJCQkJCQlmcHJpbnRmKEYsIiUwMngiLCooKHVuc2lnbmVkIGNoYXIqKXZhbC0+ZGF0YStqKSk7CgkJCQlmcHV0cygiXG4iLEYpOwoJCQl9CgkJCS8qIGRlc2NlbmQgcmVjdXJzaXZlbHkgKi8KCQkJaWYgKCFfc2F2ZXN1YmtleShGLGxweGtleS0+bmV4dHN1YixsZXZlbCsxLGFsbCkpCgkJCQlyZXR1cm4gMDsKCQl9CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCXJldHVybiAxOwp9CgpzdGF0aWMgaW50Cl9zYXZlc3VicmVnKEZJTEUgKkYsTFBLRVlTVFJVQ1QgbHBrZXksaW50IGFsbCkgewoJZnByaW50ZihGLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWRcbiIsUkVHSVNUUllfU0FWRV9WRVJTSU9OKTsKCV9zYXZlX2NoZWNrX3RhaW50ZWQobHBrZXktPm5leHRzdWIpOwoJcmV0dXJuIF9zYXZlc3Via2V5KEYsbHBrZXktPm5leHRzdWIsMCxhbGwpOwp9CgpzdGF0aWMgQk9PTDMyCl9zYXZlcmVnKExQS0VZU1RSVUNUIGxwa2V5LGNoYXIgKmZuLGludCBhbGwpIHsKCUZJTEUJKkY7CgoJRj1mb3BlbihmbiwidyIpOwoJaWYgKEY9PU5VTEwpIHsKCQlXQVJOKHJlZywiQ291bGRuJ3Qgb3BlbiAlcyBmb3Igd3JpdGluZzogJXNcbiIsCgkJCWZuLHN0cmVycm9yKGVycm5vKQoJCSk7CgkJcmV0dXJuIEZBTFNFOwoJfQoJaWYgKCFfc2F2ZXN1YnJlZyhGLGxwa2V5LGFsbCkpIHsKCQlmY2xvc2UoRik7CgkJdW5saW5rKGZuKTsKCQlXQVJOKHJlZywiRmFpbGVkIHRvIHNhdmUga2V5cywgcGVyaGFwcyBubyBtb3JlIGRpc2tzcGFjZSBmb3IgJXM/XG4iLGZuKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglmY2xvc2UoRik7CiAgICAgICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX1NhdmVSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwp2b2lkIFNIRUxMX1NhdmVSZWdpc3RyeSggdm9pZCApCnsKCWNoYXIJKmZuOwoJc3RydWN0CXBhc3N3ZAkqcHdkOwoJY2hhcglidWZbNF07CglIS0VZCWhrZXk7CglpbnQJYWxsOwoKICAgIFRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCglhbGw9MDsKCWlmIChSZWdPcGVuS2V5MTYoSEtFWV9DVVJSRU5UX1VTRVIsS0VZX1JFR0lTVFJZLCZoa2V5KSE9RVJST1JfU1VDQ0VTUykgewoJCXN0cmNweShidWYsInllcyIpOwoJfSBlbHNlIHsKCQlEV09SRCBsZW4sanVuayx0eXBlOwoKCQlsZW49NDsKCQlpZiAoCShFUlJPUl9TVUNDRVNTIT1SZWdRdWVyeVZhbHVlRXgzMkEoCgkJCQloa2V5LAoJCQkJVkFMX1NBVkVVUERBVEVELAoJCQkJJmp1bmssCgkJCQkmdHlwZSwKCQkJCWJ1ZiwKCQkJCSZsZW4KCQkJKSl8fCAodHlwZSE9UkVHX1NaKQoJCSkKCQkJc3RyY3B5KGJ1ZiwieWVzIik7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9CglpZiAobHN0cmNtcGkzMkEoYnVmLCJ5ZXMiKSkKCQlhbGw9MTsKCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CglpZiAocHdkIT1OVUxMICYmIHB3ZC0+cHdfZGlyIT1OVUxMKQogICAgICAgIHsKICAgICAgICAgICAgICAgIGNoYXIgKnRtcDsKCgkJZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihwd2QtPnB3X2RpcikgKyBzdHJsZW4oV0lORV9QUkVGSVgpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJsZW4oU0FWRV9DVVJSRU5UX1VTRVIpICsgMiApOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYKTsKCQkvKiBjcmVhdGUgdGhlIGRpcmVjdG9yeS4gZG9uJ3QgY2FyZSBhYm91dCBlcnJvcmNvZGVzLiAqLwoJCW1rZGlyKGZuLDA3NTUpOyAvKiBkcnd4ci14ci14ICovCgkJc3RyY2F0KGZuLCIvIlNBVkVfQ1VSUkVOVF9VU0VSKTsKCQl0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwoJCXN0cmNweSh0bXAsZm4pO3N0cmNhdCh0bXAsIi50bXAiKTsKCQlpZiAoX3NhdmVyZWcoa2V5X2N1cnJlbnRfdXNlcix0bXAsYWxsKSkgewoJCQlpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CgkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKCQkJCXVubGluayh0bXApOwoJCQl9CgkJfQoJCWZyZWUodG1wKTsKCQlmcmVlKGZuKTsKCQlmbj0oY2hhciopeG1hbGxvYyhzdHJsZW4ocHdkLT5wd19kaXIpK3N0cmxlbihXSU5FX1BSRUZJWCkrc3RybGVuKFNBVkVfTE9DQUxfTUFDSElORSkrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwoJCXRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CgkJc3RyY3B5KHRtcCxmbik7c3RyY2F0KHRtcCwiLnRtcCIpOwoJCWlmIChfc2F2ZXJlZyhrZXlfbG9jYWxfbWFjaGluZSx0bXAsYWxsKSkgewoJCQlpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CgkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKCQkJCXVubGluayh0bXApOwoJCQl9CgkJfQoJCWZyZWUodG1wKTsKCQlmcmVlKGZuKTsKCX0gZWxzZQoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVkLlxuIixnZXR1aWQoKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKiogTE9BRCBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2ZpbmRfb3JfYWRkX2tleSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgX2ZpbmRfb3JfYWRkX2tleSggTFBLRVlTVFJVQ1QgbHBrZXksIExQV1NUUiBrZXluYW1lICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5LCpscGxwa2V5OwoKCWlmICgoIWtleW5hbWUpIHx8IChrZXluYW1lWzBdPT0wKSkgewoJCWZyZWUoa2V5bmFtZSk7CgkJcmV0dXJuIGxwa2V5OwoJfQoJbHBscGtleT0gJihscGtleS0+bmV4dHN1Yik7CglscHhrZXkJPSAqbHBscGtleTsKCXdoaWxlIChscHhrZXkpIHsKCQlpZiAoIWxzdHJjbXBpMzJXKGxweGtleS0+a2V5bmFtZSxrZXluYW1lKSkKCQkJYnJlYWs7CgkJbHBscGtleQk9ICYobHB4a2V5LT5uZXh0KTsKCQlscHhrZXkJPSAqbHBscGtleTsKCX0KCWlmIChscHhrZXk9PU5VTEwpIHsKCQkqbHBscGtleSA9IChMUEtFWVNUUlVDVCl4bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTsKCQlscHhrZXkJPSAqbHBscGtleTsKCQltZW1zZXQobHB4a2V5LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpOwoJCWxweGtleS0+a2V5bmFtZQk9IGtleW5hbWU7Cgl9IGVsc2UKCQlmcmVlKGtleW5hbWUpOwoJcmV0dXJuIGxweGtleTsKfQoKc3RhdGljIHZvaWQKX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJTFBLRVlTVFJVQ1QgbHBrZXksTFBXU1RSIG5hbWUsRFdPUkQgdHlwZSxMUEJZVEUgZGF0YSxEV09SRCBsZW4sCglEV09SRCBsYXN0bW9kaWZpZWQKKSB7CglMUEtFWVZBTFVFCXZhbD1OVUxMOwoJaW50CQlpOwoKCWlmIChuYW1lICYmICEqbmFtZSkgey8qIGVtcHR5IHN0cmluZyBlcXVhbHMgZGVmYXVsdCAoTlVMTCkgdmFsdWUgKi8KCQlmcmVlKG5hbWUpOwoJCW5hbWUgPSBOVUxMOwoJfQoKCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJdmFsPWxwa2V5LT52YWx1ZXMraTsKCQlpZiAobmFtZT09TlVMTCkgewoJCQlpZiAodmFsLT5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7CgkJfSBlbHNlIHsKCQkJaWYgKAl2YWwtPm5hbWUhPU5VTEwgJiYgCgkJCQkhbHN0cmNtcGkzMlcodmFsLT5uYW1lLG5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJCX0KCX0KCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewoJCWxwa2V5LT52YWx1ZXMgPSB4cmVhbGxvYygKCQkJbHBrZXktPnZhbHVlcywKCQkJKCsrbHBrZXktPm5yb2Z2YWx1ZXMpKnNpemVvZihLRVlWQUxVRSkKCQkpOwoJCXZhbD1scGtleS0+dmFsdWVzK2k7CgkJbWVtc2V0KHZhbCwnXDAnLHNpemVvZihLRVlWQUxVRSkpOwoJCXZhbC0+bmFtZSA9IG5hbWU7Cgl9IGVsc2UgewoJCWlmIChuYW1lKQoJCQlmcmVlKG5hbWUpOwoJfQoJaWYgKHZhbC0+bGFzdG1vZGlmaWVkPGxhc3Rtb2RpZmllZCkgewoJCXZhbC0+bGFzdG1vZGlmaWVkPWxhc3Rtb2RpZmllZDsKCQl2YWwtPnR5cGUgPSB0eXBlOwoJCXZhbC0+bGVuICA9IGxlbjsKCQlpZiAodmFsLT5kYXRhKSAKCQkJZnJlZSh2YWwtPmRhdGEpOwoJCXZhbC0+ZGF0YSA9IGRhdGE7Cgl9IGVsc2UKCQlmcmVlKGRhdGEpOwp9CgoKLyogcmVhZHMgYSBsaW5lIGluY2x1ZGluZyBkeW5hbWljYWxseSBlbmxhcmdpbmcgdGhlIHJlYWRidWZmZXIgYW5kIHRocm93aW5nCiAqIGF3YXkgY29tbWVudHMKICovCnN0YXRpYyBpbnQgCl93aW5lX3JlYWRfbGluZShGSUxFICpGLGNoYXIgKipidWYsaW50ICpsZW4pIHsKCWNoYXIJKnMsKmN1cnJlYWQ7CglpbnQJbXlsZW4sY3Vyb2ZmOwoKCWN1cnJlYWQJPSAqYnVmOwoJbXlsZW4JPSAqbGVuOwoJKipidWYJPSAnXDAnOwoJd2hpbGUgKDEpIHsKCQl3aGlsZSAoMSkgewoJCQlzPWZnZXRzKGN1cnJlYWQsbXlsZW4sRik7CgkJCWlmIChzPT1OVUxMKQoJCQkJcmV0dXJuIDA7IC8qIEVPRiAqLwoJCQlpZiAoTlVMTD09KHM9c3RyY2hyKGN1cnJlYWQsJ1xuJykpKSB7CgkJCQkvKiBidWZmZXIgd2Fzbid0IGxhcmdlIGVub3VnaCAqLwoJCQkJY3Vyb2ZmCT0gc3RybGVuKCpidWYpOwoJCQkJKmJ1Zgk9IHhyZWFsbG9jKCpidWYsKmxlbioyKTsKCQkJCWN1cnJlYWQJPSAqYnVmICsgY3Vyb2ZmOwoJCQkJbXlsZW4JPSAqbGVuOwkvKiB3ZSBmaWxsZWQgdXAgdGhlIGJ1ZmZlciBhbmQgCgkJCQkJCSAqIGdvdCBuZXcgJypsZW4nIGJ5dGVzIHRvIGZpbGwKCQkJCQkJICovCgkJCQkqbGVuCT0gKmxlbiAqIDI7CgkJCX0gZWxzZSB7CgkJCQkqcz0nXDAnOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLyogdGhyb3cgYXdheSBjb21tZW50cyAqLwoJCWlmICgqKmJ1Zj09JyMnIHx8ICoqYnVmPT0nOycpIHsKCQkJY3VycmVhZAk9ICpidWY7CgkJCW15bGVuCT0gKmxlbjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzKSAJLyogZ290IGVuZCBvZiBsaW5lICovCgkJCWJyZWFrOwoJfQoJcmV0dXJuIDE7Cn0KCi8qIGNvbnZlcnRzIGEgY2hhciogaW50byBhIFVOSUNPREUgc3RyaW5nICh1cCB0byBhIHNwZWNpYWwgY2hhcikKICogYW5kIHJldHVybnMgdGhlIHBvc2l0aW9uIGV4YWN0bHkgYWZ0ZXIgdGhhdCBzdHJpbmcKICovCnN0YXRpYyBjaGFyKgpfd2luZV9yZWFkX1VTVFJJTkcoY2hhciAqYnVmLExQV1NUUiAqc3RyKSB7CgljaGFyCSpzOwoJTFBXU1RSCXdzOwoKCS8qIHJlYWQgdXAgdG8gIj0iIG9yICJcMCIgb3IgIlxuIiAqLwoJcwk9IGJ1ZjsKCWlmICgqcyA9PSAnPScpIHsKCQkvKiBlbXB0eSBzdHJpbmcgaXMgdGhlIHdpbjMuMSBkZWZhdWx0IHZhbHVlKE5VTEwpKi8KCQkqc3RyCT0gTlVMTDsKCQlyZXR1cm4gczsKCX0KCSpzdHIJPSAoTFBXU1RSKXhtYWxsb2MoMipzdHJsZW4oYnVmKSsyKTsKCXdzCT0gKnN0cjsKCXdoaWxlICgqcyAmJiAoKnMhPSdcbicpICYmICgqcyE9Jz0nKSkgewoJCWlmICgqcyE9J1xcJykKCQkJKndzKys9KigodW5zaWduZWQgY2hhciopcysrKTsKCQllbHNlIHsKCQkJcysrOwoJCQlpZiAoKnM9PSdcXCcpIHsKCQkJCSp3cysrPSdcXCc7CgkJCQlzKys7CgkJCQljb250aW51ZTsKCQkJfQoJCQlpZiAoKnMhPSd1JykgewoJCQkJV0FSTihyZWcsIk5vbiB1bmljb2RlIGVzY2FwZSBzZXF1ZW5jZSBcXCVjIGZvdW5kIGluIHwlc3xcbiIsKnMsYnVmKTsKCQkJCSp3cysrPSdcXCc7CgkJCQkqd3MrKz0qcysrOwoJCQl9IGVsc2UgewoJCQkJY2hhcgl4YnVmWzVdOwoJCQkJaW50CXdjOwoKCQkJCXMrKzsKCQkJCW1lbWNweSh4YnVmLHMsNCk7eGJ1Zls0XT0nXDAnOwoJCQkJaWYgKCFzc2NhbmYoeGJ1ZiwiJXgiLCZ3YykpCgkJCQkJV0FSTihyZWcsIlN0cmFuZ2UgZXNjYXBlIHNlcXVlbmNlICVzIGZvdW5kIGluIHwlc3xcbiIseGJ1ZixidWYpOwoJCQkJcys9NDsKCQkJCSp3cysrCT0odW5zaWduZWQgc2hvcnQpd2M7CgkJCX0KCQl9Cgl9Cgkqd3MJPSAwOwoJd3MJPSAqc3RyOwoJaWYgKCp3cykKCQkqc3RyCT0gc3RyZHVwVygqc3RyKTsKCWVsc2UKCQkqc3RyCT0gTlVMTDsKCWZyZWUod3MpOwoJcmV0dXJuIHM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJrZXkgW0ludGVybmFsXQogKgogKiBOT1RFUwogKiAgICBJdCBzZWVtcyBsaWtlIHRoaXMgaXMgcmV0dXJuaW5nIGEgYm9vbGVhbi4gIFNob3VsZCBpdD8KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiAxCiAqICAgIEZhaWx1cmU6IDAKICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YmtleSggRklMRSAqRiwgTFBLRVlTVFJVQ1QgbHBrZXksIGludCBsZXZlbCwgY2hhciAqKmJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKmJ1ZmxlbiwgRFdPUkQgb3B0ZmxhZyApCnsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJaTsKCWNoYXIJCSpzOwoJTFBXU1RSCQluYW1lOwoKICAgIFRSQUNFKHJlZywiKCVwLCVwLCVkLCVzLCVkLCVseClcbiIsIEYsIGxwa2V5LCBsZXZlbCwgZGVidWdzdHJfYSgqYnVmKSwKICAgICAgICAgICpidWZsZW4sIG9wdGZsYWcpOwoKICAgIGxwa2V5LT5mbGFncyB8PSBvcHRmbGFnOwoKICAgIC8qIEdvb2QuICBXZSBhbHJlYWR5IGdvdCBhIGxpbmUgaGVyZSAuLi4gc28gcGFyc2UgaXQgKi8KICAgIGxweGtleSA9IE5VTEw7CiAgICB3aGlsZSAoMSkgewogICAgICAgIGk9MDtzPSpidWY7CiAgICAgICAgd2hpbGUgKCpzPT0nXHQnKSB7CiAgICAgICAgICAgIHMrKzsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KICAgICAgICBpZiAoaT5sZXZlbCkgewogICAgICAgICAgICBpZiAobHB4a2V5PT1OVUxMKSB7CiAgICAgICAgICAgICAgICBXQVJOKHJlZywiR290IGEgc3ViaGllcmFyY2h5IHdpdGhvdXQgcmVzcC4ga2V5P1xuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBfd2luZV9sb2Fkc3Via2V5KEYsbHB4a2V5LGxldmVsKzEsYnVmLGJ1ZmxlbixvcHRmbGFnKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKCQkvKiBsZXQgdGhlIGNhbGxlciBoYW5kbGUgdGhpcyBsaW5lICovCgkJaWYgKGk8bGV2ZWwgfHwgKipidWY9PSdcMCcpCgkJCXJldHVybiAxOwoKCQkvKiBpdCBjYW4gYmU6IGEgdmFsdWUgb3IgYSBrZXluYW1lLiBQYXJzZSB0aGUgbmFtZSBmaXJzdCAqLwoJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsJm5hbWUpOwoKCQkvKiBzd2l0Y2goKSBkZWZhdWx0OiBoYWNrIHRvIGF2b2lkIGdvdG9zICovCgkJc3dpdGNoICgwKSB7CgkJZGVmYXVsdDoKCQkJaWYgKCpzPT0nXDAnKSB7CgkJCQlscHhrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxuYW1lKTsKCQkJfSBlbHNlIHsKCQkJCUxQQllURQkJZGF0YTsKCQkJCWludAkJbGVuLGxhc3Rtb2RpZmllZCx0eXBlOwoKCQkJCWlmICgqcyE9Jz0nKSB7CgkJCQkJV0FSTihyZWcsIlVuZXhwZWN0ZWQgY2hhcmFjdGVyOiAlY1xuIiwqcyk7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlzKys7CgkJCQlpZiAoMiE9c3NjYW5mKHMsIiVkLCVkLCIsJnR5cGUsJmxhc3Rtb2RpZmllZCkpIHsKCQkJCQlXQVJOKHJlZywiSGF2ZW4ndCB1bmRlcnN0b29kIHBvc3NpYmxlIHZhbHVlIGluIHwlc3wsIHNraXBwaW5nLlxuIiwqYnVmKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCS8qIHNraXAgdGhlIDIgLCAqLwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlpZiAoKDE8PHR5cGUpICYgVU5JQ09OVk1BU0spIHsKCQkJCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLChMUFdTVFIqKSZkYXRhKTsKCQkJCQlpZiAoZGF0YSkKCQkJCQkJbGVuID0gbHN0cmxlbjMyVygoTFBXU1RSKWRhdGEpKjIrMjsKCQkJCQllbHNlCQoJCQkJCQlsZW4gPSAwOwoJCQkJfSBlbHNlIHsKCQkJCQlsZW49c3RybGVuKHMpLzI7CgkJCQkJZGF0YSA9IChMUEJZVEUpeG1hbGxvYyhsZW4rMSk7CgkJCQkJZm9yIChpPTA7aTxsZW47aSsrKSB7CgkJCQkJCWRhdGFbaV09MDsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV09KCpzLScwJyk8PDQ7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nYScrJ1x4YScpPDw0OwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ0EnKydceGEnKTw8NDsKCQkJCQkJcysrOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXXw9KnMtJzAnOwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ2EnKydceGEnOwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ0EnKydceGEnOwoJCQkJCQlzKys7CgkJCQkJfQoJCQkJfQoJCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKGxwa2V5LG5hbWUsdHlwZSxkYXRhLGxlbixsYXN0bW9kaWZpZWQpOwoJCQl9CgkJfQoJCS8qIHJlYWQgdGhlIG5leHQgbGluZSAqLwoJCWlmICghX3dpbmVfcmVhZF9saW5lKEYsYnVmLGJ1ZmxlbikpCgkJCXJldHVybiAxOwogICAgfQogICAgcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3VicmVnKCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgRFdPUkQgb3B0ZmxhZyApCnsKCWludAl2ZXI7CgljaGFyCSpidWY7CglpbnQJYnVmbGVuOwoKCWJ1Zj14bWFsbG9jKDEwKTtidWZsZW49MTA7CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXNzY2FuZihidWYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAodmVyIT1SRUdJU1RSWV9TQVZFX1ZFUlNJT04pIHsKCQlUUkFDRShyZWcsIk9sZCBmb3JtYXQgKCVkKSByZWdpc3RyeSBmb3VuZCwgaWdub3JpbmcgaXQuIChidWYgd2FzICVzKS5cbiIsdmVyLGJ1Zik7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9sb2Fkc3Via2V5KEYsbHBrZXksMCwmYnVmLCZidWZsZW4sb3B0ZmxhZykpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglmcmVlKGJ1Zik7CglyZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfd2luZV9sb2FkcmVnKCBMUEtFWVNUUlVDVCBscGtleSwgY2hhciAqZm4sIERXT1JEIG9wdGZsYWcgKQp7CiAgICBGSUxFICpGOwoKICAgIFRSQUNFKHJlZywiKCVwLCVzLCVseClcbiIsbHBrZXksZGVidWdzdHJfYShmbiksb3B0ZmxhZyk7CgogICAgRiA9IGZvcGVuKGZuLCJyYiIpOwogICAgaWYgKEY9PU5VTEwpIHsKICAgICAgICBXQVJOKHJlZywiQ291bGRuJ3Qgb3BlbiAlcyBmb3IgcmVhZGluZzogJXNcbiIsZm4sc3RyZXJyb3IoZXJybm8pICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKCFfd2luZV9sb2Fkc3VicmVnKEYsbHBrZXksb3B0ZmxhZykpIHsKICAgICAgICBmY2xvc2UoRik7CiAgICAgICAgdW5saW5rKGZuKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmY2xvc2UoRik7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9jb3B5X3JlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9jb3B5X3JlZ2lzdHJ5KCBMUEtFWVNUUlVDVCBmcm9tLCBMUEtFWVNUUlVDVCB0byApCnsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJajsKCUxQS0VZVkFMVUUJdmFsZnJvbTsKCglmcm9tPWZyb20tPm5leHRzdWI7Cgl3aGlsZSAoZnJvbSkgewoJCWxweGtleSA9IF9maW5kX29yX2FkZF9rZXkodG8sc3RyZHVwVyhmcm9tLT5rZXluYW1lKSk7CgoJCWZvciAoaj0wO2o8ZnJvbS0+bnJvZnZhbHVlcztqKyspIHsKCQkJTFBXU1RSCW5hbWU7CgkJCUxQQllURQlkYXRhOwoKCQkJdmFsZnJvbSA9IGZyb20tPnZhbHVlcytqOwoJCQluYW1lPXZhbGZyb20tPm5hbWU7CgkJCWlmIChuYW1lKSBuYW1lPXN0cmR1cFcobmFtZSk7CgkJCWRhdGE9KExQQllURSl4bWFsbG9jKHZhbGZyb20tPmxlbik7CgkJCW1lbWNweShkYXRhLHZhbGZyb20tPmRhdGEsdmFsZnJvbS0+bGVuKTsKCgkJCV9maW5kX29yX2FkZF92YWx1ZSgKCQkJCWxweGtleSwKCQkJCW5hbWUsCgkJCQl2YWxmcm9tLT50eXBlLAoJCQkJZGF0YSwKCQkJCXZhbGZyb20tPmxlbiwKCQkJCXZhbGZyb20tPmxhc3Rtb2RpZmllZAoJCQkpOwoJCX0KCQlfY29weV9yZWdpc3RyeShmcm9tLGxweGtleSk7CgkJZnJvbSA9IGZyb20tPm5leHQ7Cgl9Cn0KCgovKiBXSU5ET1dTIDk1IFJFR0lTVFJZIExPQURFUiAqLwovKiAKICogU3RydWN0dXJlIG9mIGEgd2luOTUgcmVnaXN0cnkgZGF0YWJhc2UuCiAqIG1haW4gaGVhZGVyOgogKiAwIDoJIkNSRUciCS0gbWFnaWMKICogNCA6CURXT1JEIHZlcnNpb24KICogOCA6CURXT1JEIG9mZnNldF9vZl9SR0RCX3BhcnQKICogMEMuLjBGOgk/IChzb21lb25lIGZpbGwgaW4gcGxlYXNlKQogKiAxMDogIFdPUkQJbnVtYmVyIG9mIFJHREIgYmxvY2tzCiAqIDEyOiAgV09SRAk/CiAqIDE0OiAgV09SRAlhbHdheXMgMDAwMD8KICogMTY6ICBXT1JECWFsd2F5cyAwMDAxPwogKiAxOC4uMUY6CT8gKHNvbWVvbmUgZmlsbCBpbiBwbGVhc2UpCiAqCiAqIDIwOiBSR0tOX3NlY3Rpb246CiAqICAgaGVhZGVyOgogKiAJMCA6CQkiUkdLTiIJLSBtYWdpYwogKiAgICAgIDQgOiBEV09SRAlvZmZzZXQgdG8gZmlyc3QgUkdEQiBzZWN0aW9uCiAqICAgICAgOCA6IERXT1JECW9mZnNldCB0byA/CiAqIAlDLi4weDFCOiAJPyAoZmlsbCBpbikKICogICAgICAweDIwIC4uLiBvZmZzZXRfb2ZfUkdEQl9wYXJ0OiBEaXNrIEtleSBFbnRyeSBzdHJ1Y3R1cmVzCiAqCiAqICAgRGlzayBLZXkgRW50cnkgU3RydWN0dXJlOgogKgkwMDogRFdPUkQJLSBGcmVlIGVudHJ5IGluZGljYXRvcig/KQogKgkwNDogRFdPUkQJLSBIYXNoID0gc3VtIG9mIGJ5dGVzIG9mIGtleW5hbWUKICoJMDg6IERXT1JECS0gUm9vdCBrZXkgaW5kaWNhdG9yPyB1bmtub3duLCBidXQgdXN1YWxseSAweEZGRkZGRkZGIG9uIHdpbjk1IHN5c3RlbXMKICoJMEM6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIFByZXZpb3VzTGV2ZWwgS2V5LgogKgkxMDogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgTmV4dCBTdWJsZXZlbCBLZXkuCiAqCTE0OiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBOZXh0IEtleSAob24gc2FtZSBsZXZlbCkuCiAqIERLRVA+MTg6IFdPUkQJLSBOciwgTG93IFNpZ25pZmljYW50IHBhcnQuCiAqCTFBOiBXT1JECS0gTnIsIEhpZ2ggU2lnbmlmaWNhbnQgcGFydC4KICoKICogVGhlIGRpc2sgYWRkcmVzcyBhbHdheXMgcG9pbnRzIHRvIHRoZSBuciBwYXJ0IG9mIHRoZSBwcmV2aW91cyBrZXkgZW50cnkgCiAqIG9mIHRoZSByZWZlcmVuY2VkIGtleS4gRG9uJ3QgYXNrIG1lIHdoeSwgb3IgZXZlbiBpZiBJIGdvdCB0aGlzIGNvcnJlY3QKICogZnJvbSBzdGFyaW5nIGF0IDFrZyBvZiBoZXhkdW1wcy4gKERLRVApCiAqCiAqIFRoZSBIaWdoIHNpZ25pZmljYW50IHBhcnQgb2YgdGhlIHN0cnVjdHVyZSBzZWVtcyB0byBlcXVhbCB0aGUgbnVtYmVyCiAqIG9mIHRoZSBSR0RCIHNlY3Rpb24uIFRoZSBsb3cgc2lnbmlmaWNhbnQgcGFydCBpcyBhIHVuaXF1ZSBJRCB3aXRoaW4KICogdGhhdCBSR0RCIHNlY3Rpb24KICoKICogVGhlcmUgYXJlIHR3byBtaW5vciBjb3JyZWN0aW9ucyB0byB0aGUgcG9zaXRpb24gb2YgdGhhdCBzdHJ1Y3R1cmUuCiAqIDEuIElmIHRoZSBhZGRyZXNzIGlzIHh4eDAxNCBvciB4eHgwMTggaXQgd2lsbCBiZSBhbGlnbmVkIHRvIHh4eDAxYyBBTkQgCiAqICAgIHRoZSBES0UgcmVyZWFkIGZyb20gdGhlcmUuCiAqIDIuIElmIHRoZSBhZGRyZXNzIGlzIHh4eEZGeCBpdCB3aWxsIGJlIGFsaWduZWQgdG8gKHh4eCsxKTAwMC4KICogQ1BTIC0gSSBoYXZlIG5vdCBleHBlcmllbmNlZCB0aGUgYWJvdmUgcGhlbm9tZW5vbiBpbiBteSByZWdpc3RyeSBmaWxlcwogKgogKiBSR0RCX3NlY3Rpb246CiAqIAkwMDoJCSJSR0RCIgktIG1hZ2ljCiAqCTA0OiBEV09SRAlvZmZzZXQgdG8gbmV4dCBSR0RCIHNlY3Rpb24KICoJMDg6IERXT1JECT8KICoJMEM6IFdPUkQJYWx3YXlzIDAwMGQ/CiAqCTBFOiBXT1JECVJHREIgYmxvY2sgbnVtYmVyCiAqCTEwOglEV09SRAk/IChlcXVhbHMgdmFsdWUgYXQgb2Zmc2V0IDQgLSB2YWx1ZSBhdCBvZmZzZXQgOCkKICoJMTQuLjFGOgkJPwogKgkyMC4uLi4uOglkaXNrIGtleXMKICoKICogZGlzayBrZXk6CiAqIAkwMDogCURXT1JECW5leHRrZXlvZmZzZXQJLSBvZmZzZXQgdG8gdGhlIG5leHQgZGlzayBrZXkgc3RydWN0dXJlCiAqCTA4OiAJV09SRAluckxTCQktIGxvdyBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBBOiAJV09SRAluckhTCQktIGhpZ2ggc2lnbmlmaWNhbnQgcGFydCBvZiBOUgogKgkwQzogCURXT1JECWJ5dGVzdXNlZAktIGJ5dGVzIHVzZWQgaW4gdGhpcyBzdHJ1Y3R1cmUuCiAqCTEwOiAJV09SRAluYW1lX2xlbgktIGxlbmd0aCBvZiBuYW1lIGluIGJ5dGVzLiB3aXRob3V0IFwwCiAqCTEyOiAJV09SRAlucl9vZl92YWx1ZXMJLSBudW1iZXIgb2YgdmFsdWVzLgogKgkxNDogCWNoYXIJbmFtZVtuYW1lX2xlbl0JLSBuYW1lIHN0cmluZy4gTm8gXDAuCiAqCTE0K25hbWVfbGVuOiBkaXNrIHZhbHVlcwogKgluZXh0a2V5b2Zmc2V0OiAuLi4gbmV4dCBkaXNrIGtleQogKgogKiBkaXNrIHZhbHVlOgogKgkwMDoJRFdPUkQJdHlwZQkJLSB2YWx1ZSB0eXBlIChobW0sIGNvdWxkIGJlIFdPUkQgdG9vKQogKgkwNDoJRFdPUkQJCQktIHVua25vd24sIHVzdWFsbHkgMAogKgkwODoJV09SRAluYW1lbGVuCQktIGxlbmd0aCBvZiBOYW1lLiAwIG1lYW5zIG5hbWU9TlVMTAogKgkwQzoJV09SRAlkYXRhbGVuCQktIGxlbmd0aCBvZiBEYXRhLgogKgkxMDoJY2hhcgluYW1lW25hbWVsZW5dCS0gbmFtZSwgbm8gXDAKICoJMTArbmFtZWxlbjogQllURQlkYXRhW2RhdGFsZW5dIC0gZGF0YSwgd2l0aG91dCBcMCBpZiBzdHJpbmcKICoJMTArbmFtZWxlbitkYXRhbGVuOiBuZXh0IHZhbHVlcyBvciBkaXNrIGtleQogKgogKiBEaXNrIGtleXMgYXJlIGxheWVkIG91dCBmbGF0IC4uLiBCdXQsIHNvbWV0aW1lcywgbnJMUyBhbmQgbnJIUyBhcmUgYm90aAogKiAweEZGRkYsIHdoaWNoIG1lYW5zIHNraXBwaW5nIG92ZXIgbmV4dGtleW9mZnNldCBieXRlcyAoaW5jbHVkaW5nIHRoaXMKICogc3RydWN0dXJlKSBhbmQgcmVhZGluZyBhbm90aGVyIFJHREJfc2VjdGlvbi4KICogcmVwZWF0IHVudGlsIGVuZCBvZiBmaWxlLgogKgogKiBBbiBpbnRlcmVzdGluZyByZWxhdGlvbnNoaXAgZXhpc3RzIGluIFJHREJfc2VjdGlvbi4gVGhlIHZhbHVlIGF0IG9mZnNldAogKiAxMCBlcXVhbHMgdGhlIHZhbHVlIGF0IG9mZnNldCA0IG1pbnVzIHRoZSB2YWx1ZSBhdCBvZmZzZXQgOC4gSSBoYXZlIG5vCiAqIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKgogKiBGSVhNRTogdGhpcyBkZXNjcmlwdGlvbiBuZWVkcyBzb21lIHNlcmlvdXMgaGVscCwgeWVzLgogKi8KCnN0cnVjdAlfdzk1a2V5dmFsdWUgewoJdW5zaWduZWQgbG9uZwkJdHlwZTsKCXVuc2lnbmVkIHNob3J0CQlkYXRhbGVuOwoJY2hhcgkJCSpuYW1lOwoJdW5zaWduZWQgY2hhcgkJKmRhdGE7Cgl1bnNpZ25lZCBsb25nCQl4MTsKCWludAkJCWxhc3Rtb2RpZmllZDsKfTsKCnN0cnVjdCAJX3c5NWtleSB7CgljaGFyCQkJKm5hbWU7CglpbnQJCQlucm9mdmFsczsKCXN0cnVjdAlfdzk1a2V5dmFsdWUJKnZhbHVlczsKCXN0cnVjdCBfdzk1a2V5CQkqcHJldmx2bDsKCXN0cnVjdCBfdzk1a2V5CQkqbmV4dHN1YjsKCXN0cnVjdCBfdzk1a2V5CQkqbmV4dDsKfTsKCgpzdHJ1Y3QgX3c5NV9pbmZvIHsKICBjaGFyICpyZ2tuYnVmZmVyOwogIGludCAgcmdrbnNpemU7CiAgY2hhciAqcmdkYmJ1ZmZlcjsKICBpbnQgIHJnZGJzaXplOwogIGludCAgZGVwdGg7CiAgaW50ICBsYXN0bW9kaWZpZWQ7Cn07CgpMUFdTVFIgc3RyY3Z0QTJXKExQQ1NUUiBzcmMsIGludCBuY2hhcnMpCgp7CiAgIExQV1NUUiBkZXN0ID0geG1hbGxvYyAoMiAqIG5jaGFycyArIDIpOwoKICAgbHN0cmNweW5BdG9XKGRlc3Qsc3JjLG5jaGFycysxKTsKICAgZGVzdFtuY2hhcnNdID0gMDsKICAgcmV0dXJuIGRlc3Q7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfcHJvY2Vzc0tleSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgX3c5NV9wcm9jZXNzS2V5ICggTFBLRVlTVFJVQ1QgbHBrZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuckxTLCBpbnQgbnJNUywgc3RydWN0IF93OTVfaW5mbyAqaW5mbyApCgp7CiAgLyogRGlzayBLZXkgSGVhZGVyIHN0cnVjdHVyZSAoUkdEQiBwYXJ0KSAqLwoJc3RydWN0CWRraCB7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nCQluZXh0a2V5b2ZmOyAKCQl1bnNpZ25lZCBzaG9ydAkJbnJMUzsKCQl1bnNpZ25lZCBzaG9ydAkJbnJNUzsKCQl1bnNpZ25lZCBsb25nCQlieXRlc3VzZWQ7CgkJdW5zaWduZWQgc2hvcnQJCWtleW5hbWVsZW47CgkJdW5zaWduZWQgc2hvcnQJCXZhbHVlczsKCQl1bnNpZ25lZCBsb25nCQl4eDE7CgkJLyoga2V5bmFtZSAqLwoJCS8qIGRpc2sga2V5IHZhbHVlcyBvciBub3RoaW5nICovCgl9OwoJLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlICovCglzdHJ1Y3QJZGt2IHsKCQl1bnNpZ25lZCBsb25nCQl0eXBlOwoJCXVuc2lnbmVkIGxvbmcJCXgxOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxuYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxkYXRhbGVuOwoJCS8qIHZhbG5hbWUsIHZhbGRhdGEgKi8KCX07CgoJCglzdHJ1Y3QJZGtoIGRraDsKCWludAlieXRlc3JlYWQgPSAwOwoJY2hhciAgICAqcmdkYmRhdGEgPSBpbmZvLT5yZ2RiYnVmZmVyOwoJaW50ICAgICBuYnl0ZXMgPSBpbmZvLT5yZ2Ric2l6ZTsKCWNoYXIgICAgKmN1cmRhdGEgPSByZ2RiZGF0YTsKCWNoYXIgICAgKmVuZCA9IHJnZGJkYXRhICsgbmJ5dGVzOwoJaW50ICAgICBvZmZfbmV4dF9yZ2RiOwoJY2hhciAgICAqbmV4dCA9IHJnZGJkYXRhOwoJaW50ICAgICBucmdkYiwgaTsKCUxQS0VZU1RSVUNUCWxweGtleTsKCQoJZG8gewoJICBjdXJkYXRhID0gbmV4dDsKCSAgaWYgKHN0cm5jbXAoY3VyZGF0YSwgIlJHREIiLCA0KSkgcmV0dXJuIChOVUxMKTsKCSAgICAKCSAgbWVtY3B5KCZvZmZfbmV4dF9yZ2RiLGN1cmRhdGErNCw0KTsKCSAgbmV4dCA9IGN1cmRhdGEgKyBvZmZfbmV4dF9yZ2RiOwoJICBucmdkYiA9IChpbnQpICooKHNob3J0ICopY3VyZGF0YSArIDcpOwoKCX0gd2hpbGUgKG5yZ2RiICE9IG5yTVMgJiYgKG5leHQgPCBlbmQpKTsKCgkvKiBjdXJkYXRhIG5vdyBwb2ludHMgdG8gdGhlIHN0YXJ0IG9mIHRoZSByaWdodCBSR0RCIHNlY3Rpb24gKi8KCWN1cmRhdGEgKz0gMHgyMDsKCiNkZWZpbmUgWFJFQUQod2hlcmV0byxsZW4pIFwKCWlmICgoY3VyZGF0YSArIGxlbikgPGVuZCkge1wKCQltZW1jcHkod2hlcmV0byxjdXJkYXRhLGxlbik7XAoJCWN1cmRhdGErPWxlbjtcCgkJYnl0ZXNyZWFkKz1sZW47XAoJfQoKCWRvIHsKCSAgWFJFQUQoJmRraCwgc2l6ZW9mIChka2gpKTsKCSAgaWYgKGRraC5uckxTID09IG5yTFMpIGJyZWFrOwoKCSAgY3VyZGF0YSArPSBka2gubmV4dGtleW9mZiAtIHNpemVvZihka2gpOwoJfSB3aGlsZSAoY3VyZGF0YSA8IG5leHQpOwoKCWlmIChka2gubnJMUyAhPSBuckxTKSByZXR1cm4gKE5VTEwpOwoKCWlmIChucmdkYiAhPSBka2gubnJNUykgewoJICByZXR1cm4gKE5VTEwpOwoJfQoKICAgICAgICBhc3NlcnQoKGRraC5rZXluYW1lbGVuPDIpIHx8IGN1cmRhdGFbMF0pOwoJbHB4a2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksc3RyY3Z0QTJXKGN1cmRhdGEsIGRraC5rZXluYW1lbGVuKSk7CgljdXJkYXRhICs9IGRraC5rZXluYW1lbGVuOwoKCWZvciAoaT0wO2k8IGRraC52YWx1ZXM7IGkrKykgewoJICBzdHJ1Y3QgZGt2IGRrdjsKCSAgTFBCWVRFIGRhdGE7CgkgIGludCBsZW47CgkgIExQV1NUUiBuYW1lOwoKCSAgWFJFQUQoJmRrdixzaXplb2YoZGt2KSk7CgoJICBuYW1lID0gc3RyY3Z0QTJXKGN1cmRhdGEsIGRrdi52YWxuYW1lbGVuKTsKCSAgY3VyZGF0YSArPSBka3YudmFsbmFtZWxlbjsKCgkgIGlmICgoMSA8PCBka3YudHlwZSkgJiBVTklDT05WTUFTSykgewoJICAgIGRhdGEgPSAoTFBCWVRFKSBzdHJjdnRBMlcoY3VyZGF0YSwgZGt2LnZhbGRhdGFsZW4pOwoJICAgIGxlbiA9IDIqKGRrdi52YWxkYXRhbGVuICsgMSk7CgkgIH0gZWxzZSB7CgkgICAgLyogSSBkb24ndCB0aGluayB3ZSB3YW50IHRvIE5VTEwgdGVybWluYXRlIGFsbCBkYXRhICovCgkgICAgZGF0YSA9IHhtYWxsb2MoZGt2LnZhbGRhdGFsZW4pOwoJICAgIG1lbWNweSAoZGF0YSwgY3VyZGF0YSwgZGt2LnZhbGRhdGFsZW4pOwoJICAgIGxlbiA9IGRrdi52YWxkYXRhbGVuOwoJICB9CgoJICBjdXJkYXRhICs9IGRrdi52YWxkYXRhbGVuOwoJICAKCSAgX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJCQkgICAgIGxweGtleSwKCQkJICAgICBuYW1lLAoJCQkgICAgIGRrdi50eXBlLAoJCQkgICAgIGRhdGEsCgkJCSAgICAgbGVuLAoJCQkgICAgIGluZm8tPmxhc3Rtb2RpZmllZAoJCQkgICAgICk7CgoJfQoKCXJldHVybiAobHB4a2V5KTsKfQoKc3RhdGljIHZvaWQKX3c5NV93YWxrcmdrbihMUEtFWVNUUlVDVCBwcmV2a2V5LCBjaGFyICpvZmYsIHN0cnVjdCBfdzk1X2luZm8gKmluZm8pCgp7CiAgLyogRGlzayBLZXkgRW50cnkgc3RydWN0dXJlIChSR0tOIHBhcnQpICovCiAgc3RydWN0CWRrZSB7CiAgICB1bnNpZ25lZCBsb25nCQl4MTsKICAgIHVuc2lnbmVkIGxvbmcJCXgyOwogICAgdW5zaWduZWQgbG9uZwkJeDM7Lyp1c3VhbGx5IDB4RkZGRkZGRkYgKi8KICAgIHVuc2lnbmVkIGxvbmcJCXByZXZsdmw7CiAgICB1bnNpZ25lZCBsb25nCQluZXh0c3ViOwogICAgdW5zaWduZWQgbG9uZwkJbmV4dDsKICAgIHVuc2lnbmVkIHNob3J0CQluckxTOwogICAgdW5zaWduZWQgc2hvcnQJCW5yTVM7CiAgfSAqZGtlID0gKHN0cnVjdCBka2UgKilvZmY7CiAgTFBLRVlTVFJVQ1QgIGxweGtleTsKCiAgaWYgKGRrZSA9PSBOVUxMKSB7CiAgICBka2UgPSAoc3RydWN0IGRrZSAqKSAoKGNoYXIgKilpbmZvLT5yZ2tuYnVmZmVyKTsKICB9CgogIGxweGtleSA9IF93OTVfcHJvY2Vzc0tleShwcmV2a2V5LCBka2UtPm5yTFMsIGRrZS0+bnJNUywgaW5mbyk7CiAgLyogWFhYIDwtLSBUaGlzIGlzIGEgaGFjayovCiAgaWYgKCFscHhrZXkpIHsKICAgIGxweGtleSA9IHByZXZrZXk7CiAgfQoKICBpZiAoZGtlLT5uZXh0c3ViICE9IC0xICYmIAogICAgICAoKGRrZS0+bmV4dHN1YiAtIDB4MjApIDwgaW5mby0+cmdrbnNpemUpIAogICAgICAmJiAoZGtlLT5uZXh0c3ViID4gMHgyMCkpIHsKICAgIAogICAgX3c5NV93YWxrcmdrbihscHhrZXksIAoJCSAgaW5mby0+cmdrbmJ1ZmZlciArIGRrZS0+bmV4dHN1YiAtIDB4MjAsIAoJCSAgaW5mbyk7CiAgfQogIAogIGlmIChka2UtPm5leHQgIT0gLTEgJiYgCiAgICAgICgoZGtlLT5uZXh0IC0gMHgyMCkgPCBpbmZvLT5yZ2tuc2l6ZSkgJiYgCiAgICAgIChka2UtPm5leHQgPiAweDIwKSkgewogICAgX3c5NV93YWxrcmdrbihwcmV2a2V5LCAgCgkJICBpbmZvLT5yZ2tuYnVmZmVyICsgZGtlLT5uZXh0IC0gMHgyMCwKCQkgIGluZm8pOwogIH0KCiAgcmV0dXJuOwp9CgpzdGF0aWMgdm9pZApfdzk1X2xvYWRyZWcoY2hhciogZm4sTFBLRVlTVFJVQ1QgbHBrZXkpIHsKCUhGSUxFMzIJCWhmZDsKCWNoYXIJCW1hZ2ljWzVdOwoJdW5zaWduZWQgbG9uZwl3aGVyZSx2ZXJzaW9uLHJnZGJzZWN0aW9uLGVuZDsKCXN0cnVjdCAgICAgICAgICBfdzk1X2luZm8gaW5mbzsKCU9GU1RSVUNUCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmZGluZm87CgoJVFJBQ0UocmVnLCJMb2FkaW5nIFdpbjk1IHJlZ2lzdHJ5IGRhdGFiYXNlICclcydcbiIsZm4pOwoJaGZkPU9wZW5GaWxlMzIoZm4sJm9mcyxPRl9SRUFEKTsKCWlmIChoZmQ9PUhGSUxFX0VSUk9SMzIpCgkJcmV0dXJuOwoJbWFnaWNbNF09MDsKCWlmICg0IT1fbHJlYWQzMihoZmQsbWFnaWMsNCkpCgkJcmV0dXJuOwoJaWYgKHN0cmNtcChtYWdpYywiQ1JFRyIpKSB7CgkJV0FSTihyZWcsIiVzIGlzIG5vdCBhIHc5NSByZWdpc3RyeS5cbiIsZm4pOwoJCXJldHVybjsKCX0KCWlmICg0IT1fbHJlYWQzMihoZmQsJnZlcnNpb24sNCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZDMyKGhmZCwmcmdkYnNlY3Rpb24sNCkpCgkJcmV0dXJuOwoJaWYgKC0xPT1fbGxzZWVrMzIoaGZkLDB4MjAsU0VFS19TRVQpKQoJCXJldHVybjsKCWlmICg0IT1fbHJlYWQzMihoZmQsbWFnaWMsNCkpCgkJcmV0dXJuOwoJaWYgKHN0cmNtcChtYWdpYywiUkdLTiIpKSB7CgkJV0FSTihyZWcsICJzZWNvbmQgSUZGIGhlYWRlciBub3QgUkdLTiwgYnV0ICVzXG4iLCBtYWdpYyk7CgkJcmV0dXJuOwoJfQoKCS8qIFNURVAgMTogS2V5bGluayBzdHJ1Y3R1cmVzICovCglpZiAoLTE9PV9sbHNlZWszMihoZmQsMHg0MCxTRUVLX1NFVCkpCgkJcmV0dXJuOwoJd2hlcmUJPSAweDQwOwoJZW5kCT0gcmdkYnNlY3Rpb247CgoJaW5mby5yZ2tuc2l6ZSA9IGVuZCAtIHdoZXJlOwoJaW5mby5yZ2tuYnVmZmVyID0gKGNoYXIqKXhtYWxsb2MoaW5mby5yZ2tuc2l6ZSk7CglpZiAoaW5mby5yZ2tuc2l6ZSAhPSBfbHJlYWQzMihoZmQsaW5mby5yZ2tuYnVmZmVyLGluZm8ucmdrbnNpemUpKQoJCXJldHVybjsKCglpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmZCwmaGZkaW5mbykpCgkJcmV0dXJuOwoKCWVuZCA9IGhmZGluZm8ubkZpbGVTaXplTG93OwoJaW5mby5sYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmZGluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoKCWlmICgtMT09X2xsc2VlazMyKGhmZCxyZ2Ric2VjdGlvbixTRUVLX1NFVCkpCgkJcmV0dXJuOwoKCWluZm8ucmdkYmJ1ZmZlciA9IChjaGFyKil4bWFsbG9jKGVuZC1yZ2Ric2VjdGlvbik7CglpbmZvLnJnZGJzaXplID0gZW5kIC0gcmdkYnNlY3Rpb247CgoJaWYgKGluZm8ucmdkYnNpemUgIT1fbHJlYWQzMihoZmQsaW5mby5yZ2RiYnVmZmVyLGluZm8ucmdkYnNpemUpKQoJCXJldHVybjsKCV9sY2xvc2UzMihoZmQpOwoKCV93OTVfd2Fsa3Jna24obHBrZXksIE5VTEwsICZpbmZvKTsKCglmcmVlIChpbmZvLnJnZGJidWZmZXIpOwoJZnJlZSAoaW5mby5yZ2tuYnVmZmVyKTsKfQoKCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCgovKgogICAgcmVnaGFjayAtIHdpbmRvd3MgMy4xMSByZWdpc3RyeSBkYXRhIGZvcm1hdCBkZW1vIHByb2dyYW0uCgogICAgVGhlIHJlZy5kYXQgZmlsZSBoYXMgMyBwYXJ0cywgYSBoZWFkZXIsIGEgdGFibGUgb2YgOC1ieXRlIGVudHJpZXMgdGhhdCBpcwogICAgYSBjb21iaW5lZCBoYXNoIHRhYmxlIGFuZCB0cmVlIGRlc2NyaXB0aW9uLCBhbmQgZmluYWxseSBhIHRleHQgdGFibGUuCgogICAgVGhlIGhlYWRlciBpcyBvYnZpb3VzIGZyb20gdGhlIHN0cnVjdCBoZWFkZXIuIFRoZSB0YWJvZmYxIGFuZCB0YWJvZmYyCiAgICBmaWVsZHMgYXJlIGFsd2F5cyAweDIwLCBhbmQgdGhlaXIgdXNhZ2UgaXMgdW5rbm93bi4KCiAgICBUaGUgOC1ieXRlIGVudHJ5IHRhYmxlIGhhcyB2YXJpb3VzIGVudHJ5IHR5cGVzLgoKICAgIHRhYmVudFswXSBpcyBhIHJvb3QgaW5kZXguIFRoZSBzZWNvbmQgd29yZCBoYXMgdGhlIGluZGV4IG9mIHRoZSByb290IG9mCiAgICAgICAgICAgIHRoZSBkaXJlY3RvcnkuCiAgICB0YWJlbnRbMS4uaGFzaHNpemVdIGlzIGEgaGFzaCB0YWJsZS4gVGhlIGZpcnN0IHdvcmQgaW4gdGhlIGhhc2ggZW50cnkgaXMKICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBrZXkvdmFsdWUgdGhhdCBoYXMgdGhhdCBoYXNoLiBEYXRhIHdpdGggdGhlIHNhbWUKICAgICAgICAgICAgaGFzaCB2YWx1ZSBhcmUgb24gYSBjaXJjdWxhciBsaXN0LiBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlCiAgICAgICAgICAgIGhhc2ggZW50cnkgYXJlIGFsd2F5cyB6ZXJvLgogICAgdGFiZW50W2hhc2hzaXplLi50YWJjbnRdIGlzIHRoZSB0cmVlIHN0cnVjdHVyZS4gVGhlcmUgYXJlIHR3byBraW5kcyBvZgogICAgICAgICAgICBlbnRyeTogZGlyZW50IGFuZCBrZXllbnQvdmFsZW50LiBUaGV5IGFyZSBpZGVudGlmaWVkIGJ5IGNvbnRleHQuCiAgICB0YWJlbnRbZnJlZWlkeF0gaXMgdGhlIGZpcnN0IGZyZWUgZW50cnkuIFRoZSBmaXJzdCB3b3JkIGluIGEgZnJlZSBlbnRyeQogICAgICAgICAgICBpcyB0aGUgaW5kZXggb2YgdGhlIG5leHQgZnJlZSBlbnRyeS4gVGhlIGxhc3QgaGFzIDAgYXMgYSBsaW5rLgogICAgICAgICAgICBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlIGZyZWUgbGlzdCBhcmUgcHJvYmFibHkgaXJyZWxldmFudC4KCiAgICBFbnRyaWVzIGluIHRleHQgdGFibGUgYXJlIHByZWNlZWRlZCBieSBhIHdvcmQgYXQgb2Zmc2V0LTIuIFRoaXMgd29yZAogICAgaGFzIHRoZSB2YWx1ZSAoMippbmRleCkrMSwgd2hlcmUgaW5kZXggaXMgdGhlIHJlZmVycmluZyBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBpbiB0aGUgdGFibGUuIEkgaGF2ZSBubyBzdWdnZXN0aW9uIGZvciB0aGUgMiogYW5kIHRoZSArMS4KICAgIEZvbGxvd2luZyB0aGUgd29yZCwgdGhlcmUgYXJlIE4gYnl0ZXMgb2YgZGF0YSwgYXMgcGVyIHRoZSBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBsZW5ndGguIFRoZSBvZmZzZXQgb2YgdGhlIGtleWVudC92YWxlbnQgZW50cnkgaXMgZnJvbSB0aGUgc3RhcnQKICAgIG9mIHRoZSB0ZXh0IHRhYmxlIHRvIHRoZSBmaXJzdCBkYXRhIGJ5dGUuCgogICAgVGhpcyBpbmZvcm1hdGlvbiBpcyBub3QgYXZhaWxhYmxlIGZyb20gTWljcm9zb2Z0LiBUaGUgZGF0YSBmb3JtYXQgaXMKICAgIGRlZHVjZWQgZnJvbSB0aGUgcmVnLmRhdCBmaWxlIGJ5IG1lLiBNaXN0YWtlcyBtYXkKICAgIGhhdmUgYmVlbiBtYWRlLiBJIGNsYWltIG5vIHJpZ2h0cyBhbmQgZ2l2ZSBubyBndWFyYW50ZWVzIGZvciB0aGlzIHByb2dyYW0uCgogICAgVG9yIFNq+HdhbGwsIHRvckBzbi5ubwoqLwoKLyogcmVnLmRhdCBoZWFkZXIgZm9ybWF0ICovCnN0cnVjdCBfdzMxX2hlYWRlciB7CgljaGFyCQljb29raWVbOF07CS8qICdTSENDMy4xMCcgKi8KCXVuc2lnbmVkIGxvbmcJdGFib2ZmMTsJLyogb2Zmc2V0IG9mIGhhc2ggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFib2ZmMjsJLyogb2Zmc2V0IG9mIGluZGV4IHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYmNudDsJCS8qIG51bWJlciBvZiBlbnRyaWVzIGluIGluZGV4IHRhYmxlICovCgl1bnNpZ25lZCBsb25nCXRleHRvZmY7CS8qIG9mZnNldCBvZiB0ZXh0IHBhcnQgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dHNpemU7CS8qIGJ5dGUgc2l6ZSBvZiB0ZXh0IHBhcnQgKi8KCXVuc2lnbmVkIHNob3J0CWhhc2hzaXplOwkvKiBoYXNoIHNpemUgKi8KCXVuc2lnbmVkIHNob3J0CWZyZWVpZHg7CS8qIGZyZWUgaW5kZXggKi8KfTsKCi8qIGdlbmVyaWMgZm9ybWF0IG9mIHRhYmxlIGVudHJpZXMgKi8Kc3RydWN0IF93MzFfdGFiZW50IHsKCXVuc2lnbmVkIHNob3J0IHcwLCB3MSwgdzIsIHczOwp9OwoKLyogZGlyZWN0b3J5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfZGlyZW50IHsKCXVuc2lnbmVkIHNob3J0CXNpYmxpbmdfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBzaWJsaW5nIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJY2hpbGRfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBjaGlsZCBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWtleV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGtleSBrZXllbnQgKi8KCXVuc2lnbmVkIHNob3J0CXZhbHVlX2lkeDsJLyogdGFibGUgaW5kZXggb2YgdmFsdWUgdmFsZW50ICovCn07CgovKiBrZXkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9rZXllbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHZhbHVlIHRhYmVudDogKi8Kc3RydWN0IF93MzFfdmFsZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiByZWN1cnNpdmUgaGVscGVyIGZ1bmN0aW9uIHRvIGRpc3BsYXkgYSBkaXJlY3RvcnkgdHJlZSAqLwp2b2lkCl9fdzMxX2R1bXB0cmVlKAl1bnNpZ25lZCBzaG9ydCBpZHgsCgkJdW5zaWduZWQgY2hhciAqdHh0LAoJCXN0cnVjdCBfdzMxX3RhYmVudCAqdGFiLAoJCXN0cnVjdCBfdzMxX2hlYWRlciAqaGVhZCwKCQlMUEtFWVNUUlVDVAlscGtleSwKCQl0aW1lX3QJCWxhc3Rtb2RpZmllZCwKCQlpbnQJCWxldmVsCikgewoJc3RydWN0IF93MzFfZGlyZW50CSpkaXI7CglzdHJ1Y3QgX3czMV9rZXllbnQJKmtleTsKCXN0cnVjdCBfdzMxX3ZhbGVudAkqdmFsOwoJTFBLRVlTVFJVQ1QJCXhscGtleSA9IE5VTEw7CglMUFdTVFIJCQluYW1lLHZhbHVlOwoJc3RhdGljIGNoYXIJCXRhaWxbNDAwXTsKCgl3aGlsZSAoaWR4IT0wKSB7CgkJZGlyPShzdHJ1Y3QgX3czMV9kaXJlbnQqKSZ0YWJbaWR4XTsKCgkJaWYgKGRpci0+a2V5X2lkeCkgewoJCQlrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgoJCQltZW1jcHkodGFpbCwmdHh0W2tleS0+c3RyaW5nX29mZl0sa2V5LT5sZW5ndGgpOwoJCQl0YWlsW2tleS0+bGVuZ3RoXT0nXDAnOwoJCQkvKiBhbGwgdG9wbGV2ZWwgZW50cmllcyBBTkQgdGhlIGVudHJpZXMgaW4gdGhlIAoJCQkgKiB0b3BsZXZlbCBzdWJkaXJlY3RvcnkgYmVsb25nIHRvIFxTT0ZUV0FSRVxDbGFzc2VzCgkJCSAqLwoJCQlpZiAoIWxldmVsICYmICFsc3RyY21wMzJBKHRhaWwsIi5jbGFzc2VzIikpIHsKCQkJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxscGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJCQlpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCW5hbWU9c3RyZHVwQTJXKHRhaWwpOwoKCQkJeGxwa2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksbmFtZSk7CgoJCQkvKiBvbmx5IGFkZCBpZiBsZWFmIG5vZGUgb3IgdmFsdWVkIG5vZGUgKi8KCQkJaWYgKGRpci0+dmFsdWVfaWR4IT0wfHxkaXItPmNoaWxkX2lkeD09MCkgewoJCQkJaWYgKGRpci0+dmFsdWVfaWR4KSB7CgkJCQkJdmFsPShzdHJ1Y3QgX3czMV92YWxlbnQqKSZ0YWJbZGlyLT52YWx1ZV9pZHhdOwoJCQkJCW1lbWNweSh0YWlsLCZ0eHRbdmFsLT5zdHJpbmdfb2ZmXSx2YWwtPmxlbmd0aCk7CgkJCQkJdGFpbFt2YWwtPmxlbmd0aF09J1wwJzsKCQkJCQl2YWx1ZT1zdHJkdXBBMlcodGFpbCk7CgkJCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKHhscGtleSxOVUxMLFJFR19TWiwoTFBCWVRFKXZhbHVlLGxzdHJsZW4zMlcodmFsdWUpKjIrMixsYXN0bW9kaWZpZWQpOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJVFJBQ0UocmVnLCJzdHJhbmdlOiBubyBkaXJlY3Rvcnkga2V5IG5hbWUsIGlkeD0lMDR4XG4iLCBpZHgpOwoJCX0KCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQseGxwa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQlpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3czMV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnZvaWQgX3czMV9sb2FkcmVnKCkgewoJSEZJTEUzMgkJCWhmOwoJc3RydWN0IF93MzFfaGVhZGVyCWhlYWQ7CglzdHJ1Y3QgX3czMV90YWJlbnQJKnRhYjsKCXVuc2lnbmVkIGNoYXIJCSp0eHQ7CglpbnQJCQlsZW47CglPRlNUUlVDVAkJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZpbmZvOwoJdGltZV90CQkJbGFzdG1vZGlmaWVkOwoJSEtFWQkJCWhrZXk7CglMUEtFWVNUUlVDVAkJbHBrZXk7CgogICAgVFJBQ0UocmVnLCIodm9pZClcbiIpOwoKCWhmID0gT3BlbkZpbGUzMigicmVnLmRhdCIsJm9mcyxPRl9SRUFEKTsKCWlmIChoZj09SEZJTEVfRVJST1IzMikKCQlyZXR1cm47CgoJLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCglpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQzMihoZiwmaGVhZCxzaXplb2YoaGVhZCkpKSB7CgkJRVJSKHJlZywgInJlZy5kYXQgaXMgdG9vIHNob3J0LlxuIik7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSE9MCkgewoJCUVSUihyZWcsICJyZWcuZGF0IGhhcyBiYWQgc2lnbmF0dXJlLlxuIik7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CgoJbGVuID0gaGVhZC50YWJjbnQgKiBzaXplb2Yoc3RydWN0IF93MzFfdGFiZW50KTsKCS8qIHJlYWQgYW5kIGR1bXAgaW5kZXggdGFibGUgKi8KCXRhYiA9IHhtYWxsb2MobGVuKTsKCWlmIChsZW4hPV9scmVhZDMyKGhmLHRhYixsZW4pKSB7CgkJRVJSKHJlZywiY291bGRuJ3QgcmVhZCAlZCBieXRlcy5cbiIsbGVuKTsgCgkJZnJlZSh0YWIpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoKCS8qIHJlYWQgdGV4dCAqLwoJdHh0ID0geG1hbGxvYyhoZWFkLnRleHRzaXplKTsKCWlmICgtMT09X2xsc2VlazMyKGhmLGhlYWQudGV4dG9mZixTRUVLX1NFVCkpIHsKCQlFUlIocmVnLCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoJaWYgKGhlYWQudGV4dHNpemUhPV9scmVhZDMyKGhmLHR4dCxoZWFkLnRleHRzaXplKSkgewoJCUVSUihyZWcsInRleHRibG9jayB0b28gc2hvcnQgKCVkIGluc3RlYWQgb2YgJWxkKS5cbiIsbGVuLGhlYWQudGV4dHNpemUpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoKCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGYsJmhmaW5mbykpIHsKCQlFUlIocmVnLCJHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CglsYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CgoJaWYgKFJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiU09GVFdBUkVcXENsYXNzZXMiLCZoa2V5KSE9RVJST1JfU1VDQ0VTUykKCQlyZXR1cm47CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwoJX193MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLDApOwoJZnJlZSh0YWIpOwoJZnJlZSh0eHQpOwoJX2xjbG9zZTMyKGhmKTsKCXJldHVybjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX0xvYWRSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwp2b2lkIFNIRUxMX0xvYWRSZWdpc3RyeSggdm9pZCApCnsKCWNoYXIJKmZuOwoJc3RydWN0CXBhc3N3ZAkqcHdkOwoJTFBLRVlTVFJVQ1QJbHBrZXk7CglIS0VZCQloa2V5OwoKICAgIFRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCglpZiAoa2V5X2NsYXNzZXNfcm9vdD09TlVMTCkKCQlTSEVMTF9Jbml0KCk7CgoJLyogTG9hZCB3aW5kb3dzIDMuMSBlbnRyaWVzICovCglfdzMxX2xvYWRyZWcoKTsKCS8qIExvYWQgd2luZG93cyA5NSBlbnRyaWVzICovCglfdzk1X2xvYWRyZWcoIkM6XFxzeXN0ZW0uMXN0IiwJa2V5X2xvY2FsX21hY2hpbmUpOwoJX3c5NV9sb2FkcmVnKCJzeXN0ZW0uZGF0IiwJa2V5X2xvY2FsX21hY2hpbmUpOwoJX3c5NV9sb2FkcmVnKCJ1c2VyLmRhdCIsCWtleV91c2Vycyk7CgoJLyogdGhlIGdsb2JhbCB1c2VyIGRlZmF1bHQgaXMgbG9hZGVkIHVuZGVyIEhLRVlfVVNFUlNcXC5EZWZhdWx0ICovCglSZWdDcmVhdGVLZXkxNihIS0VZX1VTRVJTLCIuRGVmYXVsdCIsJmhrZXkpOwoJbHBrZXkgPSBsb29rdXBfaGtleShoa2V5KTsKICAgICAgICBpZighbHBrZXkpCiAgICAgICAgICAgIFdBUk4ocmVnLCJDb3VsZCBub3QgY3JlYXRlIGdsb2JhbCB1c2VyIGRlZmF1bHQga2V5XG4iKTsKCV93aW5lX2xvYWRyZWcobHBrZXksU0FWRV9VU0VSU19ERUZBVUxULDApOwoKCS8qIEhLRVlfVVNFUlNcXC5EZWZhdWx0IGlzIGNvcGllZCB0byBIS0VZX0NVUlJFTlRfVVNFUiAqLwoJX2NvcHlfcmVnaXN0cnkobHBrZXksa2V5X2N1cnJlbnRfdXNlcik7CglSZWdDbG9zZUtleShoa2V5KTsKCgkvKiB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgKi8KCV93aW5lX2xvYWRyZWcoa2V5X2xvY2FsX21hY2hpbmUsU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQsMCk7CgoJLyogbG9hZCB0aGUgdXNlciBzYXZlZCByZWdpc3RyaWVzICovCgoJLyogRklYTUU6IHVzZSBnZXRlbnYoIkhPTUUiKSBvciBnZXRwd3VpZChnZXR1aWQoKSktPnB3X2RpciA/PyAqLwoKCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CglpZiAocHdkIT1OVUxMICYmIHB3ZC0+cHdfZGlyIT1OVUxMKSB7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0NVUlJFTlRfVVNFUik7CgkJX3dpbmVfbG9hZHJlZyhrZXlfY3VycmVudF91c2VyLGZuLFJFR19PUFRJT05fVEFJTlRFRCk7CgkJZnJlZShmbik7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9NQUNISU5FKTsKCQlfd2luZV9sb2FkcmVnKGtleV9sb2NhbF9tYWNoaW5lLGZuLFJFR19PUFRJT05fVEFJTlRFRCk7CgkJZnJlZShmbik7Cgl9IGVsc2UKCQlXQVJOKHJlZywiRmFpbGVkIHRvIGdldCBob21lZGlyZWN0b3J5IG9mIFVJRCAlZC5cbiIsZ2V0dWlkKCkpOwoJaWYgKEVSUk9SX1NVQ0NFU1M9PVJlZ0NyZWF0ZUtleTE2KEhLRVlfQ1VSUkVOVF9VU0VSLEtFWV9SRUdJU1RSWSwmaGtleSkpIHsKCQlEV09SRAlqdW5rLHR5cGUsbGVuOwoJCWNoYXIJZGF0YVs1XTsKCgkJbGVuPTQ7CgkJaWYgKCgJUmVnUXVlcnlWYWx1ZUV4MzJBKAoJCQkJaGtleSwKCQkJCVZBTF9TQVZFVVBEQVRFRCwKCQkJCSZqdW5rLAoJCQkJJnR5cGUsCgkJCQlkYXRhLAoJCQkJJmxlbgoJCQkpIT1FUlJPUl9TVUNDRVNTKSB8fAoJCQl0eXBlICE9IFJFR19TWgoJCSkKCQkJUmVnU2V0VmFsdWVFeDMyQShoa2V5LFZBTF9TQVZFVVBEQVRFRCwwLFJFR19TWiwieWVzIiw0KTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKiogQVBJIEZVTkNUSU9OUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qCiAqIE9wZW4gS2V5cy4KICoKICogQWxsIGZ1bmN0aW9ucyBhcmUgc3R1YnMgdG8gUmVnT3BlbktleUV4MzJXIHdoZXJlIGFsbCB0aGUKICogbWFnaWMgaGFwcGVucy4gCiAqCiAqIEZJWE1FOiBzZWN1cml0eSxvcHRpb25zLGRlc2lyZWRhY2Nlc3MsLi4uCiAqCiAqIENhbGxwYXRoOgogKiBSZWdPcGVuS2V5MTYgLT4gUmVnT3BlbktleTMyQSAtPiBSZWdPcGVuS2V5RXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdPcGVuS2V5MzJXICAgLT4gUmVnT3BlbktleUV4MzJXIAogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXlFeDMyVyBbQURWQVBJMzIuMTUwXQogKiBPcGVucyB0aGUgc3BlY2lmaWVkIGtleQogKgogKiBVbmxpa2UgUmVnQ3JlYXRlS2V5RXgsIHRoaXMgZG9lcyBub3QgY3JlYXRlIHRoZSBrZXkgaWYgaXQgZG9lcyBub3QgZXhpc3QuCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBzelN1YktleSBbSV0gTmFtZSBvZiBzdWJrZXkgdG8gb3BlbgogKiAgICBkd1Jlc2VydmVkIFtJXSBSZXNlcnZlZCAtIG11c3QgYmUgemVybwogKiAgICBzYW1EZXNpcmVkIFtJXSBTZWN1cml0eSBhY2Nlc3MgbWFzawogKiAgICByZXRrZXkgICAgIFtPXSBBZGRyZXNzIG9mIGhhbmRsZSBvZiBvcGVuIGtleQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXlFeDMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR1NBTSBzYW1EZXNpcmVkLCBMUEhLRVkgcmV0a2V5ICkKewoJTFBLRVlTVFJVQ1QJbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVseCwlcClcbiIsIGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxkd1Jlc2VydmVkLAogICAgICAgICAgc2FtRGVzaXJlZCxyZXRrZXkpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpIHsKICAgICAgICBXQVJOKHJlZywiSW52YWxpZCBoYW5kbGU6ICV4XG4iLGhrZXkpOwogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKICAgIH0KCiAgICBpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KSB7CiAgICAgICAgLyogRWl0aGVyIE5VTEwgb3IgcG9pbnRlciB0byBlbXB0eSBzdHJpbmcsIHNvIHJldHVybiBhIG5ldyBoYW5kbGUKICAgICAgICAgICB0byB0aGUgb3JpZ2luYWwgaGtleSAqLwogICAgICAgIGFkZF9oYW5kbGUoKytjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKICAgICAgICAqcmV0a2V5PWN1cnJlbnRoYW5kbGU7CiAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CiAgICB9CgoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpID0gMDsKCXdoaWxlICgoaTx3cGMpICYmICh3cHNbaV1bMF09PSdcMCcpKSBpKys7CglscHhrZXkgPSBscE5leHRLZXk7CgogICAgd2hpbGUgKHdwc1tpXSkgewogICAgICAgIGxweGtleT1scE5leHRLZXktPm5leHRzdWI7CiAgICAgICAgd2hpbGUgKGxweGtleSkgewogICAgICAgICAgICBpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBscHhrZXk9bHB4a2V5LT5uZXh0OwogICAgICAgIH0KCiAgICAgICAgaWYgKCFscHhrZXkpIHsKICAgICAgICAgICAgVFJBQ0UocmVnLCJDb3VsZCBub3QgZmluZCBzdWJrZXkgJXNcbiIsZGVidWdzdHJfdyh3cHNbaV0pKTsKICAgICAgICAgICAgRlJFRV9LRVlfUEFUSDsKICAgICAgICAgICAgcmV0dXJuIEVSUk9SX0JBREtFWTsKICAgICAgICB9CiAgICAgICAgaSsrOwogICAgICAgIGxwTmV4dEtleSA9IGxweGtleTsKICAgIH0KCiAgICBhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscHhrZXksc2FtRGVzaXJlZCk7CiAgICAqcmV0a2V5ID0gY3VycmVudGhhbmRsZTsKICAgIFRSQUNFKHJlZywiICBSZXR1cm5pbmcgJXhcbiIsIGN1cnJlbnRoYW5kbGUpOwogICAgRlJFRV9LRVlfUEFUSDsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5MzJXIFtBRFZBUEkzMi4xNTFdCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICByZXR1cm4gUmVnT3BlbktleUV4MzJXKGhrZXksbHBzelN1YktleSwwLEtFWV9BTExfQUNDRVNTLHJldGtleSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXlFeDMyQSBbQURWQVBJMzIuMTQ5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXlFeDMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHU0FNIHNhbURlc2lyZWQsIExQSEtFWSByZXRrZXkgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVcgPSBIRUFQX3N0cmR1cEF0b1coR2V0UHJvY2Vzc0hlYXAoKSwwLGxwc3pTdWJLZXkpOwogICAgRFdPUkQgcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbHgsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxkd1Jlc2VydmVkLAogICAgICAgICAgc2FtRGVzaXJlZCxyZXRrZXkpOwoKICAgIHJldCA9IFJlZ09wZW5LZXlFeDMyVyhoa2V5LGxwc3pTdWJLZXlXLGR3UmVzZXJ2ZWQsc2FtRGVzaXJlZCxyZXRrZXkpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXkzMkEgW0FEVkFQSTMyLjE0OF0KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0dXJuIFJlZ09wZW5LZXlFeDMyQShoa2V5LGxwc3pTdWJLZXksMCxLRVlfQUxMX0FDQ0VTUyxyZXRrZXkpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5MTYgW1NIRUxMLjFdIFtLRVJORUwuMjE3XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdPcGVuS2V5MzJBKGhrZXksbHBzelN1YktleSxyZXRrZXkpOwp9CgoKLyogCiAqIENyZWF0ZSBrZXlzCiAqIAogKiBBbGwgdGhvc2UgZnVuY3Rpb25zIGNvbnZlcnQgdGhlaXIgcmVzcGVjdGl2ZSAKICogYXJndW1lbnRzIGFuZCBjYWxsIFJlZ0NyZWF0ZUtleUV4VyBhdCB0aGUgZW5kLgogKgogKiBGSVhNRTogbm8gc2VjdXJpdHksbm8gYWNjZXNzIGF0dHJpYixubyBvcHRpb25oYW5kbGluZyB5ZXQuCiAqCiAqIENhbGxwYXRoOgogKiBSZWdDcmVhdGVLZXkxNiAtPiBSZWdDcmVhdGVLZXkzMkEgLT4gUmVnQ3JlYXRlS2V5RXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnQ3JlYXRlS2V5MzJXICAgLT4gUmVnQ3JlYXRlS2V5RXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXlFeDMyVyBbQURWQVBJMzIuMTMxXQogKgogKiBQQVJBTVMKICogICAgLi4uCiAqICAgIHJldGtleSAgIFtPXSBBZGRyZXNzIG9mIGJ1ZmZlciBmb3Igb3BlbmVkIGhhbmRsZQogKiAgICBscERpc3BvcyBbT10gUmVjZWl2ZXMgUkVHX0NSRUFURURfTkVXX0tFWSBvciBSRUdfT1BFTkVEX0VYSVNUSU5HX0tFWQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleUV4MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdSZXNlcnZlZCwgTFBXU1RSIGxwc3pDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZmR3T3B0aW9ucywgUkVHU0FNIHNhbURlc2lyZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIGxwU2VjQXR0cmlicywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBIS0VZIHJldGtleSwgTFBEV09SRCBscERpc3BvcyApCnsKCUxQS0VZU1RSVUNUCSpscGxwUHJldktleSxscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCiAgICAvKkZJWE1FOiBoYW5kbGUgc2VjdXJpdHkvYWNjZXNzL3doYXRldmVyICovCgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVseCwlbHgsJXAsJXAsJXApXG4iLCBoa2V5LAoJCWRlYnVnc3RyX3cobHBzelN1YktleSksIGR3UmVzZXJ2ZWQsIGRlYnVnc3RyX3cobHBzekNsYXNzKSwKCQlmZHdPcHRpb25zLCBzYW1EZXNpcmVkLCBscFNlY0F0dHJpYnMsIHJldGtleSwgbHBEaXNwb3MpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0JBREtFWTsKCiAgICBpZiAobHBzelN1YktleVswXSA9PSAnXFwnKSB7CiAgICAgICAgV0FSTihyZWcsIlN1YmtleSAlcyBtdXN0IG5vdCBiZWdpbiB3aXRoIGJhY2tzbGFzaC5cbiIsZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CiAgICAgICAgcmV0dXJuIEVSUk9SX0JBRF9QQVRITkFNRTsKICAgIH0KCglpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KSB7CgkJYWRkX2hhbmRsZSgrK2N1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwoJCSpyZXRrZXk9Y3VycmVudGhhbmRsZTsKICAgICAgICAgICAgICAgIFRSQUNFKHJlZywgIlJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CgkJbHBOZXh0S2V5LT5mbGFnc3w9UkVHX09QVElPTl9UQUlOVEVEOwoJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJfQoKCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleQk9IGxwTmV4dEtleTsKCXdoaWxlICh3cHNbaV0pIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21waTMyVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJCWJyZWFrOwoJCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJCX0KCQlpZiAoIWxweGtleSkKCQkJYnJlYWs7CgkJaSsrOwoJCWxwTmV4dEtleQk9IGxweGtleTsKCX0KCWlmIChscHhrZXkpIHsKCQlhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscHhrZXksc2FtRGVzaXJlZCk7CgkJbHB4a2V5LT5mbGFncyAgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoJCSpyZXRrZXkJCT0gY3VycmVudGhhbmRsZTsKICAgICAgICAgICAgICAgIFRSQUNFKHJlZywgIlJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CgkJaWYgKGxwRGlzcG9zKQoJCQkqbHBEaXNwb3MJPSBSRUdfT1BFTkVEX0VYSVNUSU5HX0tFWTsKCQlGUkVFX0tFWV9QQVRIOwoJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJfQoKCS8qIEdvb2QuICBOb3cgdGhlIGhhcmQgcGFydCAqLwoJd2hpbGUgKHdwc1tpXSkgewoJCWxwbHBQcmV2S2V5CT0gJihscE5leHRLZXktPm5leHRzdWIpOwoJCWxweGtleQkJPSAqbHBscFByZXZLZXk7CgkJd2hpbGUgKGxweGtleSkgewoJCQlscGxwUHJldktleQk9ICYobHB4a2V5LT5uZXh0KTsKCQkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl9CgkJKmxwbHBQcmV2S2V5PW1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJaWYgKCEqbHBscFByZXZLZXkpIHsKCQkJRlJFRV9LRVlfUEFUSDsKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nIE9VVE9GTUVNT1JZXG4iKTsKCQkJcmV0dXJuIEVSUk9SX09VVE9GTUVNT1JZOwoJCX0KCQltZW1zZXQoKmxwbHBQcmV2S2V5LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpOwogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCJBZGRpbmcgJXNcbiIsIGRlYnVnc3RyX3cod3BzW2ldKSk7CgkJKCpscGxwUHJldktleSktPmtleW5hbWUJPSBzdHJkdXBXKHdwc1tpXSk7CgkJKCpscGxwUHJldktleSktPm5leHQJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5uZXh0c3ViCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+dmFsdWVzCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+bnJvZnZhbHVlcyA9IDA7CgkJKCpscGxwUHJldktleSktPmZsYWdzIAk9IFJFR19PUFRJT05fVEFJTlRFRDsKCQlpZiAobHBzekNsYXNzKQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBzdHJkdXBXKGxwc3pDbGFzcyk7CgkJZWxzZQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBOVUxMOwoJCWxwTmV4dEtleQk9ICpscGxwUHJldktleTsKCQlpKys7Cgl9CglhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgoJLypGSVhNRTogZmxhZyBoYW5kbGluZyBjb3JyZWN0PyAqLwoJbHBOZXh0S2V5LT5mbGFncz0gZmR3T3B0aW9ucyB8UkVHX09QVElPTl9UQUlOVEVEOwoJaWYgKGxwc3pDbGFzcykKCQlscE5leHRLZXktPmNsYXNzID0gc3RyZHVwVyhscHN6Q2xhc3MpOwoJZWxzZQoJCWxwTmV4dEtleS0+Y2xhc3MgPSBOVUxMOwoJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwogICAgICAgIFRSQUNFKHJlZywgIlJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CglpZiAobHBEaXNwb3MpCgkJKmxwRGlzcG9zCT0gUkVHX0NSRUFURURfTkVXX0tFWTsKCUZSRUVfS0VZX1BBVEg7CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ3JlYXRlS2V5MzJXIFtBRFZBUEkzMi4xMzJdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIERXT1JEIGp1bms7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLCBoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdDcmVhdGVLZXlFeDMyVyggaGtleSwgbHBzelN1YktleSwgMCwgTlVMTCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfQUxMX0FDQ0VTUyxOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXRrZXksICZqdW5rKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ3JlYXRlS2V5RXgzMkEgW0FEVkFQSTMyLjEzMF0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXlFeDMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiBscHN6Q2xhc3MsIERXT1JEIGZkd09wdGlvbnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR1NBTSBzYW1EZXNpcmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgbHBTZWNBdHRyaWJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEhLRVkgcmV0a2V5LCBMUERXT1JEIGxwRGlzcG9zICkKewogICAgTFBXU1RSIGxwc3pTdWJLZXlXLCBscHN6Q2xhc3NXOwogICAgRFdPUkQgIHJldDsKCiAgICBUUkFDRShyZWcsIigleCwlcywlbGQsJXMsJWx4LCVseCwlcCwlcCwlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLAogICAgICAgICAgZHdSZXNlcnZlZCxkZWJ1Z3N0cl9hKGxwc3pDbGFzcyksZmR3T3B0aW9ucyxzYW1EZXNpcmVkLGxwU2VjQXR0cmlicywKICAgICAgICAgIHJldGtleSxscERpc3Bvcyk7CgogICAgbHBzelN1YktleVcgPSBIRUFQX3N0cmR1cEF0b1coR2V0UHJvY2Vzc0hlYXAoKSwwLGxwc3pTdWJLZXkpOwovKgoJaWYgKGxwc3pTdWJLZXkpCgkJbHBzelN1YktleVc9c3RyZHVwQTJXKGxwc3pTdWJLZXkpOwoJZWxzZQoJCWxwc3pTdWJLZXlXPU5VTEw7CiovCglpZiAobHBzekNsYXNzKQoJCWxwc3pDbGFzc1c9c3RyZHVwQTJXKGxwc3pDbGFzcyk7CgllbHNlCgkJbHBzekNsYXNzVz1OVUxMOwogICAgcmV0ID0gUmVnQ3JlYXRlS2V5RXgzMlcoIGhrZXksIGxwc3pTdWJLZXlXLCBkd1Jlc2VydmVkLCBscHN6Q2xhc3NXLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZHdPcHRpb25zLCBzYW1EZXNpcmVkLCBscFNlY0F0dHJpYnMsIHJldGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBEaXNwb3MgKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxscHN6U3ViS2V5Vyk7Ci8qCglpZiAobHBzelN1YktleVcpCgkJZnJlZShscHN6U3ViS2V5Vyk7CiovCglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ3JlYXRlS2V5MzJBIFtBRFZBUEkzMi4xMjldCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgRFdPUkQganVuazsKCiAgICBUUkFDRShyZWcsIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CgoJcmV0dXJuCVJlZ0NyZWF0ZUtleUV4MzJBKAoJCWhrZXksCQkvKiBrZXkgaGFuZGxlICovCgkJbHBzelN1YktleSwJLyogc3Via2V5IG5hbWUgKi8KCQkwLAkJLyogcmVzZXJ2ZWQgPSAwICovCgkJTlVMTCwJCS8qIGxwc3pDbGFzcz8gRklYTUU6ID8gKi8KCQlSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwvKiBvcHRpb25zICovCgkJS0VZX0FMTF9BQ0NFU1MsCS8qIGRlc2lyZWQgYWNjZXNzIGF0dHJpYnMgKi8KCQlOVUxMLAkJLyogbHBzZWN1cml0eSBhdHRyaWJ1dGVzICovCgkJcmV0a2V5LAkJLyogbHByZXRrZXkgKi8KCQkmanVuawkJLyogZGlzcG9zaXRpb24gdmFsdWUgKi8KCSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleTE2IFtTSEVMTC4yXSBbS0VSTkVMLjIxOF0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdDcmVhdGVLZXkzMkEoIGhrZXksIGxwc3pTdWJLZXksIHJldGtleSApOwp9CgoKLyogCiAqIFF1ZXJ5IFZhbHVlIEZ1bmN0aW9ucwogKiBXaW4zMiBkaWZmZXJzIGJldHdlZW4ga2V5bmFtZXMgYW5kIHZhbHVlbmFtZXMuIAogKiBtdWx0aXBsZSB2YWx1ZXMgbWF5IGJlbG9uZyB0byBvbmUga2V5LCB0aGUgc3BlY2lhbCB2YWx1ZQogKiB3aXRoIG5hbWUgTlVMTCBpcyB0aGUgZGVmYXVsdCB2YWx1ZSB1c2VkIGJ5IHRoZSB3aW4zMQogKiBjb21wYXQgZnVuY3Rpb25zLgogKgogKiBDYWxscGF0aDoKICogUmVnUXVlcnlWYWx1ZTE2IC0+IFJlZ1F1ZXJ5VmFsdWUzMkEgLT4gUmVnUXVlcnlWYWx1ZUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdRdWVyeVZhbHVlMzJXIC0+IFJlZ1F1ZXJ5VmFsdWVFeDMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWVFeDMyVyBbQURWQVBJMzIuMTU4XQogKiBSZXRyaWV2ZXMgdHlwZSBhbmQgZGF0YSBmb3IgYSBzcGVjaWZpZWQgbmFtZSBhc3NvY2lhdGVkIHdpdGggYW4gb3BlbiBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldICAgSGFuZGxlIG9mIGtleSB0byBxdWVyeQogKiAgICBscFZhbHVlTmFtZSAgIFtJXSAgIE5hbWUgb2YgdmFsdWUgdG8gcXVlcnkKICogICAgbHBkd1Jlc2VydmVkICBbSV0gICBSZXNlcnZlZCAtIG11c3QgYmUgTlVMTAogKiAgICBscGR3VHlwZSAgICAgIFtPXSAgIEFkZHJlc3Mgb2YgYnVmZmVyIGZvciB2YWx1ZSB0eXBlLiAgSWYgTlVMTCwgdGhlIHR5cGUKICogICAgICAgICAgICAgICAgICAgICAgICBpcyBub3QgcmVxdWlyZWQuCiAqICAgIGxwYkRhdGEgICAgICAgW09dICAgQWRkcmVzcyBvZiBkYXRhIGJ1ZmZlci4gIElmIE5VTEwsIHRoZSBhY3R1YWwgZGF0YSBpcwogKiAgICAgICAgICAgICAgICAgICAgICAgIG5vdCByZXF1aXJlZC4KICogICAgbHBjYkRhdGEgICAgICBbSS9PXSBBZGRyZXNzIG9mIGRhdGEgYnVmZmVyIHNpemUKICoKICogUkVUVVJOUyAKICogICAgRVJST1JfU1VDQ0VTUzogICBTdWNjZXNzCiAqICAgIEVSUk9SX01PUkVfREFUQTogVGhlIHNwZWNpZmllZCBidWZmZXIgaXMgbm90IGJpZyBlbm91Z2ggdG8gaG9sZCB0aGUgZGF0YQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDMyVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBWYWx1ZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1Jlc2VydmVkLCBMUERXT1JEIGxwZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgbHBiRGF0YSwgTFBEV09SRCBscGNiRGF0YSApCnsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJaW50CQlpOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVwLCVwLCVsZClcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLCBscGR3VHlwZSwgbHBiRGF0YSwgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwa2V5KSB7CiAgICAgICAgVFJBQ0UocmVnLCAiSW52YWxpZCBoYW5kbGUoJXgpXG4iLGhrZXkpOwogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKICAgIH0KCiAgICAvKiBBbiBlbXB0eSBuYW1lIHN0cmluZyBpcyBlcXVpdmFsZW50IHRvIE5VTEwgKi8KICAgIGlmIChscFZhbHVlTmFtZSAmJiAhKmxwVmFsdWVOYW1lKQogICAgICAgIGxwVmFsdWVOYW1lID0gTlVMTDsKCglpZiAobHBWYWx1ZU5hbWU9PU5VTEwpIHsKICAgICAgICAgICAgICAgIC8qIFVzZSBrZXkncyB1bm5hbWVkIG9yIGRlZmF1bHQgdmFsdWUsIGlmIGFueSAqLwoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewogICAgICAgICAgICAgICAgLyogU2VhcmNoIGZvciB0aGUga2V5IG5hbWUgKi8KCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKAlscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYKCQkJCSFsc3RyY21waTMyVyhscFZhbHVlTmFtZSxscGtleS0+dmFsdWVzW2ldLm5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJfQoKCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCJLZXkgbm90IGZvdW5kXG4iKTsKCQlpZiAobHBWYWx1ZU5hbWU9PU5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogRW1wdHkga2V5bmFtZSBub3QgZm91bmQgKi8KCQkJaWYgKGxwYkRhdGEpIHsKCQkJCSooV0NIQVIqKWxwYkRhdGEgPSAwOwoJCQkJKmxwY2JEYXRhCT0gMjsKCQkJfQoJCQlpZiAobHBkd1R5cGUpCgkJCQkqbHBkd1R5cGUJPSBSRUdfU1o7CiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKHJlZywgIlJldHVybmluZyBhbiBlbXB0eSBzdHJpbmdcbiIpOwoJCQlyZXR1cm4gRVJST1JfU1VDQ0VTUzsKCQl9CgkJcmV0dXJuIEVSUk9SX0JBREtFWTsgLyogRklYTUUgKi8KCX0KCiAgICBpZiAobHBkd1R5cGUpCiAgICAgICAgKmxwZHdUeXBlID0gbHBrZXktPnZhbHVlc1tpXS50eXBlOwoKICAgIGlmIChscGJEYXRhPT1OVUxMKSB7CiAgICAgICAgLyogRGF0YSBpcyBub3QgcmVxdWlyZWQgKi8KICAgICAgICBpZiAobHBjYkRhdGE9PU5VTEwpIHsKICAgICAgICAgICAgLyogQW5kIGRhdGEgc2l6ZSBpcyBub3QgcmVxdWlyZWQgKi8KICAgICAgICAgICAgLyogU28gYWxsIHRoYXQgaXMgcmV0dXJuZWQgaXMgdGhlIHR5cGUgKHNldCBhYm92ZSkgKi8KICAgICAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CiAgICAgICAgfQogICAgICAgIC8qIFNldCB0aGUgc2l6ZSByZXF1aXJlZCBhbmQgcmV0dXJuIHN1Y2Nlc3MgKi8KICAgICAgICAqbHBjYkRhdGEgPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAoKmxwY2JEYXRhPGxwa2V5LT52YWx1ZXNbaV0ubGVuKSB7CiAgICAgICAgLyogVGhlIHNpemUgd2FzIHNwZWNpZmllZCwgYnV0IHRoZSBkYXRhIGlzIHRvbyBiaWcgZm9yIGl0ICovCiAgICAgICAgLyogSW5zdGVhZCBvZiBzZXR0aW5nIGl0IHRvIE5VTEwsIGZpbGwgaW4gd2l0aCBhcyBtdWNoIGFzIHBvc3NpYmxlICovCiAgICAgICAgLyogQnV0IHRoZSBkb2NzIGRvIG5vdCBzcGVjaWZ5IGhvdyB0byBoYW5kbGUgdGhlIGxwYkRhdGEgaGVyZSAqLwogICAgICAgIC8qICooV0NIQVIqKWxwYkRhdGE9IDA7ICovCiAgICAgICAgbWVtY3B5KGxwYkRhdGEsbHBrZXktPnZhbHVlc1tpXS5kYXRhLCpscGNiRGF0YSk7CiAgICAgICAgKmxwY2JEYXRhID0gbHBrZXktPnZhbHVlc1tpXS5sZW47CiAgICAgICAgcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKICAgIH0KCiAgICBtZW1jcHkobHBiRGF0YSxscGtleS0+dmFsdWVzW2ldLmRhdGEsbHBrZXktPnZhbHVlc1tpXS5sZW4pOwoKICAgIC8qIEV4dHJhIGRlYnVnZ2luZyBvdXRwdXQgKi8KICAgIGlmIChscGR3VHlwZSkgewogICAgICAgIHN3aXRjaCgqbHBkd1R5cGUpewogICAgICAgICAgICBjYXNlIFJFR19TWjoKICAgICAgICAgICAgICAgIFRSQUNFKHJlZywiIERhdGEoc3opPSVzXG4iLGRlYnVnc3RyX3coKExQQ1dTVFIpbHBiRGF0YSkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUkVHX0RXT1JEOgogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCIgRGF0YShkd29yZCk9JWx4XG4iLCAoRFdPUkQpKmxwYkRhdGEpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUkVHX0JJTkFSWToKICAgICAgICAgICAgICAgIFRSQUNFKHJlZywiIERhdGEoYmluYXJ5KVxuIik7CiAgICAgICAgICAgICAgICAvKiBJcyB0aGVyZSBhIHdheSBvZiBwcmludGluZyB0aGlzIGluIHJlYWRhYmxlIGZvcm0/ICovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIFRSQUNFKHJlZywgIlVua25vd24gZGF0YSB0eXBlICVsZFxuIiwgKmxwZHdUeXBlKTsKICAgICAgICB9IC8qIHN3aXRjaCAqLwogICAgfSAvKiBpZiAqLwoKICAgIC8qIFNldCB0aGUgYWN0dWFsIHNpemUgKi8KICAgICpscGNiRGF0YSA9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWUzMlcgW0FEVkFQSTMyLjE1OV0KICoKICogTk9URVMKICogICAgV2h5IGlzIHRoaXMgY2FsbGluZyBSZWdPcGVuS2V5MzJXPwogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUzMlcoIEhLRVkgaGtleSwgTFBXU1RSIGxwc3pTdWJLZXksIExQV1NUUiBscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CglIS0VZCXhoa2V5OwoJRFdPUkQJcmV0LGxwZHdUeXBlOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGxwc3pEYXRhLAogICAgICAgICAgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKCS8qIG9ubHkgb3BlbiBzdWJrZXksIGlmIHdlIHJlYWxseSBkbyBkZXNjZW5kICovCglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldAk9IFJlZ09wZW5LZXkzMlcoaGtleSxscHN6U3ViS2V5LCZ4aGtleSk7CgkJaWYgKHJldCE9RVJST1JfU1VDQ0VTUykKCQkJcmV0dXJuIHJldDsKCX0gZWxzZQoJCXhoa2V5CT0gaGtleTsKCglscGR3VHlwZQk9IFJFR19TWjsKCXJldAk9IFJlZ1F1ZXJ5VmFsdWVFeDMyVygKCQl4aGtleSwKCQlOVUxMLAkJLyogdmFybmFtZSBOVUxMIC0+IGNvbXBhdCAqLwoJCU5VTEwsCQkvKiBscGR3UmVzZXJ2ZWQsIG11c3QgYmUgTlVMTCAqLwoJCSZscGR3VHlwZSwKCQkoTFBCWVRFKWxwc3pEYXRhLAoJCWxwY2JEYXRhCgkpOwoJaWYgKHhoa2V5IT1oa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWVFeDMyQSBbQURWQVBJMzIuMTU3XQogKgogKiBDYW4gdGhpcyB1c2UgSEVBUF9zdHJkdXBBdG9XPwogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDMyQSggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGxwYkRhdGEsIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUFdTVFIJbHBzelZhbHVlTmFtZVc7CglMUEJZVEUJYnVmOwoJRFdPUkQJcmV0LG15eGxlbjsKCURXT1JECSpteWxlbjsKCURXT1JECXR5cGU7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIiwgaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIGlmIChscHN6VmFsdWVOYW1lKQogICAgICAgIGxwc3pWYWx1ZU5hbWVXPXN0cmR1cEEyVyhscHN6VmFsdWVOYW1lKTsKICAgIGVsc2UgCiAgICAgICAgbHBzelZhbHVlTmFtZVc9TlVMTDsKCiAgICBpZiAobHBkd1R5cGUpCiAgICAgICAgdHlwZT0qbHBkd1R5cGU7CgoJaWYgKGxwYkRhdGEpIHsKCQlteXhsZW4gID0gMDsKCQlteWxlbgk9ICZteXhsZW47CgkJYnVmCT0geG1hbGxvYyg0KTsKICAgICAgICAgICAgICAgIC8qIE9ubHkgZ2V0IHRoZSBzaXplIGZvciBub3cgKi8KCQlyZXQ9UmVnUXVlcnlWYWx1ZUV4MzJXKAoJCQloa2V5LAoJCQlscHN6VmFsdWVOYW1lVywKCQkJbHBkd1Jlc2VydmVkLAoJCQkmdHlwZSwKCQkJYnVmLAoJCQlteWxlbgoJCSk7CgkJZnJlZShidWYpOwoJCWlmIChyZXQ9PUVSUk9SX01PUkVfREFUQSkgewoJCQlidWYJPSAoTFBCWVRFKXhtYWxsb2MoKm15bGVuKTsKCQl9IGVsc2UgewoJCQlidWYJPSAoTFBCWVRFKXhtYWxsb2MoMiooKmxwY2JEYXRhKSk7CgkJCW15eGxlbiAgPSAyKigqbHBjYkRhdGEpOwoJCX0KCX0gZWxzZSB7CgkJYnVmPU5VTEw7CgkJaWYgKGxwY2JEYXRhKSB7CgkJCW15eGxlbgk9ICpscGNiRGF0YSoyOwoJCQlteWxlbgk9ICZteXhsZW47CgkJfSBlbHNlCgkJCW15bGVuCT0gTlVMTDsKCX0KICAgICAgICAvKiBOb3cgZ2V0IHRoZSBkYXRhICovCglyZXQ9UmVnUXVlcnlWYWx1ZUV4MzJXKAoJCWhrZXksCgkJbHBzelZhbHVlTmFtZVcsCgkJbHBkd1Jlc2VydmVkLAoJCSZ0eXBlLAoJCWJ1ZiwKCQlteWxlbgoJKTsKCWlmIChscGR3VHlwZSkgCgkJKmxwZHdUeXBlPXR5cGU7CgoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCWlmIChidWYpIHsKCQkJaWYgKFVOSUNPTlZNQVNLICYgKDE8PCh0eXBlKSkpIHsKCQkJCS8qIGNvbnZlcnQgVU5JQ09ERSB0byBBU0NJSSAqLwoJCQkJbHN0cmNweVd0b0EobHBiRGF0YSwoTFBXU1RSKWJ1Zik7CgkJCQkqbHBjYkRhdGEJPSBteXhsZW4vMjsKCQkJfSBlbHNlIHsKCQkJCWlmIChteXhsZW4+KmxwY2JEYXRhKQoJCQkJCXJldAk9IEVSUk9SX01PUkVfREFUQTsKCQkJCWVsc2UKCQkJCQltZW1jcHkobHBiRGF0YSxidWYsbXl4bGVuKTsKCgkJCQkqbHBjYkRhdGEJPSBteXhsZW47CgkJCX0KCQl9IGVsc2UgewoJCQlpZiAoKFVOSUNPTlZNQVNLICYgKDE8PCh0eXBlKSkpICYmIGxwY2JEYXRhKQoJCQkJKmxwY2JEYXRhCT0gbXl4bGVuLzI7CgkJfQoJfSBlbHNlIHsKCQlpZiAoKFVOSUNPTlZNQVNLICYgKDE8PCh0eXBlKSkpICYmIGxwY2JEYXRhKQoJCQkqbHBjYkRhdGEJPSBteXhsZW4vMjsKCX0KCWlmIChidWYpCgkJZnJlZShidWYpOwoKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWVFeDE2IFtLRVJORUwuMjI1XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGxwYkRhdGEsIExQRFdPUkQgbHBjYkRhdGEgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlcCwlcCwlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhPypscGNiRGF0YTowKTsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlRXgzMkEoIGhrZXksIGxwc3pWYWx1ZU5hbWUsIGxwZHdSZXNlcnZlZCwgbHBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscGJEYXRhLCBscGNiRGF0YSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlMzJBIFtBRFZBUEkzMi4xNTZdCiAqCiAqIE5PVEVTCiAqICAgIFdoeSBpcyB0aGlzIGNhbGxpbmcgUmVnT3BlbktleTE2PwogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUzMkEoCglIS0VZCWhrZXksCglMUFNUUglscHN6U3ViS2V5LAoJTFBTVFIJbHBzekRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJSEtFWQl4aGtleTsKCURXT1JECXJldCxscGR3VHlwZTsKCiAgICBUUkFDRShyZWcsIigleCwlcywlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxscHN6RGF0YSwKICAgICAgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCgkvKiBvbmx5IG9wZW4gc3Via2V5LCBpZiB3ZSByZWFsbHkgZG8gZGVzY2VuZCAqLwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQgPSBSZWdPcGVuS2V5MTYoaGtleSxscHN6U3ViS2V5LCZ4aGtleSk7CgkJaWYgKHJldCE9RVJST1JfU1VDQ0VTUykKCQkJcmV0dXJuIHJldDsKCX0gZWxzZQoJCXhoa2V5CT0gaGtleTsKCglscGR3VHlwZQk9IFJFR19TWjsKCXJldAk9IFJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQl4aGtleSwKCQlOVUxMLAkJLyogbHBzelZhbHVlTmFtZSBOVUxMIC0+IGNvbXBhdCAqLwoJCU5VTEwsCQkvKiBscGR3UmVzZXJ2ZWQsIG11c3QgYmUgTlVMTCAqLwoJCSZscGR3VHlwZSwKCQkoTFBCWVRFKWxwc3pEYXRhLAoJCWxwY2JEYXRhCgkpOwoJaWYgKHhoa2V5IT1oa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWUxNiBbU0hFTEwuNl0gW0tFUk5FTC4yMjRdCiAqCiAqIE5PVEVTCiAqICAgIElzIHRoaXMgSEFDSyBzdGlsbCBhcHBsaWNhYmxlPwogKgogKiBIQUNLCiAqICAgIFRoZSAxNmJpdCBSZWdRdWVyeVZhbHVlIGRvZXNuJ3QgaGFuZGxlIHNlbGVjdG9yYmxvY2tzIGFueXdheSwgc28gd2UganVzdAogKiAgICBtYXNrIG91dCB0aGUgaGlnaCAxNiBiaXQuICBUaGlzIChub3Qgc28gbXVjaCBpbmNpZGVudGx5KSBob3BlZnVsbHkgZml4ZXMKICogICAgQWxkdXMgRkg0KQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUxNiggSEtFWSBoa2V5LCBMUFNUUiBscHN6U3ViS2V5LCBMUFNUUiBscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGxwc3pEYXRhLAogICAgICAgICAgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIGlmIChscGNiRGF0YSkKICAgICAgICAqbHBjYkRhdGEgJj0gMHhGRkZGOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWUzMkEoaGtleSxscHN6U3ViS2V5LGxwc3pEYXRhLGxwY2JEYXRhKTsKfQoKCi8qCiAqIFNldHRpbmcgdmFsdWVzIG9mIFJlZ2lzdHJ5IGtleXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ1NldFZhbHVlMTYgLT4gUmVnU2V0VmFsdWUzMkEgLT4gUmVnU2V0VmFsdWVFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnU2V0VmFsdWUzMlcgICAtPiBSZWdTZXRWYWx1ZUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWVFeDMyVyBbQURWQVBJMzIuMTcwXQogKiBTZXRzIHRoZSBkYXRhIGFuZCB0eXBlIG9mIGEgdmFsdWUgdW5kZXIgYSByZWdpc3RlciBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldIEhhbmRsZSBvZiBrZXkgdG8gc2V0IHZhbHVlIGZvcgogKiAgICBscHN6VmFsdWVOYW1lIFtJXSBOYW1lIG9mIHZhbHVlIHRvIHNldAogKiAgICBkd1Jlc2VydmVkICAgIFtJXSBSZXNlcnZlZCAtIG11c3QgYmUgemVybwogKiAgICBkd1R5cGUgICAgICAgIFtJXSBGbGFnIGZvciB2YWx1ZSB0eXBlCiAqICAgIGxwYkRhdGEgICAgICAgW0ldIEFkZHJlc3Mgb2YgdmFsdWUgZGF0YQogKiAgICBjYkRhdGEgICAgICAgIFtJXSBTaXplIG9mIHZhbHVlIGRhdGEKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MzJXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6VmFsdWVOYW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3UmVzZXJ2ZWQsIERXT1JEIGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBjYkRhdGEpCnsKICAgIExQS0VZU1RSVUNUIGxwa2V5OwogICAgaW50IGk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgZHdSZXNlcnZlZCwgZHdUeXBlLCBscGJEYXRhLCBjYkRhdGEpOwoKICAgIHN3aXRjaCAoZHdUeXBlKSB7CiAgICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgICAgIFRSQUNFKHJlZywiIERhdGEoc3opPSVzXG4iLCBkZWJ1Z3N0cl93KChMUENXU1RSKWxwYkRhdGEpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfQklOQVJZOgogICAgICAgICAgICBUUkFDRShyZWcsIiBEYXRhKGJpbmFyeSlcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19EV09SRDoKICAgICAgICAgICAgVFJBQ0UocmVnLCIgRGF0YShkd29yZCk9JWx4XG4iLCAoRFdPUkQpKmxwYkRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBUUkFDRShyZWcsIlVua25vd24gdHlwZTogJWxkXG4iLCBkd1R5cGUpOwogICAgfQoKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KSB7CiAgICAgICAgICAgIFdBUk4ocmVnLCJSZXR1cm5pbmcgYmFka2V5XG4iKTsKICAgICAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwogICAgICAgIH0KCglscGtleS0+ZmxhZ3MgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoKCWlmIChscHN6VmFsdWVOYW1lPT1OVUxMKSB7CiAgICAgICAgICAgICAvKiBTZXRzIHR5cGUgYW5kIG5hbWUgZm9yIGtleSdzIHVubmFtZWQgb3IgZGVmYXVsdCB2YWx1ZSAqLwoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXBpMzJXKGxwc3pWYWx1ZU5hbWUsbHBrZXktPnZhbHVlc1tpXS5uYW1lKQoJCQkpCgkJCQlicmVhazsKCX0KCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewoJCWxwa2V5LT52YWx1ZXMgPSAoTFBLRVlWQUxVRSl4cmVhbGxvYygKCQkJCQlscGtleS0+dmFsdWVzLAoJCQkJCShscGtleS0+bnJvZnZhbHVlcysxKSpzaXplb2YoS0VZVkFMVUUpCgkJCQkpOwoJCWxwa2V5LT5ucm9mdmFsdWVzKys7CgkJbWVtc2V0KGxwa2V5LT52YWx1ZXMraSwnXDAnLHNpemVvZihLRVlWQUxVRSkpOwoJfQoJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQlpZiAobHBzelZhbHVlTmFtZSkKCQkJbHBrZXktPnZhbHVlc1tpXS5uYW1lID0gc3RyZHVwVyhscHN6VmFsdWVOYW1lKTsKCQllbHNlCgkJCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSA9IE5VTEw7CglscGtleS0+dmFsdWVzW2ldLmxlbgk9IGNiRGF0YTsKCWxwa2V5LT52YWx1ZXNbaV0udHlwZQk9IGR3VHlwZTsKCWlmIChscGtleS0+dmFsdWVzW2ldLmRhdGEgIT1OVUxMKQoJCWZyZWUobHBrZXktPnZhbHVlc1tpXS5kYXRhKTsKCWxwa2V5LT52YWx1ZXNbaV0uZGF0YQk9IChMUEJZVEUpeG1hbGxvYyhjYkRhdGEpOwoJbHBrZXktPnZhbHVlc1tpXS5sYXN0bW9kaWZpZWQgPSB0aW1lKE5VTEwpOwoJbWVtY3B5KGxwa2V5LT52YWx1ZXNbaV0uZGF0YSxscGJEYXRhLGNiRGF0YSk7CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWVFeDMyQSBbQURWQVBJMzIuMTY5XQogKgogKiBOT1RFUwogKiAgICBDYW4gdGhpcyB1c2UgdGhlIHN0YW5kYXJkIEhFQVBfc3RyZHVwQXRvVyBpbnN0ZWFkPwogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXgzMkEoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3UmVzZXJ2ZWQsIERXT1JEIGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBjYkRhdGEgKQp7CglMUEJZVEUJYnVmOwoJTFBXU1RSCWxwc3pWYWx1ZU5hbWVXOwoJRFdPUkQJcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlTmFtZSksCiAgICAgICAgICBkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YSk7CgoJaWYgKCgxPDxkd1R5cGUpICYgVU5JQ09OVk1BU0spIHsKCQlidWY9KExQQllURSlzdHJkdXBBMlcobHBiRGF0YSk7CgkJY2JEYXRhPTIqc3RybGVuKGxwYkRhdGEpKzI7Cgl9IGVsc2UKCQlidWY9bHBiRGF0YTsKCWlmIChscHN6VmFsdWVOYW1lKQoJCWxwc3pWYWx1ZU5hbWVXID0gc3RyZHVwQTJXKGxwc3pWYWx1ZU5hbWUpOwoJZWxzZQoJCWxwc3pWYWx1ZU5hbWVXID0gTlVMTDsKCXJldD1SZWdTZXRWYWx1ZUV4MzJXKGhrZXksbHBzelZhbHVlTmFtZVcsZHdSZXNlcnZlZCxkd1R5cGUsYnVmLGNiRGF0YSk7CglpZiAobHBzelZhbHVlTmFtZVcpCgkJZnJlZShscHN6VmFsdWVOYW1lVyk7CglpZiAoYnVmIT1scGJEYXRhKQoJCWZyZWUoYnVmKTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgxNiBbS0VSTkVMLjIyNl0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgRFdPUkQgY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsZHdUeXBlLGxwYkRhdGEsY2JEYXRhKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUV4MzJBKCBoa2V5LCBscHN6VmFsdWVOYW1lLCBkd1Jlc2VydmVkLCBkd1R5cGUsIGxwYkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2JEYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMzJXCVtBRFZBUEkzMi4xNzFdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUzMlcoCglIS0VZCWhrZXksCglMUENXU1RSCWxwc3pTdWJLZXksCglEV09SRAlkd1R5cGUsCglMUENXU1RSCWxwc3pEYXRhLAoJRFdPUkQJY2JEYXRhCikgewoJSEtFWQl4aGtleTsKCURXT1JECXJldDsKCglUUkFDRShyZWcsIigleCwlcywlbGQsJXMsJWxkKVxuIiwKCQloa2V5LFcyQyhscHN6U3ViS2V5LDApLGR3VHlwZSxXMkMobHBzekRhdGEsMCksY2JEYXRhCgkpOwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQ9UmVnQ3JlYXRlS2V5MzJXKGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleT1oa2V5OwoJaWYgKGR3VHlwZSE9UkVHX1NaKSB7CgkJVFJBQ0UocmVnLCJSZWdTZXRWYWx1ZVggY2FsbGVkIHdpdGggZHdUeXBlPSVsZCFcbiIsZHdUeXBlKTsKCQlkd1R5cGU9UkVHX1NaOwoJfQoJaWYgKGNiRGF0YSE9Mipsc3RybGVuMzJXKGxwc3pEYXRhKSsyKSB7CgkJVFJBQ0UocmVnLCJSZWdTZXRWYWx1ZVggY2FsbGVkIHdpdGggbGVuPSVsZCAhPSBzdHJsZW4oJXMpKzE9JWQhXG4iLAoJCQljYkRhdGEsVzJDKGxwc3pEYXRhLDApLDIqbHN0cmxlbjMyVyhscHN6RGF0YSkrMgoJCSk7CgkJY2JEYXRhPTIqbHN0cmxlbjMyVyhscHN6RGF0YSkrMjsKCX0KCXJldD1SZWdTZXRWYWx1ZUV4MzJXKHhoa2V5LE5VTEwsMCxkd1R5cGUsKExQQllURSlscHN6RGF0YSxjYkRhdGEpOwoJaWYgKGhrZXkhPXhoa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMzJBIFtBRFZBUEkzMi4xNjhdCiAqCiAqIE5PVEVTCiAqICAgIFdoeSBpcyB0aGlzIGNhbGxpbmcgUmVnQ3JlYXRlS2V5MTY/CiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUzMkEoCglIS0VZCWhrZXksCglMUENTVFIJbHBzelN1YktleSwKCURXT1JECWR3VHlwZSwKCUxQQ1NUUglscHN6RGF0YSwKCURXT1JECWNiRGF0YQopIHsKCURXT1JECXJldDsKCUhLRVkJeGhrZXk7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsCgkJaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEKCSk7CglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldD1SZWdDcmVhdGVLZXkxNihoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXk9aGtleTsKCglpZiAoZHdUeXBlIT1SRUdfU1opIHsKCQlUUkFDRShyZWcsIlJlZ1NldFZhbHVlQSBjYWxsZWQgd2l0aCBkd1R5cGU9JWxkIVxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT1zdHJsZW4obHBzekRhdGEpKzEpCgkJY2JEYXRhPXN0cmxlbihscHN6RGF0YSkrMTsKCXJldD1SZWdTZXRWYWx1ZUV4MzJBKHhoa2V5LE5VTEwsMCxkd1R5cGUsKExQQllURSlscHN6RGF0YSxjYkRhdGEpOwoJaWYgKHhoa2V5IT1oa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMTYgW0tFUk5FTC4yMjFdIFtTSEVMTC41XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JECWR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscHN6RGF0YSwgRFdPUkQgY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGR3VHlwZSwKICAgICAgICAgIGRlYnVnc3RyX2EobHBzekRhdGEpLGNiRGF0YSk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWUzMkEoaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEpOwp9CgoKLyogCiAqIEtleSBFbnVtZXJhdGlvbgogKgogKiBDYWxscGF0aDoKICogUmVnRW51bUtleTE2IC0+IFJlZ0VudW1LZXkzMkEgLT4gUmVnRW51bUtleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdFbnVtS2V5MzJXICAgLT4gUmVnRW51bUtleUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleUV4MzJXIFtBRFZBUEkzMi4xMzldCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleUV4MzJXKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQV1NUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE5hbWUsIExQRFdPUkQgbHBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgbHBzekNsYXNzLCBMUERXT1JEIGxwY2NoQ2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFVElNRSAqZnQgKQp7CglMUEtFWVNUUlVDVAlscGtleSxscHhrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZCwlcCwlcCwlcCwlcClcbiIsaGtleSxpU3Via2V5LGxwc3pOYW1lLAogICAgICAgICAgKmxwY2NoTmFtZSxscGR3UmVzZXJ2ZWQsbHBzekNsYXNzLGxwY2NoQ2xhc3MsZnQpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglpZiAoIWxwa2V5LT5uZXh0c3ViKQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoJbHB4a2V5PWxwa2V5LT5uZXh0c3ViOwoJd2hpbGUgKGlTdWJrZXkgJiYgbHB4a2V5KSB7CgkJaVN1YmtleS0tOwoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9CglpZiAoaVN1YmtleSB8fCAhbHB4a2V5KQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoJaWYgKDIqbHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpKzI+KmxwY2NoTmFtZSkKCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJbWVtY3B5KGxwc3pOYW1lLGxweGtleS0+a2V5bmFtZSxsc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSkqMisyKTsKCWlmIChscHN6Q2xhc3MpIHsKCQkvKiB3aGF0IHNob3VsZCB3ZSB3cml0ZSBpbnRvIGl0PyAqLwoJCSpscHN6Q2xhc3MJPSAwOwoJCSpscGNjaENsYXNzCT0gMjsKCX0KCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5MzJXIFtBRFZBUEkzMi4xNDBdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTMyVyggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFdTVFIgbHBzek5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbHBjY2hOYW1lICkKewogICAgRklMRVRJTUUJZnQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZSk7CiAgICByZXR1cm4gUmVnRW51bUtleUV4MzJXKGhrZXksaVN1YmtleSxscHN6TmFtZSwmbHBjY2hOYW1lLE5VTEwsTlVMTCxOVUxMLCZmdCk7Cn0KCgovKiBSZWdFbnVtS2V5RXhBCQlbQURWQVBJMzIuMTM4XSAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleUV4MzJBKAoJSEtFWQloa2V5LAoJRFdPUkQJaVN1YmtleSwKCUxQU1RSCWxwc3pOYW1lLAoJTFBEV09SRAlscGNjaE5hbWUsCglMUERXT1JECWxwZHdSZXNlcnZlZCwKCUxQU1RSCWxwc3pDbGFzcywKCUxQRFdPUkQJbHBjY2hDbGFzcywKCUZJTEVUSU1FCSpmdAopIHsKCURXT1JECXJldCxscGNjaE5hbWVXLGxwY2NoQ2xhc3NXOwoJTFBXU1RSCWxwc3pOYW1lVyxscHN6Q2xhc3NXOwoKCglUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlTdWJrZXksbHBzek5hbWUsKmxwY2NoTmFtZSxscGR3UmVzZXJ2ZWQsbHBzekNsYXNzLGxwY2NoQ2xhc3MsZnQKCSk7CglpZiAobHBzek5hbWUpIHsKCQlscHN6TmFtZVcJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoTmFtZSoyKTsKCQlscGNjaE5hbWVXCT0gKmxwY2NoTmFtZSoyOwoJfSBlbHNlIHsKCQlscHN6TmFtZVcJPSBOVUxMOwoJCWxwY2NoTmFtZVcgCT0gMDsKCX0KCWlmIChscHN6Q2xhc3MpIHsKCQlscHN6Q2xhc3NXCQk9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hDbGFzcyoyKTsKCQlscGNjaENsYXNzVwk9ICpscGNjaENsYXNzKjI7Cgl9IGVsc2UgewoJCWxwc3pDbGFzc1cJPTA7CgkJbHBjY2hDbGFzc1c9MDsKCX0KCXJldD1SZWdFbnVtS2V5RXgzMlcoCgkJaGtleSwKCQlpU3Via2V5LAoJCWxwc3pOYW1lVywKCQkmbHBjY2hOYW1lVywKCQlscGR3UmVzZXJ2ZWQsCgkJbHBzekNsYXNzVywKCQkmbHBjY2hDbGFzc1csCgkJZnQKCSk7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJbHN0cmNweVd0b0EobHBzek5hbWUsbHBzek5hbWVXKTsKCQkqbHBjY2hOYW1lPXN0cmxlbihscHN6TmFtZSk7CgkJaWYgKGxwc3pDbGFzc1cpIHsKCQkJbHN0cmNweVd0b0EobHBzekNsYXNzLGxwc3pDbGFzc1cpOwoJCQkqbHBjY2hDbGFzcz1zdHJsZW4obHBzekNsYXNzKTsKCQl9Cgl9CglpZiAobHBzek5hbWVXKQoJCWZyZWUobHBzek5hbWVXKTsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5MzJBIFtBRFZBUEkzMi4xMzddCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTMyQSggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGxwY2NoTmFtZSApCnsKICAgIEZJTEVUSU1FCWZ0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwogICAgcmV0dXJuIFJlZ0VudW1LZXlFeDMyQSggaGtleSwgaVN1YmtleSwgbHBzek5hbWUsICZscGNjaE5hbWUsIE5VTEwsIE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgJmZ0ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXkxNiBbU0hFTEwuN10gW0tFUk5FTC4yMTZdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTE2KCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKICAgIHJldHVybiBSZWdFbnVtS2V5MzJBKCBoa2V5LCBpU3Via2V5LCBscHN6TmFtZSwgbHBjY2hOYW1lKTsKfQoKCi8qIAogKiBFbnVtZXJhdGUgUmVnaXN0cnkgVmFsdWVzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdFbnVtVmFsdWUxNiAtPiBSZWdFbnVtVmFsdWUzMkEgLT4gUmVnRW51bVZhbHVlMzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bVZhbHVlMzJXIFtBRFZBUEkzMi4xNDJdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMzJXKAoJSEtFWSBoa2V5LAoJRFdPUkQgaVZhbHVlLAoJTFBXU1RSIGxwc3pWYWx1ZSwKCUxQRFdPUkQJbHBjY2hWYWx1ZSwKCUxQRFdPUkQJbHBkUmVzZXJ2ZWQsCglMUERXT1JECWxwZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglMUEtFWVZBTFVFCXZhbDsKCglUUkFDRShyZWcsIigleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksaVZhbHVlLGxwc3pWYWx1ZSxscGNjaFZhbHVlLGxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEKCSk7CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscGtleSkKCQlyZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJaWYgKGxwa2V5LT5ucm9mdmFsdWVzPD1pVmFsdWUpCgkJcmV0dXJuIEVSUk9SX05PX01PUkVfSVRFTVM7Cgl2YWwJPSBscGtleS0+dmFsdWVzK2lWYWx1ZTsKCglpZiAodmFsLT5uYW1lKSB7CgkJaWYgKGxzdHJsZW4zMlcodmFsLT5uYW1lKSoyKzI+KmxwY2NoVmFsdWUpIHsKCQkJKmxwY2NoVmFsdWUgPSBsc3RybGVuMzJXKHZhbC0+bmFtZSkqMisyOwoJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCX0KCQltZW1jcHkobHBzelZhbHVlLHZhbC0+bmFtZSwyKmxzdHJsZW4zMlcodmFsLT5uYW1lKSsyKTsKCQkqbHBjY2hWYWx1ZT1sc3RybGVuMzJXKHZhbC0+bmFtZSkqMisyOwoJfSBlbHNlIHsKCQkqbHBzelZhbHVlCT0gMDsKCQkqbHBjY2hWYWx1ZQk9IDA7Cgl9CglpZiAobHBkd1R5cGUpCgkJKmxwZHdUeXBlPXZhbC0+dHlwZTsKCWlmIChscGJEYXRhKSB7CgkJaWYgKHZhbC0+bGVuPipscGNiRGF0YSkKCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQltZW1jcHkobHBiRGF0YSx2YWwtPmRhdGEsdmFsLT5sZW4pOwoJCSpscGNiRGF0YSA9IHZhbC0+bGVuOwoJfQoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKiBSZWdFbnVtVmFsdWVBCQlbQURWQVBJMzIuMTQxXSAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMzJBKAoJSEtFWQloa2V5LAoJRFdPUkQJaVZhbHVlLAoJTFBTVFIJbHBzelZhbHVlLAoJTFBEV09SRAlscGNjaFZhbHVlLAoJTFBEV09SRAlscGRSZXNlcnZlZCwKCUxQRFdPUkQJbHBkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglMUFdTVFIJbHBzelZhbHVlVzsKCUxQQllURQlscGJEYXRhVzsKCURXT1JECXJldCxscGNiRGF0YVc7CgoJVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSxscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhCgkpOwoKCWxwc3pWYWx1ZVcgPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoVmFsdWUqMik7CglpZiAobHBiRGF0YSkgewoJCWxwYkRhdGFXID0gKExQQllURSl4bWFsbG9jKCpscGNiRGF0YSoyKTsKCQlscGNiRGF0YVcgPSAqbHBjYkRhdGEqMjsKCX0gZWxzZQoJCWxwYkRhdGFXID0gTlVMTDsKCXJldD1SZWdFbnVtVmFsdWUzMlcoCgkJaGtleSwKCQlpVmFsdWUsCgkJbHBzelZhbHVlVywKCQlscGNjaFZhbHVlLAoJCWxwZFJlc2VydmVkLAoJCWxwZHdUeXBlLAoJCWxwYkRhdGFXLAoJCSZscGNiRGF0YVcKCSk7CgoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCWxzdHJjcHlXdG9BKGxwc3pWYWx1ZSxscHN6VmFsdWVXKTsKCQlpZiAobHBiRGF0YSkgewoJCQlpZiAoKDE8PCpscGR3VHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJbHN0cmNweVd0b0EobHBiRGF0YSwoTFBXU1RSKWxwYkRhdGFXKTsKCQkJfSBlbHNlIHsKCQkJCWlmIChscGNiRGF0YVcgPiAqbHBjYkRhdGEpCgkJCQkJcmV0CT0gRVJST1JfTU9SRV9EQVRBOwoJCQkJZWxzZQoJCQkJCW1lbWNweShscGJEYXRhLGxwYkRhdGFXLGxwY2JEYXRhVyk7CgkJCX0KCQkJKmxwY2JEYXRhID0gbHBjYkRhdGFXOwoJCX0KCX0KCWlmIChscGJEYXRhVykKCQlmcmVlKGxwYkRhdGFXKTsKCWlmIChscHN6VmFsdWVXKQoJCWZyZWUobHBzelZhbHVlVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUxNiBbS0VSTkVMLjIyM10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUxNiggSEtFWSBoa2V5LCBEV09SRCBpVmFsdWUsIExQU1RSIGxwc3pWYWx1ZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaFZhbHVlLCBMUERXT1JEIGxwZFJlc2VydmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsCiAgICAgICAgICBscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhKTsKICAgIHJldHVybiBSZWdFbnVtVmFsdWUzMkEoIGhrZXksIGlWYWx1ZSwgbHBzelZhbHVlLCBscGNjaFZhbHVlLCBscGRSZXNlcnZlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBscGR3VHlwZSwgbHBiRGF0YSwgbHBjYkRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ2xvc2VLZXkgW1NIRUxMLjNdIFtLRVJORUwuMjIwXSBbQURWQVBJMzIuMTI2XQogKiBSZWxlYXNlcyB0aGUgaGFuZGxlIG9mIHRoZSBzcGVjaWZpZWQga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIGNsb3NlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnQ2xvc2VLZXkoIEhLRVkgaGtleSApCnsKICAgIFRSQUNFKHJlZywiKCV4KVxuIixoa2V5KTsKICAgIHJldHVybiByZW1vdmVfaGFuZGxlKGhrZXkpOwp9CgoKLyogCiAqIERlbGV0ZSByZWdpc3RyeSBrZXkKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZUtleTE2IC0+IFJlZ0RlbGV0ZUtleTMyQSAtPiBSZWdEZWxldGVLZXkzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVLZXkzMlcgW0FEVkFQSTMyLjEzNF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldCiAqICAgIGxwc3pTdWJLZXkgW0ldCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5MzJXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6U3ViS2V5ICkKewoJTFBLRVlTVFJVQ1QJKmxwbHBQcmV2S2V5LGxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpIHsKICAgICAgICBUUkFDRShyZWcsICIgIEludmFsaWQgaGFuZGxlLlxuIik7CiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwogICAgfQoKCS8qIHdlIG5lZWQgdG8ga25vdyB0aGUgcHJldmlvdXMga2V5IGluIHRoZSBoaWVyLiAqLwoJaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkgewoJCVRSQUNFKHJlZywgIiAgQmFka2V5WzJdLlxuIik7CgkJcmV0dXJuIEVSUk9SX0JBREtFWTsKCX0KCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKGk8d3BjLTEpIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJVFJBQ0UocmVnLCAiICBTY2FubmluZyBbJXNdXG4iLAoJCQkJICAgICBXMkMgKGxweGtleS0+a2V5bmFtZSwgMCkpOwoJCQlpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KSB7CgkJCUZSRUVfS0VZX1BBVEg7CgkJCVRSQUNFKHJlZywgIiAgTm90IGZvdW5kLlxuIik7CgkJCS8qIG5vdCBmb3VuZCBpcyBzdWNjZXNzICovCgkJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJCX0KCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJbHB4a2V5CT0gbHBOZXh0S2V5LT5uZXh0c3ViOwoJbHBscFByZXZLZXkgPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7Cgl3aGlsZSAobHB4a2V5KSB7CgkJVFJBQ0UocmVnLCAiICBTY2FubmluZyBbJXNdXG4iLAoJCQkgICAgIFcyQyAobHB4a2V5LT5rZXluYW1lLCAwKSk7CgkJaWYgKCFsc3RyY21waTMyVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJYnJlYWs7CgkJbHBscFByZXZLZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJbHB4a2V5CQk9IGxweGtleS0+bmV4dDsKCX0KCglpZiAoIWxweGtleSkgewoJCUZSRUVfS0VZX1BBVEg7CgkJV0FSTihyZWcgLCAiICBOb3QgZm91bmQuXG4iKTsKCQlyZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7Cgl9CgoJaWYgKGxweGtleS0+bmV4dHN1YikgewoJCUZSRUVfS0VZX1BBVEg7CgkJV0FSTihyZWcgLCAiICBOb3QgZW1wdHkuXG4iKTsKCQlyZXR1cm4gRVJST1JfQ0FOVFdSSVRFOwoJfQoJKmxwbHBQcmV2S2V5CT0gbHB4a2V5LT5uZXh0OwoJZnJlZShscHhrZXktPmtleW5hbWUpOwoJaWYgKGxweGtleS0+Y2xhc3MpCgkJZnJlZShscHhrZXktPmNsYXNzKTsKCWlmIChscHhrZXktPnZhbHVlcykKCQlmcmVlKGxweGtleS0+dmFsdWVzKTsKCWZyZWUobHB4a2V5KTsKCUZSRUVfS0VZX1BBVEg7CglUUkFDRShyZWcsICIgIERvbmUuXG4iKTsKCXJldHVybglFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVLZXkzMkEgW0FEVkFQSTMyLjEzM10KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXkgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVc7CiAgICBEV09SRCAgcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIixoa2V5LGxwc3pTdWJLZXkpOwogICAgbHBzelN1YktleVcgPSBIRUFQX3N0cmR1cEF0b1coIEdldFByb2Nlc3NIZWFwKCksIDAsIGxwc3pTdWJLZXkgKTsKICAgIHJldCA9IFJlZ0RlbGV0ZUtleTMyVyggaGtleSwgbHBzelN1YktleVcgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBscHN6U3ViS2V5VyApOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlS2V5MTYgW1NIRUxMLjRdIFtLRVJORUwuMjE5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSk7CiAgICByZXR1cm4gUmVnRGVsZXRlS2V5MzJBKCBoa2V5LCBscHN6U3ViS2V5ICk7Cn0KCgovKiAKICogRGVsZXRlIHJlZ2lzdHJ5IHZhbHVlCiAqCiAqIENhbGxwYXRoOgogKiBSZWdEZWxldGVWYWx1ZTE2IC0+IFJlZ0RlbGV0ZVZhbHVlMzJBIC0+IFJlZ0RlbGV0ZVZhbHVlMzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlVmFsdWUzMlcgW0FEVkFQSTMyLjEzNl0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICBbSV0KICogICAgbHBzelZhbHVlIFtJXQogKgogKiBSRVRVUk5TCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUzMlcoIEhLRVkgaGtleSwgTFBXU1RSIGxwc3pWYWx1ZSApCnsKCURXT1JECQlpOwoJTFBLRVlTVFJVQ1QJbHBrZXk7CglMUEtFWVZBTFVFCXZhbDsKCiAgICBUUkFDRShyZWcsIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pWYWx1ZSkpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglpZiAobHBzelZhbHVlKSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmICgJbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmCgkJCQkhbHN0cmNtcGkzMlcobHBrZXktPnZhbHVlc1tpXS5uYW1lLGxwc3pWYWx1ZSkKCQkJKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9CgogICAgaWYgKGkgPT0gbHBrZXktPm5yb2Z2YWx1ZXMpCiAgICAgICAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoKCXZhbAk9IGxwa2V5LT52YWx1ZXMraTsKCWlmICh2YWwtPm5hbWUpIGZyZWUodmFsLT5uYW1lKTsKCWlmICh2YWwtPmRhdGEpIGZyZWUodmFsLT5kYXRhKTsKCW1lbWNweSgJCgkJbHBrZXktPnZhbHVlcytpLAoJCWxwa2V5LT52YWx1ZXMraSsxLAoJCXNpemVvZihLRVlWQUxVRSkqKGxwa2V5LT5ucm9mdmFsdWVzLWktMSkKCSk7CglscGtleS0+dmFsdWVzCT0gKExQS0VZVkFMVUUpeHJlYWxsb2MoCgkJCQlscGtleS0+dmFsdWVzLAoJCQkJKGxwa2V5LT5ucm9mdmFsdWVzLTEpKnNpemVvZihLRVlWQUxVRSkKCQkJKTsKCWxwa2V5LT5ucm9mdmFsdWVzLS07CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlVmFsdWUzMkEgW0FEVkFQSTMyLjEzNV0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTMyQSggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWUgKQp7CiAgICBMUFdTVFIgbHBzelZhbHVlVzsKICAgIERXT1JEICByZXQ7CgogICAgVFJBQ0UocmVnLCAiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlKSk7CiAgICBscHN6VmFsdWVXPUhFQVBfc3RyZHVwQXRvVyhHZXRQcm9jZXNzSGVhcCgpLDAsbHBzelZhbHVlKTsKICAgIHJldCA9IFJlZ0RlbGV0ZVZhbHVlMzJXKCBoa2V5LCBscHN6VmFsdWVXICk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsbHBzelZhbHVlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVWYWx1ZTE2IFtLRVJORUwuMjIyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLCBoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlKSk7CiAgICByZXR1cm4gUmVnRGVsZXRlVmFsdWUzMkEoaGtleSxscHN6VmFsdWUpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdGbHVzaEtleSBbS0VSTkVMLjIyN10gW0FEVkFQSTMyLjE0M10KICogV3JpdGVzIGtleSB0byByZWdpc3RyeQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byB3cml0ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0ZsdXNoS2V5KCBIS0VZIGhrZXkgKQp7CiAgICBGSVhNRShyZWcsICIoJXgpOiBzdHViXG4iLCBoa2V5KTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyogRklYTUU6IGxwY2NoWFhYWCAuLi4gaXMgdGhpcyBjb3VudGluZyBpbiBXQ0hBUlMgb3IgaW4gQllURXMgPz8gKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlJbmZvS2V5MzJXIFtBRFZBUEkzMi4xNTNdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlJbmZvS2V5MzJXKAoJSEtFWQloa2V5LAoJTFBXU1RSCWxwc3pDbGFzcywKCUxQRFdPUkQJbHBjY2hDbGFzcywKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBEV09SRAlscGNTdWJLZXlzLAoJTFBEV09SRAlscGNjaE1heFN1YmtleSwKCUxQRFdPUkQJbHBjY2hNYXhDbGFzcywKCUxQRFdPUkQJbHBjVmFsdWVzLAoJTFBEV09SRAlscGNjaE1heFZhbHVlTmFtZSwKCUxQRFdPUkQJbHBjY2JNYXhWYWx1ZURhdGEsCglMUERXT1JECWxwY2JTZWN1cml0eURlc2NyaXB0b3IsCglGSUxFVElNRQkqZnQKKSB7CglMUEtFWVNUUlVDVAlscGtleSxscHhrZXk7CglpbnQJCW5yb2ZrZXlzLG1heHN1YmtleSxtYXhjbGFzcyxtYXh2bmFtZSxtYXh2ZGF0YTsKCWludAkJaTsKCglUUkFDRShyZWcsIigleCwuLi4uLi4pXG4iLGhrZXkpOwoJbHBrZXkgPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoJaWYgKGxwc3pDbGFzcykgewoJCWlmIChscGtleS0+Y2xhc3MpIHsKCQkJaWYgKGxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyKzI+KmxwY2NoQ2xhc3MpIHsKCQkJCSpscGNjaENsYXNzPWxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyOwoJCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQkJfQoJCQkqbHBjY2hDbGFzcz1sc3RybGVuMzJXKGxwa2V5LT5jbGFzcykqMjsKCQkJbWVtY3B5KGxwc3pDbGFzcyxscGtleS0+Y2xhc3MsbHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKTsKCQl9IGVsc2UgewoJCQkqbHBzekNsYXNzCT0gMDsKCQkJKmxwY2NoQ2xhc3MJPSAwOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGxwY2NoQ2xhc3MpCgkJCSpscGNjaENsYXNzCT0gbHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjI7Cgl9CglscHhrZXk9bHBrZXktPm5leHRzdWI7Cglucm9ma2V5cz1tYXhzdWJrZXk9bWF4Y2xhc3M9bWF4dm5hbWU9bWF4dmRhdGE9MDsKCXdoaWxlIChscHhrZXkpIHsKCQlucm9ma2V5cysrOwoJCWlmIChsc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSk+bWF4c3Via2V5KQoJCQltYXhzdWJrZXk9bHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpOwoJCWlmIChscHhrZXktPmNsYXNzICYmIGxzdHJsZW4zMlcobHB4a2V5LT5jbGFzcyk+bWF4Y2xhc3MpCgkJCW1heGNsYXNzPWxzdHJsZW4zMlcobHB4a2V5LT5jbGFzcyk7CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJTFBLRVlWQUxVRQl2YWw9bHBrZXktPnZhbHVlcytpOwoKCQlpZiAodmFsLT5uYW1lICYmIGxzdHJsZW4zMlcodmFsLT5uYW1lKT5tYXh2bmFtZSkKCQkJbWF4dm5hbWU9bHN0cmxlbjMyVyh2YWwtPm5hbWUpOwoJCWlmICh2YWwtPmxlbj5tYXh2ZGF0YSkKCQkJbWF4dmRhdGE9dmFsLT5sZW47Cgl9CglpZiAoIW1heGNsYXNzKSBtYXhjbGFzcwk9IDE7CglpZiAoIW1heHZuYW1lKSBtYXh2bmFtZQk9IDE7CglpZiAobHBjVmFsdWVzKQoJCSpscGNWYWx1ZXMJPSBscGtleS0+bnJvZnZhbHVlczsKCWlmIChscGNTdWJLZXlzKQoJCSpscGNTdWJLZXlzCT0gbnJvZmtleXM7CglpZiAobHBjY2hNYXhTdWJrZXkpCgkJKmxwY2NoTWF4U3Via2V5CT0gbWF4c3Via2V5KjI7CglpZiAobHBjY2hNYXhDbGFzcykKCQkqbHBjY2hNYXhDbGFzcwk9IG1heGNsYXNzKjI7CglpZiAobHBjY2hNYXhWYWx1ZU5hbWUpCgkJKmxwY2NoTWF4VmFsdWVOYW1lPSBtYXh2bmFtZTsKCWlmIChscGNjYk1heFZhbHVlRGF0YSkKCQkqbHBjY2JNYXhWYWx1ZURhdGE9IG1heHZkYXRhOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKiBSZWdRdWVyeUluZm9LZXlBCQlbQURWQVBJMzIuMTUyXSAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlJbmZvS2V5MzJBKAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzekNsYXNzLAoJTFBEV09SRAlscGNjaENsYXNzLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUERXT1JECWxwY1N1YktleXMsCglMUERXT1JECWxwY2NoTWF4U3Via2V5LAoJTFBEV09SRAlscGNjaE1heENsYXNzLAoJTFBEV09SRAlscGNWYWx1ZXMsCglMUERXT1JECWxwY2NoTWF4VmFsdWVOYW1lLAoJTFBEV09SRAlscGNjYk1heFZhbHVlRGF0YSwKCUxQRFdPUkQJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCUZJTEVUSU1FCSpmdAopIHsKCUxQV1NUUgkJbHBzekNsYXNzVzsKCURXT1JECQlyZXQ7CgoJVFJBQ0UocmVnLCIoJXgsLi4uLi4uKVxuIixoa2V5KTsKCWlmIChscHN6Q2xhc3MpIHsKCQkqbHBjY2hDbGFzcyo9IDI7CgkJbHBzekNsYXNzVyAgPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoQ2xhc3MpOwoKCX0gZWxzZQoJCWxwc3pDbGFzc1cgID0gTlVMTDsKCXJldD1SZWdRdWVyeUluZm9LZXkzMlcoCgkJaGtleSwKCQlscHN6Q2xhc3NXLAoJCWxwY2NoQ2xhc3MsCgkJbHBkd1Jlc2VydmVkLAoJCWxwY1N1YktleXMsCgkJbHBjY2hNYXhTdWJrZXksCgkJbHBjY2hNYXhDbGFzcywKCQlscGNWYWx1ZXMsCgkJbHBjY2hNYXhWYWx1ZU5hbWUsCgkJbHBjY2JNYXhWYWx1ZURhdGEsCgkJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCQlmdAoJKTsKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MgJiYgbHBzekNsYXNzKQoJCWxzdHJjcHlXdG9BKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCWlmIChscGNjaENsYXNzKQoJCSpscGNjaENsYXNzLz0yOwoJaWYgKGxwY2NoTWF4U3Via2V5KQoJCSpscGNjaE1heFN1YmtleS89MjsKCWlmIChscGNjaE1heENsYXNzKQoJCSpscGNjaE1heENsYXNzLz0yOwoJaWYgKGxwY2NoTWF4VmFsdWVOYW1lKQoJCSpscGNjaE1heFZhbHVlTmFtZS89MjsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnkzMlcgW0FEVkFQSTMyLjEyOF0KICovCkxPTkcgV0lOQVBJIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyVyggTFBDV1NUUiBtYWNoaW5lLCBIS0VZIGhrZXksIExQSEtFWSByZXNrZXkgKQp7CiAgICBGSVhNRShyZWcsIiglcywleCwlcCk6IHN0dWJcbiIsZGVidWdzdHJfdyhtYWNoaW5lKSxoa2V5LHJlc2tleSk7CiAgICByZXR1cm4gRVJST1JfQkFEX05FVFBBVEg7IC8qIEZJWE1FICovCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyQSBbQURWQVBJMzIuMTI3XQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5MzJBKCBMUENTVFIgbWFjaGluZSwgSEtFWSBoa2V5LCBMUEhLRVkgcmVza2V5ICkKewogICAgRFdPUkQgcmV0OwogICAgTFBXU1RSIG1hY2hpbmVXID0gSEVBUF9zdHJkdXBBdG9XKEdldFByb2Nlc3NIZWFwKCksMCxtYWNoaW5lKTsKICAgIHJldCA9IFJlZ0Nvbm5lY3RSZWdpc3RyeTMyVyggbWFjaGluZVcsIGhrZXksIHJlc2tleSApOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLG1hY2hpbmVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0dldEtleVNlY3VyaXR5IFtBRFZBUEkzMi4xNDRdCiAqIFJldHJpZXZlcyBhIGNvcHkgb2Ygc2VjdXJpdHkgZGVzY3JpcHRvciBwcm90ZWN0aW5nIHRoZSByZWdpc3RyeSBrZXkKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkxPTkcgV0lOQVBJIFJlZ0dldEtleVNlY3VyaXR5KCBIS0VZIGhrZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0VDVVJJVFlfSU5GT1JNQVRJT04gU2VjdXJpdHlJbmZvcm1hdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfREVTQ1JJUFRPUiBwU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CiAgICBscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUUocmVnLCAiKCVkLCVsZCwlcCwlcCk6IHN0dWJcbiIsIGhrZXksIFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICBwU2VjdXJpdHlEZXNjcmlwdG9yLCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdMb2FkS2V5MzJXIFtBRFZBUEkzMi4/Pz9dCiAqLwpMT05HIFdJTkFQSSBSZWdMb2FkS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBDV1NUUiBscHN6RmlsZSApCnsKICAgIEZJWE1FKHJlZywiKCV4LCVzLCVzKTogc3R1YlxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwc3pGaWxlKSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTG9hZEtleTMyQSBbQURWQVBJMzIuPz8/XQogKi8KTE9ORyBXSU5BUEkgUmVnTG9hZEtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBDU1RSIGxwc3pGaWxlICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBzelN1YktleVcgPSBIRUFQX3N0cmR1cEF0b1coR2V0UHJvY2Vzc0hlYXAoKSwwLGxwc3pTdWJLZXkpOwogICAgTFBXU1RSIGxwc3pGaWxlVyA9IEhFQVBfc3RyZHVwQXRvVyhHZXRQcm9jZXNzSGVhcCgpLDAsbHBzekZpbGUpOwogICAgcmV0ID0gUmVnTG9hZEtleTMyVyggaGtleSwgbHBzelN1YktleVcsIGxwc3pGaWxlVyApOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLGxwc3pGaWxlVyk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsbHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTm90aWZ5Q2hhbmdlS2V5VmFsdWUgW0FEVkFQSTMyLj8/P10KICovCkxPTkcgV0lOQVBJIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlKCBIS0VZIGhrZXksIEJPT0wzMiBmV2F0Y2hTdWJUcmVlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGZkd05vdGlmeUZpbHRlciwgSEFORExFMzIgaEV2ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTDMyIGZBc3luYyApCnsKICAgIEZJWE1FKHJlZywiKCV4LCVpLCVsZCwlZCwlaSk6IHN0dWJcbiIsaGtleSxmV2F0Y2hTdWJUcmVlLGZkd05vdGlmeUZpbHRlciwKICAgICAgICAgIGhFdmVudCxmQXN5bmMpOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCg==