LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICoKICogRGVjZW1iZXIgMjEsIDE5OTcgLSBLZXZpbiBDb3plbnMKICogRml4ZWQgYnVncyBpbiB0aGUgX3c5NV9sb2FkcmVnKCkgZnVuY3Rpb24uIEFkZGVkIGV4dHJhIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyB0aGUgZm9ybWF0IG9mIHRoZSBXaW5kb3dzICc5NSByZWdpc3RyeSBmaWxlcy4KICoKICogTk9URVMKICogICAgV2hlbiBjaGFuZ2luZyB0aGlzIGZpbGUsIHBsZWFzZSByZS1ydW4gdGhlIHJlZ3Rlc3QgcHJvZ3JhbSB0byBlbnN1cmUKICogICAgdGhlIGNvbmRpdGlvbnMgYXJlIGhhbmRsZWQgcHJvcGVybHkuCiAqCiAqIFRPRE8KICogICAgU2VjdXJpdHkgYWNjZXNzCiAqICAgIE9wdGlvbiBoYW5kbGluZwogKiAgICBUaW1lIGZvciBSZWdFbnVtS2V5KiwgUmVnUXVlcnlJbmZvS2V5KgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPHN5cy9lcnJuby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxwd2QuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAid2luLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAiaGVhcC5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAid2ludmVyc2lvbi5oIgoKc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCh2b2lkKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCi8qIE5PVEU6IGRvIG5vdCBhcHBlbmQgYSAvLiBsaW51eCcgbWtkaXIoKSBXSUxMIEZBSUwgaWYgeW91IGRvIHRoYXQgKi8KI2RlZmluZSBXSU5FX1BSRUZJWAkJCSIvLndpbmUiCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUCQkiL3Vzci9sb2NhbC9ldGMvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUCSIvdXNyL2xvY2FsL2V0Yy93aW5lLnN5c3RlbXJlZyIKCi8qIHJlbGF0aXZlIGluIH51c2VyLy53aW5lLyA6ICovCiNkZWZpbmUgU0FWRV9DVVJSRU5UX1VTRVIJCSJ1c2VyLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX01BQ0hJTkUJCSJzeXN0ZW0ucmVnIgoKI2RlZmluZSBLRVlfUkVHSVNUUlkJIlNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeSIKI2RlZmluZSBWQUxfU0FWRVVQREFURUQJIlNhdmVPbmx5VXBkYXRlZEtleXMiCgovKiBvbmUgdmFsdWUgb2YgYSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZVkFMVUUKewogICAgTFBXU1RSICAgbmFtZTsgICAgICAgICAgLyogbmFtZSBvZiB2YWx1ZSAoVU5JQ09ERSkgb3IgTlVMTCBmb3Igd2luMzEgKi8KICAgIERXT1JEICAgIHR5cGU7ICAgICAgICAgIC8qIHR5cGUgb2YgdmFsdWUgKi8KICAgIERXT1JEICAgIGxlbjsgICAgICAgICAgIC8qIGxlbmd0aCBvZiBkYXRhIGluIEJZVEVzICovCiAgICBEV09SRCAgICBsYXN0bW9kaWZpZWQ7ICAvKiB0aW1lIG9mIHNlY29uZHMgc2luY2UgMS4xLjE5NzAgKi8KICAgIExQQllURSAgIGRhdGE7ICAgICAgICAgIC8qIGNvbnRlbnQsIG1heSBiZSBzdHJpbmdzLCBiaW5hcmllcywgZXRjLiAqLwp9IEtFWVZBTFVFLCpMUEtFWVZBTFVFOwoKLyogYSByZWdpc3RyeSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZU1RSVUNUCnsKICAgIExQV1NUUiAgICAgICAgICAgICAgIGtleW5hbWU7ICAgICAgIC8qIG5hbWUgb2YgVEhJUyBrZXkgKFVOSUNPREUpICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBmbGFnczsgICAgICAgICAvKiBmbGFncy4gKi8KICAgIExQV1NUUiAgICAgICAgICAgICAgIGNsYXNzOwogICAgLyogdmFsdWVzICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBucm9mdmFsdWVzOyAgICAvKiBuciBvZiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIExQS0VZVkFMVUUgICAgICAgICAgIHZhbHVlczsgICAgICAgIC8qIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgLyoga2V5IG1hbmFnZW1lbnQgcG9pbnRlcnMgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHQ7ICAgICAgICAgIC8qIG5leHQga2V5IG9uIHNhbWUgaGllcmFyY2h5ICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0c3ViOyAgICAgICAvKiBrZXlzIHRoYXQgaGFuZyBiZWxvdyBUSElTIGtleSAqLwp9IEtFWVNUUlVDVCwgKkxQS0VZU1RSVUNUOwoKCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jbGFzc2VzX3Jvb3Q9TlVMTDsJLyogd2luZG93cyAzLjEgZ2xvYmFsIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF91c2VyPU5VTEw7CS8qIHVzZXIgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9sb2NhbF9tYWNoaW5lPU5VTEw7LyogbWFjaGluZSBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3VzZXJzPU5VTEw7CS8qIGFsbCB1c2Vycz8gKi8KCi8qIGR5bmFtaWMsIG5vdCBzYXZlZCAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfcGVyZm9ybWFuY2VfZGF0YT1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF9jb25maWc9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2R5bl9kYXRhPU5VTEw7CgovKiB3aGF0IHZhbHVldHlwZXMgZG8gd2UgbmVlZCB0byBjb252ZXJ0PyAqLwojZGVmaW5lIFVOSUNPTlZNQVNLCSgoMTw8UkVHX1NaKXwoMTw8UkVHX01VTFRJX1NaKXwoMTw8UkVHX0VYUEFORF9TWikpCgoKc3RhdGljIHN0cnVjdCBvcGVuaGFuZGxlIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCVJFR1NBTQkJYWNjZXNzbWFzazsKfSAgKm9wZW5oYW5kbGVzPU5VTEw7CnN0YXRpYyBpbnQJbnJvZm9wZW5oYW5kbGVzPTA7Ci8qIFN0YXJ0cyBhZnRlciAxIGJlY2F1c2UgMCwxIGFyZSByZXNlcnZlZCBmb3IgV2luMTYgKi8KLyogTm90ZTogU2hvdWxkIGFsd2F5cyBiZSBldmVuLCBhcyBXaW45NSBBRFZBUEkzMi5ETEwgcmVzZXJ2ZXMgb2RkCiAgICAgICAgIEhLRVlzIGZvciByZW1vdGUgcmVnaXN0cnkgYWNjZXNzICovCnN0YXRpYyBpbnQJY3VycmVudGhhbmRsZT0yOwoKCi8qCiAqIFFVRVNUSU9OCiAqICAgQXJlIHRoZXNlIGRvaW5nIHRoZSBzYW1lIGFzIEhFQVBfc3RyZHVwQXRvVyBhbmQgSEVBUF9zdHJkdXBXdG9BPwogKiAgIElmIHNvLCBjYW4gd2UgcmVtb3ZlIHRoZW0/CiAqIEFOU1dFUgogKiAgIE5vLCB0aGUgbWVtb3J5IGhhbmRsaW5nIGZ1bmN0aW9ucyBhcmUgY2FsbGVkIHZlcnkgb2Z0ZW4gaW4gaGVyZSwgCiAqICAganVzdCByZXBsYWNpbmcgdGhlbSBieSBIZWFwQWxsb2MoU3lzdGVtSGVhcCwuLi4pIG1ha2VzIHJlZ2lzdHJ5CiAqICAgbG9hZGluZyAxMDAgdGltZXMgc2xvd2VyLiAtTU0KICovCnN0YXRpYyBMUFdTVFIgc3RyZHVwQTJXKExQQ1NUUiBzcmMpCnsKICAgIGlmKHNyYykgewoJTFBXU1RSIGRlc3Q9eG1hbGxvYygyKnN0cmxlbihzcmMpKzIpOwoJbHN0cmNweUF0b1coZGVzdCxzcmMpOwoJcmV0dXJuIGRlc3Q7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIExQV1NUUiBzdHJkdXBXKExQQ1dTVFIgYSkgewoJTFBXU1RSCWI7CglpbnQJbGVuOwoKICAgIGlmKGEpIHsKCWxlbj1zaXplb2YoV0NIQVIpKihsc3RybGVuMzJXKGEpKzEpOwoJYj0oTFBXU1RSKXhtYWxsb2MobGVuKTsKCW1lbWNweShiLGEsbGVuKTsKCXJldHVybiBiOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCkxQV1NUUiBzdHJjdnRBMlcoTFBDU1RSIHNyYywgaW50IG5jaGFycykKCnsKICAgTFBXU1RSIGRlc3QgPSB4bWFsbG9jICgyICogbmNoYXJzICsgMik7CgogICBsc3RyY3B5bkF0b1coZGVzdCxzcmMsbmNoYXJzKzEpOwogICBkZXN0W25jaGFyc10gPSAwOwogICByZXR1cm4gZGVzdDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogaXNfc3RhbmRhcmRfaGtleSBbSW50ZXJuYWxdCiAqIERldGVybWluZXMgaWYgYSBoa2V5IGlzIGEgc3RhbmRhcmQga2V5CiAqLwpzdGF0aWMgQk9PTDMyIGlzX3N0YW5kYXJkX2hrZXkoIEhLRVkgaGtleSApCnsKICAgIHN3aXRjaChoa2V5KSB7CiAgICAgICAgY2FzZSAweDAwMDAwMDAwOgogICAgICAgIGNhc2UgMHgwMDAwMDAwMToKICAgICAgICBjYXNlIEhLRVlfQ0xBU1NFU19ST09UOgogICAgICAgIGNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKICAgICAgICBjYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgogICAgICAgIGNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgogICAgICAgIGNhc2UgSEtFWV9VU0VSUzoKICAgICAgICBjYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKICAgICAgICBjYXNlIEhLRVlfRFlOX0RBVEE6CiAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBhZGRfaGFuZGxlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIGFkZF9oYW5kbGUoIEhLRVkgaGtleSwgTFBLRVlTVFJVQ1QgbHBrZXksIFJFR1NBTSBhY2Nlc3NtYXNrICkKewogICAgaW50IGk7CgogICAgVFJBQ0UocmVnLCIoMHgleCwlcCwweCVseClcbiIsaGtleSxscGtleSxhY2Nlc3NtYXNrKTsKICAgIC8qIENoZWNrIGZvciBkdXBsaWNhdGVzICovCiAgICBmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspIHsKICAgICAgICBpZiAob3BlbmhhbmRsZXNbaV0ubHBrZXk9PWxwa2V5KSB7CiAgICAgICAgICAgIC8qIFRoaXMgaXMgbm90IHJlYWxseSBhbiBlcnJvciAtIHRoZSB1c2VyIGlzIGFsbG93ZWQgdG8gY3JlYXRlCiAgICAgICAgICAgICAgIHR3byAob3IgbW9yZSkgaGFuZGxlcyB0byB0aGUgc2FtZSBrZXkgKi8KICAgICAgICAgICAgLypXQVJOKHJlZywgIkFkZGluZyBrZXkgJXAgdHdpY2VcbiIsbHBrZXkpOyovCiAgICAgICAgfQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KSB7CiAgICAgICAgICAgIFdBUk4ocmVnLCAiQWRkaW5nIGhhbmRsZSAleCB0d2ljZVxuIixoa2V5KTsKICAgICAgICB9CiAgICB9CiAgICBvcGVuaGFuZGxlcz14cmVhbGxvYyggb3BlbmhhbmRsZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcysxKSk7CgogICAgb3BlbmhhbmRsZXNbaV0ubHBrZXkgPSBscGtleTsKICAgIG9wZW5oYW5kbGVzW2ldLmhrZXkgPSBoa2V5OwogICAgb3BlbmhhbmRsZXNbaV0uYWNjZXNzbWFzayA9IGFjY2Vzc21hc2s7CiAgICBucm9mb3BlbmhhbmRsZXMrKzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZ2V0X2hhbmRsZSBbSW50ZXJuYWxdCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogUG9pbnRlciB0byBrZXkKICogICAgRmFpbHVyZTogTlVMTAogKi8Kc3RhdGljIExQS0VZU1RSVUNUIGdldF9oYW5kbGUoIEhLRVkgaGtleSApCnsKICAgIGludCBpOwoKICAgIGZvciAoaT0wOyBpPG5yb2ZvcGVuaGFuZGxlczsgaSsrKQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5ID09IGhrZXkpCiAgICAgICAgICAgIHJldHVybiBvcGVuaGFuZGxlc1tpXS5scGtleTsKICAgIFdBUk4ocmVnLCAiQ291bGQgbm90IGZpbmQgaGFuZGxlIDB4JXhcbiIsaGtleSk7CiAgICByZXR1cm4gTlVMTDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogcmVtb3ZlX2hhbmRsZSBbSW50ZXJuYWxdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHJlbW92ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRVJST1JfSU5WQUxJRF9IQU5ETEUKICovCnN0YXRpYyBEV09SRCByZW1vdmVfaGFuZGxlKCBIS0VZIGhrZXkgKQp7CiAgICBpbnQgaTsKCiAgICBmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspCiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpCiAgICAgICAgICAgIGJyZWFrOwoKICAgIGlmIChpID09IG5yb2ZvcGVuaGFuZGxlcykgewogICAgICAgIFdBUk4ocmVnLCAiQ291bGQgbm90IGZpbmQgaGFuZGxlIDB4JXhcbiIsaGtleSk7CiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwogICAgfQoKICAgIG1lbWNweSggb3BlbmhhbmRsZXMraSwKICAgICAgICAgICAgb3BlbmhhbmRsZXMraSsxLAogICAgICAgICAgICBzaXplb2Yoc3RydWN0IG9wZW5oYW5kbGUpKihucm9mb3BlbmhhbmRsZXMtaS0xKQogICAgKTsKICAgIG9wZW5oYW5kbGVzPXhyZWFsbG9jKG9wZW5oYW5kbGVzLHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy0xKSk7CiAgICBucm9mb3BlbmhhbmRsZXMtLTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGxvb2t1cF9oa2V5IFtJbnRlcm5hbF0KICogCiAqIEp1c3QgYXMgdGhlIG5hbWUgc2F5cy4gQ3JlYXRlcyB0aGUgcm9vdCBrZXlzIG9uIGRlbWFuZCwgc28gd2UgY2FuIGNhbGwgdGhlCiAqIFJlZyogZnVuY3Rpb25zIGF0IGFueSB0aW1lLgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFBvaW50ZXIgdG8ga2V5IHN0cnVjdHVyZQogKiAgICBGYWlsdXJlOiBOVUxMCiAqLwojZGVmaW5lIEFERF9ST09UX0tFWSh4eCkgXAoJeHggPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7XAoJbWVtc2V0KHh4LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpO1wKCXh4LT5rZXluYW1lPSBzdHJkdXBBMlcoIjxzaG91bGRfbm90X2FwcGVhcl9hbnl3aGVyZT4iKTsKCnN0YXRpYyBMUEtFWVNUUlVDVCBsb29rdXBfaGtleSggSEtFWSBoa2V5ICkKewoJc3dpdGNoIChoa2V5KSB7CgkvKiAwIGFuZCAxIGFyZSB2YWxpZCByb290a2V5cyBpbiB3aW4xNiBzaGVsbC5kbGwgYW5kIGFyZSB1c2VkIGJ5CgkgKiBzb21lIHByb2dyYW1zLiBEbyBub3QgcmVtb3ZlIHRob3NlIGNhc2VzLiAtTU0KCSAqLwogICAgCWNhc2UgMHgwMDAwMDAwMDoKCWNhc2UgMHgwMDAwMDAwMToKCWNhc2UgSEtFWV9DTEFTU0VTX1JPT1Q6IHsKCQlpZiAoIWtleV9jbGFzc2VzX3Jvb3QpIHsKCQkJSEtFWQljbF9yX2hrZXk7CgoJCQkvKiBjYWxscyBsb29rdXBfaGtleSByZWN1cnNpdmVseSwgVFdJQ0UgKi8KCQkJaWYgKFJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiU09GVFdBUkVcXENsYXNzZXMiLCZjbF9yX2hrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJCQlFUlIocmVnLCJDb3VsZCBub3QgY3JlYXRlIEhLTE1cXFNPRlRXQVJFXFxDbGFzc2VzLiBUaGlzIGlzIGltcG9zc2libGUuXG4iKTsKCQkJCWV4aXQoMSk7CgkJCX0KCQkJa2V5X2NsYXNzZXNfcm9vdCA9IGxvb2t1cF9oa2V5KGNsX3JfaGtleSk7CgkJfQoJCXJldHVybiBrZXlfY2xhc3Nlc19yb290OwoJfQoJY2FzZSBIS0VZX0NVUlJFTlRfVVNFUjoKCQlpZiAoIWtleV9jdXJyZW50X3VzZXIpIHsKCQkJSEtFWQljX3VfaGtleTsKCQkJc3RydWN0CXBhc3N3ZAkqcHdkOwoKCQkJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCQkJLyogY2FsbHMgbG9va3VwX2hrZXkgcmVjdXJzaXZlbHksIFRXSUNFICovCgkJCWlmIChwd2QgJiYgcHdkLT5wd19uYW1lKSB7CgkJCQlpZiAoUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUyxwd2QtPnB3X25hbWUsJmNfdV9oa2V5KSE9RVJST1JfU1VDQ0VTUykgewoJCQkJCUVSUihyZWcsIkNvdWxkIG5vdCBjcmVhdGUgSFVcXCVzLiBUaGlzIGlzIGltcG9zc2libGUuXG4iLHB3ZC0+cHdfbmFtZSk7CgkJCQkJZXhpdCgxKTsKCQkJCX0KCQkJCWtleV9jdXJyZW50X3VzZXIgPSBsb29rdXBfaGtleShjX3VfaGtleSk7CgkJCX0gZWxzZSB7CgkJCQkvKiBub3RoaW5nIGZvdW5kLCB1c2Ugc3RhbmRhbG9uZSAqLwoJCQkJQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X3VzZXIpOwoJCQl9CgkJfQoJCXJldHVybiBrZXlfY3VycmVudF91c2VyOwoJY2FzZSBIS0VZX0xPQ0FMX01BQ0hJTkU6CgkJaWYgKCFrZXlfbG9jYWxfbWFjaGluZSkgewoJCQlBRERfUk9PVF9LRVkoa2V5X2xvY2FsX21hY2hpbmUpOwoJCQlSRUdJU1RSWV9Jbml0KCk7CgkJfQoJCXJldHVybiBrZXlfbG9jYWxfbWFjaGluZTsKCWNhc2UgSEtFWV9VU0VSUzoKCQlpZiAoIWtleV91c2VycykgewoJCQlBRERfUk9PVF9LRVkoa2V5X3VzZXJzKTsKCQl9CgkJcmV0dXJuIGtleV91c2VyczsKCWNhc2UgSEtFWV9QRVJGT1JNQU5DRV9EQVRBOgoJCWlmICgha2V5X3BlcmZvcm1hbmNlX2RhdGEpIHsKCQkJQUREX1JPT1RfS0VZKGtleV9wZXJmb3JtYW5jZV9kYXRhKTsKCQl9CgkJcmV0dXJuIGtleV9wZXJmb3JtYW5jZV9kYXRhOwoJY2FzZSBIS0VZX0RZTl9EQVRBOgoJCWlmICgha2V5X2R5bl9kYXRhKSB7CgkJCUFERF9ST09UX0tFWShrZXlfZHluX2RhdGEpOwoJCX0KCQlyZXR1cm4ga2V5X2R5bl9kYXRhOwoJY2FzZSBIS0VZX0NVUlJFTlRfQ09ORklHOgoJCWlmICgha2V5X2N1cnJlbnRfY29uZmlnKSB7CgkJCUFERF9ST09UX0tFWShrZXlfY3VycmVudF9jb25maWcpOwoJCX0KCQlyZXR1cm4ga2V5X2N1cnJlbnRfY29uZmlnOwoJZGVmYXVsdDoKCQlyZXR1cm4gZ2V0X2hhbmRsZShoa2V5KTsKCX0KCS8qTk9UUkVBQ0hFRCovCn0KI3VuZGVmIEFERF9ST09UX0tFWQovKiBzbyB3ZSBkb24ndCBhY2NpZGVudGx5IGFjY2VzcyB0aGVtIC4uLiAqLwojZGVmaW5lIGtleV9jdXJyZW50X2NvbmZpZyBOVUxMIE5VTEwKI2RlZmluZSBrZXlfY3VycmVudF91c2VyIE5VTEwgTlVMTAojZGVmaW5lIGtleV91c2VycyBOVUxMIE5VTEwKI2RlZmluZSBrZXlfbG9jYWxfbWFjaGluZSBOVUxMIE5VTEwKI2RlZmluZSBrZXlfY2xhc3Nlc19yb290IE5VTEwgTlVMTAojZGVmaW5lIGtleV9keW5fZGF0YSBOVUxMIE5VTEwKI2RlZmluZSBrZXlfcGVyZm9ybWFuY2VfZGF0YSBOVUxMIE5VTEwKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogc3BsaXRfa2V5cGF0aCBbSW50ZXJuYWxdCiAqIHNwbGl0cyB0aGUgdW5pY29kZSBzdHJpbmcgJ3dwJyBpbnRvIGFuIGFycmF5IG9mIHN0cmluZ3MuCiAqIHRoZSBhcnJheSBpcyBhbGxvY2F0ZWQgYnkgdGhpcyBmdW5jdGlvbi4gCiAqIEZyZWUgdGhlIGFycmF5IHVzaW5nIEZSRUVfS0VZX1BBVEgKICoKICogUEFSQU1TCiAqICAgIHdwICBbSV0gU3RyaW5nIHRvIHNwbGl0IHVwCiAqICAgIHdwdiBbT10gQXJyYXkgb2YgcG9pbnRlcnMgdG8gc3RyaW5ncwogKiAgICB3cGMgW09dIE51bWJlciBvZiBjb21wb25lbnRzCiAqLwpzdGF0aWMgdm9pZCBzcGxpdF9rZXlwYXRoKCBMUENXU1RSIHdwLCBMUFdTVFIgKip3cHYsIGludCAqd3BjKQp7CiAgICBpbnQJaSxqLGxlbjsKICAgIExQV1NUUiB3czsKCiAgICBUUkFDRShyZWcsIiglcywlcCwlcClcbiIsZGVidWdzdHJfdyh3cCksd3B2LHdwYyk7CgogICAgd3MJPSBIRUFQX3N0cmR1cFcoIFN5c3RlbUhlYXAsIDAsIHdwICk7CgogICAgLyogV2Uga25vdyB3ZSBoYXZlIGF0IGxlYXN0IG9uZSBzdWJzdHJpbmcgKi8KICAgICp3cGMgPSAxOwoKICAgIC8qIFJlcGxhY2UgZWFjaCBiYWNrc2xhc2ggd2l0aCBOVUxMLCBhbmQgaW5jcmVtZW50IHRoZSBjb3VudCAqLwogICAgZm9yIChpPTA7d3NbaV07aSsrKSB7CiAgICAgICAgaWYgKHdzW2ldPT0nXFwnKSB7CiAgICAgICAgICAgIHdzW2ldPTA7CiAgICAgICAgICAgICgqd3BjKSsrOwogICAgICAgIH0KICAgIH0KCiAgICBsZW4gPSBpOwoKICAgIC8qIEFsbG9jYXRlIHRoZSBzcGFjZSBmb3IgdGhlIGFycmF5IG9mIHBvaW50ZXJzLCBsZWF2aW5nIHJvb20gZm9yIHRoZQogICAgICAgTlVMTCBhdCB0aGUgZW5kICovCiAgICAqd3B2ID0gKExQV1NUUiopSGVhcEFsbG9jKCBTeXN0ZW1IZWFwLCAwLCBzaXplb2YoTFBXU1RSKSooKndwYysyKSk7CiAgICAoKndwdilbMF09IHdzOwoKICAgIC8qIEFzc2lnbiBlYWNoIHBvaW50ZXIgdG8gdGhlIGFwcHJvcHJpYXRlIGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nICovCiAgICBqID0gMTsKICAgIGZvciAoaT0xO2k8bGVuO2krKykKICAgICAgICBpZiAod3NbaS0xXT09MCkgewogICAgICAgICAgICAoKndwdilbaisrXT13cytpOwogICAgICAgICAgICAvKiBUUkFDRShyZWcsICIgU3ViaXRlbSAlZCA9ICVzXG4iLGotMSxkZWJ1Z3N0cl93KCgqd3B2KVtqLTFdKSk7ICovCiAgICAgICAgfQoKICAgICgqd3B2KVtqXT1OVUxMOwp9CiNkZWZpbmUgRlJFRV9LRVlfUEFUSCBIZWFwRnJlZShTeXN0ZW1IZWFwLDAsd3BzWzBdKTtIZWFwRnJlZShTeXN0ZW1IZWFwLDAsd3BzKTsKCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUkVHSVNUUllfSW5pdCBbSW50ZXJuYWxdCiAqIFJlZ2lzdHJ5IGluaXRpYWxpc2F0aW9uLCBhbGxvY2F0ZXMgc29tZSBkZWZhdWx0IGtleXMuIAogKi8Kc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCh2b2lkKSB7CglIS0VZCWhrZXk7CgljaGFyCWJ1ZlsyMDBdOwoKCVRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCglSZWdDcmVhdGVLZXkxNihIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIkhBUkRXQVJFXFxERVNDUklQVElPTlxcU3lzdGVtIiwmaGtleSk7CglSZWdTZXRWYWx1ZUV4MzJBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3cgTlRcXEN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRCdWlsZE51bWJlcgoJICoJCQkJCQlDdXJyZW50VHlwZQoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3duZXIKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE9yZ2FuaXphdGlvbgoJICoKCSAqLwoJLyogU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXFNOTVBcXFBhcmFtZXRlcnNcXFJGQzExNTZBZ2VudAoJICogCQkJCQlzdHJpbmcJU3lzQ29udGFjdAoJICogCQkJCQlzdHJpbmcJU3lzTG9jYXRpb24KCSAqIAkJCQkJCVN5c1NlcnZpY2VzCgkgKi8JCQkJCQkKCWlmICgtMSE9Z2V0aG9zdG5hbWUoYnVmLDIwMCkpIHsKCQlSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXENvbnRyb2xcXENvbXB1dGVyTmFtZVxcQ29tcHV0ZXJOYW1lIiwmaGtleSk7CgkJUmVnU2V0VmFsdWVFeDE2KGhrZXksIkNvbXB1dGVyTmFtZSIsMCxSRUdfU1osYnVmLHN0cmxlbihidWYpKzEpOwoJCVJlZ0Nsb3NlS2V5KGhrZXkpOwoJfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKiBTQVZFIFJlZ2lzdHJ5IEZ1bmN0aW9uICoqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIFJFR0lTVFJZX1NBVkVfVkVSU0lPTgkweDAwMDAwMDAxCgovKiBSZWdpc3RyeSBzYXZlZm9ybWF0OgogKiBJZiB5b3UgY2hhbmdlIGl0LCBpbmNyZWFzZSBhYm92ZSBudW1iZXIgYnkgMSwgd2hpY2ggd2lsbCBmbHVzaAogKiBvbGQgcmVnaXN0cnkgZGF0YWJhc2UgZmlsZXMuCiAqIAogKiBHbG9iYWw6CiAqIAkiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIgogKiAJc3Via2V5cy4uLi4KICogU3Via2V5czoKICogCWtleW5hbWUKICoJCXZhbHVlbmFtZT1sYXN0bW9kaWZpZWQsdHlwZSxkYXRhCiAqCQkuLi4KICoJCXN1YmtleXMKICoJLi4uCiAqIGtleW5hbWUsdmFsdWVuYW1lLHN0cmluZ2RhdGE6CiAqCXRoZSB1c3VhbCBhc2NpaSBjaGFyYWN0ZXJzIGZyb20gMHgwMC0weGZmICh3ZWxsLCBub3QgMHgwMCkKICoJYW5kIFx1WFhYWCBhcyBVTklDT0RFIHZhbHVlIFhYWFggd2l0aCBYWFhYPjB4ZmYKICoJKCAiPVxcXHQiIGVzY2FwZWQgaW4gXHVYWFhYIGZvcm0uKQogKiB0eXBlLGxhc3Rtb2RpZmllZDogCiAqCWludAogKiAKICogRklYTUU6IGRvZXNuJ3Qgc2F2ZSAnY2xhc3MnICh3aGF0IGRvZXMgaXQgbWVhbiBhbnl3YXk/KSwgbm9yIGZsYWdzLgogKgogKiBbSEtFWV9DVVJSRU5UX1VTRVJcXFNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeV0KICogU2F2ZU9ubHlVcGRhdGVkS2V5cz15ZXMKICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlX2NoZWNrX3RhaW50ZWQgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfc2F2ZV9jaGVja190YWludGVkKCBMUEtFWVNUUlVDVCBscGtleSApCnsKCWludAkJdGFpbnRlZDsKCglpZiAoIWxwa2V5KQoJCXJldHVybiAwOwoJaWYgKGxwa2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkKCQl0YWludGVkID0gMTsKCWVsc2UKCQl0YWludGVkID0gMDsKCXdoaWxlIChscGtleSkgewoJCWlmIChfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKSkgewoJCQlscGtleS0+ZmxhZ3MgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoJCQl0YWludGVkID0gMTsKCQl9CgkJbHBrZXkJPSBscGtleS0+bmV4dDsKCX0KCXJldHVybiB0YWludGVkOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlX1VTVFJJTkcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3NhdmVfVVNUUklORyggRklMRSAqRiwgTFBXU1RSIHdzdHIsIGludCBlc2NhcGVlcSApCnsKCUxQV1NUUglzOwoJaW50CWRvZXNjYXBlOwoKCWlmICh3c3RyPT1OVUxMKQoJCXJldHVybjsKCXM9d3N0cjsKCXdoaWxlICgqcykgewoJCWRvZXNjYXBlPTA7CgkJaWYgKCpzPjB4ZmYpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoKnM9PSdcbicpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoZXNjYXBlZXEgJiYgKnM9PSc9JykKCQkJZG9lc2NhcGUgPSAxOwoJCWlmICgqcz09J1xcJykKICAgICAgICAgICAgICAgICAgICAgICAgZnB1dGMoKnMsRik7IC8qIGlmIFxcIHRoZW4gcHV0IGl0IHR3aWNlLiAqLwoJCWlmIChkb2VzY2FwZSkKCQkJZnByaW50ZihGLCJcXHUlMDR4IiwqKCh1bnNpZ25lZCBzaG9ydCopcykpOwoJCWVsc2UKCQkJZnB1dGMoKnMsRik7CgkJcysrOwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlc3Via2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3NhdmVzdWJrZXkoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgbGV2ZWwsIGludCBhbGwgKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWksdGFicyxqOwoKCWxweGtleQk9IGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJIShscHhrZXktPmZsYWdzICYgUkVHX09QVElPTl9WT0xBVElMRSkgJiYKCQkJKGFsbCB8fCAobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkpCgkJKSB7CgkJCWZvciAodGFicz1sZXZlbDt0YWJzLS07KQoJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJX3NhdmVfVVNUUklORyhGLGxweGtleS0+a2V5bmFtZSwxKTsKCQkJZnB1dHMoIlxuIixGKTsKCQkJZm9yIChpPTA7aTxscHhrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJCQlMUEtFWVZBTFVFCXZhbD1scHhrZXktPnZhbHVlcytpOwoKCQkJCWZvciAodGFicz1sZXZlbCsxO3RhYnMtLTspCgkJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJCV9zYXZlX1VTVFJJTkcoRix2YWwtPm5hbWUsMCk7CgkJCQlmcHV0YygnPScsRik7CgkJCQlmcHJpbnRmKEYsIiVsZCwlbGQsIix2YWwtPnR5cGUsdmFsLT5sYXN0bW9kaWZpZWQpOwoJCQkJaWYgKCgxPDx2YWwtPnR5cGUpICYgVU5JQ09OVk1BU0spCgkJCQkJX3NhdmVfVVNUUklORyhGLChMUFdTVFIpdmFsLT5kYXRhLDApOwoJCQkJZWxzZQoJCQkJCWZvciAoaj0wO2o8dmFsLT5sZW47aisrKQoJCQkJCQlmcHJpbnRmKEYsIiUwMngiLCooKHVuc2lnbmVkIGNoYXIqKXZhbC0+ZGF0YStqKSk7CgkJCQlmcHV0cygiXG4iLEYpOwoJCQl9CgkJCS8qIGRlc2NlbmQgcmVjdXJzaXZlbHkgKi8KCQkJaWYgKCFfc2F2ZXN1YmtleShGLGxweGtleS0+bmV4dHN1YixsZXZlbCsxLGFsbCkpCgkJCQlyZXR1cm4gMDsKCQl9CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXN1YnJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF9zYXZlc3VicmVnKCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGFsbCApCnsKCWZwcmludGYoRiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkXG4iLFJFR0lTVFJZX1NBVkVfVkVSU0lPTik7Cglfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKTsKCXJldHVybiBfc2F2ZXN1YmtleShGLGxwa2V5LT5uZXh0c3ViLDAsYWxsKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIEJPT0wzMiBfc2F2ZXJlZyggTFBLRVlTVFJVQ1QgbHBrZXksIGNoYXIgKmZuLCBpbnQgYWxsICkKewoJRklMRQkqRjsKCglGPWZvcGVuKGZuLCJ3Iik7CglpZiAoRj09TlVMTCkgewoJCVdBUk4ocmVnLCJDb3VsZG4ndCBvcGVuICVzIGZvciB3cml0aW5nOiAlc1xuIiwKCQkJZm4sc3RyZXJyb3IoZXJybm8pCgkJKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglpZiAoIV9zYXZlc3VicmVnKEYsbHBrZXksYWxsKSkgewoJCWZjbG9zZShGKTsKCQl1bmxpbmsoZm4pOwoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gc2F2ZSBrZXlzLCBwZXJoYXBzIG5vIG1vcmUgZGlza3NwYWNlIGZvciAlcz9cbiIsZm4pOwoJCXJldHVybiBGQUxTRTsKCX0KCWZjbG9zZShGKTsKICAgICAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfU2F2ZVJlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnZvaWQgU0hFTExfU2F2ZVJlZ2lzdHJ5KCB2b2lkICkKewoJY2hhcgkqZm47CglzdHJ1Y3QJcGFzc3dkCSpwd2Q7CgljaGFyCWJ1Zls0XTsKCUhLRVkJaGtleTsKCWludAlhbGw7CgogICAgVFJBQ0UocmVnLCIodm9pZClcbiIpOwoKCWFsbD0wOwoJaWYgKFJlZ09wZW5LZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJc3RyY3B5KGJ1ZiwieWVzIik7Cgl9IGVsc2UgewoJCURXT1JEIGxlbixqdW5rLHR5cGU7CgoJCWxlbj00OwoJCWlmICgJKEVSUk9SX1NVQ0NFU1MhPVJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQkJCWhrZXksCgkJCQlWQUxfU0FWRVVQREFURUQsCgkJCQkmanVuaywKCQkJCSZ0eXBlLAoJCQkJYnVmLAoJCQkJJmxlbgoJCQkpKXx8ICh0eXBlIT1SRUdfU1opCgkJKQoJCQlzdHJjcHkoYnVmLCJ5ZXMiKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KCWlmIChsc3RyY21waTMyQShidWYsInllcyIpKQoJCWFsbD0xOwoJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCWlmIChwd2QhPU5VTEwgJiYgcHdkLT5wd19kaXIhPU5VTEwpCiAgICAgICAgewogICAgICAgICAgICAgICAgY2hhciAqdG1wOwoKCQlmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKHB3ZC0+cHdfZGlyKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikgKyAyICk7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgpOwoJCS8qIGNyZWF0ZSB0aGUgZGlyZWN0b3J5LiBkb24ndCBjYXJlIGFib3V0IGVycm9yY29kZXMuICovCgkJbWtkaXIoZm4sMDc1NSk7IC8qIGRyd3hyLXhyLXggKi8KCQlzdHJjYXQoZm4sIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwoJCXRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CgkJc3RyY3B5KHRtcCxmbik7c3RyY2F0KHRtcCwiLnRtcCIpOwoJCWlmIChfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUiksdG1wLGFsbCkpIHsKCQkJaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewoJCQkJcGVycm9yKCJyZW5hbWUgdG1wIHJlZ2lzdHJ5Iik7CgkJCQl1bmxpbmsodG1wKTsKCQkJfQoJCX0KCQlmcmVlKHRtcCk7CgkJZnJlZShmbik7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9NQUNISU5FKTsKCQl0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwoJCXN0cmNweSh0bXAsZm4pO3N0cmNhdCh0bXAsIi50bXAiKTsKCQlpZiAoX3NhdmVyZWcobG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSx0bXAsYWxsKSkgewoJCQlpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CgkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKCQkJCXVubGluayh0bXApOwoJCQl9CgkJfQoJCWZyZWUodG1wKTsKCQlmcmVlKGZuKTsKCX0gZWxzZQoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVkLlxuIixnZXR1aWQoKSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqIExPQUQgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmluZF9vcl9hZGRfa2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBMUEtFWVNUUlVDVCBfZmluZF9vcl9hZGRfa2V5KCBMUEtFWVNUUlVDVCBscGtleSwgTFBXU1RSIGtleW5hbWUgKQp7CglMUEtFWVNUUlVDVAlscHhrZXksKmxwbHBrZXk7CgoJaWYgKCgha2V5bmFtZSkgfHwgKGtleW5hbWVbMF09PTApKSB7CgkJZnJlZShrZXluYW1lKTsKCQlyZXR1cm4gbHBrZXk7Cgl9CglscGxwa2V5PSAmKGxwa2V5LT5uZXh0c3ViKTsKCWxweGtleQk9ICpscGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJKGxweGtleS0+a2V5bmFtZVswXT09a2V5bmFtZVswXSkgJiYgCgkJCSFsc3RyY21waTMyVyhscHhrZXktPmtleW5hbWUsa2V5bmFtZSkKCQkpCgkJCWJyZWFrOwoJCWxwbHBrZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7Cgl9CglpZiAobHB4a2V5PT1OVUxMKSB7CgkJKmxwbHBrZXkgPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7CgkJbWVtc2V0KGxweGtleSwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTsKCQlscHhrZXktPmtleW5hbWUJPSBrZXluYW1lOwoJfSBlbHNlCgkJZnJlZShrZXluYW1lKTsKCXJldHVybiBscHhrZXk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2ZpbmRfb3JfYWRkX3ZhbHVlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9maW5kX29yX2FkZF92YWx1ZSggTFBLRVlTVFJVQ1QgbHBrZXksIExQV1NUUiBuYW1lLCBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBkYXRhLCBEV09SRCBsZW4sIERXT1JEIGxhc3Rtb2RpZmllZCApCnsKCUxQS0VZVkFMVUUJdmFsPU5VTEw7CglpbnQJCWk7CgoJaWYgKG5hbWUgJiYgISpuYW1lKSB7LyogZW1wdHkgc3RyaW5nIGVxdWFscyBkZWZhdWx0IChOVUxMKSB2YWx1ZSAqLwoJCWZyZWUobmFtZSk7CgkJbmFtZSA9IE5VTEw7Cgl9CgoJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCWlmIChuYW1lPT1OVUxMKSB7CgkJCWlmICh2YWwtPm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCQl9IGVsc2UgewoJCQlpZiAoCXZhbC0+bmFtZSE9TlVMTCAmJiAKCQkJCXZhbC0+bmFtZVswXT09bmFtZVswXSAmJgoJCQkJIWxzdHJjbXBpMzJXKHZhbC0+bmFtZSxuYW1lKQoJCQkpCgkJCQlicmVhazsKCQl9Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0geHJlYWxsb2MoCgkJCWxwa2V5LT52YWx1ZXMsCgkJCSgrK2xwa2V5LT5ucm9mdmFsdWVzKSpzaXplb2YoS0VZVkFMVUUpCgkJKTsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCW1lbXNldCh2YWwsJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCQl2YWwtPm5hbWUgPSBuYW1lOwoJfSBlbHNlIHsKCQlpZiAobmFtZSkKCQkJZnJlZShuYW1lKTsKCX0KCWlmICh2YWwtPmxhc3Rtb2RpZmllZDxsYXN0bW9kaWZpZWQpIHsKCQl2YWwtPmxhc3Rtb2RpZmllZD1sYXN0bW9kaWZpZWQ7CgkJdmFsLT50eXBlID0gdHlwZTsKCQl2YWwtPmxlbiAgPSBsZW47CgkJaWYgKHZhbC0+ZGF0YSkgCgkJCWZyZWUodmFsLT5kYXRhKTsKCQl2YWwtPmRhdGEgPSBkYXRhOwoJfSBlbHNlCgkJZnJlZShkYXRhKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9saW5lIFtJbnRlcm5hbF0KICoKICogcmVhZHMgYSBsaW5lIGluY2x1ZGluZyBkeW5hbWljYWxseSBlbmxhcmdpbmcgdGhlIHJlYWRidWZmZXIgYW5kIHRocm93aW5nCiAqIGF3YXkgY29tbWVudHMKICovCnN0YXRpYyBpbnQgX3dpbmVfcmVhZF9saW5lKCBGSUxFICpGLCBjaGFyICoqYnVmLCBpbnQgKmxlbiApCnsKCWNoYXIJKnMsKmN1cnJlYWQ7CglpbnQJbXlsZW4sY3Vyb2ZmOwoKCWN1cnJlYWQJPSAqYnVmOwoJbXlsZW4JPSAqbGVuOwoJKipidWYJPSAnXDAnOwoJd2hpbGUgKDEpIHsKCQl3aGlsZSAoMSkgewoJCQlzPWZnZXRzKGN1cnJlYWQsbXlsZW4sRik7CgkJCWlmIChzPT1OVUxMKQoJCQkJcmV0dXJuIDA7IC8qIEVPRiAqLwoJCQlpZiAoTlVMTD09KHM9c3RyY2hyKGN1cnJlYWQsJ1xuJykpKSB7CgkJCQkvKiBidWZmZXIgd2Fzbid0IGxhcmdlIGVub3VnaCAqLwoJCQkJY3Vyb2ZmCT0gc3RybGVuKCpidWYpOwoJCQkJKmJ1Zgk9IHhyZWFsbG9jKCpidWYsKmxlbioyKTsKCQkJCWN1cnJlYWQJPSAqYnVmICsgY3Vyb2ZmOwoJCQkJbXlsZW4JPSAqbGVuOwkvKiB3ZSBmaWxsZWQgdXAgdGhlIGJ1ZmZlciBhbmQgCgkJCQkJCSAqIGdvdCBuZXcgJypsZW4nIGJ5dGVzIHRvIGZpbGwKCQkJCQkJICovCgkJCQkqbGVuCT0gKmxlbiAqIDI7CgkJCX0gZWxzZSB7CgkJCQkqcz0nXDAnOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLyogdGhyb3cgYXdheSBjb21tZW50cyAqLwoJCWlmICgqKmJ1Zj09JyMnIHx8ICoqYnVmPT0nOycpIHsKCQkJY3VycmVhZAk9ICpidWY7CgkJCW15bGVuCT0gKmxlbjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzKSAJLyogZ290IGVuZCBvZiBsaW5lICovCgkJCWJyZWFrOwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfVVNUUklORyBbSW50ZXJuYWxdCiAqCiAqIGNvbnZlcnRzIGEgY2hhciogaW50byBhIFVOSUNPREUgc3RyaW5nICh1cCB0byBhIHNwZWNpYWwgY2hhcikKICogYW5kIHJldHVybnMgdGhlIHBvc2l0aW9uIGV4YWN0bHkgYWZ0ZXIgdGhhdCBzdHJpbmcKICovCnN0YXRpYyBjaGFyKiBfd2luZV9yZWFkX1VTVFJJTkcoIGNoYXIgKmJ1ZiwgTFBXU1RSICpzdHIgKQp7CgljaGFyCSpzOwoJTFBXU1RSCXdzOwoKCS8qIHJlYWQgdXAgdG8gIj0iIG9yICJcMCIgb3IgIlxuIiAqLwoJcwk9IGJ1ZjsKCWlmICgqcyA9PSAnPScpIHsKCQkvKiBlbXB0eSBzdHJpbmcgaXMgdGhlIHdpbjMuMSBkZWZhdWx0IHZhbHVlKE5VTEwpKi8KCQkqc3RyCT0gTlVMTDsKCQlyZXR1cm4gczsKCX0KCSpzdHIJPSAoTFBXU1RSKXhtYWxsb2MoMipzdHJsZW4oYnVmKSsyKTsKCXdzCT0gKnN0cjsKCXdoaWxlICgqcyAmJiAoKnMhPSdcbicpICYmICgqcyE9Jz0nKSkgewoJCWlmICgqcyE9J1xcJykKCQkJKndzKys9KigodW5zaWduZWQgY2hhciopcysrKTsKCQllbHNlIHsKCQkJcysrOwoJCQlpZiAoISpzKSB7CgkJCQkvKiBEYW5nbGluZyBcIC4uLiBtYXkgb25seSBoYXBwZW4gaWYgYSByZWdpc3RyeQoJCQkJICogd3JpdGUgd2FzIHNob3J0LiBGSVhNRTogV2hhdCBkbyB0bz8KCQkJCSAqLwoJCQkJIGJyZWFrOwoJCQl9CgkJCWlmICgqcz09J1xcJykgewoJCQkJKndzKys9J1xcJzsKCQkJCXMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWlmICgqcyE9J3UnKSB7CgkJCQlXQVJOKHJlZywiTm9uIHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlIFxcJWMgZm91bmQgaW4gfCVzfFxuIiwqcyxidWYpOwoJCQkJKndzKys9J1xcJzsKCQkJCSp3cysrPSpzKys7CgkJCX0gZWxzZSB7CgkJCQljaGFyCXhidWZbNV07CgkJCQlpbnQJd2M7CgoJCQkJcysrOwoJCQkJbWVtY3B5KHhidWYscyw0KTt4YnVmWzRdPSdcMCc7CgkJCQlpZiAoIXNzY2FuZih4YnVmLCIleCIsJndjKSkKCQkJCQlXQVJOKHJlZywiU3RyYW5nZSBlc2NhcGUgc2VxdWVuY2UgJXMgZm91bmQgaW4gfCVzfFxuIix4YnVmLGJ1Zik7CgkJCQlzKz00OwoJCQkJKndzKysJPSh1bnNpZ25lZCBzaG9ydCl3YzsKCQkJfQoJCX0KCX0KCSp3cwk9IDA7Cgl3cwk9ICpzdHI7CglpZiAoKndzKQoJCSpzdHIJPSBzdHJkdXBXKCpzdHIpOwoJZWxzZQoJCSpzdHIJPSBOVUxMOwoJZnJlZSh3cyk7CglyZXR1cm4gczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHN1YmtleSBbSW50ZXJuYWxdCiAqCiAqIE5PVEVTCiAqICAgIEl0IHNlZW1zIGxpa2UgdGhpcyBpcyByZXR1cm5pbmcgYSBib29sZWFuLiAgU2hvdWxkIGl0PwogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IDEKICogICAgRmFpbHVyZTogMAogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3Via2V5KCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGxldmVsLCBjaGFyICoqYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqYnVmbGVuLCBEV09SRCBvcHRmbGFnICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlpOwoJY2hhcgkJKnM7CglMUFdTVFIJCW5hbWU7CgogICAgVFJBQ0UocmVnLCIoJXAsJXAsJWQsJXMsJWQsJWx4KVxuIiwgRiwgbHBrZXksIGxldmVsLCBkZWJ1Z3N0cl9hKCpidWYpLAogICAgICAgICAgKmJ1Zmxlbiwgb3B0ZmxhZyk7CgogICAgbHBrZXktPmZsYWdzIHw9IG9wdGZsYWc7CgogICAgLyogR29vZC4gIFdlIGFscmVhZHkgZ290IGEgbGluZSBoZXJlIC4uLiBzbyBwYXJzZSBpdCAqLwogICAgbHB4a2V5ID0gTlVMTDsKICAgIHdoaWxlICgxKSB7CiAgICAgICAgaT0wO3M9KmJ1ZjsKICAgICAgICB3aGlsZSAoKnM9PSdcdCcpIHsKICAgICAgICAgICAgcysrOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQogICAgICAgIGlmIChpPmxldmVsKSB7CiAgICAgICAgICAgIGlmIChscHhrZXk9PU5VTEwpIHsKICAgICAgICAgICAgICAgIFdBUk4ocmVnLCJHb3QgYSBzdWJoaWVyYXJjaHkgd2l0aG91dCByZXNwLiBrZXk/XG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF93aW5lX2xvYWRzdWJrZXkoRixscHhrZXksbGV2ZWwrMSxidWYsYnVmbGVuLG9wdGZsYWcpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoJCS8qIGxldCB0aGUgY2FsbGVyIGhhbmRsZSB0aGlzIGxpbmUgKi8KCQlpZiAoaTxsZXZlbCB8fCAqKmJ1Zj09J1wwJykKCQkJcmV0dXJuIDE7CgoJCS8qIGl0IGNhbiBiZTogYSB2YWx1ZSBvciBhIGtleW5hbWUuIFBhcnNlIHRoZSBuYW1lIGZpcnN0ICovCgkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywmbmFtZSk7CgoJCS8qIHN3aXRjaCgpIGRlZmF1bHQ6IGhhY2sgdG8gYXZvaWQgZ290b3MgKi8KCQlzd2l0Y2ggKDApIHsKCQlkZWZhdWx0OgoJCQlpZiAoKnM9PSdcMCcpIHsKCQkJCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoJCQl9IGVsc2UgewoJCQkJTFBCWVRFCQlkYXRhOwoJCQkJaW50CQlsZW4sbGFzdG1vZGlmaWVkLHR5cGU7CgoJCQkJaWYgKCpzIT0nPScpIHsKCQkJCQlXQVJOKHJlZywiVW5leHBlY3RlZCBjaGFyYWN0ZXI6ICVjXG4iLCpzKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCXMrKzsKCQkJCWlmICgyIT1zc2NhbmYocywiJWQsJWQsIiwmdHlwZSwmbGFzdG1vZGlmaWVkKSkgewoJCQkJCVdBUk4ocmVnLCJIYXZlbid0IHVuZGVyc3Rvb2QgcG9zc2libGUgdmFsdWUgaW4gfCVzfCwgc2tpcHBpbmcuXG4iLCpidWYpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJLyogc2tpcCB0aGUgMiAsICovCgkJCQlzPXN0cmNocihzLCcsJyk7cysrOwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCWlmICgoMTw8dHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsKExQV1NUUiopJmRhdGEpOwoJCQkJCWlmIChkYXRhKQoJCQkJCQlsZW4gPSBsc3RybGVuMzJXKChMUFdTVFIpZGF0YSkqMisyOwoJCQkJCWVsc2UJCgkJCQkJCWxlbiA9IDA7CgkJCQl9IGVsc2UgewoJCQkJCWxlbj1zdHJsZW4ocykvMjsKCQkJCQlkYXRhID0gKExQQllURSl4bWFsbG9jKGxlbisxKTsKCQkJCQlmb3IgKGk9MDtpPGxlbjtpKyspIHsKCQkJCQkJZGF0YVtpXT0wOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXT0oKnMtJzAnKTw8NDsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV09KCpzLSdhJysnXHhhJyk8PDQ7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nQScrJ1x4YScpPDw0OwoJCQkJCQlzKys7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldfD0qcy0nMCc7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nYScrJ1x4YSc7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nQScrJ1x4YSc7CgkJCQkJCXMrKzsKCQkJCQl9CgkJCQl9CgkJCQlfZmluZF9vcl9hZGRfdmFsdWUobHBrZXksbmFtZSx0eXBlLGRhdGEsbGVuLGxhc3Rtb2RpZmllZCk7CgkJCX0KCQl9CgkJLyogcmVhZCB0aGUgbmV4dCBsaW5lICovCgkJaWYgKCFfd2luZV9yZWFkX2xpbmUoRixidWYsYnVmbGVuKSkKCQkJcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHN1YnJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93aW5lX2xvYWRzdWJyZWcoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBEV09SRCBvcHRmbGFnICkKewoJaW50CXZlcjsKCWNoYXIJKmJ1ZjsKCWludAlidWZsZW47CgoJYnVmPXhtYWxsb2MoMTApO2J1Zmxlbj0xMDsKCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghc3NjYW5mKGJ1ZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIiwmdmVyKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICh2ZXIhPVJFR0lTVFJZX1NBVkVfVkVSU0lPTikgewoJCVRSQUNFKHJlZywiT2xkIGZvcm1hdCAoJWQpIHJlZ2lzdHJ5IGZvdW5kLCBpZ25vcmluZyBpdC4gKGJ1ZiB3YXMgJXMpLlxuIix2ZXIsYnVmKTsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIV93aW5lX2xvYWRzdWJrZXkoRixscGtleSwwLCZidWYsJmJ1ZmxlbixvcHRmbGFnKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWZyZWUoYnVmKTsKCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93aW5lX2xvYWRyZWcoIExQS0VZU1RSVUNUIGxwa2V5LCBjaGFyICpmbiwgRFdPUkQgb3B0ZmxhZyApCnsKICAgIEZJTEUgKkY7CgogICAgVFJBQ0UocmVnLCIoJXAsJXMsJWx4KVxuIixscGtleSxkZWJ1Z3N0cl9hKGZuKSxvcHRmbGFnKTsKCiAgICBGID0gZm9wZW4oZm4sInJiIik7CiAgICBpZiAoRj09TlVMTCkgewogICAgICAgIFdBUk4ocmVnLCJDb3VsZG4ndCBvcGVuICVzIGZvciByZWFkaW5nOiAlc1xuIixmbixzdHJlcnJvcihlcnJubykgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoIV93aW5lX2xvYWRzdWJyZWcoRixscGtleSxvcHRmbGFnKSkgewogICAgICAgIGZjbG9zZShGKTsKICAgICAgICB1bmxpbmsoZm4pOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGZjbG9zZShGKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2NvcHlfcmVnaXN0cnkgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX2NvcHlfcmVnaXN0cnkoIExQS0VZU1RSVUNUIGZyb20sIExQS0VZU1RSVUNUIHRvICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlqOwoJTFBLRVlWQUxVRQl2YWxmcm9tOwoKCWZyb209ZnJvbS0+bmV4dHN1YjsKCXdoaWxlIChmcm9tKSB7CgkJbHB4a2V5ID0gX2ZpbmRfb3JfYWRkX2tleSh0byxzdHJkdXBXKGZyb20tPmtleW5hbWUpKTsKCgkJZm9yIChqPTA7ajxmcm9tLT5ucm9mdmFsdWVzO2orKykgewoJCQlMUFdTVFIJbmFtZTsKCQkJTFBCWVRFCWRhdGE7CgoJCQl2YWxmcm9tID0gZnJvbS0+dmFsdWVzK2o7CgkJCW5hbWU9dmFsZnJvbS0+bmFtZTsKCQkJaWYgKG5hbWUpIG5hbWU9c3RyZHVwVyhuYW1lKTsKCQkJZGF0YT0oTFBCWVRFKXhtYWxsb2ModmFsZnJvbS0+bGVuKTsKCQkJbWVtY3B5KGRhdGEsdmFsZnJvbS0+ZGF0YSx2YWxmcm9tLT5sZW4pOwoKCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJCQkJbHB4a2V5LAoJCQkJbmFtZSwKCQkJCXZhbGZyb20tPnR5cGUsCgkJCQlkYXRhLAoJCQkJdmFsZnJvbS0+bGVuLAoJCQkJdmFsZnJvbS0+bGFzdG1vZGlmaWVkCgkJCSk7CgkJfQoJCV9jb3B5X3JlZ2lzdHJ5KGZyb20sbHB4a2V5KTsKCQlmcm9tID0gZnJvbS0+bmV4dDsKCX0KfQoKCi8qIFdJTkRPV1MgOTUgUkVHSVNUUlkgTE9BREVSICovCi8qIAogKiBTdHJ1Y3R1cmUgb2YgYSB3aW45NSByZWdpc3RyeSBkYXRhYmFzZS4KICogbWFpbiBoZWFkZXI6CiAqIDAgOgkiQ1JFRyIJLSBtYWdpYwogKiA0IDoJRFdPUkQgdmVyc2lvbgogKiA4IDoJRFdPUkQgb2Zmc2V0X29mX1JHREJfcGFydAogKiAwQy4uMEY6CT8gKHNvbWVvbmUgZmlsbCBpbiBwbGVhc2UpCiAqIDEwOiAgV09SRAludW1iZXIgb2YgUkdEQiBibG9ja3MKICogMTI6ICBXT1JECT8KICogMTQ6ICBXT1JECWFsd2F5cyAwMDAwPwogKiAxNjogIFdPUkQJYWx3YXlzIDAwMDE/CiAqIDE4Li4xRjoJPyAoc29tZW9uZSBmaWxsIGluIHBsZWFzZSkKICoKICogMjA6IFJHS05fc2VjdGlvbjoKICogICBoZWFkZXI6CiAqIAkwIDoJCSJSR0tOIgktIG1hZ2ljCiAqICAgICAgNCA6IERXT1JECW9mZnNldCB0byBmaXJzdCBSR0RCIHNlY3Rpb24KICogICAgICA4IDogRFdPUkQJb2Zmc2V0IHRvIHRoZSByb290IHJlY29yZAogKiAJQy4uMHgxQjogCT8gKGZpbGwgaW4pCiAqICAgICAgMHgyMCAuLi4gb2Zmc2V0X29mX1JHREJfcGFydDogRGlzayBLZXkgRW50cnkgc3RydWN0dXJlcwogKgogKiAgIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZToKICoJMDA6IERXT1JECS0gRnJlZSBlbnRyeSBpbmRpY2F0b3IoPykKICoJMDQ6IERXT1JECS0gSGFzaCA9IHN1bSBvZiBieXRlcyBvZiBrZXluYW1lCiAqCTA4OiBEV09SRAktIFJvb3Qga2V5IGluZGljYXRvcj8gdW5rbm93biwgYnV0IHVzdWFsbHkgMHhGRkZGRkZGRiBvbiB3aW45NSBzeXN0ZW1zCiAqCTBDOiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBQcmV2aW91c0xldmVsIEtleS4KICoJMTA6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIE5leHQgU3VibGV2ZWwgS2V5LgogKgkxNDogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgTmV4dCBLZXkgKG9uIHNhbWUgbGV2ZWwpLgogKiBES0VQPjE4OiBXT1JECS0gTnIsIExvdyBTaWduaWZpY2FudCBwYXJ0LgogKgkxQTogV09SRAktIE5yLCBIaWdoIFNpZ25pZmljYW50IHBhcnQuCiAqCiAqIFRoZSBkaXNrIGFkZHJlc3MgYWx3YXlzIHBvaW50cyB0byB0aGUgbnIgcGFydCBvZiB0aGUgcHJldmlvdXMga2V5IGVudHJ5IAogKiBvZiB0aGUgcmVmZXJlbmNlZCBrZXkuIERvbid0IGFzayBtZSB3aHksIG9yIGV2ZW4gaWYgSSBnb3QgdGhpcyBjb3JyZWN0CiAqIGZyb20gc3RhcmluZyBhdCAxa2cgb2YgaGV4ZHVtcHMuIChES0VQKQogKgogKiBUaGUgSGlnaCBzaWduaWZpY2FudCBwYXJ0IG9mIHRoZSBzdHJ1Y3R1cmUgc2VlbXMgdG8gZXF1YWwgdGhlIG51bWJlcgogKiBvZiB0aGUgUkdEQiBzZWN0aW9uLiBUaGUgbG93IHNpZ25pZmljYW50IHBhcnQgaXMgYSB1bmlxdWUgSUQgd2l0aGluCiAqIHRoYXQgUkdEQiBzZWN0aW9uCiAqCiAqIFRoZXJlIGFyZSB0d28gbWlub3IgY29ycmVjdGlvbnMgdG8gdGhlIHBvc2l0aW9uIG9mIHRoYXQgc3RydWN0dXJlLgogKiAxLiBJZiB0aGUgYWRkcmVzcyBpcyB4eHgwMTQgb3IgeHh4MDE4IGl0IHdpbGwgYmUgYWxpZ25lZCB0byB4eHgwMWMgQU5EIAogKiAgICB0aGUgREtFIHJlcmVhZCBmcm9tIHRoZXJlLgogKiAyLiBJZiB0aGUgYWRkcmVzcyBpcyB4eHhGRnggaXQgd2lsbCBiZSBhbGlnbmVkIHRvICh4eHgrMSkwMDAuCiAqIENQUyAtIEkgaGF2ZSBub3QgZXhwZXJpZW5jZWQgdGhlIGFib3ZlIHBoZW5vbWVub24gaW4gbXkgcmVnaXN0cnkgZmlsZXMKICoKICogUkdEQl9zZWN0aW9uOgogKiAJMDA6CQkiUkdEQiIJLSBtYWdpYwogKgkwNDogRFdPUkQJb2Zmc2V0IHRvIG5leHQgUkdEQiBzZWN0aW9uCiAqCTA4OiBEV09SRAk/CiAqCTBDOiBXT1JECWFsd2F5cyAwMDBkPwogKgkwRTogV09SRAlSR0RCIGJsb2NrIG51bWJlcgogKgkxMDoJRFdPUkQJPyAoZXF1YWxzIHZhbHVlIGF0IG9mZnNldCA0IC0gdmFsdWUgYXQgb2Zmc2V0IDgpCiAqCTE0Li4xRjoJCT8KICoJMjAuLi4uLjoJZGlzayBrZXlzCiAqCiAqIGRpc2sga2V5OgogKiAJMDA6IAlEV09SRAluZXh0a2V5b2Zmc2V0CS0gb2Zmc2V0IHRvIHRoZSBuZXh0IGRpc2sga2V5IHN0cnVjdHVyZQogKgkwODogCVdPUkQJbnJMUwkJLSBsb3cgc2lnbmlmaWNhbnQgcGFydCBvZiBOUgogKgkwQTogCVdPUkQJbnJIUwkJLSBoaWdoIHNpZ25pZmljYW50IHBhcnQgb2YgTlIKICoJMEM6IAlEV09SRAlieXRlc3VzZWQJLSBieXRlcyB1c2VkIGluIHRoaXMgc3RydWN0dXJlLgogKgkxMDogCVdPUkQJbmFtZV9sZW4JLSBsZW5ndGggb2YgbmFtZSBpbiBieXRlcy4gd2l0aG91dCBcMAogKgkxMjogCVdPUkQJbnJfb2ZfdmFsdWVzCS0gbnVtYmVyIG9mIHZhbHVlcy4KICoJMTQ6IAljaGFyCW5hbWVbbmFtZV9sZW5dCS0gbmFtZSBzdHJpbmcuIE5vIFwwLgogKgkxNCtuYW1lX2xlbjogZGlzayB2YWx1ZXMKICoJbmV4dGtleW9mZnNldDogLi4uIG5leHQgZGlzayBrZXkKICoKICogZGlzayB2YWx1ZToKICoJMDA6CURXT1JECXR5cGUJCS0gdmFsdWUgdHlwZSAoaG1tLCBjb3VsZCBiZSBXT1JEIHRvbykKICoJMDQ6CURXT1JECQkJLSB1bmtub3duLCB1c3VhbGx5IDAKICoJMDg6CVdPUkQJbmFtZWxlbgkJLSBsZW5ndGggb2YgTmFtZS4gMCBtZWFucyBuYW1lPU5VTEwKICoJMEM6CVdPUkQJZGF0YWxlbgkJLSBsZW5ndGggb2YgRGF0YS4KICoJMTA6CWNoYXIJbmFtZVtuYW1lbGVuXQktIG5hbWUsIG5vIFwwCiAqCTEwK25hbWVsZW46IEJZVEUJZGF0YVtkYXRhbGVuXSAtIGRhdGEsIHdpdGhvdXQgXDAgaWYgc3RyaW5nCiAqCTEwK25hbWVsZW4rZGF0YWxlbjogbmV4dCB2YWx1ZXMgb3IgZGlzayBrZXkKICoKICogRGlzayBrZXlzIGFyZSBsYXllZCBvdXQgZmxhdCAuLi4gQnV0LCBzb21ldGltZXMsIG5yTFMgYW5kIG5ySFMgYXJlIGJvdGgKICogMHhGRkZGLCB3aGljaCBtZWFucyBza2lwcGluZyBvdmVyIG5leHRrZXlvZmZzZXQgYnl0ZXMgKGluY2x1ZGluZyB0aGlzCiAqIHN0cnVjdHVyZSkgYW5kIHJlYWRpbmcgYW5vdGhlciBSR0RCX3NlY3Rpb24uCiAqIHJlcGVhdCB1bnRpbCBlbmQgb2YgZmlsZS4KICoKICogQW4gaW50ZXJlc3RpbmcgcmVsYXRpb25zaGlwIGV4aXN0cyBpbiBSR0RCX3NlY3Rpb24uIFRoZSB2YWx1ZSBhdCBvZmZzZXQKICogMTAgZXF1YWxzIHRoZSB2YWx1ZSBhdCBvZmZzZXQgNCBtaW51cyB0aGUgdmFsdWUgYXQgb2Zmc2V0IDguIEkgaGF2ZSBubwogKiBpZGVhIGF0IHRoZSBtb21lbnQgd2hhdCB0aGlzIG1lYW5zLiAgKEtldmluIENvemVucykKICoKICogRklYTUU6IHRoaXMgZGVzY3JpcHRpb24gbmVlZHMgc29tZSBzZXJpb3VzIGhlbHAsIHllcy4KICovCgpzdHJ1Y3QJX3c5NWtleXZhbHVlIHsKCXVuc2lnbmVkIGxvbmcJCXR5cGU7Cgl1bnNpZ25lZCBzaG9ydAkJZGF0YWxlbjsKCWNoYXIJCQkqbmFtZTsKCXVuc2lnbmVkIGNoYXIJCSpkYXRhOwoJdW5zaWduZWQgbG9uZwkJeDE7CglpbnQJCQlsYXN0bW9kaWZpZWQ7Cn07CgpzdHJ1Y3QgCV93OTVrZXkgewoJY2hhcgkJCSpuYW1lOwoJaW50CQkJbnJvZnZhbHM7CglzdHJ1Y3QJX3c5NWtleXZhbHVlCSp2YWx1ZXM7CglzdHJ1Y3QgX3c5NWtleQkJKnByZXZsdmw7CglzdHJ1Y3QgX3c5NWtleQkJKm5leHRzdWI7CglzdHJ1Y3QgX3c5NWtleQkJKm5leHQ7Cn07CgoKc3RydWN0IF93OTVfaW5mbyB7CiAgY2hhciAqcmdrbmJ1ZmZlcjsKICBpbnQgIHJna25zaXplOwogIGNoYXIgKnJnZGJidWZmZXI7CiAgaW50ICByZ2Ric2l6ZTsKICBpbnQgIGRlcHRoOwogIGludCAgbGFzdG1vZGlmaWVkOwp9OwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9wcm9jZXNzS2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBMUEtFWVNUUlVDVCBfdzk1X3Byb2Nlc3NLZXkgKCBMUEtFWVNUUlVDVCBscGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5yTFMsIGludCBuck1TLCBzdHJ1Y3QgX3c5NV9pbmZvICppbmZvICkKCnsKICAvKiBEaXNrIEtleSBIZWFkZXIgc3RydWN0dXJlIChSR0RCIHBhcnQpICovCglzdHJ1Y3QJZGtoIHsKICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcJCW5leHRrZXlvZmY7IAoJCXVuc2lnbmVkIHNob3J0CQluckxTOwoJCXVuc2lnbmVkIHNob3J0CQluck1TOwoJCXVuc2lnbmVkIGxvbmcJCWJ5dGVzdXNlZDsKCQl1bnNpZ25lZCBzaG9ydAkJa2V5bmFtZWxlbjsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsdWVzOwoJCXVuc2lnbmVkIGxvbmcJCXh4MTsKCQkvKiBrZXluYW1lICovCgkJLyogZGlzayBrZXkgdmFsdWVzIG9yIG5vdGhpbmcgKi8KCX07CgkvKiBEaXNrIEtleSBWYWx1ZSBzdHJ1Y3R1cmUgKi8KCXN0cnVjdAlka3YgewoJCXVuc2lnbmVkIGxvbmcJCXR5cGU7CgkJdW5zaWduZWQgbG9uZwkJeDE7CgkJdW5zaWduZWQgc2hvcnQJCXZhbG5hbWVsZW47CgkJdW5zaWduZWQgc2hvcnQJCXZhbGRhdGFsZW47CgkJLyogdmFsbmFtZSwgdmFsZGF0YSAqLwoJfTsKCgkKCXN0cnVjdAlka2ggZGtoOwoJaW50CWJ5dGVzcmVhZCA9IDA7CgljaGFyICAgICpyZ2RiZGF0YSA9IGluZm8tPnJnZGJidWZmZXI7CglpbnQgICAgIG5ieXRlcyA9IGluZm8tPnJnZGJzaXplOwoJY2hhciAgICAqY3VyZGF0YSA9IHJnZGJkYXRhOwoJY2hhciAgICAqZW5kID0gcmdkYmRhdGEgKyBuYnl0ZXM7CglpbnQgICAgIG9mZl9uZXh0X3JnZGI7CgljaGFyICAgICpuZXh0ID0gcmdkYmRhdGE7CglpbnQgICAgIG5yZ2RiLCBpOwoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJCglkbyB7CgkgIGN1cmRhdGEgPSBuZXh0OwoJICBpZiAoc3RybmNtcChjdXJkYXRhLCAiUkdEQiIsIDQpKSByZXR1cm4gKE5VTEwpOwoJICAgIAoJICBtZW1jcHkoJm9mZl9uZXh0X3JnZGIsY3VyZGF0YSs0LDQpOwoJICBuZXh0ID0gY3VyZGF0YSArIG9mZl9uZXh0X3JnZGI7CgkgIG5yZ2RiID0gKGludCkgKigoc2hvcnQgKiljdXJkYXRhICsgNyk7CgoJfSB3aGlsZSAobnJnZGIgIT0gbnJNUyAmJiAobmV4dCA8IGVuZCkpOwoKCS8qIGN1cmRhdGEgbm93IHBvaW50cyB0byB0aGUgc3RhcnQgb2YgdGhlIHJpZ2h0IFJHREIgc2VjdGlvbiAqLwoJY3VyZGF0YSArPSAweDIwOwoKI2RlZmluZSBYUkVBRCh3aGVyZXRvLGxlbikgXAoJaWYgKChjdXJkYXRhICsgbGVuKSA8ZW5kKSB7XAoJCW1lbWNweSh3aGVyZXRvLGN1cmRhdGEsbGVuKTtcCgkJY3VyZGF0YSs9bGVuO1wKCQlieXRlc3JlYWQrPWxlbjtcCgl9CgoJd2hpbGUgKGN1cmRhdGEgPCBuZXh0KSB7CgkgIHN0cnVjdAlka2ggKnhka2ggPSAoc3RydWN0IGRraCopY3VyZGF0YTsKCgkgIGJ5dGVzcmVhZCArPSBzaXplb2YoZGtoKTsgLyogRklYTUUuLi4gbmV4dGtleW9mZj8gKi8KCSAgaWYgKHhka2gtPm5yTFMgPT0gbnJMUykgewoJICAJbWVtY3B5KCZka2gseGRraCxzaXplb2YoZGtoKSk7CgkgIAljdXJkYXRhICs9IHNpemVvZihka2gpOwoJICAJYnJlYWs7CgkgIH0KCSAgY3VyZGF0YSArPSB4ZGtoLT5uZXh0a2V5b2ZmOwoJfTsKCglpZiAoZGtoLm5yTFMgIT0gbnJMUykgcmV0dXJuIChOVUxMKTsKCglpZiAobnJnZGIgIT0gZGtoLm5yTVMpCgkgIHJldHVybiAoTlVMTCk7CgogICAgICAgIGFzc2VydCgoZGtoLmtleW5hbWVsZW48MikgfHwgY3VyZGF0YVswXSk7CglscHhrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxzdHJjdnRBMlcoY3VyZGF0YSwgZGtoLmtleW5hbWVsZW4pKTsKCWN1cmRhdGEgKz0gZGtoLmtleW5hbWVsZW47CgoJZm9yIChpPTA7aTwgZGtoLnZhbHVlczsgaSsrKSB7CgkgIHN0cnVjdCBka3YgZGt2OwoJICBMUEJZVEUgZGF0YTsKCSAgaW50IGxlbjsKCSAgTFBXU1RSIG5hbWU7CgoJICBYUkVBRCgmZGt2LHNpemVvZihka3YpKTsKCgkgIG5hbWUgPSBzdHJjdnRBMlcoY3VyZGF0YSwgZGt2LnZhbG5hbWVsZW4pOwoJICBjdXJkYXRhICs9IGRrdi52YWxuYW1lbGVuOwoKCSAgaWYgKCgxIDw8IGRrdi50eXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkgICAgZGF0YSA9IChMUEJZVEUpIHN0cmN2dEEyVyhjdXJkYXRhLCBka3YudmFsZGF0YWxlbik7CgkgICAgbGVuID0gMiooZGt2LnZhbGRhdGFsZW4gKyAxKTsKCSAgfSBlbHNlIHsKCSAgICAvKiBJIGRvbid0IHRoaW5rIHdlIHdhbnQgdG8gTlVMTCB0ZXJtaW5hdGUgYWxsIGRhdGEgKi8KCSAgICBkYXRhID0geG1hbGxvYyhka3YudmFsZGF0YWxlbik7CgkgICAgbWVtY3B5IChkYXRhLCBjdXJkYXRhLCBka3YudmFsZGF0YWxlbik7CgkgICAgbGVuID0gZGt2LnZhbGRhdGFsZW47CgkgIH0KCgkgIGN1cmRhdGEgKz0gZGt2LnZhbGRhdGFsZW47CgkgIAoJICBfZmluZF9vcl9hZGRfdmFsdWUoCgkJCSAgICAgbHB4a2V5LAoJCQkgICAgIG5hbWUsCgkJCSAgICAgZGt2LnR5cGUsCgkJCSAgICAgZGF0YSwKCQkJICAgICBsZW4sCgkJCSAgICAgaW5mby0+bGFzdG1vZGlmaWVkCgkJCSAgICAgKTsKCX0KCXJldHVybiAobHB4a2V5KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X3dhbGtyZ2tuIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93OTVfd2Fsa3Jna24oIExQS0VZU1RSVUNUIHByZXZrZXksIGNoYXIgKm9mZiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBfdzk1X2luZm8gKmluZm8gKQoKewogIC8qIERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZSAoUkdLTiBwYXJ0KSAqLwogIHN0cnVjdAlka2UgewogICAgdW5zaWduZWQgbG9uZwkJeDE7CiAgICB1bnNpZ25lZCBsb25nCQl4MjsKICAgIHVuc2lnbmVkIGxvbmcJCXgzOy8qdXN1YWxseSAweEZGRkZGRkZGICovCiAgICB1bnNpZ25lZCBsb25nCQlwcmV2bHZsOwogICAgdW5zaWduZWQgbG9uZwkJbmV4dHN1YjsKICAgIHVuc2lnbmVkIGxvbmcJCW5leHQ7CiAgICB1bnNpZ25lZCBzaG9ydAkJbnJMUzsKICAgIHVuc2lnbmVkIHNob3J0CQluck1TOwogIH0gKmRrZSA9IChzdHJ1Y3QgZGtlICopb2ZmOwogIExQS0VZU1RSVUNUICBscHhrZXk7CgogIGlmIChka2UgPT0gTlVMTCkgewogICAgZGtlID0gKHN0cnVjdCBka2UgKikgKChjaGFyICopaW5mby0+cmdrbmJ1ZmZlcik7CiAgfQoKICBscHhrZXkgPSBfdzk1X3Byb2Nlc3NLZXkocHJldmtleSwgZGtlLT5uckxTLCBka2UtPm5yTVMsIGluZm8pOwogIC8qIFhYWCA8LS0gVGhpcyBpcyBhIGhhY2sqLwogIGlmICghbHB4a2V5KSB7CiAgICBscHhrZXkgPSBwcmV2a2V5OwogIH0KCiAgaWYgKGRrZS0+bmV4dHN1YiAhPSAtMSAmJiAKICAgICAgKChka2UtPm5leHRzdWIgLSAweDIwKSA8IGluZm8tPnJna25zaXplKSAKICAgICAgJiYgKGRrZS0+bmV4dHN1YiA+IDB4MjApKSB7CiAgICAKICAgIF93OTVfd2Fsa3Jna24obHB4a2V5LCAKCQkgIGluZm8tPnJna25idWZmZXIgKyBka2UtPm5leHRzdWIgLSAweDIwLCAKCQkgIGluZm8pOwogIH0KICAKICBpZiAoZGtlLT5uZXh0ICE9IC0xICYmIAogICAgICAoKGRrZS0+bmV4dCAtIDB4MjApIDwgaW5mby0+cmdrbnNpemUpICYmIAogICAgICAoZGtlLT5uZXh0ID4gMHgyMCkpIHsKICAgIF93OTVfd2Fsa3Jna24ocHJldmtleSwgIAoJCSAgaW5mby0+cmdrbmJ1ZmZlciArIGRrZS0+bmV4dCAtIDB4MjAsCgkJICBpbmZvKTsKICB9CgogIHJldHVybjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93OTVfbG9hZHJlZyggY2hhciogZm4sIExQS0VZU1RSVUNUIGxwa2V5ICkKewoJSEZJTEUzMgkJaGZkOwoJY2hhcgkJbWFnaWNbNV07Cgl1bnNpZ25lZCBsb25nCXdoZXJlLHZlcnNpb24scmdkYnNlY3Rpb24sZW5kOwoJc3RydWN0ICAgICAgICAgIF93OTVfaW5mbyBpbmZvOwoJT0ZTVFJVQ1QJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZkaW5mbzsKCglUUkFDRShyZWcsIkxvYWRpbmcgV2luOTUgcmVnaXN0cnkgZGF0YWJhc2UgJyVzJ1xuIixmbik7CgloZmQ9T3BlbkZpbGUzMihmbiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmZD09SEZJTEVfRVJST1IzMikKCQlyZXR1cm47CgltYWdpY1s0XT0wOwoJaWYgKDQhPV9scmVhZDMyKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJDUkVHIikpIHsKCQlXQVJOKHJlZywiJXMgaXMgbm90IGEgdzk1IHJlZ2lzdHJ5LlxuIixmbik7CgkJcmV0dXJuOwoJfQoJaWYgKDQhPV9scmVhZDMyKGhmZCwmdmVyc2lvbiw0KSkKCQlyZXR1cm47CglpZiAoNCE9X2xyZWFkMzIoaGZkLCZyZ2Ric2VjdGlvbiw0KSkKCQlyZXR1cm47CglpZiAoLTE9PV9sbHNlZWszMihoZmQsMHgyMCxTRUVLX1NFVCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZDMyKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJSR0tOIikpIHsKCQlXQVJOKHJlZywgInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJXNcbiIsIG1hZ2ljKTsKCQlyZXR1cm47Cgl9CgoJLyogU1RFUCAxOiBLZXlsaW5rIHN0cnVjdHVyZXMgKi8KCWlmICgtMT09X2xsc2VlazMyKGhmZCwweDQwLFNFRUtfU0VUKSkKCQlyZXR1cm47Cgl3aGVyZQk9IDB4NDA7CgllbmQJPSByZ2Ric2VjdGlvbjsKCglpbmZvLnJna25zaXplID0gZW5kIC0gd2hlcmU7CglpbmZvLnJna25idWZmZXIgPSAoY2hhciopeG1hbGxvYyhpbmZvLnJna25zaXplKTsKCWlmIChpbmZvLnJna25zaXplICE9IF9scmVhZDMyKGhmZCxpbmZvLnJna25idWZmZXIsaW5mby5yZ2tuc2l6ZSkpCgkJcmV0dXJuOwoKCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGZkLCZoZmRpbmZvKSkKCQlyZXR1cm47CgoJZW5kID0gaGZkaW5mby5uRmlsZVNpemVMb3c7CglpbmZvLmxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZkaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CgoJaWYgKC0xPT1fbGxzZWVrMzIoaGZkLHJnZGJzZWN0aW9uLFNFRUtfU0VUKSkKCQlyZXR1cm47CgoJaW5mby5yZ2RiYnVmZmVyID0gKGNoYXIqKXhtYWxsb2MoZW5kLXJnZGJzZWN0aW9uKTsKCWluZm8ucmdkYnNpemUgPSBlbmQgLSByZ2Ric2VjdGlvbjsKCglpZiAoaW5mby5yZ2Ric2l6ZSAhPV9scmVhZDMyKGhmZCxpbmZvLnJnZGJidWZmZXIsaW5mby5yZ2Ric2l6ZSkpCgkJcmV0dXJuOwoJX2xjbG9zZTMyKGhmZCk7CgoJX3c5NV93YWxrcmdrbihscGtleSwgTlVMTCwgJmluZm8pOwoKCWZyZWUgKGluZm8ucmdkYmJ1ZmZlcik7CglmcmVlIChpbmZvLnJna25idWZmZXIpOwp9CgoKLyogV0lORE9XUyAzMSBSRUdJU1RSWSBMT0FERVIsIHN1cHBsaWVkIGJ5IFRvciBTavh3YWxsLCB0b3JAc24ubm8gKi8KCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VlZGVkIGJ5IGEgd29yZCBhdCBvZmZzZXQtMi4gVGhpcyB3b3JkCiAgICBoYXMgdGhlIHZhbHVlICgyKmluZGV4KSsxLCB3aGVyZSBpbmRleCBpcyB0aGUgcmVmZXJyaW5nIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGluIHRoZSB0YWJsZS4gSSBoYXZlIG5vIHN1Z2dlc3Rpb24gZm9yIHRoZSAyKiBhbmQgdGhlICsxLgogICAgRm9sbG93aW5nIHRoZSB3b3JkLCB0aGVyZSBhcmUgTiBieXRlcyBvZiBkYXRhLCBhcyBwZXIgdGhlIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGxlbmd0aC4gVGhlIG9mZnNldCBvZiB0aGUga2V5ZW50L3ZhbGVudCBlbnRyeSBpcyBmcm9tIHRoZSBzdGFydAogICAgb2YgdGhlIHRleHQgdGFibGUgdG8gdGhlIGZpcnN0IGRhdGEgYnl0ZS4KCiAgICBUaGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbSBNaWNyb3NvZnQuIFRoZSBkYXRhIGZvcm1hdCBpcwogICAgZGVkdWNlZCBmcm9tIHRoZSByZWcuZGF0IGZpbGUgYnkgbWUuIE1pc3Rha2VzIG1heQogICAgaGF2ZSBiZWVuIG1hZGUuIEkgY2xhaW0gbm8gcmlnaHRzIGFuZCBnaXZlIG5vIGd1YXJhbnRlZXMgZm9yIHRoaXMgcHJvZ3JhbS4KCiAgICBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vCiovCgovKiByZWcuZGF0IGhlYWRlciBmb3JtYXQgKi8Kc3RydWN0IF93MzFfaGVhZGVyIHsKCWNoYXIJCWNvb2tpZVs4XTsJLyogJ1NIQ0MzLjEwJyAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYxOwkvKiBvZmZzZXQgb2YgaGFzaCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYyOwkvKiBvZmZzZXQgb2YgaW5kZXggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFiY250OwkJLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gaW5kZXggdGFibGUgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dG9mZjsJLyogb2Zmc2V0IG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0c2l6ZTsJLyogYnl0ZSBzaXplIG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgc2hvcnQJaGFzaHNpemU7CS8qIGhhc2ggc2l6ZSAqLwoJdW5zaWduZWQgc2hvcnQJZnJlZWlkeDsJLyogZnJlZSBpbmRleCAqLwp9OwoKLyogZ2VuZXJpYyBmb3JtYXQgb2YgdGFibGUgZW50cmllcyAqLwpzdHJ1Y3QgX3czMV90YWJlbnQgewoJdW5zaWduZWQgc2hvcnQgdzAsIHcxLCB3MiwgdzM7Cn07CgovKiBkaXJlY3RvcnkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9kaXJlbnQgewoJdW5zaWduZWQgc2hvcnQJc2libGluZ19pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHNpYmxpbmcgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAljaGlsZF9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGNoaWxkIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJa2V5X2lkeDsJLyogdGFibGUgaW5kZXggb2Yga2V5IGtleWVudCAqLwoJdW5zaWduZWQgc2hvcnQJdmFsdWVfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiB2YWx1ZSB2YWxlbnQgKi8KfTsKCi8qIGtleSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2tleWVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogdmFsdWUgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV92YWxlbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdG8gZGlzcGxheSBhIGRpcmVjdG9yeSB0cmVlICovCnZvaWQKX193MzFfZHVtcHRyZWUoCXVuc2lnbmVkIHNob3J0IGlkeCwKCQl1bnNpZ25lZCBjaGFyICp0eHQsCgkJc3RydWN0IF93MzFfdGFiZW50ICp0YWIsCgkJc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAoJCUxQS0VZU1RSVUNUCWxwa2V5LAoJCXRpbWVfdAkJbGFzdG1vZGlmaWVkLAoJCWludAkJbGV2ZWwKKSB7CglzdHJ1Y3QgX3czMV9kaXJlbnQJKmRpcjsKCXN0cnVjdCBfdzMxX2tleWVudAkqa2V5OwoJc3RydWN0IF93MzFfdmFsZW50CSp2YWw7CglMUEtFWVNUUlVDVAkJeGxwa2V5ID0gTlVMTDsKCUxQV1NUUgkJCW5hbWUsdmFsdWU7CglzdGF0aWMgY2hhcgkJdGFpbFs0MDBdOwoKCXdoaWxlIChpZHghPTApIHsKCQlkaXI9KHN0cnVjdCBfdzMxX2RpcmVudCopJnRhYltpZHhdOwoKCQlpZiAoZGlyLT5rZXlfaWR4KSB7CgkJCWtleSA9IChzdHJ1Y3QgX3czMV9rZXllbnQqKSZ0YWJbZGlyLT5rZXlfaWR4XTsKCgkJCW1lbWNweSh0YWlsLCZ0eHRba2V5LT5zdHJpbmdfb2ZmXSxrZXktPmxlbmd0aCk7CgkJCXRhaWxba2V5LT5sZW5ndGhdPSdcMCc7CgkJCS8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUgCgkJCSAqIHRvcGxldmVsIHN1YmRpcmVjdG9yeSBiZWxvbmcgdG8gXFNPRlRXQVJFXENsYXNzZXMKCQkJICovCgkJCWlmICghbGV2ZWwgJiYgIWxzdHJjbXAzMkEodGFpbCwiLmNsYXNzZXMiKSkgewoJCQkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLGxwa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQkJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJCQkJY29udGludWU7CgkJCX0KCQkJbmFtZT1zdHJkdXBBMlcodGFpbCk7CgoJCQl4bHBrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxuYW1lKTsKCgkJCS8qIG9ubHkgYWRkIGlmIGxlYWYgbm9kZSBvciB2YWx1ZWQgbm9kZSAqLwoJCQlpZiAoZGlyLT52YWx1ZV9pZHghPTB8fGRpci0+Y2hpbGRfaWR4PT0wKSB7CgkJCQlpZiAoZGlyLT52YWx1ZV9pZHgpIHsKCQkJCQl2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CgkJCQkJbWVtY3B5KHRhaWwsJnR4dFt2YWwtPnN0cmluZ19vZmZdLHZhbC0+bGVuZ3RoKTsKCQkJCQl0YWlsW3ZhbC0+bGVuZ3RoXT0nXDAnOwoJCQkJCXZhbHVlPXN0cmR1cEEyVyh0YWlsKTsKCQkJCQlfZmluZF9vcl9hZGRfdmFsdWUoeGxwa2V5LE5VTEwsUkVHX1NaLChMUEJZVEUpdmFsdWUsbHN0cmxlbjMyVyh2YWx1ZSkqMisyLGxhc3Rtb2RpZmllZCk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQlUUkFDRShyZWcsInN0cmFuZ2U6IG5vIGRpcmVjdG9yeSBrZXkgbmFtZSwgaWR4PSUwNHhcbiIsIGlkeCk7CgkJfQoJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCx4bHBrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzMxX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kdm9pZCBfdzMxX2xvYWRyZWcodm9pZCkgewoJSEZJTEUzMgkJCWhmOwoJc3RydWN0IF93MzFfaGVhZGVyCWhlYWQ7CglzdHJ1Y3QgX3czMV90YWJlbnQJKnRhYjsKCXVuc2lnbmVkIGNoYXIJCSp0eHQ7CglpbnQJCQlsZW47CglPRlNUUlVDVAkJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZpbmZvOwoJdGltZV90CQkJbGFzdG1vZGlmaWVkOwoJTFBLRVlTVFJVQ1QJCWxwa2V5OwoKCVRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCgloZiA9IE9wZW5GaWxlMzIoInJlZy5kYXQiLCZvZnMsT0ZfUkVBRCk7CglpZiAoaGY9PUhGSUxFX0VSUk9SMzIpCgkJcmV0dXJuOwoKCS8qIHJlYWQgJiBkdW1wIGhlYWRlciAqLwoJaWYgKHNpemVvZihoZWFkKSE9X2xyZWFkMzIoaGYsJmhlYWQsc2l6ZW9mKGhlYWQpKSkgewoJCUVSUihyZWcsICJyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoJaWYgKG1lbWNtcChoZWFkLmNvb2tpZSwgIlNIQ0MzLjEwIiwgc2l6ZW9mKGhlYWQuY29va2llKSkhPTApIHsKCQlFUlIocmVnLCAicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoKCWxlbiA9IGhlYWQudGFiY250ICogc2l6ZW9mKHN0cnVjdCBfdzMxX3RhYmVudCk7CgkvKiByZWFkIGFuZCBkdW1wIGluZGV4IHRhYmxlICovCgl0YWIgPSB4bWFsbG9jKGxlbik7CglpZiAobGVuIT1fbHJlYWQzMihoZix0YWIsbGVuKSkgewoJCUVSUihyZWcsImNvdWxkbid0IHJlYWQgJWQgYnl0ZXMuXG4iLGxlbik7IAoJCWZyZWUodGFiKTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCgkvKiByZWFkIHRleHQgKi8KCXR4dCA9IHhtYWxsb2MoaGVhZC50ZXh0c2l6ZSk7CglpZiAoLTE9PV9sbHNlZWszMihoZixoZWFkLnRleHRvZmYsU0VFS19TRVQpKSB7CgkJRVJSKHJlZywiY291bGRuJ3Qgc2VlayB0byB0ZXh0YmxvY2suXG4iKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCWlmIChoZWFkLnRleHRzaXplIT1fbHJlYWQzMihoZix0eHQsaGVhZC50ZXh0c2l6ZSkpIHsKCQlFUlIocmVnLCJ0ZXh0YmxvY2sgdG9vIHNob3J0ICglZCBpbnN0ZWFkIG9mICVsZCkuXG4iLGxlbixoZWFkLnRleHRzaXplKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCglpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmLCZoZmluZm8pKSB7CgkJRVJSKHJlZywiR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUgZmFpbGVkPy5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoJbGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoJbHBrZXkgPSBsb29rdXBfaGtleShIS0VZX0NMQVNTRVNfUk9PVCk7CglfX3czMV9kdW1wdHJlZSh0YWJbMF0udzEsdHh0LHRhYiwmaGVhZCxscGtleSxsYXN0bW9kaWZpZWQsMCk7CglmcmVlKHRhYik7CglmcmVlKHR4dCk7CglfbGNsb3NlMzIoaGYpOwoJcmV0dXJuOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfTG9hZFJlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnZvaWQgU0hFTExfTG9hZFJlZ2lzdHJ5KCB2b2lkICkKewoJY2hhcgkqZm47CglzdHJ1Y3QJcGFzc3dkCSpwd2Q7CglMUEtFWVNUUlVDVAlscGtleTsKCUhLRVkJCWhrZXk7CgoJVFJBQ0UocmVnLCIodm9pZClcbiIpOwoKCS8qIExvYWQgd2luZG93cyAzLjEgZW50cmllcyAqLwoJX3czMV9sb2FkcmVnKCk7CgkvKiBMb2FkIHdpbmRvd3MgOTUgZW50cmllcyAqLwoJX3c5NV9sb2FkcmVnKCJDOlxcc3lzdGVtLjFzdCIsCWxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSkpOwoJX3c5NV9sb2FkcmVnKCJzeXN0ZW0uZGF0IiwJbG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSk7Cglfdzk1X2xvYWRyZWcoInVzZXIuZGF0IiwJbG9va3VwX2hrZXkoSEtFWV9VU0VSUykpOwoKCS8qIHRoZSBnbG9iYWwgdXNlciBkZWZhdWx0IGlzIGxvYWRlZCB1bmRlciBIS0VZX1VTRVJTXFwuRGVmYXVsdCAqLwoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUywiLkRlZmF1bHQiLCZoa2V5KTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICAgICAgaWYoIWxwa2V5KQogICAgICAgICAgICBXQVJOKHJlZywiQ291bGQgbm90IGNyZWF0ZSBnbG9iYWwgdXNlciBkZWZhdWx0IGtleVxuIik7Cglfd2luZV9sb2FkcmVnKGxwa2V5LFNBVkVfVVNFUlNfREVGQVVMVCwwKTsKCgkvKiBIS0VZX1VTRVJTXFwuRGVmYXVsdCBpcyBjb3BpZWQgdG8gSEtFWV9DVVJSRU5UX1VTRVIgKi8KCV9jb3B5X3JlZ2lzdHJ5KGxwa2V5LGxvb2t1cF9oa2V5KEhLRVlfQ1VSUkVOVF9VU0VSKSk7CglSZWdDbG9zZUtleShoa2V5KTsKCgkvKiB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgKi8KCV93aW5lX2xvYWRyZWcobG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSxTQVZFX0xPQ0FMX01BQ0hJTkVfREVGQVVMVCwwKTsKCgkvKiBsb2FkIHRoZSB1c2VyIHNhdmVkIHJlZ2lzdHJpZXMgKi8KCgkvKiBGSVhNRTogdXNlIGdldGVudigiSE9NRSIpIG9yIGdldHB3dWlkKGdldHVpZCgpKS0+cHdfZGlyID8/ICovCgoJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCWlmIChwd2QhPU5VTEwgJiYgcHdkLT5wd19kaXIhPU5VTEwpIHsKCQlmbj0oY2hhciopeG1hbGxvYyhzdHJsZW4ocHdkLT5wd19kaXIpK3N0cmxlbihXSU5FX1BSRUZJWCkrc3RybGVuKFNBVkVfQ1VSUkVOVF9VU0VSKSsyKTsKCQlzdHJjcHkoZm4scHdkLT5wd19kaXIpOwoJCXN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfQ1VSUkVOVF9VU0VSKTsKCQlfd2luZV9sb2FkcmVnKGxvb2t1cF9oa2V5KEhLRVlfQ1VSUkVOVF9VU0VSKSxmbixSRUdfT1BUSU9OX1RBSU5URUQpOwoJCWZyZWUoZm4pOwoJCWZuPShjaGFyKil4bWFsbG9jKHN0cmxlbihwd2QtPnB3X2Rpcikrc3RybGVuKFdJTkVfUFJFRklYKStzdHJsZW4oU0FWRV9MT0NBTF9NQUNISU5FKSsyKTsKCQlzdHJjcHkoZm4scHdkLT5wd19kaXIpOwoJCXN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfTUFDSElORSk7CgkJX3dpbmVfbG9hZHJlZyhsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpLGZuLFJFR19PUFRJT05fVEFJTlRFRCk7CgkJZnJlZShmbik7Cgl9IGVsc2UKCQlXQVJOKHJlZywiRmFpbGVkIHRvIGdldCBob21lZGlyZWN0b3J5IG9mIFVJRCAlZC5cbiIsZ2V0dWlkKCkpOwoJaWYgKEVSUk9SX1NVQ0NFU1M9PVJlZ0NyZWF0ZUtleTE2KEhLRVlfQ1VSUkVOVF9VU0VSLEtFWV9SRUdJU1RSWSwmaGtleSkpIHsKCQlEV09SRAlqdW5rLHR5cGUsbGVuOwoJCWNoYXIJZGF0YVs1XTsKCgkJbGVuPTQ7CgkJaWYgKCgJUmVnUXVlcnlWYWx1ZUV4MzJBKAoJCQkJaGtleSwKCQkJCVZBTF9TQVZFVVBEQVRFRCwKCQkJCSZqdW5rLAoJCQkJJnR5cGUsCgkJCQlkYXRhLAoJCQkJJmxlbgoJCQkpIT1FUlJPUl9TVUNDRVNTKSB8fAoJCQl0eXBlICE9IFJFR19TWgoJCSkKCQkJUmVnU2V0VmFsdWVFeDMyQShoa2V5LFZBTF9TQVZFVVBEQVRFRCwwLFJFR19TWiwieWVzIiw0KTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKiogQVBJIEZVTkNUSU9OUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qCiAqIE9wZW4gS2V5cy4KICoKICogQWxsIGZ1bmN0aW9ucyBhcmUgc3R1YnMgdG8gUmVnT3BlbktleUV4MzJXIHdoZXJlIGFsbCB0aGUKICogbWFnaWMgaGFwcGVucy4gCiAqCiAqIENhbGxwYXRoOgogKiBSZWdPcGVuS2V5MTYgLT4gUmVnT3BlbktleTMyQSAtPiBSZWdPcGVuS2V5RXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdPcGVuS2V5MzJXICAgLT4gUmVnT3BlbktleUV4MzJXIAogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXlFeDMyVyBbQURWQVBJMzIuMTUwXQogKiBPcGVucyB0aGUgc3BlY2lmaWVkIGtleQogKgogKiBVbmxpa2UgUmVnQ3JlYXRlS2V5RXgsIHRoaXMgZG9lcyBub3QgY3JlYXRlIHRoZSBrZXkgaWYgaXQgZG9lcyBub3QgZXhpc3QuCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBzelN1YktleSBbSV0gTmFtZSBvZiBzdWJrZXkgdG8gb3BlbgogKiAgICBkd1Jlc2VydmVkIFtJXSBSZXNlcnZlZCAtIG11c3QgYmUgemVybwogKiAgICBzYW1EZXNpcmVkIFtJXSBTZWN1cml0eSBhY2Nlc3MgbWFzawogKiAgICByZXRrZXkgICAgIFtPXSBBZGRyZXNzIG9mIGhhbmRsZSBvZiBvcGVuIGtleQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXlFeDMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR1NBTSBzYW1EZXNpcmVkLCBMUEhLRVkgcmV0a2V5ICkKewoJTFBLRVlTVFJVQ1QJbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgogICAgVFJBQ0UocmVnLCIoMHgleCwlcywlbGQsJWx4LCVwKVxuIiwgaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGR3UmVzZXJ2ZWQsCiAgICAgICAgICBzYW1EZXNpcmVkLHJldGtleSk7CgogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBOZXh0S2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KSB7CiAgICAgICAgLyogRWl0aGVyIE5VTEwgb3IgcG9pbnRlciB0byBlbXB0eSBzdHJpbmcsIHNvIHJldHVybiBhIG5ldyBoYW5kbGUKICAgICAgICAgICB0byB0aGUgb3JpZ2luYWwgaGtleSAqLwogICAgICAgIGN1cnJlbnRoYW5kbGUgKz0gMjsKICAgICAgICBhZGRfaGFuZGxlKGN1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwogICAgICAgICpyZXRrZXk9Y3VycmVudGhhbmRsZTsKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAobHBzelN1YktleVswXSA9PSAnXFwnKSB7CiAgICAgICAgV0FSTihyZWcsIlN1YmtleSAlcyBtdXN0IG5vdCBiZWdpbiB3aXRoIGJhY2tzbGFzaC5cbiIsZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CiAgICAgICAgcmV0dXJuIEVSUk9SX0JBRF9QQVRITkFNRTsKICAgIH0KCglzcGxpdF9rZXlwYXRoKGxwc3pTdWJLZXksJndwcywmd3BjKTsKCWkgPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleSA9IGxwTmV4dEtleTsKCiAgICB3aGlsZSAod3BzW2ldKSB7CiAgICAgICAgbHB4a2V5PWxwTmV4dEtleS0+bmV4dHN1YjsKICAgICAgICB3aGlsZSAobHB4a2V5KSB7CiAgICAgICAgICAgIGlmICghbHN0cmNtcGkzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxweGtleT1scHhrZXktPm5leHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWxweGtleSkgewogICAgICAgICAgICBUUkFDRShyZWcsIkNvdWxkIG5vdCBmaW5kIHN1YmtleSAlc1xuIixkZWJ1Z3N0cl93KHdwc1tpXSkpOwogICAgICAgICAgICBGUkVFX0tFWV9QQVRIOwogICAgICAgICAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7CiAgICAgICAgfQogICAgICAgIGkrKzsKICAgICAgICBscE5leHRLZXkgPSBscHhrZXk7CiAgICB9CgogICAgY3VycmVudGhhbmRsZSArPSAyOwogICAgYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKICAgICpyZXRrZXkgPSBjdXJyZW50aGFuZGxlOwogICAgVFJBQ0UocmVnLCIgIFJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CiAgICBGUkVFX0tFWV9QQVRIOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXlFeDMyQSBbQURWQVBJMzIuMTQ5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXlFeDMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHU0FNIHNhbURlc2lyZWQsIExQSEtFWSByZXRrZXkgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVcgPSBzdHJkdXBBMlcobHBzelN1YktleSk7CiAgICBEV09SRCByZXQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVseCwlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGR3UmVzZXJ2ZWQsCiAgICAgICAgICBzYW1EZXNpcmVkLHJldGtleSk7CiAgICByZXQgPSBSZWdPcGVuS2V5RXgzMlcoIGhrZXksIGxwc3pTdWJLZXlXLCBkd1Jlc2VydmVkLCBzYW1EZXNpcmVkLCByZXRrZXkgKTsKICAgIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleTMyVyBbQURWQVBJMzIuMTUxXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkgdG8gb3BlbgogKiAgICByZXRrZXkgICAgIFtPXSBBZGRyZXNzIG9mIGhhbmRsZSBvZiBvcGVuIGtleQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0dXJuIFJlZ09wZW5LZXlFeDMyVyggaGtleSwgbHBzelN1YktleSwgMCwgS0VZX0FMTF9BQ0NFU1MsIHJldGtleSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5MzJBIFtBRFZBUEkzMi4xNDhdCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIERXT1JEIHJldDsKICAgIExQV1NUUiBscHN6U3ViS2V5VyA9IHN0cmR1cEEyVyhscHN6U3ViS2V5KTsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldCA9ICBSZWdPcGVuS2V5MzJXKCBoa2V5LCBscHN6U3ViS2V5VywgcmV0a2V5ICk7CiAgICBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXkxNiBbU0hFTEwuMV0gW0tFUk5FTC4yMTddCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0dXJuIFJlZ09wZW5LZXkzMkEoIGhrZXksIGxwc3pTdWJLZXksIHJldGtleSApOwp9CgoKLyogCiAqIENyZWF0ZSBrZXlzCiAqIAogKiBBbGwgdGhvc2UgZnVuY3Rpb25zIGNvbnZlcnQgdGhlaXIgcmVzcGVjdGl2ZSAKICogYXJndW1lbnRzIGFuZCBjYWxsIFJlZ0NyZWF0ZUtleUV4VyBhdCB0aGUgZW5kLgogKgogKiBXZSBzdGF5IGF3YXkgZnJvbSB0aGUgRXggZnVuY3Rpb25zIGFzIGxvbmcgYXMgcG9zc2libGUgYmVjYXVzZSB0aGVyZSBhcmUKICogZGlmZmVyZW5jZXMgaW4gdGhlIHJldHVybiB2YWx1ZXMKICoKICogQ2FsbHBhdGg6CiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdDcmVhdGVLZXlFeDMyQSBcCiAqIFJlZ0NyZWF0ZUtleTE2IC0+IFJlZ0NyZWF0ZUtleTMyQSAtPiBSZWdDcmVhdGVLZXkzMlcgICAtPiBSZWdDcmVhdGVLZXlFeDMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleUV4MzJXIFtBRFZBUEkzMi4xMzFdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgW0ldIEhhbmRsZSBvZiBhbiBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5ICAgW0ldIEFkZHJlc3Mgb2Ygc3Via2V5IG5hbWUKICogICAgZHdSZXNlcnZlZCAgIFtJXSBSZXNlcnZlZCAtIG11c3QgYmUgMAogKiAgICBscHN6Q2xhc3MgICAgW0ldIEFkZHJlc3Mgb2YgY2xhc3Mgc3RyaW5nCiAqICAgIGZkd09wdGlvbnMgICBbSV0gU3BlY2lhbCBvcHRpb25zIGZsYWcKICogICAgc2FtRGVzaXJlZCAgIFtJXSBEZXNpcmVkIHNlY3VyaXR5IGFjY2VzcwogKiAgICBscFNlY0F0dHJpYnMgW0ldIEFkZHJlc3Mgb2Yga2V5IHNlY3VyaXR5IHN0cnVjdHVyZQogKiAgICByZXRrZXkgICAgICAgW09dIEFkZHJlc3Mgb2YgYnVmZmVyIGZvciBvcGVuZWQgaGFuZGxlCiAqICAgIGxwRGlzcG9zICAgICBbT10gUmVjZWl2ZXMgUkVHX0NSRUFURURfTkVXX0tFWSBvciBSRUdfT1BFTkVEX0VYSVNUSU5HX0tFWQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleUV4MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdSZXNlcnZlZCwgTFBXU1RSIGxwc3pDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZmR3T3B0aW9ucywgUkVHU0FNIHNhbURlc2lyZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIGxwU2VjQXR0cmlicywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBIS0VZIHJldGtleSwgTFBEV09SRCBscERpc3BvcyApCnsKCUxQS0VZU1RSVUNUCSpscGxwUHJldktleSxscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCiAgICBUUkFDRShyZWcsIigleCwlcywlbGQsJXMsJWx4LCVseCwlcCwlcCwlcClcbiIsIGhrZXksCgkJZGVidWdzdHJfdyhscHN6U3ViS2V5KSwgZHdSZXNlcnZlZCwgZGVidWdzdHJfdyhscHN6Q2xhc3MpLAoJCWZkd09wdGlvbnMsIHNhbURlc2lyZWQsIGxwU2VjQXR0cmlicywgcmV0a2V5LCBscERpc3Bvcyk7CgogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgLyogQ2hlY2sgZm9yIHZhbGlkIG9wdGlvbnMgKi8KICAgIHN3aXRjaChmZHdPcHRpb25zKSB7CiAgICAgICAgY2FzZSBSRUdfT1BUSU9OX05PTl9WT0xBVElMRToKICAgICAgICBjYXNlIFJFR19PUFRJT05fVk9MQVRJTEU6CiAgICAgICAgY2FzZSBSRUdfT1BUSU9OX0JBQ0tVUF9SRVNUT1JFOgogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CiAgICB9CgogICAgLyogU2FtIGhhcyB0byBiZSBhIGNvbWJpbmF0aW9uIG9mIHRoZSBmb2xsb3dpbmcgKi8KICAgIGlmICghKHNhbURlc2lyZWQgJiAKICAgICAgICAgIChLRVlfQUxMX0FDQ0VTUyB8IEtFWV9DUkVBVEVfTElOSyB8IEtFWV9DUkVBVEVfU1VCX0tFWSB8IAogICAgICAgICAgIEtFWV9FTlVNRVJBVEVfU1VCX0tFWVMgfCBLRVlfRVhFQ1VURSB8IEtFWV9OT1RJRlkgfAogICAgICAgICAgIEtFWV9RVUVSWV9WQUxVRSB8IEtFWV9SRUFEIHwgS0VZX1NFVF9WQUxVRSB8IEtFWV9XUklURSkpKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCglpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KSB7CiAgICAgICAgICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CgkJYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKCQkqcmV0a2V5PWN1cnJlbnRoYW5kbGU7CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsICJSZXR1cm5pbmcgJXhcbiIsIGN1cnJlbnRoYW5kbGUpOwoJCWxwTmV4dEtleS0+ZmxhZ3N8PVJFR19PUFRJT05fVEFJTlRFRDsKCQlyZXR1cm4gRVJST1JfU1VDQ0VTUzsKCX0KCiAgICBpZiAobHBzelN1YktleVswXSA9PSAnXFwnKSB7CiAgICAgICAgV0FSTihyZWcsIlN1YmtleSAlcyBtdXN0IG5vdCBiZWdpbiB3aXRoIGJhY2tzbGFzaC5cbiIsZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CiAgICAgICAgcmV0dXJuIEVSUk9SX0JBRF9QQVRITkFNRTsKICAgIH0KCglzcGxpdF9rZXlwYXRoKGxwc3pTdWJLZXksJndwcywmd3BjKTsKCWkgCT0gMDsKCXdoaWxlICgoaTx3cGMpICYmICh3cHNbaV1bMF09PSdcMCcpKSBpKys7CglscHhrZXkJPSBscE5leHRLZXk7Cgl3aGlsZSAod3BzW2ldKSB7CgkJbHB4a2V5PWxwTmV4dEtleS0+bmV4dHN1YjsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCWlmICghbHN0cmNtcGkzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCQlicmVhazsKCQkJbHB4a2V5PWxweGtleS0+bmV4dDsKCQl9CgkJaWYgKCFscHhrZXkpCgkJCWJyZWFrOwoJCWkrKzsKCQlscE5leHRLZXkJPSBscHhrZXk7Cgl9CglpZiAobHB4a2V5KSB7CiAgICAgICAgICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CgkJYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKCQlscHhrZXktPmZsYWdzICB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCQlpZiAobHBEaXNwb3MpCgkJCSpscERpc3Bvcwk9IFJFR19PUEVORURfRVhJU1RJTkdfS0VZOwoJCUZSRUVfS0VZX1BBVEg7CgkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgl9CgoJLyogR29vZC4gIE5vdyB0aGUgaGFyZCBwYXJ0ICovCgl3aGlsZSAod3BzW2ldKSB7CgkJbHBscFByZXZLZXkJPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7CgkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCQlscHhrZXkJCT0gKmxwbHBQcmV2S2V5OwoJCX0KCQkqbHBscFByZXZLZXk9bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTsKCQlpZiAoISpscGxwUHJldktleSkgewoJCQlGUkVFX0tFWV9QQVRIOwogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRShyZWcsICJSZXR1cm5pbmcgT1VUT0ZNRU1PUllcbiIpOwoJCQlyZXR1cm4gRVJST1JfT1VUT0ZNRU1PUlk7CgkJfQoJCW1lbXNldCgqbHBscFByZXZLZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsIkFkZGluZyAlc1xuIiwgZGVidWdzdHJfdyh3cHNbaV0pKTsKCQkoKmxwbHBQcmV2S2V5KS0+a2V5bmFtZQk9IHN0cmR1cFcod3BzW2ldKTsKCQkoKmxwbHBQcmV2S2V5KS0+bmV4dAk9IE5VTEw7CgkJKCpscGxwUHJldktleSktPm5leHRzdWIJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT52YWx1ZXMJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5ucm9mdmFsdWVzID0gMDsKCQkoKmxwbHBQcmV2S2V5KS0+ZmxhZ3MgCT0gUkVHX09QVElPTl9UQUlOVEVEOwoJCWlmIChscHN6Q2xhc3MpCgkJCSgqbHBscFByZXZLZXkpLT5jbGFzcyA9IHN0cmR1cFcobHBzekNsYXNzKTsKCQllbHNlCgkJCSgqbHBscFByZXZLZXkpLT5jbGFzcyA9IE5VTEw7CgkJbHBOZXh0S2V5CT0gKmxwbHBQcmV2S2V5OwoJCWkrKzsKCX0KICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CglhZGRfaGFuZGxlKGN1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwoKCS8qRklYTUU6IGZsYWcgaGFuZGxpbmcgY29ycmVjdD8gKi8KCWxwTmV4dEtleS0+ZmxhZ3M9IGZkd09wdGlvbnMgfFJFR19PUFRJT05fVEFJTlRFRDsKCWlmIChscHN6Q2xhc3MpCgkJbHBOZXh0S2V5LT5jbGFzcyA9IHN0cmR1cFcobHBzekNsYXNzKTsKCWVsc2UKCQlscE5leHRLZXktPmNsYXNzID0gTlVMTDsKCSpyZXRrZXkJCT0gY3VycmVudGhhbmRsZTsKICAgICAgICBUUkFDRShyZWcsICJSZXR1cm5pbmcgJXhcbiIsIGN1cnJlbnRoYW5kbGUpOwoJaWYgKGxwRGlzcG9zKQoJCSpscERpc3Bvcwk9IFJFR19DUkVBVEVEX05FV19LRVk7CglGUkVFX0tFWV9QQVRIOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleUV4MzJBIFtBRFZBUEkzMi4xMzBdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5RXgzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgbHBzekNsYXNzLCBEV09SRCBmZHdPcHRpb25zLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdTQU0gc2FtRGVzaXJlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIGxwU2VjQXR0cmlicywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBIS0VZIHJldGtleSwgTFBEV09SRCBscERpc3BvcyApCnsKICAgIExQV1NUUiBscHN6U3ViS2V5VywgbHBzekNsYXNzVzsKICAgIERXT1JEICByZXQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVseCwlbHgsJXAsJXAsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsZGVidWdzdHJfYShscHN6Q2xhc3MpLGZkd09wdGlvbnMsc2FtRGVzaXJlZCxscFNlY0F0dHJpYnMsCiAgICAgICAgICByZXRrZXksbHBEaXNwb3MpOwoKICAgIGxwc3pTdWJLZXlXID0gbHBzelN1YktleT9zdHJkdXBBMlcobHBzelN1YktleSk6TlVMTDsKICAgIGxwc3pDbGFzc1cgPSBscHN6Q2xhc3M/c3RyZHVwQTJXKGxwc3pDbGFzcyk6TlVMTDsKCiAgICByZXQgPSBSZWdDcmVhdGVLZXlFeDMyVyggaGtleSwgbHBzelN1YktleVcsIGR3UmVzZXJ2ZWQsIGxwc3pDbGFzc1csIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkd09wdGlvbnMsIHNhbURlc2lyZWQsIGxwU2VjQXR0cmlicywgcmV0a2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscERpc3BvcyApOwoKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIGlmKGxwc3pDbGFzc1cpIGZyZWUobHBzekNsYXNzVyk7CgogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ3JlYXRlS2V5MzJXIFtBRFZBUEkzMi4xMzJdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIERXT1JEIGp1bms7CiAgICBMUEtFWVNUUlVDVAlscE5leHRLZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLCBoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkscmV0a2V5KTsKCiAgICAvKiBUaGlzIGNoZWNrIGlzIGhlcmUgYmVjYXVzZSB0aGUgcmV0dXJuIHZhbHVlIGlzIGRpZmZlcmVudCB0aGFuIHRoZQogICAgICAgb25lIGZyb20gdGhlIEV4IGZ1bmN0aW9ucyAqLwogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfQkFES0VZOwoKICAgIHJldHVybiBSZWdDcmVhdGVLZXlFeDMyVyggaGtleSwgbHBzelN1YktleSwgMCwgTlVMTCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfQUxMX0FDQ0VTUywgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0a2V5LCAmanVuayk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleTMyQSBbQURWQVBJMzIuMTI5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIERXT1JEIHJldDsKICAgIExQV1NUUiBscHN6U3ViS2V5VzsKCiAgICBUUkFDRShyZWcsIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICBscHN6U3ViS2V5VyA9IGxwc3pTdWJLZXk/c3RyZHVwQTJXKGxwc3pTdWJLZXkpOk5VTEw7CiAgICByZXQgPSBSZWdDcmVhdGVLZXkzMlcoIGhrZXksIGxwc3pTdWJLZXlXLCByZXRrZXkgKTsKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleTE2IFtTSEVMTC4yXSBbS0VSTkVMLjIxOF0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdDcmVhdGVLZXkzMkEoIGhrZXksIGxwc3pTdWJLZXksIHJldGtleSApOwp9CgoKLyogCiAqIFF1ZXJ5IFZhbHVlIEZ1bmN0aW9ucwogKiBXaW4zMiBkaWZmZXJzIGJldHdlZW4ga2V5bmFtZXMgYW5kIHZhbHVlbmFtZXMuIAogKiBtdWx0aXBsZSB2YWx1ZXMgbWF5IGJlbG9uZyB0byBvbmUga2V5LCB0aGUgc3BlY2lhbCB2YWx1ZQogKiB3aXRoIG5hbWUgTlVMTCBpcyB0aGUgZGVmYXVsdCB2YWx1ZSB1c2VkIGJ5IHRoZSB3aW4zMQogKiBjb21wYXQgZnVuY3Rpb25zLgogKgogKiBDYWxscGF0aDoKICogUmVnUXVlcnlWYWx1ZTE2IC0+IFJlZ1F1ZXJ5VmFsdWUzMkEgLT4gUmVnUXVlcnlWYWx1ZUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnUXVlcnlWYWx1ZTMyVyAtPiBSZWdRdWVyeVZhbHVlRXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlRXgzMlcgW0FEVkFQSTMyLjE1OF0KICogUmV0cmlldmVzIHR5cGUgYW5kIGRhdGEgZm9yIGEgc3BlY2lmaWVkIG5hbWUgYXNzb2NpYXRlZCB3aXRoIGFuIG9wZW4ga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgIFtJXSAgIEhhbmRsZSBvZiBrZXkgdG8gcXVlcnkKICogICAgbHBWYWx1ZU5hbWUgICBbSV0gICBOYW1lIG9mIHZhbHVlIHRvIHF1ZXJ5CiAqICAgIGxwZHdSZXNlcnZlZCAgW0ldICAgUmVzZXJ2ZWQgLSBtdXN0IGJlIE5VTEwKICogICAgbHBkd1R5cGUgICAgICBbT10gICBBZGRyZXNzIG9mIGJ1ZmZlciBmb3IgdmFsdWUgdHlwZS4gIElmIE5VTEwsIHRoZSB0eXBlCiAqICAgICAgICAgICAgICAgICAgICAgICAgaXMgbm90IHJlcXVpcmVkLgogKiAgICBscGJEYXRhICAgICAgIFtPXSAgIEFkZHJlc3Mgb2YgZGF0YSBidWZmZXIuICBJZiBOVUxMLCB0aGUgYWN0dWFsIGRhdGEgaXMKICogICAgICAgICAgICAgICAgICAgICAgICBub3QgcmVxdWlyZWQuCiAqICAgIGxwY2JEYXRhICAgICAgW0kvT10gQWRkcmVzcyBvZiBkYXRhIGJ1ZmZlciBzaXplCiAqCiAqIFJFVFVSTlMgCiAqICAgIEVSUk9SX1NVQ0NFU1M6ICAgU3VjY2VzcwogKiAgICBFUlJPUl9NT1JFX0RBVEE6IFRoZSBzcGVjaWZpZWQgYnVmZmVyIGlzIG5vdCBiaWcgZW5vdWdoIHRvIGhvbGQgdGhlIGRhdGEKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXgzMlcoIEhLRVkgaGtleSwgTFBXU1RSIGxwVmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGxwYkRhdGEsIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUEtFWVNUUlVDVAlscGtleTsKCWludAkJaTsKCiAgICBUUkFDRShyZWcsIigweCV4LCVzLCVwLCVwLCVwLCVsZClcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLCBscGR3VHlwZSwgbHBiRGF0YSwgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICAvKiBSZXNlcnZlZCBtdXN0IGJlIE5VTEwgKGF0IGxlYXN0IGZvciBub3cpICovCiAgICBpZiAobHBkd1Jlc2VydmVkKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICAvKiBBbiBlbXB0eSBuYW1lIHN0cmluZyBpcyBlcXVpdmFsZW50IHRvIE5VTEwgKi8KICAgIGlmIChscFZhbHVlTmFtZSAmJiAhKmxwVmFsdWVOYW1lKQogICAgICAgIGxwVmFsdWVOYW1lID0gTlVMTDsKCglpZiAobHBWYWx1ZU5hbWU9PU5VTEwpIHsKICAgICAgICAgICAgICAgIC8qIFVzZSBrZXkncyB1bm5hbWVkIG9yIGRlZmF1bHQgdmFsdWUsIGlmIGFueSAqLwoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewogICAgICAgICAgICAgICAgLyogU2VhcmNoIGZvciB0aGUga2V5IG5hbWUgKi8KCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKAlscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYKCQkJCSFsc3RyY21waTMyVyhscFZhbHVlTmFtZSxscGtleS0+dmFsdWVzW2ldLm5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJfQoKCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCJLZXkgbm90IGZvdW5kXG4iKTsKCQlpZiAobHBWYWx1ZU5hbWU9PU5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogRW1wdHkga2V5bmFtZSBub3QgZm91bmQgKi8KCQkJaWYgKGxwYkRhdGEpIHsKCQkJCSooV0NIQVIqKWxwYkRhdGEgPSAwOwoJCQkJKmxwY2JEYXRhCT0gMjsKCQkJfQoJCQlpZiAobHBkd1R5cGUpCgkJCQkqbHBkd1R5cGUJPSBSRUdfU1o7CiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKHJlZywgIlJldHVybmluZyBhbiBlbXB0eSBzdHJpbmdcbiIpOwoJCQlyZXR1cm4gRVJST1JfU1VDQ0VTUzsKCQl9CgkJcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoJfQoKICAgIGlmIChscGR3VHlwZSkKICAgICAgICAqbHBkd1R5cGUgPSBscGtleS0+dmFsdWVzW2ldLnR5cGU7CgogICAgaWYgKGxwYkRhdGE9PU5VTEwpIHsKICAgICAgICAvKiBEYXRhIGlzIG5vdCByZXF1aXJlZCAqLwogICAgICAgIGlmIChscGNiRGF0YT09TlVMTCkgewogICAgICAgICAgICAvKiBBbmQgZGF0YSBzaXplIGlzIG5vdCByZXF1aXJlZCAqLwogICAgICAgICAgICAvKiBTbyBhbGwgdGhhdCBpcyByZXR1cm5lZCBpcyB0aGUgdHlwZSAoc2V0IGFib3ZlKSAqLwogICAgICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKICAgICAgICB9CiAgICAgICAgLyogU2V0IHRoZSBzaXplIHJlcXVpcmVkIGFuZCByZXR1cm4gc3VjY2VzcyAqLwogICAgICAgICpscGNiRGF0YSA9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwogICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwogICAgfQoKICAgIGlmICgqbHBjYkRhdGE8bHBrZXktPnZhbHVlc1tpXS5sZW4pIHsKICAgICAgICAvKiBUaGUgc2l6ZSB3YXMgc3BlY2lmaWVkLCBidXQgdGhlIGRhdGEgaXMgdG9vIGJpZyBmb3IgaXQgKi8KICAgICAgICAvKiBJbnN0ZWFkIG9mIHNldHRpbmcgaXQgdG8gTlVMTCwgZmlsbCBpbiB3aXRoIGFzIG11Y2ggYXMgcG9zc2libGUgKi8KICAgICAgICAvKiBCdXQgdGhlIGRvY3MgZG8gbm90IHNwZWNpZnkgaG93IHRvIGhhbmRsZSB0aGUgbHBiRGF0YSBoZXJlICovCiAgICAgICAgLyogKihXQ0hBUiopbHBiRGF0YT0gMDsgKi8KICAgICAgICBtZW1jcHkobHBiRGF0YSxscGtleS0+dmFsdWVzW2ldLmRhdGEsKmxwY2JEYXRhKTsKICAgICAgICAqbHBjYkRhdGEgPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKICAgICAgICByZXR1cm4gRVJST1JfTU9SRV9EQVRBOwogICAgfQoKICAgIG1lbWNweShscGJEYXRhLGxwa2V5LT52YWx1ZXNbaV0uZGF0YSxscGtleS0+dmFsdWVzW2ldLmxlbik7CgogICAgLyogRXh0cmEgZGVidWdnaW5nIG91dHB1dCAqLwogICAgaWYgKGxwZHdUeXBlKSB7CiAgICAgICAgc3dpdGNoKCpscGR3VHlwZSl7CiAgICAgICAgICAgIGNhc2UgUkVHX1NaOgogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCIgRGF0YShzeik9JXNcbiIsZGVidWdzdHJfdygoTFBDV1NUUilscGJEYXRhKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsIiBEYXRhKGR3b3JkKT0lbHhcbiIsIChEV09SRCkqbHBiRGF0YSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBSRUdfQklOQVJZOgogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCIgRGF0YShiaW5hcnkpXG4iKTsKICAgICAgICAgICAgICAgIC8qIElzIHRoZXJlIGEgd2F5IG9mIHByaW50aW5nIHRoaXMgaW4gcmVhZGFibGUgZm9ybT8gKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiVW5rbm93biBkYXRhIHR5cGUgJWxkXG4iLCAqbHBkd1R5cGUpOwogICAgICAgIH0gLyogc3dpdGNoICovCiAgICB9IC8qIGlmICovCgogICAgLyogU2V0IHRoZSBhY3R1YWwgc2l6ZSAqLwogICAgKmxwY2JEYXRhID0gbHBrZXktPnZhbHVlc1tpXS5sZW47CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZTMyVyBbQURWQVBJMzIuMTU5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUzMlcoIEhLRVkgaGtleSwgTFBXU1RSIGxwc3pTdWJLZXksIExQV1NUUiBscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CglIS0VZCXhoa2V5OwoJRFdPUkQJcmV0LGxwZHdUeXBlOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGxwc3pEYXRhLAogICAgICAgICAgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIC8qIE9ubHkgb3BlbiBzdWJrZXksIGlmIHdlIHJlYWxseSBkbyBkZXNjZW5kICovCiAgICBpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewogICAgICAgIHJldCA9IFJlZ09wZW5LZXkzMlcoIGhrZXksIGxwc3pTdWJLZXksICZ4aGtleSApOwogICAgICAgIGlmIChyZXQgIT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgICAgICBXQVJOKHJlZywgIkNvdWxkIG5vdCBvcGVuICVzXG4iLCBkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICB9IGVsc2UKICAgICAgICB4aGtleSA9IGhrZXk7CgogICAgbHBkd1R5cGUgPSBSRUdfU1o7CiAgICByZXQgPSBSZWdRdWVyeVZhbHVlRXgzMlcoIHhoa2V5LCBOVUxMLCBOVUxMLCAmbHBkd1R5cGUsIChMUEJZVEUpbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwY2JEYXRhICk7CiAgICBpZiAoeGhrZXkgIT0gaGtleSkKICAgICAgICBSZWdDbG9zZUtleSh4aGtleSk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlRXgzMkEgW0FEVkFQSTMyLjE1N10KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXgzMkEoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBscGJEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBXU1RSCWxwc3pWYWx1ZU5hbWVXOwoJTFBCWVRFCWJ1ZjsKCURXT1JECXJldCxteXhsZW47CglEV09SRAkqbXlsZW47CglEV09SRAl0eXBlOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVwLCVwLCVsZClcbiIsIGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBscHN6VmFsdWVOYW1lVyA9IGxwc3pWYWx1ZU5hbWU/c3RyZHVwQTJXKGxwc3pWYWx1ZU5hbWUpOk5VTEw7CgogICAgLyogV2h5IHdvdWxkIHRoaXMgYmUgc2V0PyBJdCBpcyBqdXN0IGFuIG91dHB1dCAqLwogICAgaWYgKGxwZHdUeXBlKQogICAgICAgIHR5cGUgPSAqbHBkd1R5cGU7CgoJaWYgKGxwYkRhdGEpIHsKCQlteXhsZW4gID0gMDsKCQlteWxlbgk9ICZteXhsZW47CgkJYnVmCT0geG1hbGxvYyg0KTsKICAgICAgICAgICAgICAgIC8qIE9ubHkgZ2V0IHRoZSBzaXplIGZvciBub3cgKi8KCQlyZXQgPSBSZWdRdWVyeVZhbHVlRXgzMlcoIGhrZXksIGxwc3pWYWx1ZU5hbWVXLCBscGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0eXBlLCBidWYsIG15bGVuICk7CgkJZnJlZShidWYpOwoJCWlmIChyZXQ9PUVSUk9SX01PUkVfREFUQSkgewoJCQlidWYJPSAoTFBCWVRFKXhtYWxsb2MoKm15bGVuKTsKCQl9IGVsc2UgewoJCQlidWYJPSAoTFBCWVRFKXhtYWxsb2MoMiooKmxwY2JEYXRhKSk7CgkJCW15eGxlbiAgPSAyKigqbHBjYkRhdGEpOwoJCX0KCX0gZWxzZSB7CgkJLyogRGF0YSBpcyBub3QgcmVxdWlyZWQgKi8KCQlidWY9TlVMTDsKCQlpZiAobHBjYkRhdGEpIHsKCQkJbXl4bGVuCT0gKmxwY2JEYXRhKjI7CgkJCW15bGVuCT0gJm15eGxlbjsKCQl9IGVsc2UKCQkJbXlsZW4JPSBOVUxMOwoJfQoKICAgICAgICAvKiBOb3cgZ2V0IHRoZSBkYXRhICovCglyZXQgPSBSZWdRdWVyeVZhbHVlRXgzMlcoIGhrZXksIGxwc3pWYWx1ZU5hbWVXLCBscGR3UmVzZXJ2ZWQsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmLCBteWxlbiApOwoJaWYgKGxwZHdUeXBlKSAKCQkqbHBkd1R5cGU9dHlwZTsKCglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJaWYgKGJ1ZikgewoJCQlpZiAoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgewoJCQkJLyogY29udmVydCBVTklDT0RFIHRvIEFTQ0lJICovCgkJCQlsc3RyY3B5V3RvQShscGJEYXRhLChMUFdTVFIpYnVmKTsKCQkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJCQl9IGVsc2UgewoJCQkJaWYgKG15eGxlbj4qbHBjYkRhdGEpCgkJCQkJcmV0CT0gRVJST1JfTU9SRV9EQVRBOwoJCQkJZWxzZQoJCQkJCW1lbWNweShscGJEYXRhLGJ1ZixteXhsZW4pOwoKCQkJCSpscGNiRGF0YQk9IG15eGxlbjsKCQkJfQoJCX0gZWxzZSB7CgkJCWlmICgoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgJiYgbHBjYkRhdGEpCgkJCQkqbHBjYkRhdGEJPSBteXhsZW4vMjsKCQl9Cgl9IGVsc2UgewoJCWlmICgoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgJiYgbHBjYkRhdGEpCgkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJfQoKICAgIGlmKGJ1ZikgZnJlZShidWYpOwogICAgaWYobHBzelZhbHVlTmFtZVcpIGZyZWUobHBzelZhbHVlTmFtZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZUV4MTYgW0tFUk5FTC4yMjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgbHBiRGF0YSwgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVwLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeDMyQSggaGtleSwgbHBzelZhbHVlTmFtZSwgbHBkd1Jlc2VydmVkLCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwYkRhdGEsIGxwY2JEYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWUzMkEgW0FEVkFQSTMyLjE1Nl0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMzJBKCBIS0VZIGhrZXksIExQU1RSIGxwc3pTdWJLZXksIExQU1RSIGxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIEhLRVkgeGhrZXk7CiAgICBEV09SRCByZXQsIGR3VHlwZTsKCiAgICBUUkFDRShyZWcsIigleCwlcywlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxscHN6RGF0YSwKICAgICAgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewogICAgICAgIHJldCA9IFJlZ09wZW5LZXkxNiggaGtleSwgbHBzelN1YktleSwgJnhoa2V5ICk7CiAgICAgICAgaWYoIHJldCAhPSBFUlJPUl9TVUNDRVNTICkKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgIH0gZWxzZQogICAgICAgIHhoa2V5ID0gaGtleTsKCiAgICBkd1R5cGUgPSBSRUdfU1o7CiAgICByZXQgPSBSZWdRdWVyeVZhbHVlRXgzMkEoIHhoa2V5LCBOVUxMLE5VTEwsICZkd1R5cGUsIChMUEJZVEUpbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwY2JEYXRhICk7CiAgICBpZiggeGhrZXkgIT0gaGtleSApCiAgICAgICAgUmVnQ2xvc2VLZXkoIHhoa2V5ICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlMTYgW1NIRUxMLjZdIFtLRVJORUwuMjI0XQogKgogKiBOT1RFUwogKiAgICBJcyB0aGlzIEhBQ0sgc3RpbGwgYXBwbGljYWJsZT8KICoKICogSEFDSwogKiAgICBUaGUgMTZiaXQgUmVnUXVlcnlWYWx1ZSBkb2Vzbid0IGhhbmRsZSBzZWxlY3RvcmJsb2NrcyBhbnl3YXksIHNvIHdlIGp1c3QKICogICAgbWFzayBvdXQgdGhlIGhpZ2ggMTYgYml0LiAgVGhpcyAobm90IHNvIG11Y2ggaW5jaWRlbnRseSkgaG9wZWZ1bGx5IGZpeGVzCiAqICAgIEFsZHVzIEZINCkKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelN1YktleSwgTFBTVFIgbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxscHN6RGF0YSwKICAgICAgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBpZiAobHBjYkRhdGEpCiAgICAgICAgKmxwY2JEYXRhICY9IDB4RkZGRjsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlMzJBKGhrZXksbHBzelN1YktleSxscHN6RGF0YSxscGNiRGF0YSk7Cn0KCgovKgogKiBTZXR0aW5nIHZhbHVlcyBvZiBSZWdpc3RyeSBrZXlzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdTZXRWYWx1ZTE2IC0+IFJlZ1NldFZhbHVlMzJBIC0+IFJlZ1NldFZhbHVlRXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1NldFZhbHVlMzJXICAgLT4gUmVnU2V0VmFsdWVFeDMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgzMlcgW0FEVkFQSTMyLjE3MF0KICogU2V0cyB0aGUgZGF0YSBhbmQgdHlwZSBvZiBhIHZhbHVlIHVuZGVyIGEgcmVnaXN0ZXIga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgIFtJXSBIYW5kbGUgb2Yga2V5IHRvIHNldCB2YWx1ZSBmb3IKICogICAgbHBzelZhbHVlTmFtZSBbSV0gTmFtZSBvZiB2YWx1ZSB0byBzZXQKICogICAgZHdSZXNlcnZlZCAgICBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIHplcm8KICogICAgZHdUeXBlICAgICAgICBbSV0gRmxhZyBmb3IgdmFsdWUgdHlwZQogKiAgICBscGJEYXRhICAgICAgIFtJXSBBZGRyZXNzIG9mIHZhbHVlIGRhdGEKICogICAgY2JEYXRhICAgICAgICBbSV0gU2l6ZSBvZiB2YWx1ZSBkYXRhCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDMyVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzelZhbHVlTmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1Jlc2VydmVkLCBEV09SRCBkd1R5cGUsIExQQllURSBscGJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgY2JEYXRhKQp7CiAgICBMUEtFWVNUUlVDVCBscGtleTsKICAgIGludCBpOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuIiwgaGtleSwgZGVidWdzdHJfdyhscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsIGR3VHlwZSwgbHBiRGF0YSwgY2JEYXRhKTsKCiAgICBzd2l0Y2ggKGR3VHlwZSkgewogICAgICAgIGNhc2UgUkVHX1NaOgogICAgICAgICAgICBUUkFDRShyZWcsIiBEYXRhKHN6KT0lc1xuIiwgZGVidWdzdHJfdygoTFBDV1NUUilscGJEYXRhKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX0JJTkFSWToKICAgICAgICAgICAgVFJBQ0UocmVnLCIgRGF0YShiaW5hcnkpXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgICAgIFRSQUNFKHJlZywiIERhdGEoZHdvcmQpPSVseFxuIiwgKERXT1JEKWxwYkRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBUUkFDRShyZWcsIlVua25vd24gdHlwZTogJWxkXG4iLCBkd1R5cGUpOwogICAgfQoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKCWxwa2V5LT5mbGFncyB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgoJaWYgKGxwc3pWYWx1ZU5hbWU9PU5VTEwpIHsKICAgICAgICAgICAgIC8qIFNldHMgdHlwZSBhbmQgbmFtZSBmb3Iga2V5J3MgdW5uYW1lZCBvciBkZWZhdWx0IHZhbHVlICovCgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCX0gZWxzZSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmICgJbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmCgkJCQkhbHN0cmNtcGkzMlcobHBzelZhbHVlTmFtZSxscGtleS0+dmFsdWVzW2ldLm5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CgkJbHBrZXktPnZhbHVlcyA9IChMUEtFWVZBTFVFKXhyZWFsbG9jKAoJCQkJCWxwa2V5LT52YWx1ZXMsCgkJCQkJKGxwa2V5LT5ucm9mdmFsdWVzKzEpKnNpemVvZihLRVlWQUxVRSkKCQkJCSk7CgkJbHBrZXktPm5yb2Z2YWx1ZXMrKzsKCQltZW1zZXQobHBrZXktPnZhbHVlcytpLCdcMCcsc2l6ZW9mKEtFWVZBTFVFKSk7Cgl9CglpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKSB7CgkJaWYgKGxwc3pWYWx1ZU5hbWUpCgkJCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSA9IHN0cmR1cFcobHBzelZhbHVlTmFtZSk7CgkJZWxzZQoJCQlscGtleS0+dmFsdWVzW2ldLm5hbWUgPSBOVUxMOwoJfQoJbHBrZXktPnZhbHVlc1tpXS5sZW4JPSBjYkRhdGE7CglscGtleS0+dmFsdWVzW2ldLnR5cGUJPSBkd1R5cGU7CglpZiAobHBrZXktPnZhbHVlc1tpXS5kYXRhICE9TlVMTCkKCQlmcmVlKGxwa2V5LT52YWx1ZXNbaV0uZGF0YSk7CglscGtleS0+dmFsdWVzW2ldLmRhdGEJPSAoTFBCWVRFKXhtYWxsb2MoY2JEYXRhKTsKCWxwa2V5LT52YWx1ZXNbaV0ubGFzdG1vZGlmaWVkID0gdGltZShOVUxMKTsKCW1lbWNweShscGtleS0+dmFsdWVzW2ldLmRhdGEsbHBiRGF0YSxjYkRhdGEpOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgzMkEgW0FEVkFQSTMyLjE2OV0KICoKICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MzJBKCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1Jlc2VydmVkLCBEV09SRCBkd1R5cGUsIExQQllURSBscGJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgY2JEYXRhICkKewoJTFBCWVRFCWJ1ZjsKCUxQV1NUUglscHN6VmFsdWVOYW1lVzsKCURXT1JECXJldDsKCiAgICBUUkFDRShyZWcsIigleCwlcywlbGQsJWxkLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEpOwoKCWlmICgoMTw8ZHdUeXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJYnVmPShMUEJZVEUpc3RyZHVwQTJXKGxwYkRhdGEpOwoJCWNiRGF0YT0yKnN0cmxlbihscGJEYXRhKSsyOwoJfSBlbHNlCgkJYnVmPWxwYkRhdGE7CglpZiAobHBzelZhbHVlTmFtZSkKCQlscHN6VmFsdWVOYW1lVyA9IHN0cmR1cEEyVyhscHN6VmFsdWVOYW1lKTsKCWVsc2UKCQlscHN6VmFsdWVOYW1lVyA9IE5VTEw7CglyZXQ9UmVnU2V0VmFsdWVFeDMyVyhoa2V5LGxwc3pWYWx1ZU5hbWVXLGR3UmVzZXJ2ZWQsZHdUeXBlLGJ1ZixjYkRhdGEpOwoJaWYgKGxwc3pWYWx1ZU5hbWVXKQoJCWZyZWUobHBzelZhbHVlTmFtZVcpOwoJaWYgKGJ1ZiE9bHBiRGF0YSkKCQlmcmVlKGJ1Zik7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZUV4MTYgW0tFUk5FTC4yMjZdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZU5hbWUsIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsIERXT1JEIGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlTmFtZSksCiAgICAgICAgICBkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YSk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVFeDMyQSggaGtleSwgbHBzelZhbHVlTmFtZSwgZHdSZXNlcnZlZCwgZHdUeXBlLCBscGJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNiRGF0YSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZTMyVwlbQURWQVBJMzIuMTcxXQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgRFdPUkQgZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbHBzekRhdGEsIERXT1JEIGNiRGF0YSApCnsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQ7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsCgkJaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGR3VHlwZSxkZWJ1Z3N0cl93KGxwc3pEYXRhKSxjYkRhdGEKCSk7CglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldD1SZWdDcmVhdGVLZXkzMlcoaGtleSxscHN6U3ViS2V5LCZ4aGtleSk7CgkJaWYgKHJldCE9RVJST1JfU1VDQ0VTUykKCQkJcmV0dXJuIHJldDsKCX0gZWxzZQoJCXhoa2V5PWhrZXk7CglpZiAoZHdUeXBlIT1SRUdfU1opIHsKCQlUUkFDRShyZWcsImR3VHlwZT0lbGQgLSBDaGFuZ2luZyB0byBSRUdfU1pcbiIsZHdUeXBlKTsKCQlkd1R5cGU9UkVHX1NaOwoJfQoJaWYgKGNiRGF0YSE9Mipsc3RybGVuMzJXKGxwc3pEYXRhKSsyKSB7CgkJVFJBQ0UocmVnLCJMZW49JWxkICE9IHN0cmxlbiglcykrMT0lZCFcbiIsCgkJCWNiRGF0YSxkZWJ1Z3N0cl93KGxwc3pEYXRhKSwyKmxzdHJsZW4zMlcobHBzekRhdGEpKzIKCQkpOwoJCWNiRGF0YT0yKmxzdHJsZW4zMlcobHBzekRhdGEpKzI7Cgl9CglyZXQ9UmVnU2V0VmFsdWVFeDMyVyh4aGtleSxOVUxMLDAsZHdUeXBlLChMUEJZVEUpbHBzekRhdGEsY2JEYXRhKTsKCWlmIChoa2V5IT14aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZTMyQSBbQURWQVBJMzIuMTY4XQogKgogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwc3pEYXRhLCBEV09SRCBjYkRhdGEgKQp7CglEV09SRAlyZXQ7CglIS0VZCXhoa2V5OwoKCVRSQUNFKHJlZywiKCV4LCVzLCVsZCwlcywlbGQpXG4iLGhrZXksbHBzelN1YktleSxkd1R5cGUsbHBzekRhdGEsY2JEYXRhKTsKCWlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CgkJcmV0PVJlZ0NyZWF0ZUtleTE2KGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleT1oa2V5OwoKCWlmIChkd1R5cGUhPVJFR19TWikgewoJCVRSQUNFKHJlZywiZHdUeXBlPSVsZCFcbiIsZHdUeXBlKTsKCQlkd1R5cGU9UkVHX1NaOwoJfQoJaWYgKGNiRGF0YSE9c3RybGVuKGxwc3pEYXRhKSsxKQoJCWNiRGF0YT1zdHJsZW4obHBzekRhdGEpKzE7CglyZXQ9UmVnU2V0VmFsdWVFeDMyQSh4aGtleSxOVUxMLDAsZHdUeXBlLChMUEJZVEUpbHBzekRhdGEsY2JEYXRhKTsKCWlmICh4aGtleSE9aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZTE2IFtLRVJORUwuMjIxXSBbU0hFTEwuNV0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRAlkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBzekRhdGEsIERXT1JEIGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlcywlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxkd1R5cGUsCiAgICAgICAgICBkZWJ1Z3N0cl9hKGxwc3pEYXRhKSxjYkRhdGEpOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlMzJBKGhrZXksbHBzelN1YktleSxkd1R5cGUsbHBzekRhdGEsY2JEYXRhKTsKfQoKCi8qIAogKiBLZXkgRW51bWVyYXRpb24KICoKICogQ2FsbHBhdGg6CiAqIFJlZ0VudW1LZXkxNiAtPiBSZWdFbnVtS2V5MzJBIC0+IFJlZ0VudW1LZXlFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ0VudW1LZXkzMlcgICAtPiBSZWdFbnVtS2V5RXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5RXgzMlcgW0FEVkFQSTMyLjEzOV0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICBbSV0gSGFuZGxlIHRvIGtleSB0byBlbnVtZXJhdGUKICogICAgaVN1YktleSAgICAgIFtJXSBJbmRleCBvZiBzdWJrZXkgdG8gZW51bWVyYXRlCiAqICAgIGxwc3pOYW1lICAgICBbT10gQnVmZmVyIGZvciBzdWJrZXkgbmFtZQogKiAgICBscGNjaE5hbWUgICAgW09dIFNpemUgb2Ygc3Via2V5IGJ1ZmZlcgogKiAgICBscGR3UmVzZXJ2ZWQgW0ldIFJlc2VydmVkCiAqICAgIGxwc3pDbGFzcyAgICBbT10gQnVmZmVyIGZvciBjbGFzcyBzdHJpbmcKICogICAgbHBjY2hDbGFzcyAgIFtPXSBTaXplIG9mIGNsYXNzIGJ1ZmZlcgogKiAgICBmdCAgICAgICAgICAgW09dIFRpbWUga2V5IGxhc3Qgd3JpdHRlbiB0bwogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlFeDMyVyggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFdTVFIgbHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hOYW1lLCBMUERXT1JEIGxwZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGxwc3pDbGFzcywgTFBEV09SRCBscGNjaENsYXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRVRJTUUgKmZ0ICkKewoJTFBLRVlTVFJVQ1QJbHBrZXksbHB4a2V5OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQsJXAsJXAsJXAsJXApXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSwKICAgICAgICAgICpscGNjaE5hbWUsbHBkd1Jlc2VydmVkLGxwc3pDbGFzcyxscGNjaENsYXNzLGZ0KTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglpZiAoIWxwa2V5LT5uZXh0c3ViKQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoJbHB4a2V5PWxwa2V5LT5uZXh0c3ViOwoKICAgIC8qIFRyYXZlcnNlIHRoZSBzdWJrZXlzICovCgl3aGlsZSAoaVN1YmtleSAmJiBscHhrZXkpIHsKCQlpU3Via2V5LS07CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCglpZiAoaVN1YmtleSB8fCAhbHB4a2V5KQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoJaWYgKGxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKSsxPipscGNjaE5hbWUpCgkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCW1lbWNweShscHN6TmFtZSxscHhrZXktPmtleW5hbWUsbHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpKjIrMik7CgogICAgICAgIGlmICgqbHBjY2hOYW1lKQogICAgICAgICAgICAqbHBjY2hOYW1lID0gbHN0cmxlbjMyVyhscHN6TmFtZSk7CgoJaWYgKGxwc3pDbGFzcykgewoJCS8qIEZJWE1FOiB3aGF0IHNob3VsZCB3ZSB3cml0ZSBpbnRvIGl0PyAqLwoJCSpscHN6Q2xhc3MJPSAwOwoJCSpscGNjaENsYXNzCT0gMjsKCX0KCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5MzJXIFtBRFZBUEkzMi4xNDBdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTMyVyggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFdTVFIgbHBzek5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbHBjY2hOYW1lICkKewogICAgRklMRVRJTUUJZnQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZSk7CiAgICByZXR1cm4gUmVnRW51bUtleUV4MzJXKGhrZXksaVN1YmtleSxscHN6TmFtZSwmbHBjY2hOYW1lLE5VTEwsTlVMTCxOVUxMLCZmdCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXlFeDMyQSBbQURWQVBJMzIuMTM4XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlFeDMyQSggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE5hbWUsIExQRFdPUkQgbHBkd1Jlc2VydmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgbHBzekNsYXNzLCBMUERXT1JEIGxwY2NoQ2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFVElNRSAqZnQgKQp7CglEV09SRAlyZXQsbHBjY2hOYW1lVyxscGNjaENsYXNzVzsKCUxQV1NUUglscHN6TmFtZVcsbHBzekNsYXNzVzsKCgoJVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZCwlcCwlcCwlcCwlcClcbiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLCpscGNjaE5hbWUsbHBkd1Jlc2VydmVkLGxwc3pDbGFzcyxscGNjaENsYXNzLGZ0CgkpOwoJaWYgKGxwc3pOYW1lKSB7CgkJbHBzek5hbWVXCT0gKExQV1NUUil4bWFsbG9jKCpscGNjaE5hbWUqMik7CgkJbHBjY2hOYW1lVwk9ICpscGNjaE5hbWU7Cgl9IGVsc2UgewoJCWxwc3pOYW1lVwk9IE5VTEw7CgkJbHBjY2hOYW1lVyAJPSAwOwoJfQoJaWYgKGxwc3pDbGFzcykgewoJCWxwc3pDbGFzc1cJCT0gKExQV1NUUil4bWFsbG9jKCpscGNjaENsYXNzKjIpOwoJCWxwY2NoQ2xhc3NXCT0gKmxwY2NoQ2xhc3M7Cgl9IGVsc2UgewoJCWxwc3pDbGFzc1cJPTA7CgkJbHBjY2hDbGFzc1c9MDsKCX0KCXJldD1SZWdFbnVtS2V5RXgzMlcoCgkJaGtleSwKCQlpU3Via2V5LAoJCWxwc3pOYW1lVywKCQkmbHBjY2hOYW1lVywKCQlscGR3UmVzZXJ2ZWQsCgkJbHBzekNsYXNzVywKCQkmbHBjY2hDbGFzc1csCgkJZnQKCSk7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJbHN0cmNweVd0b0EobHBzek5hbWUsbHBzek5hbWVXKTsKCQkqbHBjY2hOYW1lPXN0cmxlbihscHN6TmFtZSk7CgkJaWYgKGxwc3pDbGFzc1cpIHsKCQkJbHN0cmNweVd0b0EobHBzekNsYXNzLGxwc3pDbGFzc1cpOwoJCQkqbHBjY2hDbGFzcz1zdHJsZW4obHBzekNsYXNzKTsKCQl9Cgl9CglpZiAobHBzek5hbWVXKQoJCWZyZWUobHBzek5hbWVXKTsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5MzJBIFtBRFZBUEkzMi4xMzddCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTMyQSggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGxwY2NoTmFtZSApCnsKICAgIEZJTEVUSU1FCWZ0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwogICAgcmV0dXJuIFJlZ0VudW1LZXlFeDMyQSggaGtleSwgaVN1YmtleSwgbHBzek5hbWUsICZscGNjaE5hbWUsIE5VTEwsIE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgJmZ0ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXkxNiBbU0hFTEwuN10gW0tFUk5FTC4yMTZdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTE2KCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKICAgIHJldHVybiBSZWdFbnVtS2V5MzJBKCBoa2V5LCBpU3Via2V5LCBscHN6TmFtZSwgbHBjY2hOYW1lKTsKfQoKCi8qIAogKiBFbnVtZXJhdGUgUmVnaXN0cnkgVmFsdWVzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdFbnVtVmFsdWUxNiAtPiBSZWdFbnVtVmFsdWUzMkEgLT4gUmVnRW51bVZhbHVlMzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bVZhbHVlMzJXIFtBRFZBUEkzMi4xNDJdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICBbSV0gSGFuZGxlIHRvIGtleSB0byBxdWVyeQogKiAgICBpVmFsdWUgICAgICBbSV0gSW5kZXggb2YgdmFsdWUgdG8gcXVlcnkKICogICAgbHBzelZhbHVlICAgW09dIFZhbHVlIHN0cmluZwogKiAgICBscGNjaFZhbHVlICBbT10gU2l6ZSBvZiB2YWx1ZSBidWZmZXIKICogICAgbHBkUmVzZXJ2ZWQgW0ldIFJlc2VydmVkCiAqICAgIGxwZHdUeXBlICAgIFtPXSBUeXBlIGNvZGUKICogICAgbHBiRGF0YSAgICAgW09dIFZhbHVlIGRhdGEKICogICAgbHBjYkRhdGEgICAgW09dIFNpemUgb2YgZGF0YSBidWZmZXIKICoKICogTm90ZTogIHdpZGUgY2hhcmFjdGVyIGZ1bmN0aW9ucyB0aGF0IHRha2UgYW5kL29yIHJldHVybiAiY2hhcmFjdGVyIGNvdW50cyIKICogIHVzZSBUQ0hBUiAodGhhdCBpcyB1bnNpZ25lZCBzaG9ydCBvciBjaGFyKSBub3QgYnl0ZSBjb3VudHMuCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMzJXKCBIS0VZIGhrZXksIERXT1JEIGlWYWx1ZSwgTFBXU1RSIGxwc3pWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaFZhbHVlLCBMUERXT1JEIGxwZFJlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsZGVidWdzdHJfdyhscHN6VmFsdWUpLAogICAgICAgICAgbHBjY2hWYWx1ZSxscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBpZiAobHBrZXktPm5yb2Z2YWx1ZXMgPD0gaVZhbHVlKQogICAgICAgIHJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoKICAgIC8qIEZJWE1FOiBTaG91bGQgdGhpcyBiZSBscGtleS0+dmFsdWVzICsgaVZhbHVlICogc2l6ZW9mKEtFWVZBTFVFKT8gKi8KICAgIHZhbCA9IGxwa2V5LT52YWx1ZXMgKyBpVmFsdWU7CgoJaWYgKHZhbC0+bmFtZSkgewoJICAgICAgICBpZiAobHN0cmxlbjMyVyh2YWwtPm5hbWUpKzE+KmxwY2NoVmFsdWUpIHsKCQkJKmxwY2NoVmFsdWUgPSBsc3RybGVuMzJXKHZhbC0+bmFtZSkrMTsKCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQl9CgkJbWVtY3B5KGxwc3pWYWx1ZSx2YWwtPm5hbWUsMipsc3RybGVuMzJXKHZhbC0+bmFtZSkrMik7CgkJKmxwY2NoVmFsdWU9bHN0cmxlbjMyVyh2YWwtPm5hbWUpOwoJfSBlbHNlIHsKCQkqbHBzelZhbHVlCT0gMDsKCQkqbHBjY2hWYWx1ZQk9IDA7Cgl9CgogICAgLyogQ2FuIGJlIE5VTEwgaWYgdGhlIHR5cGUgY29kZSBpcyBub3QgcmVxdWlyZWQgKi8KICAgIGlmIChscGR3VHlwZSkKICAgICAgICAqbHBkd1R5cGUgPSB2YWwtPnR5cGU7CgoJaWYgKGxwYkRhdGEpIHsKCQlpZiAodmFsLT5sZW4+KmxwY2JEYXRhKQoJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCW1lbWNweShscGJEYXRhLHZhbC0+ZGF0YSx2YWwtPmxlbik7CgkJKmxwY2JEYXRhID0gdmFsLT5sZW47Cgl9CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bVZhbHVlMzJBIFtBRFZBUEkzMi4xNDFdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMzJBKCBIS0VZIGhrZXksIERXT1JEIGlWYWx1ZSwgTFBTVFIgbHBzelZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoVmFsdWUsIExQRFdPUkQgbHBkUmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1R5cGUsIExQQllURSBscGJEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKCUxQV1NUUglscHN6VmFsdWVXOwoJTFBCWVRFCWxwYkRhdGFXOwoJRFdPUkQJcmV0LGxwY2JEYXRhVzsKCURXT1JEIGR3VHlwZTsKCglUUkFDRShyZWcsIigleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLGhrZXksaVZhbHVlLGxwc3pWYWx1ZSxscGNjaFZhbHVlLAoJCWxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEpOwoKCWxwc3pWYWx1ZVcgPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoVmFsdWUqMik7CglpZiAobHBiRGF0YSkgewoJCWxwYkRhdGFXID0gKExQQllURSl4bWFsbG9jKCpscGNiRGF0YSoyKTsKCQlscGNiRGF0YVcgPSAqbHBjYkRhdGE7Cgl9IGVsc2UKCQlscGJEYXRhVyA9IE5VTEw7CgoJcmV0ID0gUmVnRW51bVZhbHVlMzJXKCBoa2V5LCBpVmFsdWUsIGxwc3pWYWx1ZVcsIGxwY2NoVmFsdWUsIAoJCQkJbHBkUmVzZXJ2ZWQsICZkd1R5cGUsIGxwYkRhdGFXLCAmbHBjYkRhdGFXICk7CgoJaWYgKGxwZHdUeXBlKQoJCSpscGR3VHlwZSA9IGR3VHlwZTsKCglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJbHN0cmNweVd0b0EobHBzelZhbHVlLGxwc3pWYWx1ZVcpOwoJCWlmIChscGJEYXRhKSB7CgkJCWlmICgoMTw8ZHdUeXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJCQlsc3RyY3B5V3RvQShscGJEYXRhLChMUFdTVFIpbHBiRGF0YVcpOwoJCQl9IGVsc2UgewoJCQkJaWYgKGxwY2JEYXRhVyA+ICpscGNiRGF0YSkKCQkJCQlyZXQJPSBFUlJPUl9NT1JFX0RBVEE7CgkJCQllbHNlCgkJCQkJbWVtY3B5KGxwYkRhdGEsbHBiRGF0YVcsbHBjYkRhdGFXKTsKCQkJfQoJCQkqbHBjYkRhdGEgPSBscGNiRGF0YVc7CgkJfQoJfQogICAgaWYgKGxwYkRhdGFXKSBmcmVlKGxwYkRhdGFXKTsKICAgIGlmIChscHN6VmFsdWVXKSBmcmVlKGxwc3pWYWx1ZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bVZhbHVlMTYgW0tFUk5FTC4yMjNdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMTYoIEhLRVkgaGtleSwgRFdPUkQgaVZhbHVlLCBMUFNUUiBscHN6VmFsdWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hWYWx1ZSwgTFBEV09SRCBscGRSZXNlcnZlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLGhrZXksaVZhbHVlLGxwc3pWYWx1ZSxscGNjaFZhbHVlLAogICAgICAgICAgbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YSk7CiAgICByZXR1cm4gUmVnRW51bVZhbHVlMzJBKCBoa2V5LCBpVmFsdWUsIGxwc3pWYWx1ZSwgbHBjY2hWYWx1ZSwgbHBkUmVzZXJ2ZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBkd1R5cGUsIGxwYkRhdGEsIGxwY2JEYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nsb3NlS2V5IFtTSEVMTC4zXSBbS0VSTkVMLjIyMF0gW0FEVkFQSTMyLjEyNl0KICogUmVsZWFzZXMgdGhlIGhhbmRsZSBvZiB0aGUgc3BlY2lmaWVkIGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byBjbG9zZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0Nsb3NlS2V5KCBIS0VZIGhrZXkgKQp7CiAgICBUUkFDRShyZWcsIigleClcbiIsaGtleSk7CgogICAgLyogVGhlIHN0YW5kYXJkIGhhbmRsZXMgYXJlIGFsbG93ZWQgdG8gc3VjY2VlZCwgZXZlbiB0aG91Z2ggdGhleSBhcmUgbm90CiAgICAgICBjbG9zZWQgKi8KICAgIGlmIChpc19zdGFuZGFyZF9oa2V5KGhrZXkpKQogICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwoKICAgIHJldHVybiByZW1vdmVfaGFuZGxlKGhrZXkpOwp9CgoKLyogCiAqIERlbGV0ZSByZWdpc3RyeSBrZXkKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZUtleTE2IC0+IFJlZ0RlbGV0ZUtleTMyQSAtPiBSZWdEZWxldGVLZXkzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVLZXkzMlcgW0FEVkFQSTMyLjEzNF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldIEhhbmRsZSB0byBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5IFtJXSBOYW1lIG9mIHN1YmtleSB0byBkZWxldGUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkzMlcoIEhLRVkgaGtleSwgTFBXU1RSIGxwc3pTdWJLZXkgKQp7CglMUEtFWVNUUlVDVAkqbHBscFByZXZLZXksbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CgogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgLyogU3Via2V5IHBhcmFtIGNhbm5vdCBiZSBOVUxMICovCiAgICBpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KQogICAgICAgIHJldHVybiBFUlJPUl9CQURLRVk7CgogICAgLyogV2UgbmVlZCB0byBrbm93IHRoZSBwcmV2aW91cyBrZXkgaW4gdGhlIGhpZXIuICovCglzcGxpdF9rZXlwYXRoKGxwc3pTdWJLZXksJndwcywmd3BjKTsKCWkgCT0gMDsKCWxweGtleQk9IGxwTmV4dEtleTsKCXdoaWxlIChpPHdwYy0xKSB7CgkJbHB4a2V5PWxwTmV4dEtleS0+bmV4dHN1YjsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCVRSQUNFKHJlZywgIiAgU2Nhbm5pbmcgWyVzXVxuIiwKCQkJCSAgICAgZGVidWdzdHJfdyhscHhrZXktPmtleW5hbWUpKTsKCQkJaWYgKCFsc3RyY21waTMyVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJCWJyZWFrOwoJCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJCX0KCQlpZiAoIWxweGtleSkgewoJCQlGUkVFX0tFWV9QQVRIOwoJCQlUUkFDRShyZWcsICIgIE5vdCBmb3VuZC5cbiIpOwoJCQkvKiBub3QgZm91bmQgaXMgc3VjY2VzcyAqLwoJCQlyZXR1cm4gRVJST1JfU1VDQ0VTUzsKCQl9CgkJaSsrOwoJCWxwTmV4dEtleQk9IGxweGtleTsKCX0KCWxweGtleQk9IGxwTmV4dEtleS0+bmV4dHN1YjsKCWxwbHBQcmV2S2V5ID0gJihscE5leHRLZXktPm5leHRzdWIpOwoJd2hpbGUgKGxweGtleSkgewoJCVRSQUNFKHJlZywgIiAgU2Nhbm5pbmcgWyVzXVxuIiwKCQkJICAgICBkZWJ1Z3N0cl93KGxweGtleS0+a2V5bmFtZSkpOwoJCWlmICghbHN0cmNtcGkzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCWJyZWFrOwoJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCWxweGtleQkJPSBscHhrZXktPm5leHQ7Cgl9CgoJaWYgKCFscHhrZXkpIHsKCQlGUkVFX0tFWV9QQVRIOwoJCVdBUk4ocmVnICwgIiAgTm90IGZvdW5kLlxuIik7CgkJcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoJfQoKCWlmIChscHhrZXktPm5leHRzdWIpIHsKCQlGUkVFX0tFWV9QQVRIOwoJCVdBUk4ocmVnICwgIiAgTm90IGVtcHR5LlxuIik7CgkJcmV0dXJuIEVSUk9SX0NBTlRXUklURTsKCX0KCSpscGxwUHJldktleQk9IGxweGtleS0+bmV4dDsKCWZyZWUobHB4a2V5LT5rZXluYW1lKTsKCWlmIChscHhrZXktPmNsYXNzKQoJCWZyZWUobHB4a2V5LT5jbGFzcyk7CglpZiAobHB4a2V5LT52YWx1ZXMpCgkJZnJlZShscHhrZXktPnZhbHVlcyk7CglmcmVlKGxweGtleSk7CglGUkVFX0tFWV9QQVRIOwoJVFJBQ0UocmVnLCAiICBEb25lLlxuIik7CglyZXR1cm4JRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlS2V5MzJBIFtBRFZBUEkzMi4xMzNdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5ICkKewogICAgTFBXU1RSIGxwc3pTdWJLZXlXOwogICAgRFdPUkQgIHJldDsKCiAgICBUUkFDRShyZWcsIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpKTsKICAgIGxwc3pTdWJLZXlXID0gbHBzelN1YktleT9zdHJkdXBBMlcobHBzelN1YktleSk6TlVMTDsKICAgIHJldCA9IFJlZ0RlbGV0ZUtleTMyVyggaGtleSwgbHBzelN1YktleVcgKTsKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZUtleTE2IFtTSEVMTC40XSBbS0VSTkVMLjIxOV0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkpOwogICAgcmV0dXJuIFJlZ0RlbGV0ZUtleTMyQSggaGtleSwgbHBzelN1YktleSApOwp9CgoKLyogCiAqIERlbGV0ZSByZWdpc3RyeSB2YWx1ZQogKgogKiBDYWxscGF0aDoKICogUmVnRGVsZXRlVmFsdWUxNiAtPiBSZWdEZWxldGVWYWx1ZTMyQSAtPiBSZWdEZWxldGVWYWx1ZTMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZVZhbHVlMzJXIFtBRFZBUEkzMi4xMzZdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgW0ldCiAqICAgIGxwc3pWYWx1ZSBbSV0KICoKICogUkVUVVJOUwogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMzJXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6VmFsdWUgKQp7CglEV09SRAkJaTsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJTFBLRVlWQUxVRQl2YWw7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscHN6VmFsdWUpKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglpZiAobHBzelZhbHVlKSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmICgJbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmCgkJCQkhbHN0cmNtcGkzMlcobHBrZXktPnZhbHVlc1tpXS5uYW1lLGxwc3pWYWx1ZSkKCQkJKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9CgogICAgaWYgKGkgPT0gbHBrZXktPm5yb2Z2YWx1ZXMpCiAgICAgICAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoKCXZhbAk9IGxwa2V5LT52YWx1ZXMraTsKCWlmICh2YWwtPm5hbWUpIGZyZWUodmFsLT5uYW1lKTsKCWlmICh2YWwtPmRhdGEpIGZyZWUodmFsLT5kYXRhKTsKCW1lbWNweSgJCgkJbHBrZXktPnZhbHVlcytpLAoJCWxwa2V5LT52YWx1ZXMraSsxLAoJCXNpemVvZihLRVlWQUxVRSkqKGxwa2V5LT5ucm9mdmFsdWVzLWktMSkKCSk7CglscGtleS0+dmFsdWVzCT0gKExQS0VZVkFMVUUpeHJlYWxsb2MoCgkJCQlscGtleS0+dmFsdWVzLAoJCQkJKGxwa2V5LT5ucm9mdmFsdWVzLTEpKnNpemVvZihLRVlWQUxVRSkKCQkJKTsKCWxwa2V5LT5ucm9mdmFsdWVzLS07CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlVmFsdWUzMkEgW0FEVkFQSTMyLjEzNV0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTMyQSggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWUgKQp7CiAgICBMUFdTVFIgbHBzelZhbHVlVzsKICAgIERXT1JEICByZXQ7CgogICAgVFJBQ0UocmVnLCAiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlKSk7CiAgICBscHN6VmFsdWVXID0gbHBzelZhbHVlP3N0cmR1cEEyVyhscHN6VmFsdWUpOk5VTEw7CiAgICByZXQgPSBSZWdEZWxldGVWYWx1ZTMyVyggaGtleSwgbHBzelZhbHVlVyApOwogICAgaWYobHBzelZhbHVlVykgZnJlZShscHN6VmFsdWVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZVZhbHVlMTYgW0tFUk5FTC4yMjJdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUxNiggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWUgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcylcbiIsIGhrZXksZGVidWdzdHJfYShscHN6VmFsdWUpKTsKICAgIHJldHVybiBSZWdEZWxldGVWYWx1ZTMyQSggaGtleSwgbHBzelZhbHVlICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0ZsdXNoS2V5IFtLRVJORUwuMjI3XSBbQURWQVBJMzIuMTQzXQogKiBXcml0ZXMga2V5IHRvIHJlZ2lzdHJ5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdyaXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkoIEhLRVkgaGtleSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwogICAgQk9PTDMyIHJldDsKCiAgICBUUkFDRShyZWcsICIoJXgpXG4iLCBoa2V5KTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBFUlIocmVnLCAiV2hhdCBpcyB0aGUgY29ycmVjdCBmaWxlbmFtZT9cbiIpOwoKICAgIHJldCA9IF9zYXZlcmVnKCBscGtleSwgImZvby5iYXIiLCBUUlVFKTsKCiAgICBpZiggcmV0ICkgewogICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwogICAgfSBlbHNlCiAgICAgICAgcmV0dXJuIEVSUk9SX1VOS05PV047ICAvKiBGSVhNRSAqLwp9CgoKLyogRklYTUU6IGxwY2NoWFhYWCAuLi4gaXMgdGhpcyBjb3VudGluZyBpbiBXQ0hBUlMgb3IgaW4gQllURXMgPz8gKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5SW5mb0tleTMyVyBbQURWQVBJMzIuMTUzXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgICAgICAgICBbSV0gSGFuZGxlIHRvIGtleSB0byBxdWVyeQogKiAgICBscHN6Q2xhc3MgICAgICAgICAgICAgIFtPXSBCdWZmZXIgZm9yIGNsYXNzIHN0cmluZwogKiAgICBscGNjaENsYXNzICAgICAgICAgICAgIFtPXSBTaXplIG9mIGNsYXNzIHN0cmluZyBidWZmZXIKICogICAgbHBkd1Jlc2VydmVkICAgICAgICAgICBbSV0gUmVzZXJ2ZWQKICogICAgbHBjU3ViS2V5cyAgICAgICAgICAgICBbSV0gQnVmZmVyIGZvciBudW1iZXIgb2Ygc3Via2V5cwogKiAgICBscGNjaE1heFN1YktleSAgICAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3Qgc3Via2V5IG5hbWUgbGVuZ3RoCiAqICAgIGxwY2NoTWF4Q2xhc3MgICAgICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCBjbGFzcyBzdHJpbmcgbGVuZ3RoCiAqICAgIGxwY1ZhbHVlcyAgICAgICAgICAgICAgW09dIEJ1ZmZlciBmb3IgbnVtYmVyIG9mIHZhbHVlIGVudHJpZXMKICogICAgbHBjY2hNYXhWYWx1ZU5hbWUgICAgICBbT10gQnVmZmVyIGZvciBsb25nZXN0IHZhbHVlIG5hbWUgbGVuZ3RoCiAqICAgIGxwY2NiTWF4VmFsdWVEYXRhICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCB2YWx1ZSBkYXRhIGxlbmd0aAogKiAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yIFtPXSBCdWZmZXIgZm9yIHNlY3VyaXR5IGRlc2NyaXB0b3IgbGVuZ3RoCiAqICAgIGZ0CiAqIC0gd2luOTUgYWxsb3dzIGxwc3pDbGFzcyB0byBiZSB2YWxpZCBhbmQgbHBjY2hDbGFzcyB0byBiZSBOVUxMIAogKiAtIHdpbm50IHJldHVybnMgRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgaWYgbHBzekNsYXNzIGlzIHZhbGlkIGFuZAogKiAgIGxwY2NoQ2xhc3MgaXMgTlVMTAogKiAtIGJvdGggYWxsb3cgbHBzekNsYXNzIHRvIGJlIE5VTEwgYW5kIGxwY2NoQ2xhc3MgdG8gYmUgTlVMTCAKICogKGl0J3MgaGFyZCB0byB0ZXN0IHZhbGlkaXR5LCBzbyB0ZXN0ICFOVUxMIGluc3RlYWQpCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlJbmZvS2V5MzJXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6Q2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoQ2xhc3MsIExQRFdPUkQgbHBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY1N1YktleXMsIExQRFdPUkQgbHBjY2hNYXhTdWJrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hNYXhDbGFzcywgTFBEV09SRCBscGNWYWx1ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hNYXhWYWx1ZU5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NiTWF4VmFsdWVEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yLCBGSUxFVElNRSAqZnQgKQp7CglMUEtFWVNUUlVDVAlscGtleSxscHhrZXk7CglpbnQJCW5yb2ZrZXlzLG1heHN1YmtleSxtYXhjbGFzcyxtYXh2bmFtZSxtYXh2ZGF0YTsKCWludAkJaTsKCglUUkFDRShyZWcsIigleCwlcCwuLi4pXG4iLGhrZXksbHBzekNsYXNzKTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCWlmIChscHN6Q2xhc3MpIHsKICAgCSAgICAgICAgaWYgKFZFUlNJT05fR2V0VmVyc2lvbigpID09IE5UNDAgJiYgbHBjY2hDbGFzcyA9PSBOVUxMKSB7CgkJICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCQl9CgkJLyogZWl0aGVyIGxwY2NoQ2xhc3MgaXMgdmFsaWQgb3IgdGhpcyBpcyB3aW45NSBhbmQgbHBjY2hDbGFzcwoJCSAgIGNvdWxkIGJlIGludmFsaWQgKi8KCQlpZiAobHBrZXktPmNsYXNzKSB7CgkJICAgICAgICBEV09SRCBjbGFzc0xlbiA9IGxzdHJsZW4zMlcobHBrZXktPmNsYXNzKTsKCgkJCWlmIChscGNjaENsYXNzICYmIGNsYXNzTGVuKzE+KmxwY2NoQ2xhc3MpIHsKCQkJCSpscGNjaENsYXNzPWNsYXNzTGVuKzE7CgkJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCQl9CgkJCWlmIChscGNjaENsYXNzKQoJCQkgICAgKmxwY2NoQ2xhc3M9Y2xhc3NMZW47CgkJCW1lbWNweShscHN6Q2xhc3MsbHBrZXktPmNsYXNzLCBjbGFzc0xlbioyICsgMik7CgkJfSBlbHNlIHsKCQkJKmxwc3pDbGFzcwk9IDA7CgkJCWlmIChscGNjaENsYXNzKQoJCQkgICAgKmxwY2NoQ2xhc3MJPSAwOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGxwY2NoQ2xhc3MpCgkJCSpscGNjaENsYXNzCT0gbHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpOwoJfQoJbHB4a2V5PWxwa2V5LT5uZXh0c3ViOwoJbnJvZmtleXM9bWF4c3Via2V5PW1heGNsYXNzPW1heHZuYW1lPW1heHZkYXRhPTA7Cgl3aGlsZSAobHB4a2V5KSB7CgkJbnJvZmtleXMrKzsKCQlpZiAobHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpPm1heHN1YmtleSkKCQkJbWF4c3Via2V5PWxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKTsKCQlpZiAobHB4a2V5LT5jbGFzcyAmJiBsc3RybGVuMzJXKGxweGtleS0+Y2xhc3MpPm1heGNsYXNzKQoJCQltYXhjbGFzcz1sc3RybGVuMzJXKGxweGtleS0+Y2xhc3MpOwoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9Cglmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykgewoJCUxQS0VZVkFMVUUJdmFsPWxwa2V5LT52YWx1ZXMraTsKCgkJaWYgKHZhbC0+bmFtZSAmJiBsc3RybGVuMzJXKHZhbC0+bmFtZSk+bWF4dm5hbWUpCgkJCW1heHZuYW1lPWxzdHJsZW4zMlcodmFsLT5uYW1lKTsKCQlpZiAodmFsLT5sZW4+bWF4dmRhdGEpCgkJCW1heHZkYXRhPXZhbC0+bGVuOwoJfQoJaWYgKCFtYXhjbGFzcykgbWF4Y2xhc3MJPSAxOwoJaWYgKCFtYXh2bmFtZSkgbWF4dm5hbWUJPSAxOwoJaWYgKGxwY1ZhbHVlcykKCQkqbHBjVmFsdWVzCT0gbHBrZXktPm5yb2Z2YWx1ZXM7CglpZiAobHBjU3ViS2V5cykKCQkqbHBjU3ViS2V5cwk9IG5yb2ZrZXlzOwoJaWYgKGxwY2NoTWF4U3Via2V5KQoJCSpscGNjaE1heFN1YmtleQk9IG1heHN1YmtleTsKCWlmIChscGNjaE1heENsYXNzKQoJCSpscGNjaE1heENsYXNzCT0gbWF4Y2xhc3M7CglpZiAobHBjY2hNYXhWYWx1ZU5hbWUpCgkJKmxwY2NoTWF4VmFsdWVOYW1lPSBtYXh2bmFtZTsKCWlmIChscGNjYk1heFZhbHVlRGF0YSkKCQkqbHBjY2JNYXhWYWx1ZURhdGE9IG1heHZkYXRhOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5SW5mb0tleTMyQSBbQURWQVBJMzIuMTUyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5SW5mb0tleTMyQSggSEtFWSBoa2V5LCBMUFNUUiBscHN6Q2xhc3MsIExQRFdPUkQgbHBjY2hDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBjU3ViS2V5cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE1heFN1YmtleSwgTFBEV09SRCBscGNjaE1heENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY1ZhbHVlcywgTFBEV09SRCBscGNjaE1heFZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjYk1heFZhbHVlRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwgRklMRVRJTUUgKmZ0ICkKewoJTFBXU1RSCQlscHN6Q2xhc3NXID0gTlVMTDsKCURXT1JECQlyZXQ7CgoJVFJBQ0UocmVnLCIoJXgsJXAsJXAuLi4uLi4pXG4iLGhrZXksIGxwc3pDbGFzcywgbHBjY2hDbGFzcyk7CglpZiAobHBzekNsYXNzKSB7CgkJaWYgKGxwY2NoQ2xhc3MpIHsKCQkgICAgbHBzekNsYXNzVyAgPSAoTFBXU1RSKXhtYWxsb2MoKCpscGNjaENsYXNzKSAqIDIpOwoJCX0gZWxzZSBpZiAoVkVSU0lPTl9HZXRWZXJzaW9uKCkgPT0gV0lOOTUpIHsKCQkgICAgLyogd2luOTUgIGFsbG93cyBscGNjaENsYXNzIHRvIGJlIG51bGwgKi8KCQkgICAgLyogd2UgZG9uJ3Qga25vdyBob3cgYmlnIGxwc3pDbGFzcyBpcywgd291bGQgCgkJICAgICAgIE1BWF9QQVRITkFNRV9MRU4gYmUgdGhlIGNvcnJlY3QgZGVmYXVsdD8gKi8KCQkgICAgbHBzekNsYXNzVyAgPSAoTFBXU1RSKXhtYWxsb2MoTUFYX1BBVEhOQU1FX0xFTioyKTsgCgkJfQoKCX0gZWxzZQoJCWxwc3pDbGFzc1cgID0gTlVMTDsKCXJldD1SZWdRdWVyeUluZm9LZXkzMlcoCgkJaGtleSwKCQlscHN6Q2xhc3NXLAoJCWxwY2NoQ2xhc3MsCgkJbHBkd1Jlc2VydmVkLAoJCWxwY1N1YktleXMsCgkJbHBjY2hNYXhTdWJrZXksCgkJbHBjY2hNYXhDbGFzcywKCQlscGNWYWx1ZXMsCgkJbHBjY2hNYXhWYWx1ZU5hbWUsCgkJbHBjY2JNYXhWYWx1ZURhdGEsCgkJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCQlmdAoJKTsKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MgJiYgbHBzekNsYXNzKQoJCWxzdHJjcHlXdG9BKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnkzMlcgW0FEVkFQSTMyLjEyOF0KICoKICogUEFSQU1TCiAqICAgIGxwTWFjaGluZU5hbWUgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiByZW1vdGUgY29tcHV0ZXIKICogICAgaEhleSAgICAgICAgICBbSV0gUHJlZGVmaW5lZCByZWdpc3RyeSBoYW5kbGUKICogICAgcGhrUmVzdWx0ICAgICBbSV0gQWRkcmVzcyBvZiBidWZmZXIgZm9yIHJlbW90ZSByZWdpc3RyeSBoYW5kbGUKICovCkxPTkcgV0lOQVBJIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyVyggTFBDV1NUUiBscE1hY2hpbmVOYW1lLCBIS0VZIGhLZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSBwaGtSZXN1bHQgKQp7CiAgICBUUkFDRShyZWcsIiglcywleCwlcCk6IHN0dWJcbiIsZGVidWdzdHJfdyhscE1hY2hpbmVOYW1lKSxoS2V5LHBoa1Jlc3VsdCk7CgogICAgaWYgKCFscE1hY2hpbmVOYW1lIHx8ICEqbHBNYWNoaW5lTmFtZSkgewogICAgICAgIC8qIFVzZSB0aGUgbG9jYWwgbWFjaGluZSBuYW1lICovCiAgICAgICAgcmV0dXJuIFJlZ09wZW5LZXkxNiggaEtleSwgIiIsIHBoa1Jlc3VsdCApOwogICAgfQoKICAgIEZJWE1FKHJlZywiQ2Fubm90IGNvbm5lY3QgdG8gJXNcbiIsZGVidWdzdHJfdyhscE1hY2hpbmVOYW1lKSk7CiAgICByZXR1cm4gRVJST1JfQkFEX05FVFBBVEg7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyQSBbQURWQVBJMzIuMTI3XQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5MzJBKCBMUENTVFIgbWFjaGluZSwgSEtFWSBoa2V5LCBMUEhLRVkgcmVza2V5ICkKewogICAgRFdPUkQgcmV0OwogICAgTFBXU1RSIG1hY2hpbmVXID0gc3RyZHVwQTJXKG1hY2hpbmUpOwogICAgcmV0ID0gUmVnQ29ubmVjdFJlZ2lzdHJ5MzJXKCBtYWNoaW5lVywgaGtleSwgcmVza2V5ICk7CiAgICBmcmVlKG1hY2hpbmVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0dldEtleVNlY3VyaXR5IFtBRFZBUEkzMi4xNDRdCiAqIFJldHJpZXZlcyBhIGNvcHkgb2Ygc2VjdXJpdHkgZGVzY3JpcHRvciBwcm90ZWN0aW5nIHRoZSByZWdpc3RyeSBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICAgICAgICAgW0ldICAgT3BlbiBoYW5kbGUgb2Yga2V5IHRvIHNldAogKiAgICBTZWN1cml0eUluZm9ybWF0aW9uICAgIFtJXSAgIERlc2NyaXB0b3IgY29udGVudHMKICogICAgcFNlY3VyaXR5RGVzY3JpcHRvciAgICBbT10gICBBZGRyZXNzIG9mIGRlc2NyaXB0b3IgZm9yIGtleQogKiAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yIFtJL09dIEFkZHJlc3Mgb2Ygc2l6ZSBvZiBidWZmZXIgYW5kIGRlc2NyaXB0aW9uCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpMT05HIFdJTkFQSSBSZWdHZXRLZXlTZWN1cml0eSggSEtFWSBoa2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFQ1VSSVRZX0lORk9STUFUSU9OIFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksU2VjdXJpdHlJbmZvcm1hdGlvbixwU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvcj8qbHBjYlNlY3VyaXR5RGVzY3JpcHRvcjowKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICAvKiBGSVhNRTogQ2hlY2sgZm9yIHZhbGlkIFNlY3VyaXR5SW5mb3JtYXRpb24gdmFsdWVzICovCgogICAgaWYgKCpscGNiU2VjdXJpdHlEZXNjcmlwdG9yIDwgc2l6ZW9mKCpwU2VjdXJpdHlEZXNjcmlwdG9yKSkKICAgICAgICByZXR1cm4gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUjsKCiAgICBGSVhNRShyZWcsICIoJXgsJWxkLCVwLCVsZCk6IHN0dWJcbiIsaGtleSxTZWN1cml0eUluZm9ybWF0aW9uLAogICAgICAgICAgcFNlY3VyaXR5RGVzY3JpcHRvcixscGNiU2VjdXJpdHlEZXNjcmlwdG9yPypscGNiU2VjdXJpdHlEZXNjcmlwdG9yOjApOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdMb2FkS2V5MzJXIFtBRFZBUEkzMi4/Pz9dCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBzelN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleQogKiAgICBscHN6RmlsZSAgIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGZvciByZWdpc3RyeSBpbmZvcm1hdGlvbgogKi8KTE9ORyBXSU5BUEkgUmVnTG9hZEtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQQ1dTVFIgbHBzekZpbGUgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksZGVidWdzdHJfdyhscHN6RmlsZSkpOwoKICAgIC8qIERvIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5IHx8ICFscHN6RmlsZSB8fCAhKmxwc3pGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsIigleCwlcywlcyk6IHN0dWJcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLAogICAgICAgICAgZGVidWdzdHJfdyhscHN6RmlsZSkpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdMb2FkS2V5MzJBIFtBRFZBUEkzMi4/Pz9dCiAqLwpMT05HIFdJTkFQSSBSZWdMb2FkS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUENTVFIgbHBzekZpbGUgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscHN6U3ViS2V5VyA9IHN0cmR1cEEyVyhscHN6U3ViS2V5KTsKICAgIExQV1NUUiBscHN6RmlsZVcgPSBzdHJkdXBBMlcobHBzekZpbGUpOwogICAgcmV0ID0gUmVnTG9hZEtleTMyVyggaGtleSwgbHBzelN1YktleVcsIGxwc3pGaWxlVyApOwogICAgaWYobHBzekZpbGVXKSBmcmVlKGxwc3pGaWxlVyk7CiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdOb3RpZnlDaGFuZ2VLZXlWYWx1ZSBbQURWQVBJMzIuPz8/XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgIFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdhdGNoCiAqICAgIGZXYXRjaFN1YlRyZWUgICBbSV0gRmxhZyBmb3Igc3Via2V5IG5vdGlmaWNhdGlvbgogKiAgICBmZHdOb3RpZnlGaWx0ZXIgW0ldIENoYW5nZXMgdG8gYmUgcmVwb3J0ZWQKICogICAgaEV2ZW50ICAgICAgICAgIFtJXSBIYW5kbGUgb2Ygc2lnbmFsZWQgZXZlbnQKICogICAgZkFzeW5jICAgICAgICAgIFtJXSBGbGFnIGZvciBhc3luY2hyb25vdXMgcmVwb3J0aW5nCiAqLwpMT05HIFdJTkFQSSBSZWdOb3RpZnlDaGFuZ2VLZXlWYWx1ZSggSEtFWSBoa2V5LCBCT09MMzIgZldhdGNoU3ViVHJlZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBmZHdOb3RpZnlGaWx0ZXIsIEhBTkRMRTMyIGhFdmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wzMiBmQXN5bmMgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKICAgIFRSQUNFKHJlZywiKCV4LCVpLCVsZCwleCwlaSlcbiIsaGtleSxmV2F0Y2hTdWJUcmVlLGZkd05vdGlmeUZpbHRlciwKICAgICAgICAgIGhFdmVudCxmQXN5bmMpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywiKCV4LCVpLCVsZCwleCwlaSk6IHN0dWJcbiIsaGtleSxmV2F0Y2hTdWJUcmVlLGZkd05vdGlmeUZpbHRlciwKICAgICAgICAgIGhFdmVudCxmQXN5bmMpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXkzMlcgW0FEVkFQSTMyLjE3M10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBTdWJLZXkgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkgdG8gdW5sb2FkCiAqLwpMT05HIFdJTkFQSSBSZWdVbkxvYWRLZXkzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSApCnsKICAgIEZJWE1FKHJlZywiKCV4LCVzKTogc3R1YlxuIixoa2V5LCBkZWJ1Z3N0cl93KGxwU3ViS2V5KSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnVW5Mb2FkS2V5MzJBIFtBRFZBUEkzMi4xNzJdCiAqLwpMT05HIFdJTkFQSSBSZWdVbkxvYWRLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5ICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBTdWJLZXlXID0gc3RyZHVwQTJXKGxwU3ViS2V5KTsKICAgIHJldCA9IFJlZ1VuTG9hZEtleTMyVyggaGtleSwgbHBTdWJLZXlXICk7CiAgICBpZihscFN1YktleVcpIGZyZWUobHBTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldEtleVNlY3VyaXR5IFtBRFZBUEkzMi4xNjddCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgIFtJXSBPcGVuIGhhbmRsZSBvZiBrZXkgdG8gc2V0CiAqICAgIFNlY3VyaXR5SW5mbyAgW0ldIERlc2NyaXB0b3IgY29udGVudHMKICogICAgcFNlY3VyaXR5RGVzYyBbSV0gQWRkcmVzcyBvZiBkZXNjcmlwdG9yIGZvciBrZXkKICovCkxPTkcgV0lOQVBJIFJlZ1NldEtleVNlY3VyaXR5KCBIS0VZIGhrZXksIFNFQ1VSSVRZX0lORk9STUFUSU9OIFNlY3VyaXR5SW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfREVTQ1JJUFRPUiBwU2VjdXJpdHlEZXNjICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwKVxuIixoa2V5LFNlY3VyaXR5SW5mbyxwU2VjdXJpdHlEZXNjKTsKCiAgICAvKiBJdCBzZWVtcyB0byBwZXJmb3JtIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoKFNlY3VyaXR5SW5mbyAmIE9XTkVSX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBHUk9VUF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgREFDTF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgU0FDTF9TRUNVUklUWV9JTkZPUk1BVElPTikpIHsKICAgICAgICAvKiBQYXJhbSBPSyAqLwogICAgfSBlbHNlCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGlmICghcFNlY3VyaXR5RGVzYykKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUUocmVnLCI6KCV4LCVsZCwlcCk6IHN0dWJcbiIsaGtleSxTZWN1cml0eUluZm8scFNlY3VyaXR5RGVzYyk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NhdmVLZXkzMlcgW0FEVkFQSTMyLjE2Nl0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICBbSV0gSGFuZGxlIG9mIGtleSB3aGVyZSBzYXZlIGJlZ2lucwogKiAgICBscEZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgdG8gc2F2ZSB0bwogKiAgICBzYSAgICAgW0ldIEFkZHJlc3Mgb2Ygc2VjdXJpdHkgc3RydWN0dXJlCiAqLwpMT05HIFdJTkFQSSBSZWdTYXZlS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIHNhICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCAiKCV4LCVzLCVwKVxuIiwgaGtleSwgZGVidWdzdHJfdyhscEZpbGUpLCBzYSk7CgogICAgLyogSXQgYXBwZWFycyB0byBkbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscEZpbGUgfHwgISpscEZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywgIigleCwlcywlcCk6IHN0dWJcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBGaWxlKSwgc2EpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTYXZlS2V5MzJBIFtBRFZBUEkzMi4xNjVdCiAqLwpMT05HIFdJTkFQSSBSZWdTYXZlS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscEZpbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgc2EgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscEZpbGVXID0gc3RyZHVwQTJXKGxwRmlsZSk7CiAgICByZXQgPSBSZWdTYXZlS2V5MzJXKCBoa2V5LCBscEZpbGVXLCBzYSApOwogICAgZnJlZShscEZpbGVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1Jlc3RvcmVLZXkzMlcgW0FEVkFQSTMyLjE2NF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgcmVzdG9yZSBiZWdpbnMKICogICAgbHBGaWxlICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBjb250YWluaW5nIHNhdmVkIHRyZWUKICogICAgZHdGbGFncyBbSV0gT3B0aW9uYWwgZmxhZ3MKICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXkzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscEZpbGUsIERXT1JEIGR3RmxhZ3MgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRShyZWcsICIoJXgsJXMsJWxkKVxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBJdCBzZWVtcyB0byBkbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscEZpbGUgfHwgISpscEZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywiKCV4LCVzLCVsZCk6IHN0dWJcbiIsaGtleSxkZWJ1Z3N0cl93KGxwRmlsZSksZHdGbGFncyk7CgogICAgLyogQ2hlY2sgZm9yIGZpbGUgZXhpc3RlbmNlICovCgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1Jlc3RvcmVLZXkzMkEgW0FEVkFQSTMyLjE2M10KICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwRmlsZVcgPSBzdHJkdXBBMlcobHBGaWxlKTsKICAgIHJldCA9IFJlZ1Jlc3RvcmVLZXkzMlcoIGhrZXksIGxwRmlsZVcsIGR3RmxhZ3MgKTsKICAgIGlmKGxwRmlsZVcpIGZyZWUobHBGaWxlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5MzJXIFtBRFZBUEkzMi4xNjJdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscFN1YktleSAgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkKICogICAgbHBOZXdGaWxlIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGZvciBmaWxlIHdpdGggbmV3IGRhdGEKICogICAgbHBPbGRGaWxlIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGZvciBiYWNrdXAgZmlsZQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwU3ViS2V5LCBMUENXU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBscE9sZEZpbGUgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRShyZWcsIigleCwlcywlcywlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwU3ViS2V5KSwKICAgICAgICAgIGRlYnVnc3RyX3cobHBOZXdGaWxlKSxkZWJ1Z3N0cl93KGxwT2xkRmlsZSkpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywgIigleCwlcywlcywlcyk6IHN0dWJcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBTdWJLZXkpLCAKICAgICAgICAgIGRlYnVnc3RyX3cobHBOZXdGaWxlKSxkZWJ1Z3N0cl93KGxwT2xkRmlsZSkpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5MzJBIFtBRFZBUEkzMi4xNjFdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXBsYWNlS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSwgTFBDU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwT2xkRmlsZSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwU3ViS2V5VyA9IHN0cmR1cEEyVyhscFN1YktleSk7CiAgICBMUFdTVFIgbHBOZXdGaWxlVyA9IHN0cmR1cEEyVyhscE5ld0ZpbGUpOwogICAgTFBXU1RSIGxwT2xkRmlsZVcgPSBzdHJkdXBBMlcobHBPbGRGaWxlKTsKICAgIHJldCA9IFJlZ1JlcGxhY2VLZXkzMlcoIGhrZXksIGxwU3ViS2V5VywgbHBOZXdGaWxlVywgbHBPbGRGaWxlVyApOwogICAgZnJlZShscE9sZEZpbGVXKTsKICAgIGZyZWUobHBOZXdGaWxlVyk7CiAgICBmcmVlKGxwU3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9Cgo=