LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICoKICogRGVjZW1iZXIgMjEsIDE5OTcgLSBLZXZpbiBDb3plbnMKICogRml4ZWQgYnVncyBpbiB0aGUgX3c5NV9sb2FkcmVnKCkgZnVuY3Rpb24uIEFkZGVkIGV4dHJhIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyB0aGUgZm9ybWF0IG9mIHRoZSBXaW5kb3dzICc5NSByZWdpc3RyeSBmaWxlcy4KICoKICogTk9URVMKICogICAgV2hlbiBjaGFuZ2luZyB0aGlzIGZpbGUsIHBsZWFzZSByZS1ydW4gdGhlIHJlZ3Rlc3QgcHJvZ3JhbSB0byBlbnN1cmUKICogICAgdGhlIGNvbmRpdGlvbnMgYXJlIGhhbmRsZWQgcHJvcGVybHkuCiAqCiAqIFRPRE8KICogICAgU2VjdXJpdHkgYWNjZXNzCiAqICAgIE9wdGlvbiBoYW5kbGluZwogKiAgICBUaW1lIGZvciBSZWdFbnVtS2V5KiwgUmVnUXVlcnlJbmZvS2V5KgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL2ZjbnRsLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8cHdkLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJ4bWFsbG9jLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCnN0YXRpYyB2b2lkIFJFR0lTVFJZX0luaXQoKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCi8qIE5PVEU6IGRvIG5vdCBhcHBlbmQgYSAvLiBsaW51eCcgbWtkaXIoKSBXSUxMIEZBSUwgaWYgeW91IGRvIHRoYXQgKi8KI2RlZmluZSBXSU5FX1BSRUZJWAkJCSIvLndpbmUiCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUCQkiL3Vzci9sb2NhbC9ldGMvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUCSIvdXNyL2xvY2FsL2V0Yy93aW5lLnN5c3RlbXJlZyIKCi8qIHJlbGF0aXZlIGluIH51c2VyLy53aW5lLyA6ICovCiNkZWZpbmUgU0FWRV9DVVJSRU5UX1VTRVIJCSJ1c2VyLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX01BQ0hJTkUJCSJzeXN0ZW0ucmVnIgoKI2RlZmluZSBLRVlfUkVHSVNUUlkJIlNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeSIKI2RlZmluZSBWQUxfU0FWRVVQREFURUQJIlNhdmVPbmx5VXBkYXRlZEtleXMiCgovKiBvbmUgdmFsdWUgb2YgYSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZVkFMVUUKewogICAgTFBXU1RSICAgbmFtZTsgICAgICAgICAgLyogbmFtZSBvZiB2YWx1ZSAoVU5JQ09ERSkgb3IgTlVMTCBmb3Igd2luMzEgKi8KICAgIERXT1JEICAgIHR5cGU7ICAgICAgICAgIC8qIHR5cGUgb2YgdmFsdWUgKi8KICAgIERXT1JEICAgIGxlbjsgICAgICAgICAgIC8qIGxlbmd0aCBvZiBkYXRhIGluIEJZVEVzICovCiAgICBEV09SRCAgICBsYXN0bW9kaWZpZWQ7ICAvKiB0aW1lIG9mIHNlY29uZHMgc2luY2UgMS4xLjE5NzAgKi8KICAgIExQQllURSAgIGRhdGE7ICAgICAgICAgIC8qIGNvbnRlbnQsIG1heSBiZSBzdHJpbmdzLCBiaW5hcmllcywgZXRjLiAqLwp9IEtFWVZBTFVFLCpMUEtFWVZBTFVFOwoKLyogYSByZWdpc3RyeSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZU1RSVUNUCnsKICAgIExQV1NUUiAgICAgICAgICAgICAgIGtleW5hbWU7ICAgICAgIC8qIG5hbWUgb2YgVEhJUyBrZXkgKFVOSUNPREUpICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBmbGFnczsgICAgICAgICAvKiBmbGFncy4gKi8KICAgIExQV1NUUiAgICAgICAgICAgICAgIGNsYXNzOwogICAgLyogdmFsdWVzICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBucm9mdmFsdWVzOyAgICAvKiBuciBvZiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIExQS0VZVkFMVUUgICAgICAgICAgIHZhbHVlczsgICAgICAgIC8qIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgLyoga2V5IG1hbmFnZW1lbnQgcG9pbnRlcnMgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHQ7ICAgICAgICAgIC8qIG5leHQga2V5IG9uIHNhbWUgaGllcmFyY2h5ICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0c3ViOyAgICAgICAvKiBrZXlzIHRoYXQgaGFuZyBiZWxvdyBUSElTIGtleSAqLwp9IEtFWVNUUlVDVCwgKkxQS0VZU1RSVUNUOwoKCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jbGFzc2VzX3Jvb3Q9TlVMTDsJLyogd2luZG93cyAzLjEgZ2xvYmFsIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF91c2VyPU5VTEw7CS8qIHVzZXIgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9sb2NhbF9tYWNoaW5lPU5VTEw7LyogbWFjaGluZSBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3VzZXJzPU5VTEw7CS8qIGFsbCB1c2Vycz8gKi8KCi8qIGR5bmFtaWMsIG5vdCBzYXZlZCAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfcGVyZm9ybWFuY2VfZGF0YT1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF9jb25maWc9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2R5bl9kYXRhPU5VTEw7CgovKiB3aGF0IHZhbHVldHlwZXMgZG8gd2UgbmVlZCB0byBjb252ZXJ0PyAqLwojZGVmaW5lIFVOSUNPTlZNQVNLCSgoMTw8UkVHX1NaKXwoMTw8UkVHX01VTFRJX1NaKXwoMTw8UkVHX0VYUEFORF9TWikpCgoKc3RhdGljIHN0cnVjdCBvcGVuaGFuZGxlIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCVJFR1NBTQkJYWNjZXNzbWFzazsKfSAgKm9wZW5oYW5kbGVzPU5VTEw7CnN0YXRpYyBpbnQJbnJvZm9wZW5oYW5kbGVzPTA7Ci8qIFN0YXJ0cyBhZnRlciAxIGJlY2F1c2UgMCwxIGFyZSByZXNlcnZlZCBmb3IgV2luMTYgKi8Kc3RhdGljIGludAljdXJyZW50aGFuZGxlPTE7CgoKLyoKICogUVVFU1RJT04KICogICBBcmUgdGhlc2UgZG9pbmcgdGhlIHNhbWUgYXMgSEVBUF9zdHJkdXBBdG9XIGFuZCBIRUFQX3N0cmR1cFd0b0E/CiAqICAgSWYgc28sIGNhbiB3ZSByZW1vdmUgdGhlbT8KICogQU5TV0VSCiAqICAgTm8sIHRoZSBtZW1vcnkgaGFuZGxpbmcgZnVuY3Rpb25zIGFyZSBjYWxsZWQgdmVyeSBvZnRlbiBpbiBoZXJlLCAKICogICBqdXN0IHJlcGxhY2luZyB0aGVtIGJ5IEhlYXBBbGxvYyhTeXN0ZW1IZWFwLC4uLikgbWFrZXMgcmVnaXN0cnkKICogICBsb2FkaW5nIDEwMCB0aW1lcyBzbG93ZXIuIC1NTQogKi8Kc3RhdGljIExQV1NUUiBzdHJkdXBBMlcoTFBDU1RSIHNyYykKewogICAgaWYoc3JjKSB7CglMUFdTVFIgZGVzdD14bWFsbG9jKDIqc3RybGVuKHNyYykrMik7Cglsc3RyY3B5QXRvVyhkZXN0LHNyYyk7CglyZXR1cm4gZGVzdDsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMgTFBXU1RSIHN0cmR1cFcoTFBDV1NUUiBhKSB7CglMUFdTVFIJYjsKCWludAlsZW47CgogICAgaWYoYSkgewoJbGVuPXNpemVvZihXQ0hBUikqKGxzdHJsZW4zMlcoYSkrMSk7CgliPShMUFdTVFIpeG1hbGxvYyhsZW4pOwoJbWVtY3B5KGIsYSxsZW4pOwoJcmV0dXJuIGI7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKTFBXU1RSIHN0cmN2dEEyVyhMUENTVFIgc3JjLCBpbnQgbmNoYXJzKQoKewogICBMUFdTVFIgZGVzdCA9IHhtYWxsb2MgKDIgKiBuY2hhcnMgKyAyKTsKCiAgIGxzdHJjcHluQXRvVyhkZXN0LHNyYyxuY2hhcnMrMSk7CiAgIGRlc3RbbmNoYXJzXSA9IDA7CiAgIHJldHVybiBkZXN0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBpc19zdGFuZGFyZF9oa2V5IFtJbnRlcm5hbF0KICogRGV0ZXJtaW5lcyBpZiBhIGhrZXkgaXMgYSBzdGFuZGFyZCBrZXkKICovCnN0YXRpYyBCT09MMzIgaXNfc3RhbmRhcmRfaGtleSggSEtFWSBoa2V5ICkKewogICAgc3dpdGNoKGhrZXkpIHsKICAgICAgICBjYXNlIDB4MDAwMDAwMDA6CiAgICAgICAgY2FzZSAweDAwMDAwMDAxOgogICAgICAgIGNhc2UgSEtFWV9DTEFTU0VTX1JPT1Q6CiAgICAgICAgY2FzZSBIS0VZX0NVUlJFTlRfQ09ORklHOgogICAgICAgIGNhc2UgSEtFWV9DVVJSRU5UX1VTRVI6CiAgICAgICAgY2FzZSBIS0VZX0xPQ0FMX01BQ0hJTkU6CiAgICAgICAgY2FzZSBIS0VZX1VTRVJTOgogICAgICAgIGNhc2UgSEtFWV9QRVJGT1JNQU5DRV9EQVRBOgogICAgICAgIGNhc2UgSEtFWV9EWU5fREFUQToKICAgICAgICAgICAgcmV0dXJuIFRSVUU7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGFkZF9oYW5kbGUgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgYWRkX2hhbmRsZSggSEtFWSBoa2V5LCBMUEtFWVNUUlVDVCBscGtleSwgUkVHU0FNIGFjY2Vzc21hc2sgKQp7CiAgICBpbnQgaTsKCiAgICBUUkFDRShyZWcsIigleCwlcCwlbHgpXG4iLGhrZXksbHBrZXksYWNjZXNzbWFzayk7CiAgICAvKiBDaGVjayBmb3IgZHVwbGljYXRlcyAqLwogICAgZm9yIChpPTA7aTxucm9mb3BlbmhhbmRsZXM7aSsrKSB7CiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmxwa2V5PT1scGtleSkgewogICAgICAgICAgICAvKiBUaGlzIGlzIG5vdCByZWFsbHkgYW4gZXJyb3IgLSB0aGUgdXNlciBpcyBhbGxvd2VkIHRvIGNyZWF0ZQogICAgICAgICAgICAgICB0d28gKG9yIG1vcmUpIGhhbmRsZXMgdG8gdGhlIHNhbWUga2V5ICovCiAgICAgICAgICAgIC8qV0FSTihyZWcsICJBZGRpbmcga2V5ICVwIHR3aWNlXG4iLGxwa2V5KTsqLwogICAgICAgIH0KICAgICAgICBpZiAob3BlbmhhbmRsZXNbaV0uaGtleT09aGtleSkgewogICAgICAgICAgICBXQVJOKHJlZywgIkFkZGluZyBoYW5kbGUgJXggdHdpY2VcbiIsaGtleSk7CiAgICAgICAgfQogICAgfQogICAgb3BlbmhhbmRsZXM9eHJlYWxsb2MoIG9wZW5oYW5kbGVzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3RydWN0IG9wZW5oYW5kbGUpKihucm9mb3BlbmhhbmRsZXMrMSkpOwoKICAgIG9wZW5oYW5kbGVzW2ldLmxwa2V5ID0gbHBrZXk7CiAgICBvcGVuaGFuZGxlc1tpXS5oa2V5ID0gaGtleTsKICAgIG9wZW5oYW5kbGVzW2ldLmFjY2Vzc21hc2sgPSBhY2Nlc3NtYXNrOwogICAgbnJvZm9wZW5oYW5kbGVzKys7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGdldF9oYW5kbGUgW0ludGVybmFsXQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFBvaW50ZXIgdG8ga2V5CiAqICAgIEZhaWx1cmU6IE5VTEwKICovCnN0YXRpYyBMUEtFWVNUUlVDVCBnZXRfaGFuZGxlKCBIS0VZIGhrZXkgKQp7CiAgICBpbnQgaTsKCiAgICBmb3IgKGk9MDsgaTxucm9mb3BlbmhhbmRsZXM7IGkrKykKICAgICAgICBpZiAob3BlbmhhbmRsZXNbaV0uaGtleSA9PSBoa2V5KQogICAgICAgICAgICByZXR1cm4gb3BlbmhhbmRsZXNbaV0ubHBrZXk7CiAgICBXQVJOKHJlZywgIkNvdWxkIG5vdCBmaW5kIGhhbmRsZSAleFxuIixoa2V5KTsKICAgIHJldHVybiBOVUxMOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiByZW1vdmVfaGFuZGxlIFtJbnRlcm5hbF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgW0ldIEhhbmRsZSBvZiBrZXkgdG8gcmVtb3ZlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFUlJPUl9JTlZBTElEX0hBTkRMRQogKi8Kc3RhdGljIERXT1JEIHJlbW92ZV9oYW5kbGUoIEhLRVkgaGtleSApCnsKICAgIGludCBpOwoKICAgIGZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykKICAgICAgICBpZiAob3BlbmhhbmRsZXNbaV0uaGtleT09aGtleSkKICAgICAgICAgICAgYnJlYWs7CgogICAgaWYgKGkgPT0gbnJvZm9wZW5oYW5kbGVzKSB7CiAgICAgICAgV0FSTihyZWcsICJDb3VsZCBub3QgZmluZCBoYW5kbGUgJXhcbiIsaGtleSk7CiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwogICAgfQoKICAgIG1lbWNweSggb3BlbmhhbmRsZXMraSwKICAgICAgICAgICAgb3BlbmhhbmRsZXMraSsxLAogICAgICAgICAgICBzaXplb2Yoc3RydWN0IG9wZW5oYW5kbGUpKihucm9mb3BlbmhhbmRsZXMtaS0xKQogICAgKTsKICAgIG9wZW5oYW5kbGVzPXhyZWFsbG9jKG9wZW5oYW5kbGVzLHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy0xKSk7CiAgICBucm9mb3BlbmhhbmRsZXMtLTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGxvb2t1cF9oa2V5IFtJbnRlcm5hbF0KICogCiAqIEp1c3QgYXMgdGhlIG5hbWUgc2F5cy4gQ3JlYXRlcyB0aGUgcm9vdCBrZXlzIG9uIGRlbWFuZCwgc28gd2UgY2FuIGNhbGwgdGhlCiAqIFJlZyogZnVuY3Rpb25zIGF0IGFueSB0aW1lLgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFBvaW50ZXIgdG8ga2V5IHN0cnVjdHVyZQogKiAgICBGYWlsdXJlOiBOVUxMCiAqLwojZGVmaW5lIEFERF9ST09UX0tFWSh4eCkgXAoJeHggPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7XAoJbWVtc2V0KHh4LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpO1wKCXh4LT5rZXluYW1lPSBzdHJkdXBBMlcoIjxzaG91bGRfbm90X2FwcGVhcl9hbnl3aGVyZT4iKTsKCnN0YXRpYyBMUEtFWVNUUlVDVCBsb29rdXBfaGtleSggSEtFWSBoa2V5ICkKewoJc3dpdGNoIChoa2V5KSB7CgkvKiAwIGFuZCAxIGFyZSB2YWxpZCByb290a2V5cyBpbiB3aW4xNiBzaGVsbC5kbGwgYW5kIGFyZSB1c2VkIGJ5CgkgKiBzb21lIHByb2dyYW1zLiBEbyBub3QgcmVtb3ZlIHRob3NlIGNhc2VzLiAtTU0KCSAqLwogICAgCWNhc2UgMHgwMDAwMDAwMDoKCWNhc2UgMHgwMDAwMDAwMToKCWNhc2UgSEtFWV9DTEFTU0VTX1JPT1Q6IHsKCQlpZiAoIWtleV9jbGFzc2VzX3Jvb3QpIHsKCQkJSEtFWQljbF9yX2hrZXk7CgoJCQkvKiBjYWxscyBsb29rdXBfaGtleSByZWN1cnNpdmVseSwgVFdJQ0UgKi8KCQkJaWYgKFJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiU09GVFdBUkVcXENsYXNzZXMiLCZjbF9yX2hrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJCQlFUlIocmVnLCJDb3VsZCBub3QgY3JlYXRlIEhLTE1cXFNPRlRXQVJFXFxDbGFzc2VzLiBUaGlzIGlzIGltcG9zc2libGUuXG4iKTsKCQkJCWV4aXQoMSk7CgkJCX0KCQkJa2V5X2NsYXNzZXNfcm9vdCA9IGxvb2t1cF9oa2V5KGNsX3JfaGtleSk7CgkJfQoJCXJldHVybiBrZXlfY2xhc3Nlc19yb290OwoJfQoJY2FzZSBIS0VZX0NVUlJFTlRfVVNFUjoKCQlpZiAoIWtleV9jdXJyZW50X3VzZXIpIHsKCQkJSEtFWQljX3VfaGtleTsKCQkJc3RydWN0CXBhc3N3ZAkqcHdkOwoKCQkJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCQkJLyogY2FsbHMgbG9va3VwX2hrZXkgcmVjdXJzaXZlbHksIFRXSUNFICovCgkJCWlmIChwd2QgJiYgcHdkLT5wd19uYW1lKSB7CgkJCQlpZiAoUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUyxwd2QtPnB3X25hbWUsJmNfdV9oa2V5KSE9RVJST1JfU1VDQ0VTUykgewoJCQkJCUVSUihyZWcsIkNvdWxkIG5vdCBjcmVhdGUgSFVcXCVzLiBUaGlzIGlzIGltcG9zc2libGUuXG4iLHB3ZC0+cHdfbmFtZSk7CgkJCQkJZXhpdCgxKTsKCQkJCX0KCQkJCWtleV9jdXJyZW50X3VzZXIgPSBsb29rdXBfaGtleShjX3VfaGtleSk7CgkJCX0gZWxzZSB7CgkJCQkvKiBub3RoaW5nIGZvdW5kLCB1c2Ugc3RhbmRhbG9uZSAqLwoJCQkJQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X3VzZXIpOwoJCQl9CgkJfQoJCXJldHVybiBrZXlfY3VycmVudF91c2VyOwoJY2FzZSBIS0VZX0xPQ0FMX01BQ0hJTkU6CgkJaWYgKCFrZXlfbG9jYWxfbWFjaGluZSkgewoJCQlBRERfUk9PVF9LRVkoa2V5X2xvY2FsX21hY2hpbmUpOwoJCQlSRUdJU1RSWV9Jbml0KCk7CgkJfQoJCXJldHVybiBrZXlfbG9jYWxfbWFjaGluZTsKCWNhc2UgSEtFWV9VU0VSUzoKCQlpZiAoIWtleV91c2VycykgewoJCQlBRERfUk9PVF9LRVkoa2V5X3VzZXJzKTsKCQl9CgkJcmV0dXJuIGtleV91c2VyczsKCWNhc2UgSEtFWV9QRVJGT1JNQU5DRV9EQVRBOgoJCWlmICgha2V5X3BlcmZvcm1hbmNlX2RhdGEpIHsKCQkJQUREX1JPT1RfS0VZKGtleV9wZXJmb3JtYW5jZV9kYXRhKTsKCQl9CgkJcmV0dXJuIGtleV9wZXJmb3JtYW5jZV9kYXRhOwoJY2FzZSBIS0VZX0RZTl9EQVRBOgoJCWlmICgha2V5X2R5bl9kYXRhKSB7CgkJCUFERF9ST09UX0tFWShrZXlfZHluX2RhdGEpOwoJCX0KCQlyZXR1cm4ga2V5X2R5bl9kYXRhOwoJY2FzZSBIS0VZX0NVUlJFTlRfQ09ORklHOgoJCWlmICgha2V5X2N1cnJlbnRfY29uZmlnKSB7CgkJCUFERF9ST09UX0tFWShrZXlfY3VycmVudF9jb25maWcpOwoJCX0KCQlyZXR1cm4ga2V5X2N1cnJlbnRfY29uZmlnOwoJZGVmYXVsdDoKCQlyZXR1cm4gZ2V0X2hhbmRsZShoa2V5KTsKCX0KCS8qTk9UUkVBQ0hFRCovCn0KI3VuZGVmIEFERF9ST09UX0tFWQovKiBzbyB3ZSBkb24ndCBhY2NpZGVudGx5IGFjY2VzcyB0aGVtIC4uLiAqLwojZGVmaW5lIGtleV9jdXJyZW50X2NvbmZpZyBOVUxMIE5VTEwKI2RlZmluZSBrZXlfY3VycmVudF91c2VyIE5VTEwgTlVMTAojZGVmaW5lIGtleV91c2VycyBOVUxMIE5VTEwKI2RlZmluZSBrZXlfbG9jYWxfbWFjaGluZSBOVUxMIE5VTEwKI2RlZmluZSBrZXlfY2xhc3Nlc19yb290IE5VTEwgTlVMTAojZGVmaW5lIGtleV9keW5fZGF0YSBOVUxMIE5VTEwKI2RlZmluZSBrZXlfcGVyZm9ybWFuY2VfZGF0YSBOVUxMIE5VTEwKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogc3BsaXRfa2V5cGF0aCBbSW50ZXJuYWxdCiAqIHNwbGl0cyB0aGUgdW5pY29kZSBzdHJpbmcgJ3dwJyBpbnRvIGFuIGFycmF5IG9mIHN0cmluZ3MuCiAqIHRoZSBhcnJheSBpcyBhbGxvY2F0ZWQgYnkgdGhpcyBmdW5jdGlvbi4gCiAqIEZyZWUgdGhlIGFycmF5IHVzaW5nIEZSRUVfS0VZX1BBVEgKICoKICogUEFSQU1TCiAqICAgIHdwICBbSV0gU3RyaW5nIHRvIHNwbGl0IHVwCiAqICAgIHdwdiBbT10gQXJyYXkgb2YgcG9pbnRlcnMgdG8gc3RyaW5ncwogKiAgICB3cGMgW09dIE51bWJlciBvZiBjb21wb25lbnRzCiAqLwpzdGF0aWMgdm9pZCBzcGxpdF9rZXlwYXRoKCBMUENXU1RSIHdwLCBMUFdTVFIgKip3cHYsIGludCAqd3BjKQp7CiAgICBpbnQJaSxqLGxlbjsKICAgIExQV1NUUiB3czsKCiAgICBUUkFDRShyZWcsIiglcywlcCwlcClcbiIsZGVidWdzdHJfdyh3cCksd3B2LHdwYyk7CgogICAgd3MJPSBIRUFQX3N0cmR1cFcoIFN5c3RlbUhlYXAsIDAsIHdwICk7CgogICAgLyogV2Uga25vdyB3ZSBoYXZlIGF0IGxlYXN0IG9uZSBzdWJzdHJpbmcgKi8KICAgICp3cGMgPSAxOwoKICAgIC8qIFJlcGxhY2UgZWFjaCBiYWNrc2xhc2ggd2l0aCBOVUxMLCBhbmQgaW5jcmVtZW50IHRoZSBjb3VudCAqLwogICAgZm9yIChpPTA7d3NbaV07aSsrKSB7CiAgICAgICAgaWYgKHdzW2ldPT0nXFwnKSB7CiAgICAgICAgICAgIHdzW2ldPTA7CiAgICAgICAgICAgICgqd3BjKSsrOwogICAgICAgIH0KICAgIH0KCiAgICBsZW4gPSBpOwoKICAgIC8qIEFsbG9jYXRlIHRoZSBzcGFjZSBmb3IgdGhlIGFycmF5IG9mIHBvaW50ZXJzLCBsZWF2aW5nIHJvb20gZm9yIHRoZQogICAgICAgTlVMTCBhdCB0aGUgZW5kICovCiAgICAqd3B2ID0gKExQV1NUUiopSGVhcEFsbG9jKCBTeXN0ZW1IZWFwLCAwLCBzaXplb2YoTFBXU1RSKSooKndwYysyKSk7CiAgICAoKndwdilbMF09IHdzOwoKICAgIC8qIEFzc2lnbiBlYWNoIHBvaW50ZXIgdG8gdGhlIGFwcHJvcHJpYXRlIGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nICovCiAgICBqID0gMTsKICAgIGZvciAoaT0xO2k8bGVuO2krKykKICAgICAgICBpZiAod3NbaS0xXT09MCkgewogICAgICAgICAgICAoKndwdilbaisrXT13cytpOwogICAgICAgICAgICAvKiBUUkFDRShyZWcsICIgU3ViaXRlbSAlZCA9ICVzXG4iLGotMSxkZWJ1Z3N0cl93KCgqd3B2KVtqLTFdKSk7ICovCiAgICAgICAgfQoKICAgICgqd3B2KVtqXT1OVUxMOwp9CiNkZWZpbmUgRlJFRV9LRVlfUEFUSCBIZWFwRnJlZShTeXN0ZW1IZWFwLDAsd3BzWzBdKTtIZWFwRnJlZShTeXN0ZW1IZWFwLDAsd3BzKTsKCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUkVHSVNUUllfSW5pdCBbSW50ZXJuYWxdCiAqIFJlZ2lzdHJ5IGluaXRpYWxpc2F0aW9uLCBhbGxvY2F0ZXMgc29tZSBkZWZhdWx0IGtleXMuIAogKi8Kc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCgpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJVFJBQ0UocmVnLCIodm9pZClcbiIpOwoKCVJlZ0NyZWF0ZUtleTE2KEhLRVlfRFlOX0RBVEEsIlBlcmZTdGF0c1xcU3RhdERhdGEiLCZoa2V5KTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKICAgICAgICAvKiBUaGlzIHdhcyBhbiBPcGVuLCBidXQgc2luY2UgaXQgaXMgY2FsbGVkIGJlZm9yZSB0aGUgcmVhbCByZWdpc3RyaWVzCiAgICAgICAgICAgYXJlIGxvYWRlZCwgaXQgd2FzIGNoYW5nZWQgdG8gYSBDcmVhdGUgLSBNVEIgOTgwNTA3Ki8KCVJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXgzMkEoaGtleSwiSWRlbnRpZmllciIsMCxSRUdfU1osIlN5c3RlbVR5cGUgV0lORSIsc3RybGVuKCJTeXN0ZW1UeXBlIFdJTkUiKSk7CglSZWdDbG9zZUtleShoa2V5KTsKCgkvKiBcXFNPRlRXQVJFXFxNaWNyb3NvZnRcXFdpbmRvdyBOVFxcQ3VycmVudFZlcnNpb24KCSAqCQkJCQkJQ3VycmVudFZlcnNpb24KCSAqCQkJCQkJQ3VycmVudEJ1aWxkTnVtYmVyCgkgKgkJCQkJCUN1cnJlbnRUeXBlCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPd25lcgoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3JnYW5pemF0aW9uCgkgKgoJICovCgkvKiBTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxTZXJ2aWNlc1xcU05NUFxcUGFyYW1ldGVyc1xcUkZDMTE1NkFnZW50CgkgKiAJCQkJCXN0cmluZwlTeXNDb250YWN0CgkgKiAJCQkJCXN0cmluZwlTeXNMb2NhdGlvbgoJICogCQkJCQkJU3lzU2VydmljZXMKCSAqLwkJCQkJCQoJaWYgKC0xIT1nZXRob3N0bmFtZShidWYsMjAwKSkgewoJCVJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcQ29tcHV0ZXJOYW1lXFxDb21wdXRlck5hbWUiLCZoa2V5KTsKCQlSZWdTZXRWYWx1ZUV4MTYoaGtleSwiQ29tcHV0ZXJOYW1lIiwwLFJFR19TWixidWYsc3RybGVuKGJ1ZikrMSk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqIFNBVkUgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgUkVHSVNUUllfU0FWRV9WRVJTSU9OCTB4MDAwMDAwMDEKCi8qIFJlZ2lzdHJ5IHNhdmVmb3JtYXQ6CiAqIElmIHlvdSBjaGFuZ2UgaXQsIGluY3JlYXNlIGFib3ZlIG51bWJlciBieSAxLCB3aGljaCB3aWxsIGZsdXNoCiAqIG9sZCByZWdpc3RyeSBkYXRhYmFzZSBmaWxlcy4KICogCiAqIEdsb2JhbDoKICogCSJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWQiCiAqIAlzdWJrZXlzLi4uLgogKiBTdWJrZXlzOgogKiAJa2V5bmFtZQogKgkJdmFsdWVuYW1lPWxhc3Rtb2RpZmllZCx0eXBlLGRhdGEKICoJCS4uLgogKgkJc3Via2V5cwogKgkuLi4KICoga2V5bmFtZSx2YWx1ZW5hbWUsc3RyaW5nZGF0YToKICoJdGhlIHVzdWFsIGFzY2lpIGNoYXJhY3RlcnMgZnJvbSAweDAwLTB4ZmYgKHdlbGwsIG5vdCAweDAwKQogKglhbmQgXHVYWFhYIGFzIFVOSUNPREUgdmFsdWUgWFhYWCB3aXRoIFhYWFg+MHhmZgogKgkoICI9XFxcdCIgZXNjYXBlZCBpbiBcdVhYWFggZm9ybS4pCiAqIHR5cGUsbGFzdG1vZGlmaWVkOiAKICoJaW50CiAqIAogKiBGSVhNRTogZG9lc24ndCBzYXZlICdjbGFzcycgKHdoYXQgZG9lcyBpdCBtZWFuIGFueXdheT8pLCBub3IgZmxhZ3MuCiAqCiAqIFtIS0VZX0NVUlJFTlRfVVNFUlxcU29mdHdhcmVcXFRoZSBXSU5FIHRlYW1cXFdJTkVcXFJlZ2lzdHJ5XQogKiBTYXZlT25seVVwZGF0ZWRLZXlzPXllcwogKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVfY2hlY2tfdGFpbnRlZCBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF9zYXZlX2NoZWNrX3RhaW50ZWQoIExQS0VZU1RSVUNUIGxwa2V5ICkKewoJaW50CQl0YWludGVkOwoKCWlmICghbHBrZXkpCgkJcmV0dXJuIDA7CglpZiAobHBrZXktPmZsYWdzICYgUkVHX09QVElPTl9UQUlOVEVEKQoJCXRhaW50ZWQgPSAxOwoJZWxzZQoJCXRhaW50ZWQgPSAwOwoJd2hpbGUgKGxwa2V5KSB7CgkJaWYgKF9zYXZlX2NoZWNrX3RhaW50ZWQobHBrZXktPm5leHRzdWIpKSB7CgkJCWxwa2V5LT5mbGFncyB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJCXRhaW50ZWQgPSAxOwoJCX0KCQlscGtleQk9IGxwa2V5LT5uZXh0OwoJfQoJcmV0dXJuIHRhaW50ZWQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVfVVNUUklORyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfc2F2ZV9VU1RSSU5HKCBGSUxFICpGLCBMUFdTVFIgd3N0ciwgaW50IGVzY2FwZWVxICkKewoJTFBXU1RSCXM7CglpbnQJZG9lc2NhcGU7CgoJaWYgKHdzdHI9PU5VTEwpCgkJcmV0dXJuOwoJcz13c3RyOwoJd2hpbGUgKCpzKSB7CgkJZG9lc2NhcGU9MDsKCQlpZiAoKnM+MHhmZikKCQkJZG9lc2NhcGUgPSAxOwoJCWlmICgqcz09J1xuJykKCQkJZG9lc2NhcGUgPSAxOwoJCWlmIChlc2NhcGVlcSAmJiAqcz09Jz0nKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKCpzPT0nXFwnKQogICAgICAgICAgICAgICAgICAgICAgICBmcHV0YygqcyxGKTsgLyogaWYgXFwgdGhlbiBwdXQgaXQgdHdpY2UuICovCgkJaWYgKGRvZXNjYXBlKQoJCQlmcHJpbnRmKEYsIlxcdSUwNHgiLCooKHVuc2lnbmVkIHNob3J0KilzKSk7CgkJZWxzZQoJCQlmcHV0YygqcyxGKTsKCQlzKys7Cgl9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVzdWJrZXkgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfc2F2ZXN1YmtleSggRklMRSAqRiwgTFBLRVlTVFJVQ1QgbHBrZXksIGludCBsZXZlbCwgaW50IGFsbCApCnsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJaSx0YWJzLGo7CgoJbHB4a2V5CT0gbHBrZXk7Cgl3aGlsZSAobHB4a2V5KSB7CgkJaWYgKAkhKGxweGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1ZPTEFUSUxFKSAmJgoJCQkoYWxsIHx8IChscHhrZXktPmZsYWdzICYgUkVHX09QVElPTl9UQUlOVEVEKSkKCQkpIHsKCQkJZm9yICh0YWJzPWxldmVsO3RhYnMtLTspCgkJCQlmcHV0YygnXHQnLEYpOwoJCQlfc2F2ZV9VU1RSSU5HKEYsbHB4a2V5LT5rZXluYW1lLDEpOwoJCQlmcHV0cygiXG4iLEYpOwoJCQlmb3IgKGk9MDtpPGxweGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQkJCUxQS0VZVkFMVUUJdmFsPWxweGtleS0+dmFsdWVzK2k7CgoJCQkJZm9yICh0YWJzPWxldmVsKzE7dGFicy0tOykKCQkJCQlmcHV0YygnXHQnLEYpOwoJCQkJX3NhdmVfVVNUUklORyhGLHZhbC0+bmFtZSwwKTsKCQkJCWZwdXRjKCc9JyxGKTsKCQkJCWZwcmludGYoRiwiJWxkLCVsZCwiLHZhbC0+dHlwZSx2YWwtPmxhc3Rtb2RpZmllZCk7CgkJCQlpZiAoKDE8PHZhbC0+dHlwZSkgJiBVTklDT05WTUFTSykKCQkJCQlfc2F2ZV9VU1RSSU5HKEYsKExQV1NUUil2YWwtPmRhdGEsMCk7CgkJCQllbHNlCgkJCQkJZm9yIChqPTA7ajx2YWwtPmxlbjtqKyspCgkJCQkJCWZwcmludGYoRiwiJTAyeCIsKigodW5zaWduZWQgY2hhciopdmFsLT5kYXRhK2opKTsKCQkJCWZwdXRzKCJcbiIsRik7CgkJCX0KCQkJLyogZGVzY2VuZCByZWN1cnNpdmVseSAqLwoJCQlpZiAoIV9zYXZlc3Via2V5KEYsbHB4a2V5LT5uZXh0c3ViLGxldmVsKzEsYWxsKSkKCQkJCXJldHVybiAwOwoJCX0KCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlc3VicmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3NhdmVzdWJyZWcoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgYWxsICkKewoJZnByaW50ZihGLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWRcbiIsUkVHSVNUUllfU0FWRV9WRVJTSU9OKTsKCV9zYXZlX2NoZWNrX3RhaW50ZWQobHBrZXktPm5leHRzdWIpOwoJcmV0dXJuIF9zYXZlc3Via2V5KEYsbHBrZXktPm5leHRzdWIsMCxhbGwpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgQk9PTDMyIF9zYXZlcmVnKCBMUEtFWVNUUlVDVCBscGtleSwgY2hhciAqZm4sIGludCBhbGwgKQp7CglGSUxFCSpGOwoKCUY9Zm9wZW4oZm4sInciKTsKCWlmIChGPT1OVUxMKSB7CgkJV0FSTihyZWcsIkNvdWxkbid0IG9wZW4gJXMgZm9yIHdyaXRpbmc6ICVzXG4iLAoJCQlmbixzdHJlcnJvcihlcnJubykKCQkpOwoJCXJldHVybiBGQUxTRTsKCX0KCWlmICghX3NhdmVzdWJyZWcoRixscGtleSxhbGwpKSB7CgkJZmNsb3NlKEYpOwoJCXVubGluayhmbik7CgkJV0FSTihyZWcsIkZhaWxlZCB0byBzYXZlIGtleXMsIHBlcmhhcHMgbm8gbW9yZSBkaXNrc3BhY2UgZm9yICVzP1xuIixmbik7CgkJcmV0dXJuIEZBTFNFOwoJfQoJZmNsb3NlKEYpOwogICAgICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEVMTF9TYXZlUmVnaXN0cnkgW0ludGVybmFsXQogKi8Kdm9pZCBTSEVMTF9TYXZlUmVnaXN0cnkoIHZvaWQgKQp7CgljaGFyCSpmbjsKCXN0cnVjdAlwYXNzd2QJKnB3ZDsKCWNoYXIJYnVmWzRdOwoJSEtFWQloa2V5OwoJaW50CWFsbDsKCiAgICBUUkFDRShyZWcsIih2b2lkKVxuIik7CgoJYWxsPTA7CglpZiAoUmVnT3BlbktleTE2KEhLRVlfQ1VSUkVOVF9VU0VSLEtFWV9SRUdJU1RSWSwmaGtleSkhPUVSUk9SX1NVQ0NFU1MpIHsKCQlzdHJjcHkoYnVmLCJ5ZXMiKTsKCX0gZWxzZSB7CgkJRFdPUkQgbGVuLGp1bmssdHlwZTsKCgkJbGVuPTQ7CgkJaWYgKAkoRVJST1JfU1VDQ0VTUyE9UmVnUXVlcnlWYWx1ZUV4MzJBKAoJCQkJaGtleSwKCQkJCVZBTF9TQVZFVVBEQVRFRCwKCQkJCSZqdW5rLAoJCQkJJnR5cGUsCgkJCQlidWYsCgkJCQkmbGVuCgkJCSkpfHwgKHR5cGUhPVJFR19TWikKCQkpCgkJCXN0cmNweShidWYsInllcyIpOwoJCVJlZ0Nsb3NlS2V5KGhrZXkpOwoJfQoJaWYgKGxzdHJjbXBpMzJBKGJ1ZiwieWVzIikpCgkJYWxsPTE7Cglwd2Q9Z2V0cHd1aWQoZ2V0dWlkKCkpOwoJaWYgKHB3ZCE9TlVMTCAmJiBwd2QtPnB3X2RpciE9TlVMTCkKICAgICAgICB7CiAgICAgICAgICAgICAgICBjaGFyICp0bXA7CgoJCWZuPShjaGFyKil4bWFsbG9jKCBzdHJsZW4ocHdkLT5wd19kaXIpICsgc3RybGVuKFdJTkVfUFJFRklYKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfQ1VSUkVOVF9VU0VSKSArIDIgKTsKCQlzdHJjcHkoZm4scHdkLT5wd19kaXIpOwoJCXN0cmNhdChmbixXSU5FX1BSRUZJWCk7CgkJLyogY3JlYXRlIHRoZSBkaXJlY3RvcnkuIGRvbid0IGNhcmUgYWJvdXQgZXJyb3Jjb2Rlcy4gKi8KCQlta2RpcihmbiwwNzU1KTsgLyogZHJ3eHIteHIteCAqLwoJCXN0cmNhdChmbiwiLyJTQVZFX0NVUlJFTlRfVVNFUik7CgkJdG1wID0gKGNoYXIqKXhtYWxsb2Moc3RybGVuKGZuKStzdHJsZW4oIi50bXAiKSsxKTsKCQlzdHJjcHkodG1wLGZuKTtzdHJjYXQodG1wLCIudG1wIik7CgkJaWYgKF9zYXZlcmVnKGxvb2t1cF9oa2V5KEhLRVlfQ1VSUkVOVF9VU0VSKSx0bXAsYWxsKSkgewoJCQlpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CgkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKCQkJCXVubGluayh0bXApOwoJCQl9CgkJfQoJCWZyZWUodG1wKTsKCQlmcmVlKGZuKTsKCQlmbj0oY2hhciopeG1hbGxvYyhzdHJsZW4ocHdkLT5wd19kaXIpK3N0cmxlbihXSU5FX1BSRUZJWCkrc3RybGVuKFNBVkVfTE9DQUxfTUFDSElORSkrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwoJCXRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CgkJc3RyY3B5KHRtcCxmbik7c3RyY2F0KHRtcCwiLnRtcCIpOwoJCWlmIChfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpLHRtcCxhbGwpKSB7CgkJCWlmICgtMT09cmVuYW1lKHRtcCxmbikpIHsKCQkJCXBlcnJvcigicmVuYW1lIHRtcCByZWdpc3RyeSIpOwoJCQkJdW5saW5rKHRtcCk7CgkJCX0KCQl9CgkJZnJlZSh0bXApOwoJCWZyZWUoZm4pOwoJfSBlbHNlCgkJV0FSTihyZWcsIkZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWQuXG4iLGdldHVpZCgpKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKiogTE9BRCBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF9rZXkgW0ludGVybmFsXQogKi8Kc3RhdGljIExQS0VZU1RSVUNUIF9maW5kX29yX2FkZF9rZXkoIExQS0VZU1RSVUNUIGxwa2V5LCBMUFdTVFIga2V5bmFtZSApCnsKCUxQS0VZU1RSVUNUCWxweGtleSwqbHBscGtleTsKCglpZiAoKCFrZXluYW1lKSB8fCAoa2V5bmFtZVswXT09MCkpIHsKCQlmcmVlKGtleW5hbWUpOwoJCXJldHVybiBscGtleTsKCX0KCWxwbHBrZXk9ICYobHBrZXktPm5leHRzdWIpOwoJbHB4a2V5CT0gKmxwbHBrZXk7Cgl3aGlsZSAobHB4a2V5KSB7CgkJaWYgKCFsc3RyY21waTMyVyhscHhrZXktPmtleW5hbWUsa2V5bmFtZSkpCgkJCWJyZWFrOwoJCWxwbHBrZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7Cgl9CglpZiAobHB4a2V5PT1OVUxMKSB7CgkJKmxwbHBrZXkgPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7CgkJbWVtc2V0KGxweGtleSwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTsKCQlscHhrZXktPmtleW5hbWUJPSBrZXluYW1lOwoJfSBlbHNlCgkJZnJlZShrZXluYW1lKTsKCXJldHVybiBscHhrZXk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2ZpbmRfb3JfYWRkX3ZhbHVlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9maW5kX29yX2FkZF92YWx1ZSggTFBLRVlTVFJVQ1QgbHBrZXksIExQV1NUUiBuYW1lLCBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBkYXRhLCBEV09SRCBsZW4sIERXT1JEIGxhc3Rtb2RpZmllZCApCnsKCUxQS0VZVkFMVUUJdmFsPU5VTEw7CglpbnQJCWk7CgoJaWYgKG5hbWUgJiYgISpuYW1lKSB7LyogZW1wdHkgc3RyaW5nIGVxdWFscyBkZWZhdWx0IChOVUxMKSB2YWx1ZSAqLwoJCWZyZWUobmFtZSk7CgkJbmFtZSA9IE5VTEw7Cgl9CgoJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCWlmIChuYW1lPT1OVUxMKSB7CgkJCWlmICh2YWwtPm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCQl9IGVsc2UgewoJCQlpZiAoCXZhbC0+bmFtZSE9TlVMTCAmJiAKCQkJCSFsc3RyY21waTMyVyh2YWwtPm5hbWUsbmFtZSkKCQkJKQoJCQkJYnJlYWs7CgkJfQoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CgkJbHBrZXktPnZhbHVlcyA9IHhyZWFsbG9jKAoJCQlscGtleS0+dmFsdWVzLAoJCQkoKytscGtleS0+bnJvZnZhbHVlcykqc2l6ZW9mKEtFWVZBTFVFKQoJCSk7CgkJdmFsPWxwa2V5LT52YWx1ZXMraTsKCQltZW1zZXQodmFsLCdcMCcsc2l6ZW9mKEtFWVZBTFVFKSk7CgkJdmFsLT5uYW1lID0gbmFtZTsKCX0gZWxzZSB7CgkJaWYgKG5hbWUpCgkJCWZyZWUobmFtZSk7Cgl9CglpZiAodmFsLT5sYXN0bW9kaWZpZWQ8bGFzdG1vZGlmaWVkKSB7CgkJdmFsLT5sYXN0bW9kaWZpZWQ9bGFzdG1vZGlmaWVkOwoJCXZhbC0+dHlwZSA9IHR5cGU7CgkJdmFsLT5sZW4gID0gbGVuOwoJCWlmICh2YWwtPmRhdGEpIAoJCQlmcmVlKHZhbC0+ZGF0YSk7CgkJdmFsLT5kYXRhID0gZGF0YTsKCX0gZWxzZQoJCWZyZWUoZGF0YSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfbGluZSBbSW50ZXJuYWxdCiAqCiAqIHJlYWRzIGEgbGluZSBpbmNsdWRpbmcgZHluYW1pY2FsbHkgZW5sYXJnaW5nIHRoZSByZWFkYnVmZmVyIGFuZCB0aHJvd2luZwogKiBhd2F5IGNvbW1lbnRzCiAqLwpzdGF0aWMgaW50IF93aW5lX3JlYWRfbGluZSggRklMRSAqRiwgY2hhciAqKmJ1ZiwgaW50ICpsZW4gKQp7CgljaGFyCSpzLCpjdXJyZWFkOwoJaW50CW15bGVuLGN1cm9mZjsKCgljdXJyZWFkCT0gKmJ1ZjsKCW15bGVuCT0gKmxlbjsKCSoqYnVmCT0gJ1wwJzsKCXdoaWxlICgxKSB7CgkJd2hpbGUgKDEpIHsKCQkJcz1mZ2V0cyhjdXJyZWFkLG15bGVuLEYpOwoJCQlpZiAocz09TlVMTCkKCQkJCXJldHVybiAwOyAvKiBFT0YgKi8KCQkJaWYgKE5VTEw9PShzPXN0cmNocihjdXJyZWFkLCdcbicpKSkgewoJCQkJLyogYnVmZmVyIHdhc24ndCBsYXJnZSBlbm91Z2ggKi8KCQkJCWN1cm9mZgk9IHN0cmxlbigqYnVmKTsKCQkJCSpidWYJPSB4cmVhbGxvYygqYnVmLCpsZW4qMik7CgkJCQljdXJyZWFkCT0gKmJ1ZiArIGN1cm9mZjsKCQkJCW15bGVuCT0gKmxlbjsJLyogd2UgZmlsbGVkIHVwIHRoZSBidWZmZXIgYW5kIAoJCQkJCQkgKiBnb3QgbmV3ICcqbGVuJyBieXRlcyB0byBmaWxsCgkJCQkJCSAqLwoJCQkJKmxlbgk9ICpsZW4gKiAyOwoJCQl9IGVsc2UgewoJCQkJKnM9J1wwJzsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCS8qIHRocm93IGF3YXkgY29tbWVudHMgKi8KCQlpZiAoKipidWY9PScjJyB8fCAqKmJ1Zj09JzsnKSB7CgkJCWN1cnJlYWQJPSAqYnVmOwoJCQlteWxlbgk9ICpsZW47CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAocykgCS8qIGdvdCBlbmQgb2YgbGluZSAqLwoJCQlicmVhazsKCX0KCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9yZWFkX1VTVFJJTkcgW0ludGVybmFsXQogKgogKiBjb252ZXJ0cyBhIGNoYXIqIGludG8gYSBVTklDT0RFIHN0cmluZyAodXAgdG8gYSBzcGVjaWFsIGNoYXIpCiAqIGFuZCByZXR1cm5zIHRoZSBwb3NpdGlvbiBleGFjdGx5IGFmdGVyIHRoYXQgc3RyaW5nCiAqLwpzdGF0aWMgY2hhciogX3dpbmVfcmVhZF9VU1RSSU5HKCBjaGFyICpidWYsIExQV1NUUiAqc3RyICkKewoJY2hhcgkqczsKCUxQV1NUUgl3czsKCgkvKiByZWFkIHVwIHRvICI9IiBvciAiXDAiIG9yICJcbiIgKi8KCXMJPSBidWY7CglpZiAoKnMgPT0gJz0nKSB7CgkJLyogZW1wdHkgc3RyaW5nIGlzIHRoZSB3aW4zLjEgZGVmYXVsdCB2YWx1ZShOVUxMKSovCgkJKnN0cgk9IE5VTEw7CgkJcmV0dXJuIHM7Cgl9Cgkqc3RyCT0gKExQV1NUUil4bWFsbG9jKDIqc3RybGVuKGJ1ZikrMik7Cgl3cwk9ICpzdHI7Cgl3aGlsZSAoKnMgJiYgKCpzIT0nXG4nKSAmJiAoKnMhPSc9JykpIHsKCQlpZiAoKnMhPSdcXCcpCgkJCSp3cysrPSooKHVuc2lnbmVkIGNoYXIqKXMrKyk7CgkJZWxzZSB7CgkJCXMrKzsKCQkJaWYgKCpzPT0nXFwnKSB7CgkJCQkqd3MrKz0nXFwnOwoJCQkJcysrOwoJCQkJY29udGludWU7CgkJCX0KCQkJaWYgKCpzIT0ndScpIHsKCQkJCVdBUk4ocmVnLCJOb24gdW5pY29kZSBlc2NhcGUgc2VxdWVuY2UgXFwlYyBmb3VuZCBpbiB8JXN8XG4iLCpzLGJ1Zik7CgkJCQkqd3MrKz0nXFwnOwoJCQkJKndzKys9KnMrKzsKCQkJfSBlbHNlIHsKCQkJCWNoYXIJeGJ1Zls1XTsKCQkJCWludAl3YzsKCgkJCQlzKys7CgkJCQltZW1jcHkoeGJ1ZixzLDQpO3hidWZbNF09J1wwJzsKCQkJCWlmICghc3NjYW5mKHhidWYsIiV4Iiwmd2MpKQoJCQkJCVdBUk4ocmVnLCJTdHJhbmdlIGVzY2FwZSBzZXF1ZW5jZSAlcyBmb3VuZCBpbiB8JXN8XG4iLHhidWYsYnVmKTsKCQkJCXMrPTQ7CgkJCQkqd3MrKwk9KHVuc2lnbmVkIHNob3J0KXdjOwoJCQl9CgkJfQoJfQoJKndzCT0gMDsKCXdzCT0gKnN0cjsKCWlmICgqd3MpCgkJKnN0cgk9IHN0cmR1cFcoKnN0cik7CgllbHNlCgkJKnN0cgk9IE5VTEw7CglmcmVlKHdzKTsKCXJldHVybiBzOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2Fkc3Via2V5IFtJbnRlcm5hbF0KICoKICogTk9URVMKICogICAgSXQgc2VlbXMgbGlrZSB0aGlzIGlzIHJldHVybmluZyBhIGJvb2xlYW4uICBTaG91bGQgaXQ/CiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogMQogKiAgICBGYWlsdXJlOiAwCiAqLwpzdGF0aWMgaW50IF93aW5lX2xvYWRzdWJrZXkoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgbGV2ZWwsIGNoYXIgKipidWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICpidWZsZW4sIERXT1JEIG9wdGZsYWcgKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWk7CgljaGFyCQkqczsKCUxQV1NUUgkJbmFtZTsKCiAgICBUUkFDRShyZWcsIiglcCwlcCwlZCwlcywlZCwlbHgpXG4iLCBGLCBscGtleSwgbGV2ZWwsIGRlYnVnc3RyX2EoKmJ1ZiksCiAgICAgICAgICAqYnVmbGVuLCBvcHRmbGFnKTsKCiAgICBscGtleS0+ZmxhZ3MgfD0gb3B0ZmxhZzsKCiAgICAvKiBHb29kLiAgV2UgYWxyZWFkeSBnb3QgYSBsaW5lIGhlcmUgLi4uIHNvIHBhcnNlIGl0ICovCiAgICBscHhrZXkgPSBOVUxMOwogICAgd2hpbGUgKDEpIHsKICAgICAgICBpPTA7cz0qYnVmOwogICAgICAgIHdoaWxlICgqcz09J1x0JykgewogICAgICAgICAgICBzKys7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9CiAgICAgICAgaWYgKGk+bGV2ZWwpIHsKICAgICAgICAgICAgaWYgKGxweGtleT09TlVMTCkgewogICAgICAgICAgICAgICAgV0FSTihyZWcsIkdvdCBhIHN1YmhpZXJhcmNoeSB3aXRob3V0IHJlc3AuIGtleT9cbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3dpbmVfbG9hZHN1YmtleShGLGxweGtleSxsZXZlbCsxLGJ1ZixidWZsZW4sb3B0ZmxhZyk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCgkJLyogbGV0IHRoZSBjYWxsZXIgaGFuZGxlIHRoaXMgbGluZSAqLwoJCWlmIChpPGxldmVsIHx8ICoqYnVmPT0nXDAnKQoJCQlyZXR1cm4gMTsKCgkJLyogaXQgY2FuIGJlOiBhIHZhbHVlIG9yIGEga2V5bmFtZS4gUGFyc2UgdGhlIG5hbWUgZmlyc3QgKi8KCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLCZuYW1lKTsKCgkJLyogc3dpdGNoKCkgZGVmYXVsdDogaGFjayB0byBhdm9pZCBnb3RvcyAqLwoJCXN3aXRjaCAoMCkgewoJCWRlZmF1bHQ6CgkJCWlmICgqcz09J1wwJykgewoJCQkJbHB4a2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksbmFtZSk7CgkJCX0gZWxzZSB7CgkJCQlMUEJZVEUJCWRhdGE7CgkJCQlpbnQJCWxlbixsYXN0bW9kaWZpZWQsdHlwZTsKCgkJCQlpZiAoKnMhPSc9JykgewoJCQkJCVdBUk4ocmVnLCJVbmV4cGVjdGVkIGNoYXJhY3RlcjogJWNcbiIsKnMpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJcysrOwoJCQkJaWYgKDIhPXNzY2FuZihzLCIlZCwlZCwiLCZ0eXBlLCZsYXN0bW9kaWZpZWQpKSB7CgkJCQkJV0FSTihyZWcsIkhhdmVuJ3QgdW5kZXJzdG9vZCBwb3NzaWJsZSB2YWx1ZSBpbiB8JXN8LCBza2lwcGluZy5cbiIsKmJ1Zik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQkvKiBza2lwIHRoZSAyICwgKi8KCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlzPXN0cmNocihzLCcsJyk7cysrOwoJCQkJaWYgKCgxPDx0eXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJCQkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywoTFBXU1RSKikmZGF0YSk7CgkJCQkJaWYgKGRhdGEpCgkJCQkJCWxlbiA9IGxzdHJsZW4zMlcoKExQV1NUUilkYXRhKSoyKzI7CgkJCQkJZWxzZQkKCQkJCQkJbGVuID0gMDsKCQkJCX0gZWxzZSB7CgkJCQkJbGVuPXN0cmxlbihzKS8yOwoJCQkJCWRhdGEgPSAoTFBCWVRFKXhtYWxsb2MobGVuKzEpOwoJCQkJCWZvciAoaT0wO2k8bGVuO2krKykgewoJCQkJCQlkYXRhW2ldPTA7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldPSgqcy0nMCcpPDw0OwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ2EnKydceGEnKTw8NDsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV09KCpzLSdBJysnXHhhJyk8PDQ7CgkJCQkJCXMrKzsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV18PSpzLScwJzsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV18PSpzLSdhJysnXHhhJzsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV18PSpzLSdBJysnXHhhJzsKCQkJCQkJcysrOwoJCQkJCX0KCQkJCX0KCQkJCV9maW5kX29yX2FkZF92YWx1ZShscGtleSxuYW1lLHR5cGUsZGF0YSxsZW4sbGFzdG1vZGlmaWVkKTsKCQkJfQoJCX0KCQkvKiByZWFkIHRoZSBuZXh0IGxpbmUgKi8KCQlpZiAoIV93aW5lX3JlYWRfbGluZShGLGJ1ZixidWZsZW4pKQoJCQlyZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2Fkc3VicmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YnJlZyggRklMRSAqRiwgTFBLRVlTVFJVQ1QgbHBrZXksIERXT1JEIG9wdGZsYWcgKQp7CglpbnQJdmVyOwoJY2hhcgkqYnVmOwoJaW50CWJ1ZmxlbjsKCglidWY9eG1hbGxvYygxMCk7YnVmbGVuPTEwOwoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFzc2NhbmYoYnVmLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWQiLCZ2ZXIpKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKHZlciE9UkVHSVNUUllfU0FWRV9WRVJTSU9OKSB7CgkJVFJBQ0UocmVnLCJPbGQgZm9ybWF0ICglZCkgcmVnaXN0cnkgZm91bmQsIGlnbm9yaW5nIGl0LiAoYnVmIHdhcyAlcykuXG4iLHZlcixidWYpOwoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfbG9hZHN1YmtleShGLGxwa2V5LDAsJmJ1ZiwmYnVmbGVuLG9wdGZsYWcpKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJZnJlZShidWYpOwoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3dpbmVfbG9hZHJlZyggTFBLRVlTVFJVQ1QgbHBrZXksIGNoYXIgKmZuLCBEV09SRCBvcHRmbGFnICkKewogICAgRklMRSAqRjsKCiAgICBUUkFDRShyZWcsIiglcCwlcywlbHgpXG4iLGxwa2V5LGRlYnVnc3RyX2EoZm4pLG9wdGZsYWcpOwoKICAgIEYgPSBmb3BlbihmbiwicmIiKTsKICAgIGlmIChGPT1OVUxMKSB7CiAgICAgICAgV0FSTihyZWcsIkNvdWxkbid0IG9wZW4gJXMgZm9yIHJlYWRpbmc6ICVzXG4iLGZuLHN0cmVycm9yKGVycm5vKSApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmICghX3dpbmVfbG9hZHN1YnJlZyhGLGxwa2V5LG9wdGZsYWcpKSB7CiAgICAgICAgZmNsb3NlKEYpOwogICAgICAgIHVubGluayhmbik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgZmNsb3NlKEYpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfY29weV9yZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfY29weV9yZWdpc3RyeSggTFBLRVlTVFJVQ1QgZnJvbSwgTFBLRVlTVFJVQ1QgdG8gKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWo7CglMUEtFWVZBTFVFCXZhbGZyb207CgoJZnJvbT1mcm9tLT5uZXh0c3ViOwoJd2hpbGUgKGZyb20pIHsKCQlscHhrZXkgPSBfZmluZF9vcl9hZGRfa2V5KHRvLHN0cmR1cFcoZnJvbS0+a2V5bmFtZSkpOwoKCQlmb3IgKGo9MDtqPGZyb20tPm5yb2Z2YWx1ZXM7aisrKSB7CgkJCUxQV1NUUgluYW1lOwoJCQlMUEJZVEUJZGF0YTsKCgkJCXZhbGZyb20gPSBmcm9tLT52YWx1ZXMrajsKCQkJbmFtZT12YWxmcm9tLT5uYW1lOwoJCQlpZiAobmFtZSkgbmFtZT1zdHJkdXBXKG5hbWUpOwoJCQlkYXRhPShMUEJZVEUpeG1hbGxvYyh2YWxmcm9tLT5sZW4pOwoJCQltZW1jcHkoZGF0YSx2YWxmcm9tLT5kYXRhLHZhbGZyb20tPmxlbik7CgoJCQlfZmluZF9vcl9hZGRfdmFsdWUoCgkJCQlscHhrZXksCgkJCQluYW1lLAoJCQkJdmFsZnJvbS0+dHlwZSwKCQkJCWRhdGEsCgkJCQl2YWxmcm9tLT5sZW4sCgkJCQl2YWxmcm9tLT5sYXN0bW9kaWZpZWQKCQkJKTsKCQl9CgkJX2NvcHlfcmVnaXN0cnkoZnJvbSxscHhrZXkpOwoJCWZyb20gPSBmcm9tLT5uZXh0OwoJfQp9CgoKLyogV0lORE9XUyA5NSBSRUdJU1RSWSBMT0FERVIgKi8KLyogCiAqIFN0cnVjdHVyZSBvZiBhIHdpbjk1IHJlZ2lzdHJ5IGRhdGFiYXNlLgogKiBtYWluIGhlYWRlcjoKICogMCA6CSJDUkVHIgktIG1hZ2ljCiAqIDQgOglEV09SRCB2ZXJzaW9uCiAqIDggOglEV09SRCBvZmZzZXRfb2ZfUkdEQl9wYXJ0CiAqIDBDLi4wRjoJPyAoc29tZW9uZSBmaWxsIGluIHBsZWFzZSkKICogMTA6ICBXT1JECW51bWJlciBvZiBSR0RCIGJsb2NrcwogKiAxMjogIFdPUkQJPwogKiAxNDogIFdPUkQJYWx3YXlzIDAwMDA/CiAqIDE2OiAgV09SRAlhbHdheXMgMDAwMT8KICogMTguLjFGOgk/IChzb21lb25lIGZpbGwgaW4gcGxlYXNlKQogKgogKiAyMDogUkdLTl9zZWN0aW9uOgogKiAgIGhlYWRlcjoKICogCTAgOgkJIlJHS04iCS0gbWFnaWMKICogICAgICA0IDogRFdPUkQJb2Zmc2V0IHRvIGZpcnN0IFJHREIgc2VjdGlvbgogKiAgICAgIDggOiBEV09SRAlvZmZzZXQgdG8gPwogKiAJQy4uMHgxQjogCT8gKGZpbGwgaW4pCiAqICAgICAgMHgyMCAuLi4gb2Zmc2V0X29mX1JHREJfcGFydDogRGlzayBLZXkgRW50cnkgc3RydWN0dXJlcwogKgogKiAgIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZToKICoJMDA6IERXT1JECS0gRnJlZSBlbnRyeSBpbmRpY2F0b3IoPykKICoJMDQ6IERXT1JECS0gSGFzaCA9IHN1bSBvZiBieXRlcyBvZiBrZXluYW1lCiAqCTA4OiBEV09SRAktIFJvb3Qga2V5IGluZGljYXRvcj8gdW5rbm93biwgYnV0IHVzdWFsbHkgMHhGRkZGRkZGRiBvbiB3aW45NSBzeXN0ZW1zCiAqCTBDOiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBQcmV2aW91c0xldmVsIEtleS4KICoJMTA6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIE5leHQgU3VibGV2ZWwgS2V5LgogKgkxNDogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgTmV4dCBLZXkgKG9uIHNhbWUgbGV2ZWwpLgogKiBES0VQPjE4OiBXT1JECS0gTnIsIExvdyBTaWduaWZpY2FudCBwYXJ0LgogKgkxQTogV09SRAktIE5yLCBIaWdoIFNpZ25pZmljYW50IHBhcnQuCiAqCiAqIFRoZSBkaXNrIGFkZHJlc3MgYWx3YXlzIHBvaW50cyB0byB0aGUgbnIgcGFydCBvZiB0aGUgcHJldmlvdXMga2V5IGVudHJ5IAogKiBvZiB0aGUgcmVmZXJlbmNlZCBrZXkuIERvbid0IGFzayBtZSB3aHksIG9yIGV2ZW4gaWYgSSBnb3QgdGhpcyBjb3JyZWN0CiAqIGZyb20gc3RhcmluZyBhdCAxa2cgb2YgaGV4ZHVtcHMuIChES0VQKQogKgogKiBUaGUgSGlnaCBzaWduaWZpY2FudCBwYXJ0IG9mIHRoZSBzdHJ1Y3R1cmUgc2VlbXMgdG8gZXF1YWwgdGhlIG51bWJlcgogKiBvZiB0aGUgUkdEQiBzZWN0aW9uLiBUaGUgbG93IHNpZ25pZmljYW50IHBhcnQgaXMgYSB1bmlxdWUgSUQgd2l0aGluCiAqIHRoYXQgUkdEQiBzZWN0aW9uCiAqCiAqIFRoZXJlIGFyZSB0d28gbWlub3IgY29ycmVjdGlvbnMgdG8gdGhlIHBvc2l0aW9uIG9mIHRoYXQgc3RydWN0dXJlLgogKiAxLiBJZiB0aGUgYWRkcmVzcyBpcyB4eHgwMTQgb3IgeHh4MDE4IGl0IHdpbGwgYmUgYWxpZ25lZCB0byB4eHgwMWMgQU5EIAogKiAgICB0aGUgREtFIHJlcmVhZCBmcm9tIHRoZXJlLgogKiAyLiBJZiB0aGUgYWRkcmVzcyBpcyB4eHhGRnggaXQgd2lsbCBiZSBhbGlnbmVkIHRvICh4eHgrMSkwMDAuCiAqIENQUyAtIEkgaGF2ZSBub3QgZXhwZXJpZW5jZWQgdGhlIGFib3ZlIHBoZW5vbWVub24gaW4gbXkgcmVnaXN0cnkgZmlsZXMKICoKICogUkdEQl9zZWN0aW9uOgogKiAJMDA6CQkiUkdEQiIJLSBtYWdpYwogKgkwNDogRFdPUkQJb2Zmc2V0IHRvIG5leHQgUkdEQiBzZWN0aW9uCiAqCTA4OiBEV09SRAk/CiAqCTBDOiBXT1JECWFsd2F5cyAwMDBkPwogKgkwRTogV09SRAlSR0RCIGJsb2NrIG51bWJlcgogKgkxMDoJRFdPUkQJPyAoZXF1YWxzIHZhbHVlIGF0IG9mZnNldCA0IC0gdmFsdWUgYXQgb2Zmc2V0IDgpCiAqCTE0Li4xRjoJCT8KICoJMjAuLi4uLjoJZGlzayBrZXlzCiAqCiAqIGRpc2sga2V5OgogKiAJMDA6IAlEV09SRAluZXh0a2V5b2Zmc2V0CS0gb2Zmc2V0IHRvIHRoZSBuZXh0IGRpc2sga2V5IHN0cnVjdHVyZQogKgkwODogCVdPUkQJbnJMUwkJLSBsb3cgc2lnbmlmaWNhbnQgcGFydCBvZiBOUgogKgkwQTogCVdPUkQJbnJIUwkJLSBoaWdoIHNpZ25pZmljYW50IHBhcnQgb2YgTlIKICoJMEM6IAlEV09SRAlieXRlc3VzZWQJLSBieXRlcyB1c2VkIGluIHRoaXMgc3RydWN0dXJlLgogKgkxMDogCVdPUkQJbmFtZV9sZW4JLSBsZW5ndGggb2YgbmFtZSBpbiBieXRlcy4gd2l0aG91dCBcMAogKgkxMjogCVdPUkQJbnJfb2ZfdmFsdWVzCS0gbnVtYmVyIG9mIHZhbHVlcy4KICoJMTQ6IAljaGFyCW5hbWVbbmFtZV9sZW5dCS0gbmFtZSBzdHJpbmcuIE5vIFwwLgogKgkxNCtuYW1lX2xlbjogZGlzayB2YWx1ZXMKICoJbmV4dGtleW9mZnNldDogLi4uIG5leHQgZGlzayBrZXkKICoKICogZGlzayB2YWx1ZToKICoJMDA6CURXT1JECXR5cGUJCS0gdmFsdWUgdHlwZSAoaG1tLCBjb3VsZCBiZSBXT1JEIHRvbykKICoJMDQ6CURXT1JECQkJLSB1bmtub3duLCB1c3VhbGx5IDAKICoJMDg6CVdPUkQJbmFtZWxlbgkJLSBsZW5ndGggb2YgTmFtZS4gMCBtZWFucyBuYW1lPU5VTEwKICoJMEM6CVdPUkQJZGF0YWxlbgkJLSBsZW5ndGggb2YgRGF0YS4KICoJMTA6CWNoYXIJbmFtZVtuYW1lbGVuXQktIG5hbWUsIG5vIFwwCiAqCTEwK25hbWVsZW46IEJZVEUJZGF0YVtkYXRhbGVuXSAtIGRhdGEsIHdpdGhvdXQgXDAgaWYgc3RyaW5nCiAqCTEwK25hbWVsZW4rZGF0YWxlbjogbmV4dCB2YWx1ZXMgb3IgZGlzayBrZXkKICoKICogRGlzayBrZXlzIGFyZSBsYXllZCBvdXQgZmxhdCAuLi4gQnV0LCBzb21ldGltZXMsIG5yTFMgYW5kIG5ySFMgYXJlIGJvdGgKICogMHhGRkZGLCB3aGljaCBtZWFucyBza2lwcGluZyBvdmVyIG5leHRrZXlvZmZzZXQgYnl0ZXMgKGluY2x1ZGluZyB0aGlzCiAqIHN0cnVjdHVyZSkgYW5kIHJlYWRpbmcgYW5vdGhlciBSR0RCX3NlY3Rpb24uCiAqIHJlcGVhdCB1bnRpbCBlbmQgb2YgZmlsZS4KICoKICogQW4gaW50ZXJlc3RpbmcgcmVsYXRpb25zaGlwIGV4aXN0cyBpbiBSR0RCX3NlY3Rpb24uIFRoZSB2YWx1ZSBhdCBvZmZzZXQKICogMTAgZXF1YWxzIHRoZSB2YWx1ZSBhdCBvZmZzZXQgNCBtaW51cyB0aGUgdmFsdWUgYXQgb2Zmc2V0IDguIEkgaGF2ZSBubwogKiBpZGVhIGF0IHRoZSBtb21lbnQgd2hhdCB0aGlzIG1lYW5zLiAgKEtldmluIENvemVucykKICoKICogRklYTUU6IHRoaXMgZGVzY3JpcHRpb24gbmVlZHMgc29tZSBzZXJpb3VzIGhlbHAsIHllcy4KICovCgpzdHJ1Y3QJX3c5NWtleXZhbHVlIHsKCXVuc2lnbmVkIGxvbmcJCXR5cGU7Cgl1bnNpZ25lZCBzaG9ydAkJZGF0YWxlbjsKCWNoYXIJCQkqbmFtZTsKCXVuc2lnbmVkIGNoYXIJCSpkYXRhOwoJdW5zaWduZWQgbG9uZwkJeDE7CglpbnQJCQlsYXN0bW9kaWZpZWQ7Cn07CgpzdHJ1Y3QgCV93OTVrZXkgewoJY2hhcgkJCSpuYW1lOwoJaW50CQkJbnJvZnZhbHM7CglzdHJ1Y3QJX3c5NWtleXZhbHVlCSp2YWx1ZXM7CglzdHJ1Y3QgX3c5NWtleQkJKnByZXZsdmw7CglzdHJ1Y3QgX3c5NWtleQkJKm5leHRzdWI7CglzdHJ1Y3QgX3c5NWtleQkJKm5leHQ7Cn07CgoKc3RydWN0IF93OTVfaW5mbyB7CiAgY2hhciAqcmdrbmJ1ZmZlcjsKICBpbnQgIHJna25zaXplOwogIGNoYXIgKnJnZGJidWZmZXI7CiAgaW50ICByZ2Ric2l6ZTsKICBpbnQgIGRlcHRoOwogIGludCAgbGFzdG1vZGlmaWVkOwp9OwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9wcm9jZXNzS2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBMUEtFWVNUUlVDVCBfdzk1X3Byb2Nlc3NLZXkgKCBMUEtFWVNUUlVDVCBscGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5yTFMsIGludCBuck1TLCBzdHJ1Y3QgX3c5NV9pbmZvICppbmZvICkKCnsKICAvKiBEaXNrIEtleSBIZWFkZXIgc3RydWN0dXJlIChSR0RCIHBhcnQpICovCglzdHJ1Y3QJZGtoIHsKICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcJCW5leHRrZXlvZmY7IAoJCXVuc2lnbmVkIHNob3J0CQluckxTOwoJCXVuc2lnbmVkIHNob3J0CQluck1TOwoJCXVuc2lnbmVkIGxvbmcJCWJ5dGVzdXNlZDsKCQl1bnNpZ25lZCBzaG9ydAkJa2V5bmFtZWxlbjsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsdWVzOwoJCXVuc2lnbmVkIGxvbmcJCXh4MTsKCQkvKiBrZXluYW1lICovCgkJLyogZGlzayBrZXkgdmFsdWVzIG9yIG5vdGhpbmcgKi8KCX07CgkvKiBEaXNrIEtleSBWYWx1ZSBzdHJ1Y3R1cmUgKi8KCXN0cnVjdAlka3YgewoJCXVuc2lnbmVkIGxvbmcJCXR5cGU7CgkJdW5zaWduZWQgbG9uZwkJeDE7CgkJdW5zaWduZWQgc2hvcnQJCXZhbG5hbWVsZW47CgkJdW5zaWduZWQgc2hvcnQJCXZhbGRhdGFsZW47CgkJLyogdmFsbmFtZSwgdmFsZGF0YSAqLwoJfTsKCgkKCXN0cnVjdAlka2ggZGtoOwoJaW50CWJ5dGVzcmVhZCA9IDA7CgljaGFyICAgICpyZ2RiZGF0YSA9IGluZm8tPnJnZGJidWZmZXI7CglpbnQgICAgIG5ieXRlcyA9IGluZm8tPnJnZGJzaXplOwoJY2hhciAgICAqY3VyZGF0YSA9IHJnZGJkYXRhOwoJY2hhciAgICAqZW5kID0gcmdkYmRhdGEgKyBuYnl0ZXM7CglpbnQgICAgIG9mZl9uZXh0X3JnZGI7CgljaGFyICAgICpuZXh0ID0gcmdkYmRhdGE7CglpbnQgICAgIG5yZ2RiLCBpOwoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJCglkbyB7CgkgIGN1cmRhdGEgPSBuZXh0OwoJICBpZiAoc3RybmNtcChjdXJkYXRhLCAiUkdEQiIsIDQpKSByZXR1cm4gKE5VTEwpOwoJICAgIAoJICBtZW1jcHkoJm9mZl9uZXh0X3JnZGIsY3VyZGF0YSs0LDQpOwoJICBuZXh0ID0gY3VyZGF0YSArIG9mZl9uZXh0X3JnZGI7CgkgIG5yZ2RiID0gKGludCkgKigoc2hvcnQgKiljdXJkYXRhICsgNyk7CgoJfSB3aGlsZSAobnJnZGIgIT0gbnJNUyAmJiAobmV4dCA8IGVuZCkpOwoKCS8qIGN1cmRhdGEgbm93IHBvaW50cyB0byB0aGUgc3RhcnQgb2YgdGhlIHJpZ2h0IFJHREIgc2VjdGlvbiAqLwoJY3VyZGF0YSArPSAweDIwOwoKI2RlZmluZSBYUkVBRCh3aGVyZXRvLGxlbikgXAoJaWYgKChjdXJkYXRhICsgbGVuKSA8ZW5kKSB7XAoJCW1lbWNweSh3aGVyZXRvLGN1cmRhdGEsbGVuKTtcCgkJY3VyZGF0YSs9bGVuO1wKCQlieXRlc3JlYWQrPWxlbjtcCgl9CgoJZG8gewoJICBYUkVBRCgmZGtoLCBzaXplb2YgKGRraCkpOwoJICBpZiAoZGtoLm5yTFMgPT0gbnJMUykgYnJlYWs7CgoJICBjdXJkYXRhICs9IGRraC5uZXh0a2V5b2ZmIC0gc2l6ZW9mKGRraCk7Cgl9IHdoaWxlIChjdXJkYXRhIDwgbmV4dCk7CgoJaWYgKGRraC5uckxTICE9IG5yTFMpIHJldHVybiAoTlVMTCk7CgoJaWYgKG5yZ2RiICE9IGRraC5uck1TKSB7CgkgIHJldHVybiAoTlVMTCk7Cgl9CgogICAgICAgIGFzc2VydCgoZGtoLmtleW5hbWVsZW48MikgfHwgY3VyZGF0YVswXSk7CglscHhrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxzdHJjdnRBMlcoY3VyZGF0YSwgZGtoLmtleW5hbWVsZW4pKTsKCWN1cmRhdGEgKz0gZGtoLmtleW5hbWVsZW47CgoJZm9yIChpPTA7aTwgZGtoLnZhbHVlczsgaSsrKSB7CgkgIHN0cnVjdCBka3YgZGt2OwoJICBMUEJZVEUgZGF0YTsKCSAgaW50IGxlbjsKCSAgTFBXU1RSIG5hbWU7CgoJICBYUkVBRCgmZGt2LHNpemVvZihka3YpKTsKCgkgIG5hbWUgPSBzdHJjdnRBMlcoY3VyZGF0YSwgZGt2LnZhbG5hbWVsZW4pOwoJICBjdXJkYXRhICs9IGRrdi52YWxuYW1lbGVuOwoKCSAgaWYgKCgxIDw8IGRrdi50eXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkgICAgZGF0YSA9IChMUEJZVEUpIHN0cmN2dEEyVyhjdXJkYXRhLCBka3YudmFsZGF0YWxlbik7CgkgICAgbGVuID0gMiooZGt2LnZhbGRhdGFsZW4gKyAxKTsKCSAgfSBlbHNlIHsKCSAgICAvKiBJIGRvbid0IHRoaW5rIHdlIHdhbnQgdG8gTlVMTCB0ZXJtaW5hdGUgYWxsIGRhdGEgKi8KCSAgICBkYXRhID0geG1hbGxvYyhka3YudmFsZGF0YWxlbik7CgkgICAgbWVtY3B5IChkYXRhLCBjdXJkYXRhLCBka3YudmFsZGF0YWxlbik7CgkgICAgbGVuID0gZGt2LnZhbGRhdGFsZW47CgkgIH0KCgkgIGN1cmRhdGEgKz0gZGt2LnZhbGRhdGFsZW47CgkgIAoJICBfZmluZF9vcl9hZGRfdmFsdWUoCgkJCSAgICAgbHB4a2V5LAoJCQkgICAgIG5hbWUsCgkJCSAgICAgZGt2LnR5cGUsCgkJCSAgICAgZGF0YSwKCQkJICAgICBsZW4sCgkJCSAgICAgaW5mby0+bGFzdG1vZGlmaWVkCgkJCSAgICAgKTsKCgl9CgoJcmV0dXJuIChscHhrZXkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfd2Fsa3Jna24gW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3c5NV93YWxrcmdrbiggTFBLRVlTVFJVQ1QgcHJldmtleSwgY2hhciAqb2ZmLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IF93OTVfaW5mbyAqaW5mbyApCgp7CiAgLyogRGlzayBLZXkgRW50cnkgc3RydWN0dXJlIChSR0tOIHBhcnQpICovCiAgc3RydWN0CWRrZSB7CiAgICB1bnNpZ25lZCBsb25nCQl4MTsKICAgIHVuc2lnbmVkIGxvbmcJCXgyOwogICAgdW5zaWduZWQgbG9uZwkJeDM7Lyp1c3VhbGx5IDB4RkZGRkZGRkYgKi8KICAgIHVuc2lnbmVkIGxvbmcJCXByZXZsdmw7CiAgICB1bnNpZ25lZCBsb25nCQluZXh0c3ViOwogICAgdW5zaWduZWQgbG9uZwkJbmV4dDsKICAgIHVuc2lnbmVkIHNob3J0CQluckxTOwogICAgdW5zaWduZWQgc2hvcnQJCW5yTVM7CiAgfSAqZGtlID0gKHN0cnVjdCBka2UgKilvZmY7CiAgTFBLRVlTVFJVQ1QgIGxweGtleTsKCiAgaWYgKGRrZSA9PSBOVUxMKSB7CiAgICBka2UgPSAoc3RydWN0IGRrZSAqKSAoKGNoYXIgKilpbmZvLT5yZ2tuYnVmZmVyKTsKICB9CgogIGxweGtleSA9IF93OTVfcHJvY2Vzc0tleShwcmV2a2V5LCBka2UtPm5yTFMsIGRrZS0+bnJNUywgaW5mbyk7CiAgLyogWFhYIDwtLSBUaGlzIGlzIGEgaGFjayovCiAgaWYgKCFscHhrZXkpIHsKICAgIGxweGtleSA9IHByZXZrZXk7CiAgfQoKICBpZiAoZGtlLT5uZXh0c3ViICE9IC0xICYmIAogICAgICAoKGRrZS0+bmV4dHN1YiAtIDB4MjApIDwgaW5mby0+cmdrbnNpemUpIAogICAgICAmJiAoZGtlLT5uZXh0c3ViID4gMHgyMCkpIHsKICAgIAogICAgX3c5NV93YWxrcmdrbihscHhrZXksIAoJCSAgaW5mby0+cmdrbmJ1ZmZlciArIGRrZS0+bmV4dHN1YiAtIDB4MjAsIAoJCSAgaW5mbyk7CiAgfQogIAogIGlmIChka2UtPm5leHQgIT0gLTEgJiYgCiAgICAgICgoZGtlLT5uZXh0IC0gMHgyMCkgPCBpbmZvLT5yZ2tuc2l6ZSkgJiYgCiAgICAgIChka2UtPm5leHQgPiAweDIwKSkgewogICAgX3c5NV93YWxrcmdrbihwcmV2a2V5LCAgCgkJICBpbmZvLT5yZ2tuYnVmZmVyICsgZGtlLT5uZXh0IC0gMHgyMCwKCQkgIGluZm8pOwogIH0KCiAgcmV0dXJuOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvYWRyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3c5NV9sb2FkcmVnKCBjaGFyKiBmbiwgTFBLRVlTVFJVQ1QgbHBrZXkgKQp7CglIRklMRTMyCQloZmQ7CgljaGFyCQltYWdpY1s1XTsKCXVuc2lnbmVkIGxvbmcJd2hlcmUsdmVyc2lvbixyZ2Ric2VjdGlvbixlbmQ7CglzdHJ1Y3QgICAgICAgICAgX3c5NV9pbmZvIGluZm87CglPRlNUUlVDVAlvZnM7CglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmRpbmZvOwoKCVRSQUNFKHJlZywiTG9hZGluZyBXaW45NSByZWdpc3RyeSBkYXRhYmFzZSAnJXMnXG4iLGZuKTsKCWhmZD1PcGVuRmlsZTMyKGZuLCZvZnMsT0ZfUkVBRCk7CglpZiAoaGZkPT1IRklMRV9FUlJPUjMyKQoJCXJldHVybjsKCW1hZ2ljWzRdPTA7CglpZiAoNCE9X2xyZWFkMzIoaGZkLG1hZ2ljLDQpKQoJCXJldHVybjsKCWlmIChzdHJjbXAobWFnaWMsIkNSRUciKSkgewoJCVdBUk4ocmVnLCIlcyBpcyBub3QgYSB3OTUgcmVnaXN0cnkuXG4iLGZuKTsKCQlyZXR1cm47Cgl9CglpZiAoNCE9X2xyZWFkMzIoaGZkLCZ2ZXJzaW9uLDQpKQoJCXJldHVybjsKCWlmICg0IT1fbHJlYWQzMihoZmQsJnJnZGJzZWN0aW9uLDQpKQoJCXJldHVybjsKCWlmICgtMT09X2xsc2VlazMyKGhmZCwweDIwLFNFRUtfU0VUKSkKCQlyZXR1cm47CglpZiAoNCE9X2xyZWFkMzIoaGZkLG1hZ2ljLDQpKQoJCXJldHVybjsKCWlmIChzdHJjbXAobWFnaWMsIlJHS04iKSkgewoJCVdBUk4ocmVnLCAic2Vjb25kIElGRiBoZWFkZXIgbm90IFJHS04sIGJ1dCAlc1xuIiwgbWFnaWMpOwoJCXJldHVybjsKCX0KCgkvKiBTVEVQIDE6IEtleWxpbmsgc3RydWN0dXJlcyAqLwoJaWYgKC0xPT1fbGxzZWVrMzIoaGZkLDB4NDAsU0VFS19TRVQpKQoJCXJldHVybjsKCXdoZXJlCT0gMHg0MDsKCWVuZAk9IHJnZGJzZWN0aW9uOwoKCWluZm8ucmdrbnNpemUgPSBlbmQgLSB3aGVyZTsKCWluZm8ucmdrbmJ1ZmZlciA9IChjaGFyKil4bWFsbG9jKGluZm8ucmdrbnNpemUpOwoJaWYgKGluZm8ucmdrbnNpemUgIT0gX2xyZWFkMzIoaGZkLGluZm8ucmdrbmJ1ZmZlcixpbmZvLnJna25zaXplKSkKCQlyZXR1cm47CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZmQsJmhmZGluZm8pKQoJCXJldHVybjsKCgllbmQgPSBoZmRpbmZvLm5GaWxlU2l6ZUxvdzsKCWluZm8ubGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmRpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCglpZiAoLTE9PV9sbHNlZWszMihoZmQscmdkYnNlY3Rpb24sU0VFS19TRVQpKQoJCXJldHVybjsKCglpbmZvLnJnZGJidWZmZXIgPSAoY2hhciopeG1hbGxvYyhlbmQtcmdkYnNlY3Rpb24pOwoJaW5mby5yZ2Ric2l6ZSA9IGVuZCAtIHJnZGJzZWN0aW9uOwoKCWlmIChpbmZvLnJnZGJzaXplICE9X2xyZWFkMzIoaGZkLGluZm8ucmdkYmJ1ZmZlcixpbmZvLnJnZGJzaXplKSkKCQlyZXR1cm47CglfbGNsb3NlMzIoaGZkKTsKCglfdzk1X3dhbGtyZ2tuKGxwa2V5LCBOVUxMLCAmaW5mbyk7CgoJZnJlZSAoaW5mby5yZ2RiYnVmZmVyKTsKCWZyZWUgKGluZm8ucmdrbmJ1ZmZlcik7Cn0KCgovKiBXSU5ET1dTIDMxIFJFR0lTVFJZIExPQURFUiwgc3VwcGxpZWQgYnkgVG9yIFNq+HdhbGwsIHRvckBzbi5ubyAqLwoKLyoKICAgIHJlZ2hhY2sgLSB3aW5kb3dzIDMuMTEgcmVnaXN0cnkgZGF0YSBmb3JtYXQgZGVtbyBwcm9ncmFtLgoKICAgIFRoZSByZWcuZGF0IGZpbGUgaGFzIDMgcGFydHMsIGEgaGVhZGVyLCBhIHRhYmxlIG9mIDgtYnl0ZSBlbnRyaWVzIHRoYXQgaXMKICAgIGEgY29tYmluZWQgaGFzaCB0YWJsZSBhbmQgdHJlZSBkZXNjcmlwdGlvbiwgYW5kIGZpbmFsbHkgYSB0ZXh0IHRhYmxlLgoKICAgIFRoZSBoZWFkZXIgaXMgb2J2aW91cyBmcm9tIHRoZSBzdHJ1Y3QgaGVhZGVyLiBUaGUgdGFib2ZmMSBhbmQgdGFib2ZmMgogICAgZmllbGRzIGFyZSBhbHdheXMgMHgyMCwgYW5kIHRoZWlyIHVzYWdlIGlzIHVua25vd24uCgogICAgVGhlIDgtYnl0ZSBlbnRyeSB0YWJsZSBoYXMgdmFyaW91cyBlbnRyeSB0eXBlcy4KCiAgICB0YWJlbnRbMF0gaXMgYSByb290IGluZGV4LiBUaGUgc2Vjb25kIHdvcmQgaGFzIHRoZSBpbmRleCBvZiB0aGUgcm9vdCBvZgogICAgICAgICAgICB0aGUgZGlyZWN0b3J5LgogICAgdGFiZW50WzEuLmhhc2hzaXplXSBpcyBhIGhhc2ggdGFibGUuIFRoZSBmaXJzdCB3b3JkIGluIHRoZSBoYXNoIGVudHJ5IGlzCiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUga2V5L3ZhbHVlIHRoYXQgaGFzIHRoYXQgaGFzaC4gRGF0YSB3aXRoIHRoZSBzYW1lCiAgICAgICAgICAgIGhhc2ggdmFsdWUgYXJlIG9uIGEgY2lyY3VsYXIgbGlzdC4gVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZQogICAgICAgICAgICBoYXNoIGVudHJ5IGFyZSBhbHdheXMgemVyby4KICAgIHRhYmVudFtoYXNoc2l6ZS4udGFiY250XSBpcyB0aGUgdHJlZSBzdHJ1Y3R1cmUuIFRoZXJlIGFyZSB0d28ga2luZHMgb2YKICAgICAgICAgICAgZW50cnk6IGRpcmVudCBhbmQga2V5ZW50L3ZhbGVudC4gVGhleSBhcmUgaWRlbnRpZmllZCBieSBjb250ZXh0LgogICAgdGFiZW50W2ZyZWVpZHhdIGlzIHRoZSBmaXJzdCBmcmVlIGVudHJ5LiBUaGUgZmlyc3Qgd29yZCBpbiBhIGZyZWUgZW50cnkKICAgICAgICAgICAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGZyZWUgZW50cnkuIFRoZSBsYXN0IGhhcyAwIGFzIGEgbGluay4KICAgICAgICAgICAgVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZSBmcmVlIGxpc3QgYXJlIHByb2JhYmx5IGlycmVsZXZhbnQuCgogICAgRW50cmllcyBpbiB0ZXh0IHRhYmxlIGFyZSBwcmVjZWVkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewoJY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCgl1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7Cgl1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7Cgl1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCgl1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgKi8Kdm9pZApfX3czMV9kdW1wdHJlZSgJdW5zaWduZWQgc2hvcnQgaWR4LAoJCXVuc2lnbmVkIGNoYXIgKnR4dCwKCQlzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYiwKCQlzdHJ1Y3QgX3czMV9oZWFkZXIgKmhlYWQsCgkJTFBLRVlTVFJVQ1QJbHBrZXksCgkJdGltZV90CQlsYXN0bW9kaWZpZWQsCgkJaW50CQlsZXZlbAopIHsKCXN0cnVjdCBfdzMxX2RpcmVudAkqZGlyOwoJc3RydWN0IF93MzFfa2V5ZW50CSprZXk7CglzdHJ1Y3QgX3czMV92YWxlbnQJKnZhbDsKCUxQS0VZU1RSVUNUCQl4bHBrZXkgPSBOVUxMOwoJTFBXU1RSCQkJbmFtZSx2YWx1ZTsKCXN0YXRpYyBjaGFyCQl0YWlsWzQwMF07CgoJd2hpbGUgKGlkeCE9MCkgewoJCWRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgoJCWlmIChkaXItPmtleV9pZHgpIHsKCQkJa2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKCQkJbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKCQkJdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKCQkJLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZSAKCQkJICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwoJCQkgKi8KCQkJaWYgKCFsZXZlbCAmJiAhbHN0cmNtcDMyQSh0YWlsLCIuY2xhc3NlcyIpKSB7CgkJCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCQkJaWR4PWRpci0+c2libGluZ19pZHg7CgkJCQljb250aW51ZTsKCQkJfQoJCQluYW1lPXN0cmR1cEEyVyh0YWlsKTsKCgkJCXhscGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoKCQkJLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCgkJCWlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKCQkJCWlmIChkaXItPnZhbHVlX2lkeCkgewoJCQkJCXZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKCQkJCQltZW1jcHkodGFpbCwmdHh0W3ZhbC0+c3RyaW5nX29mZl0sdmFsLT5sZW5ndGgpOwoJCQkJCXRhaWxbdmFsLT5sZW5ndGhdPSdcMCc7CgkJCQkJdmFsdWU9c3RyZHVwQTJXKHRhaWwpOwoJCQkJCV9maW5kX29yX2FkZF92YWx1ZSh4bHBrZXksTlVMTCxSRUdfU1osKExQQllURSl2YWx1ZSxsc3RybGVuMzJXKHZhbHVlKSoyKzIsbGFzdG1vZGlmaWVkKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCVRSQUNFKHJlZywic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKCQl9CgkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHhscGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJaWR4PWRpci0+c2libGluZ19pZHg7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93MzFfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwp2b2lkIF93MzFfbG9hZHJlZygpIHsKCUhGSUxFMzIJCQloZjsKCXN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwoJc3RydWN0IF93MzFfdGFiZW50CSp0YWI7Cgl1bnNpZ25lZCBjaGFyCQkqdHh0OwoJaW50CQkJbGVuOwoJT0ZTVFJVQ1QJCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmaW5mbzsKCXRpbWVfdAkJCWxhc3Rtb2RpZmllZDsKCUxQS0VZU1RSVUNUCQlscGtleTsKCglUUkFDRShyZWcsIih2b2lkKVxuIik7CgoJaGYgPSBPcGVuRmlsZTMyKCJyZWcuZGF0Iiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmPT1IRklMRV9FUlJPUjMyKQoJCXJldHVybjsKCgkvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KCWlmIChzaXplb2YoaGVhZCkhPV9scmVhZDMyKGhmLCZoZWFkLHNpemVvZihoZWFkKSkpIHsKCQlFUlIocmVnLCAicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCWlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpIT0wKSB7CgkJRVJSKHJlZywgInJlZy5kYXQgaGFzIGJhZCBzaWduYXR1cmUuXG4iKTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCglsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwoJLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwoJdGFiID0geG1hbGxvYyhsZW4pOwoJaWYgKGxlbiE9X2xyZWFkMzIoaGYsdGFiLGxlbikpIHsKCQlFUlIocmVnLCJjb3VsZG4ndCByZWFkICVkIGJ5dGVzLlxuIixsZW4pOyAKCQlmcmVlKHRhYik7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CgoJLyogcmVhZCB0ZXh0ICovCgl0eHQgPSB4bWFsbG9jKGhlYWQudGV4dHNpemUpOwoJaWYgKC0xPT1fbGxzZWVrMzIoaGYsaGVhZC50ZXh0b2ZmLFNFRUtfU0VUKSkgewoJCUVSUihyZWcsImNvdWxkbid0IHNlZWsgdG8gdGV4dGJsb2NrLlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAoaGVhZC50ZXh0c2l6ZSE9X2xyZWFkMzIoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CgkJRVJSKHJlZywidGV4dGJsb2NrIHRvbyBzaG9ydCAoJWQgaW5zdGVhZCBvZiAlbGQpLlxuIixsZW4saGVhZC50ZXh0c2l6ZSk7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZiwmaGZpbmZvKSkgewoJCUVSUihyZWcsIkdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlIGZhaWxlZD8uXG4iKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCWxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoSEtFWV9DTEFTU0VTX1JPT1QpOwoJX193MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLDApOwoJZnJlZSh0YWIpOwoJZnJlZSh0eHQpOwoJX2xjbG9zZTMyKGhmKTsKCXJldHVybjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX0xvYWRSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwp2b2lkIFNIRUxMX0xvYWRSZWdpc3RyeSggdm9pZCApCnsKCWNoYXIJKmZuOwoJc3RydWN0CXBhc3N3ZAkqcHdkOwoJTFBLRVlTVFJVQ1QJbHBrZXk7CglIS0VZCQloa2V5OwoKCVRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCgkvKiBMb2FkIHdpbmRvd3MgMy4xIGVudHJpZXMgKi8KCV93MzFfbG9hZHJlZygpOwoJLyogTG9hZCB3aW5kb3dzIDk1IGVudHJpZXMgKi8KCV93OTVfbG9hZHJlZygiQzpcXHN5c3RlbS4xc3QiLAlsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpKTsKCV93OTVfbG9hZHJlZygic3lzdGVtLmRhdCIsCWxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSkpOwoJX3c5NV9sb2FkcmVnKCJ1c2VyLmRhdCIsCWxvb2t1cF9oa2V5KEhLRVlfVVNFUlMpKTsKCgkvKiB0aGUgZ2xvYmFsIHVzZXIgZGVmYXVsdCBpcyBsb2FkZWQgdW5kZXIgSEtFWV9VU0VSU1xcLkRlZmF1bHQgKi8KCVJlZ0NyZWF0ZUtleTE2KEhLRVlfVVNFUlMsIi5EZWZhdWx0IiwmaGtleSk7CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgICAgIGlmKCFscGtleSkKICAgICAgICAgICAgV0FSTihyZWcsIkNvdWxkIG5vdCBjcmVhdGUgZ2xvYmFsIHVzZXIgZGVmYXVsdCBrZXlcbiIpOwoJX3dpbmVfbG9hZHJlZyhscGtleSxTQVZFX1VTRVJTX0RFRkFVTFQsMCk7CgoJLyogSEtFWV9VU0VSU1xcLkRlZmF1bHQgaXMgY29waWVkIHRvIEhLRVlfQ1VSUkVOVF9VU0VSICovCglfY29weV9yZWdpc3RyeShscGtleSxsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogdGhlIGdsb2JhbCBtYWNoaW5lIGRlZmF1bHRzICovCglfd2luZV9sb2FkcmVnKGxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSksU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQsMCk7CgoJLyogbG9hZCB0aGUgdXNlciBzYXZlZCByZWdpc3RyaWVzICovCgoJLyogRklYTUU6IHVzZSBnZXRlbnYoIkhPTUUiKSBvciBnZXRwd3VpZChnZXR1aWQoKSktPnB3X2RpciA/PyAqLwoKCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CglpZiAocHdkIT1OVUxMICYmIHB3ZC0+cHdfZGlyIT1OVUxMKSB7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0NVUlJFTlRfVVNFUik7CgkJX3dpbmVfbG9hZHJlZyhsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUiksZm4sUkVHX09QVElPTl9UQUlOVEVEKTsKCQlmcmVlKGZuKTsKCQlmbj0oY2hhciopeG1hbGxvYyhzdHJsZW4ocHdkLT5wd19kaXIpK3N0cmxlbihXSU5FX1BSRUZJWCkrc3RybGVuKFNBVkVfTE9DQUxfTUFDSElORSkrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwoJCV93aW5lX2xvYWRyZWcobG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSxmbixSRUdfT1BUSU9OX1RBSU5URUQpOwoJCWZyZWUoZm4pOwoJfSBlbHNlCgkJV0FSTihyZWcsIkZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWQuXG4iLGdldHVpZCgpKTsKCWlmIChFUlJPUl9TVUNDRVNTPT1SZWdDcmVhdGVLZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpKSB7CgkJRFdPUkQJanVuayx0eXBlLGxlbjsKCQljaGFyCWRhdGFbNV07CgoJCWxlbj00OwoJCWlmICgoCVJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQkJCWhrZXksCgkJCQlWQUxfU0FWRVVQREFURUQsCgkJCQkmanVuaywKCQkJCSZ0eXBlLAoJCQkJZGF0YSwKCQkJCSZsZW4KCQkJKSE9RVJST1JfU1VDQ0VTUykgfHwKCQkJdHlwZSAhPSBSRUdfU1oKCQkpCgkJCVJlZ1NldFZhbHVlRXgzMkEoaGtleSxWQUxfU0FWRVVQREFURUQsMCxSRUdfU1osInllcyIsNCk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIEFQSSBGVU5DVElPTlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKgogKiBPcGVuIEtleXMuCiAqCiAqIEFsbCBmdW5jdGlvbnMgYXJlIHN0dWJzIHRvIFJlZ09wZW5LZXlFeDMyVyB3aGVyZSBhbGwgdGhlCiAqIG1hZ2ljIGhhcHBlbnMuIAogKgogKiBDYWxscGF0aDoKICogUmVnT3BlbktleTE2IC0+IFJlZ09wZW5LZXkzMkEgLT4gUmVnT3BlbktleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnT3BlbktleTMyVyAgIC0+IFJlZ09wZW5LZXlFeDMyVyAKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5RXgzMlcgW0FEVkFQSTMyLjE1MF0KICogT3BlbnMgdGhlIHNwZWNpZmllZCBrZXkKICoKICogVW5saWtlIFJlZ0NyZWF0ZUtleUV4LCB0aGlzIGRvZXMgbm90IGNyZWF0ZSB0aGUga2V5IGlmIGl0IGRvZXMgbm90IGV4aXN0LgogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIE5hbWUgb2Ygc3Via2V5IHRvIG9wZW4KICogICAgZHdSZXNlcnZlZCBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIHplcm8KICogICAgc2FtRGVzaXJlZCBbSV0gU2VjdXJpdHkgYWNjZXNzIG1hc2sKICogICAgcmV0a2V5ICAgICBbT10gQWRkcmVzcyBvZiBoYW5kbGUgb2Ygb3BlbiBrZXkKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5RXgzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdTQU0gc2FtRGVzaXJlZCwgTFBIS0VZIHJldGtleSApCnsKCUxQS0VZU1RSVUNUCWxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbHgsJXApXG4iLCBoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksZHdSZXNlcnZlZCwKICAgICAgICAgIHNhbURlc2lyZWQscmV0a2V5KTsKCiAgICBscE5leHRLZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIGlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpIHsKICAgICAgICAvKiBFaXRoZXIgTlVMTCBvciBwb2ludGVyIHRvIGVtcHR5IHN0cmluZywgc28gcmV0dXJuIGEgbmV3IGhhbmRsZQogICAgICAgICAgIHRvIHRoZSBvcmlnaW5hbCBoa2V5ICovCiAgICAgICAgYWRkX2hhbmRsZSgrK2N1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwogICAgICAgICpyZXRrZXk9Y3VycmVudGhhbmRsZTsKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAobHBzelN1YktleVswXSA9PSAnXFwnKSB7CiAgICAgICAgV0FSTihyZWcsIlN1YmtleSAlcyBtdXN0IG5vdCBiZWdpbiB3aXRoIGJhY2tzbGFzaC5cbiIsZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CiAgICAgICAgcmV0dXJuIEVSUk9SX0JBRF9QQVRITkFNRTsKICAgIH0KCglzcGxpdF9rZXlwYXRoKGxwc3pTdWJLZXksJndwcywmd3BjKTsKCWkgPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleSA9IGxwTmV4dEtleTsKCiAgICB3aGlsZSAod3BzW2ldKSB7CiAgICAgICAgbHB4a2V5PWxwTmV4dEtleS0+bmV4dHN1YjsKICAgICAgICB3aGlsZSAobHB4a2V5KSB7CiAgICAgICAgICAgIGlmICghbHN0cmNtcGkzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxweGtleT1scHhrZXktPm5leHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWxweGtleSkgewogICAgICAgICAgICBUUkFDRShyZWcsIkNvdWxkIG5vdCBmaW5kIHN1YmtleSAlc1xuIixkZWJ1Z3N0cl93KHdwc1tpXSkpOwogICAgICAgICAgICBGUkVFX0tFWV9QQVRIOwogICAgICAgICAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7CiAgICAgICAgfQogICAgICAgIGkrKzsKICAgICAgICBscE5leHRLZXkgPSBscHhrZXk7CiAgICB9CgogICAgYWRkX2hhbmRsZSgrK2N1cnJlbnRoYW5kbGUsbHB4a2V5LHNhbURlc2lyZWQpOwogICAgKnJldGtleSA9IGN1cnJlbnRoYW5kbGU7CiAgICBUUkFDRShyZWcsIiAgUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKICAgIEZSRUVfS0VZX1BBVEg7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleUV4MzJBIFtBRFZBUEkzMi4xNDldCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleUV4MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdTQU0gc2FtRGVzaXJlZCwgTFBIS0VZIHJldGtleSApCnsKICAgIExQV1NUUiBscHN6U3ViS2V5VyA9IHN0cmR1cEEyVyhscHN6U3ViS2V5KTsKICAgIERXT1JEIHJldDsKCiAgICBUUkFDRShyZWcsIigleCwlcywlbGQsJWx4LCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSksZHdSZXNlcnZlZCwKICAgICAgICAgIHNhbURlc2lyZWQscmV0a2V5KTsKICAgIHJldCA9IFJlZ09wZW5LZXlFeDMyVyggaGtleSwgbHBzelN1YktleVcsIGR3UmVzZXJ2ZWQsIHNhbURlc2lyZWQsIHJldGtleSApOwogICAgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5MzJXIFtBRFZBUEkzMi4xNTFdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBzelN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleSB0byBvcGVuCiAqICAgIHJldGtleSAgICAgW09dIEFkZHJlc3Mgb2YgaGFuZGxlIG9mIG9wZW4ga2V5CiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICByZXR1cm4gUmVnT3BlbktleUV4MzJXKCBoa2V5LCBscHN6U3ViS2V5LCAwLCBLRVlfQUxMX0FDQ0VTUywgcmV0a2V5ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXkzMkEgW0FEVkFQSTMyLjE0OF0KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgRFdPUkQgcmV0OwogICAgTFBXU1RSIGxwc3pTdWJLZXlXID0gc3RyZHVwQTJXKGxwc3pTdWJLZXkpOwogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0ID0gIFJlZ09wZW5LZXkzMlcoIGhrZXksIGxwc3pTdWJLZXlXLCByZXRrZXkgKTsKICAgIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleTE2IFtTSEVMTC4xXSBbS0VSTkVMLjIxN10KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICByZXR1cm4gUmVnT3BlbktleTMyQSggaGtleSwgbHBzelN1YktleSwgcmV0a2V5ICk7Cn0KCgovKiAKICogQ3JlYXRlIGtleXMKICogCiAqIEFsbCB0aG9zZSBmdW5jdGlvbnMgY29udmVydCB0aGVpciByZXNwZWN0aXZlIAogKiBhcmd1bWVudHMgYW5kIGNhbGwgUmVnQ3JlYXRlS2V5RXhXIGF0IHRoZSBlbmQuCiAqCiAqIFdlIHN0YXkgYXdheSBmcm9tIHRoZSBFeCBmdW5jdGlvbnMgYXMgbG9uZyBhcyBwb3NzaWJsZSBiZWNhdXNlIHRoZXJlIGFyZQogKiBkaWZmZXJlbmNlcyBpbiB0aGUgcmV0dXJuIHZhbHVlcwogKgogKiBDYWxscGF0aDoKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ0NyZWF0ZUtleUV4MzJBIFwKICogUmVnQ3JlYXRlS2V5MTYgLT4gUmVnQ3JlYXRlS2V5MzJBIC0+IFJlZ0NyZWF0ZUtleTMyVyAgIC0+IFJlZ0NyZWF0ZUtleUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ3JlYXRlS2V5RXgzMlcgW0FEVkFQSTMyLjEzMV0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICBbSV0gSGFuZGxlIG9mIGFuIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgICBbSV0gQWRkcmVzcyBvZiBzdWJrZXkgbmFtZQogKiAgICBkd1Jlc2VydmVkICAgW0ldIFJlc2VydmVkIC0gbXVzdCBiZSAwCiAqICAgIGxwc3pDbGFzcyAgICBbSV0gQWRkcmVzcyBvZiBjbGFzcyBzdHJpbmcKICogICAgZmR3T3B0aW9ucyAgIFtJXSBTcGVjaWFsIG9wdGlvbnMgZmxhZwogKiAgICBzYW1EZXNpcmVkICAgW0ldIERlc2lyZWQgc2VjdXJpdHkgYWNjZXNzCiAqICAgIGxwU2VjQXR0cmlicyBbSV0gQWRkcmVzcyBvZiBrZXkgc2VjdXJpdHkgc3RydWN0dXJlCiAqICAgIHJldGtleSAgICAgICBbT10gQWRkcmVzcyBvZiBidWZmZXIgZm9yIG9wZW5lZCBoYW5kbGUKICogICAgbHBEaXNwb3MgICAgIFtPXSBSZWNlaXZlcyBSRUdfQ1JFQVRFRF9ORVdfS0VZIG9yIFJFR19PUEVORURfRVhJU1RJTkdfS0VZCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5RXgzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1Jlc2VydmVkLCBMUFdTVFIgbHBzekNsYXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBmZHdPcHRpb25zLCBSRUdTQU0gc2FtRGVzaXJlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgbHBTZWNBdHRyaWJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEhLRVkgcmV0a2V5LCBMUERXT1JEIGxwRGlzcG9zICkKewoJTFBLRVlTVFJVQ1QJKmxwbHBQcmV2S2V5LGxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlcywlbHgsJWx4LCVwLCVwLCVwKVxuIiwgaGtleSwKCQlkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLCBkd1Jlc2VydmVkLCBkZWJ1Z3N0cl93KGxwc3pDbGFzcyksCgkJZmR3T3B0aW9ucywgc2FtRGVzaXJlZCwgbHBTZWNBdHRyaWJzLCByZXRrZXksIGxwRGlzcG9zKTsKCiAgICBscE5leHRLZXkgPSBsb29rdXBfaGtleShoa2V5KTsKICAgIGlmICghbHBOZXh0S2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICAvKiBDaGVjayBmb3IgdmFsaWQgb3B0aW9ucyAqLwogICAgc3dpdGNoKGZkd09wdGlvbnMpIHsKICAgICAgICBjYXNlIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFOgogICAgICAgIGNhc2UgUkVHX09QVElPTl9WT0xBVElMRToKICAgICAgICBjYXNlIFJFR19PUFRJT05fQkFDS1VQX1JFU1RPUkU6CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKICAgIH0KCiAgICAvKiBTYW0gaGFzIHRvIGJlIGEgY29tYmluYXRpb24gb2YgdGhlIGZvbGxvd2luZyAqLwogICAgaWYgKCEoc2FtRGVzaXJlZCAmIAogICAgICAgICAgKEtFWV9BTExfQUNDRVNTIHwgS0VZX0NSRUFURV9MSU5LIHwgS0VZX0NSRUFURV9TVUJfS0VZIHwgCiAgICAgICAgICAgS0VZX0VOVU1FUkFURV9TVUJfS0VZUyB8IEtFWV9FWEVDVVRFIHwgS0VZX05PVElGWSB8CiAgICAgICAgICAgS0VZX1FVRVJZX1ZBTFVFIHwgS0VZX1JFQUQgfCBLRVlfU0VUX1ZBTFVFIHwgS0VZX1dSSVRFKSkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKCWlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpIHsKCQlhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgkJKnJldGtleT1jdXJyZW50aGFuZGxlOwogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCQlscE5leHRLZXktPmZsYWdzfD1SRUdfT1BUSU9OX1RBSU5URUQ7CgkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgl9CgogICAgaWYgKGxwc3pTdWJLZXlbMF0gPT0gJ1xcJykgewogICAgICAgIFdBUk4ocmVnLCJTdWJrZXkgJXMgbXVzdCBub3QgYmVnaW4gd2l0aCBiYWNrc2xhc2guXG4iLGRlYnVnc3RyX3cobHBzelN1YktleSkpOwogICAgICAgIHJldHVybiBFUlJPUl9CQURfUEFUSE5BTUU7CiAgICB9CgoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7Cgl3aGlsZSAoKGk8d3BjKSAmJiAod3BzW2ldWzBdPT0nXDAnKSkgaSsrOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKHdwc1tpXSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KQoJCQlicmVhazsKCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJaWYgKGxweGtleSkgewoJCWFkZF9oYW5kbGUoKytjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKCQlscHhrZXktPmZsYWdzICB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCQlpZiAobHBEaXNwb3MpCgkJCSpscERpc3Bvcwk9IFJFR19PUEVORURfRVhJU1RJTkdfS0VZOwoJCUZSRUVfS0VZX1BBVEg7CgkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgl9CgoJLyogR29vZC4gIE5vdyB0aGUgaGFyZCBwYXJ0ICovCgl3aGlsZSAod3BzW2ldKSB7CgkJbHBscFByZXZLZXkJPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7CgkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCQlscHhrZXkJCT0gKmxwbHBQcmV2S2V5OwoJCX0KCQkqbHBscFByZXZLZXk9bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTsKCQlpZiAoISpscGxwUHJldktleSkgewoJCQlGUkVFX0tFWV9QQVRIOwogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRShyZWcsICJSZXR1cm5pbmcgT1VUT0ZNRU1PUllcbiIpOwoJCQlyZXR1cm4gRVJST1JfT1VUT0ZNRU1PUlk7CgkJfQoJCW1lbXNldCgqbHBscFByZXZLZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsIkFkZGluZyAlc1xuIiwgZGVidWdzdHJfdyh3cHNbaV0pKTsKCQkoKmxwbHBQcmV2S2V5KS0+a2V5bmFtZQk9IHN0cmR1cFcod3BzW2ldKTsKCQkoKmxwbHBQcmV2S2V5KS0+bmV4dAk9IE5VTEw7CgkJKCpscGxwUHJldktleSktPm5leHRzdWIJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT52YWx1ZXMJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5ucm9mdmFsdWVzID0gMDsKCQkoKmxwbHBQcmV2S2V5KS0+ZmxhZ3MgCT0gUkVHX09QVElPTl9UQUlOVEVEOwoJCWlmIChscHN6Q2xhc3MpCgkJCSgqbHBscFByZXZLZXkpLT5jbGFzcyA9IHN0cmR1cFcobHBzekNsYXNzKTsKCQllbHNlCgkJCSgqbHBscFByZXZLZXkpLT5jbGFzcyA9IE5VTEw7CgkJbHBOZXh0S2V5CT0gKmxwbHBQcmV2S2V5OwoJCWkrKzsKCX0KCWFkZF9oYW5kbGUoKytjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKCgkvKkZJWE1FOiBmbGFnIGhhbmRsaW5nIGNvcnJlY3Q/ICovCglscE5leHRLZXktPmZsYWdzPSBmZHdPcHRpb25zIHxSRUdfT1BUSU9OX1RBSU5URUQ7CglpZiAobHBzekNsYXNzKQoJCWxwTmV4dEtleS0+Y2xhc3MgPSBzdHJkdXBXKGxwc3pDbGFzcyk7CgllbHNlCgkJbHBOZXh0S2V5LT5jbGFzcyA9IE5VTEw7CgkqcmV0a2V5CQk9IGN1cnJlbnRoYW5kbGU7CiAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCWlmIChscERpc3BvcykKCQkqbHBEaXNwb3MJPSBSRUdfQ1JFQVRFRF9ORVdfS0VZOwoJRlJFRV9LRVlfUEFUSDsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXlFeDMyQSBbQURWQVBJMzIuMTMwXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleUV4MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGxwc3pDbGFzcywgRFdPUkQgZmR3T3B0aW9ucywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHU0FNIHNhbURlc2lyZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBscFNlY0F0dHJpYnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSByZXRrZXksIExQRFdPUkQgbHBEaXNwb3MgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVcsIGxwc3pDbGFzc1c7CiAgICBEV09SRCAgcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlcywlbHgsJWx4LCVwLCVwLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSksCiAgICAgICAgICBkd1Jlc2VydmVkLGRlYnVnc3RyX2EobHBzekNsYXNzKSxmZHdPcHRpb25zLHNhbURlc2lyZWQsbHBTZWNBdHRyaWJzLAogICAgICAgICAgcmV0a2V5LGxwRGlzcG9zKTsKCiAgICBscHN6U3ViS2V5VyA9IGxwc3pTdWJLZXk/c3RyZHVwQTJXKGxwc3pTdWJLZXkpOk5VTEw7CiAgICBscHN6Q2xhc3NXID0gbHBzekNsYXNzP3N0cmR1cEEyVyhscHN6Q2xhc3MpOk5VTEw7CgogICAgcmV0ID0gUmVnQ3JlYXRlS2V5RXgzMlcoIGhrZXksIGxwc3pTdWJLZXlXLCBkd1Jlc2VydmVkLCBscHN6Q2xhc3NXLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZHdPcHRpb25zLCBzYW1EZXNpcmVkLCBscFNlY0F0dHJpYnMsIHJldGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBEaXNwb3MgKTsKCiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICBpZihscHN6Q2xhc3NXKSBmcmVlKGxwc3pDbGFzc1cpOwoKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleTMyVyBbQURWQVBJMzIuMTMyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBEV09SRCBqdW5rOwogICAgTFBLRVlTVFJVQ1QJbHBOZXh0S2V5OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIiwgaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLHJldGtleSk7CgogICAgLyogVGhpcyBjaGVjayBpcyBoZXJlIGJlY2F1c2UgdGhlIHJldHVybiB2YWx1ZSBpcyBkaWZmZXJlbnQgdGhhbiB0aGUKICAgICAgIG9uZSBmcm9tIHRoZSBFeCBmdW5jdGlvbnMgKi8KICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0JBREtFWTsKCiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5RXgzMlcoIGhrZXksIGxwc3pTdWJLZXksIDAsIE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX0FMTF9BQ0NFU1MsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldGtleSwgJmp1bmspOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXkzMkEgW0FEVkFQSTMyLjEyOV0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBEV09SRCByZXQ7CiAgICBMUFdTVFIgbHBzelN1YktleVc7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgbHBzelN1YktleVcgPSBscHN6U3ViS2V5P3N0cmR1cEEyVyhscHN6U3ViS2V5KTpOVUxMOwogICAgcmV0ID0gUmVnQ3JlYXRlS2V5MzJXKCBoa2V5LCBscHN6U3ViS2V5VywgcmV0a2V5ICk7CiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXkxNiBbU0hFTEwuMl0gW0tFUk5FTC4yMThdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5MzJBKCBoa2V5LCBscHN6U3ViS2V5LCByZXRrZXkgKTsKfQoKCi8qIAogKiBRdWVyeSBWYWx1ZSBGdW5jdGlvbnMKICogV2luMzIgZGlmZmVycyBiZXR3ZWVuIGtleW5hbWVzIGFuZCB2YWx1ZW5hbWVzLiAKICogbXVsdGlwbGUgdmFsdWVzIG1heSBiZWxvbmcgdG8gb25lIGtleSwgdGhlIHNwZWNpYWwgdmFsdWUKICogd2l0aCBuYW1lIE5VTEwgaXMgdGhlIGRlZmF1bHQgdmFsdWUgdXNlZCBieSB0aGUgd2luMzEKICogY29tcGF0IGZ1bmN0aW9ucy4KICoKICogQ2FsbHBhdGg6CiAqIFJlZ1F1ZXJ5VmFsdWUxNiAtPiBSZWdRdWVyeVZhbHVlMzJBIC0+IFJlZ1F1ZXJ5VmFsdWVFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUzMlcgLT4gUmVnUXVlcnlWYWx1ZUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZUV4MzJXIFtBRFZBUEkzMi4xNThdCiAqIFJldHJpZXZlcyB0eXBlIGFuZCBkYXRhIGZvciBhIHNwZWNpZmllZCBuYW1lIGFzc29jaWF0ZWQgd2l0aCBhbiBvcGVuIGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICBbSV0gICBIYW5kbGUgb2Yga2V5IHRvIHF1ZXJ5CiAqICAgIGxwVmFsdWVOYW1lICAgW0ldICAgTmFtZSBvZiB2YWx1ZSB0byBxdWVyeQogKiAgICBscGR3UmVzZXJ2ZWQgIFtJXSAgIFJlc2VydmVkIC0gbXVzdCBiZSBOVUxMCiAqICAgIGxwZHdUeXBlICAgICAgW09dICAgQWRkcmVzcyBvZiBidWZmZXIgZm9yIHZhbHVlIHR5cGUuICBJZiBOVUxMLCB0aGUgdHlwZQogKiAgICAgICAgICAgICAgICAgICAgICAgIGlzIG5vdCByZXF1aXJlZC4KICogICAgbHBiRGF0YSAgICAgICBbT10gICBBZGRyZXNzIG9mIGRhdGEgYnVmZmVyLiAgSWYgTlVMTCwgdGhlIGFjdHVhbCBkYXRhIGlzCiAqICAgICAgICAgICAgICAgICAgICAgICAgbm90IHJlcXVpcmVkLgogKiAgICBscGNiRGF0YSAgICAgIFtJL09dIEFkZHJlc3Mgb2YgZGF0YSBidWZmZXIgc2l6ZQogKgogKiBSRVRVUk5TIAogKiAgICBFUlJPUl9TVUNDRVNTOiAgIFN1Y2Nlc3MKICogICAgRVJST1JfTU9SRV9EQVRBOiBUaGUgc3BlY2lmaWVkIGJ1ZmZlciBpcyBub3QgYmlnIGVub3VnaCB0byBob2xkIHRoZSBkYXRhCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MzJXKCBIS0VZIGhrZXksIExQV1NUUiBscFZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBscGJEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglpbnQJCWk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIiwgaGtleSwgZGVidWdzdHJfdyhscFZhbHVlTmFtZSksCiAgICAgICAgICBscGR3UmVzZXJ2ZWQsIGxwZHdUeXBlLCBscGJEYXRhLCBscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleShoa2V5KTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIFJlc2VydmVkIG11c3QgYmUgTlVMTCAoYXQgbGVhc3QgZm9yIG5vdykgKi8KICAgIGlmIChscGR3UmVzZXJ2ZWQpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIC8qIEFuIGVtcHR5IG5hbWUgc3RyaW5nIGlzIGVxdWl2YWxlbnQgdG8gTlVMTCAqLwogICAgaWYgKGxwVmFsdWVOYW1lICYmICEqbHBWYWx1ZU5hbWUpCiAgICAgICAgbHBWYWx1ZU5hbWUgPSBOVUxMOwoKCWlmIChscFZhbHVlTmFtZT09TlVMTCkgewogICAgICAgICAgICAgICAgLyogVXNlIGtleSdzIHVubmFtZWQgb3IgZGVmYXVsdCB2YWx1ZSwgaWYgYW55ICovCgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCX0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBTZWFyY2ggZm9yIHRoZSBrZXkgbmFtZSAqLwoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXBpMzJXKGxwVmFsdWVOYW1lLGxwa2V5LT52YWx1ZXNbaV0ubmFtZSkKCQkJKQoJCQkJYnJlYWs7Cgl9CgoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsIktleSBub3QgZm91bmRcbiIpOwoJCWlmIChscFZhbHVlTmFtZT09TlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBFbXB0eSBrZXluYW1lIG5vdCBmb3VuZCAqLwoJCQlpZiAobHBiRGF0YSkgewoJCQkJKihXQ0hBUiopbHBiRGF0YSA9IDA7CgkJCQkqbHBjYkRhdGEJPSAyOwoJCQl9CgkJCWlmIChscGR3VHlwZSkKCQkJCSpscGR3VHlwZQk9IFJFR19TWjsKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nIGFuIGVtcHR5IHN0cmluZ1xuIik7CgkJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJCX0KCQlyZXR1cm4gRVJST1JfQkFEX1BBVEhOQU1FOwoJfQoKICAgIGlmIChscGR3VHlwZSkKICAgICAgICAqbHBkd1R5cGUgPSBscGtleS0+dmFsdWVzW2ldLnR5cGU7CgogICAgaWYgKGxwYkRhdGE9PU5VTEwpIHsKICAgICAgICAvKiBEYXRhIGlzIG5vdCByZXF1aXJlZCAqLwogICAgICAgIGlmIChscGNiRGF0YT09TlVMTCkgewogICAgICAgICAgICAvKiBBbmQgZGF0YSBzaXplIGlzIG5vdCByZXF1aXJlZCAqLwogICAgICAgICAgICAvKiBTbyBhbGwgdGhhdCBpcyByZXR1cm5lZCBpcyB0aGUgdHlwZSAoc2V0IGFib3ZlKSAqLwogICAgICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKICAgICAgICB9CiAgICAgICAgLyogU2V0IHRoZSBzaXplIHJlcXVpcmVkIGFuZCByZXR1cm4gc3VjY2VzcyAqLwogICAgICAgICpscGNiRGF0YSA9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwogICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwogICAgfQoKICAgIGlmICgqbHBjYkRhdGE8bHBrZXktPnZhbHVlc1tpXS5sZW4pIHsKICAgICAgICAvKiBUaGUgc2l6ZSB3YXMgc3BlY2lmaWVkLCBidXQgdGhlIGRhdGEgaXMgdG9vIGJpZyBmb3IgaXQgKi8KICAgICAgICAvKiBJbnN0ZWFkIG9mIHNldHRpbmcgaXQgdG8gTlVMTCwgZmlsbCBpbiB3aXRoIGFzIG11Y2ggYXMgcG9zc2libGUgKi8KICAgICAgICAvKiBCdXQgdGhlIGRvY3MgZG8gbm90IHNwZWNpZnkgaG93IHRvIGhhbmRsZSB0aGUgbHBiRGF0YSBoZXJlICovCiAgICAgICAgLyogKihXQ0hBUiopbHBiRGF0YT0gMDsgKi8KICAgICAgICBtZW1jcHkobHBiRGF0YSxscGtleS0+dmFsdWVzW2ldLmRhdGEsKmxwY2JEYXRhKTsKICAgICAgICAqbHBjYkRhdGEgPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKICAgICAgICByZXR1cm4gRVJST1JfTU9SRV9EQVRBOwogICAgfQoKICAgIG1lbWNweShscGJEYXRhLGxwa2V5LT52YWx1ZXNbaV0uZGF0YSxscGtleS0+dmFsdWVzW2ldLmxlbik7CgogICAgLyogRXh0cmEgZGVidWdnaW5nIG91dHB1dCAqLwogICAgaWYgKGxwZHdUeXBlKSB7CiAgICAgICAgc3dpdGNoKCpscGR3VHlwZSl7CiAgICAgICAgICAgIGNhc2UgUkVHX1NaOgogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCIgRGF0YShzeik9JXNcbiIsZGVidWdzdHJfdygoTFBDV1NUUilscGJEYXRhKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsIiBEYXRhKGR3b3JkKT0lbHhcbiIsIChEV09SRCkqbHBiRGF0YSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBSRUdfQklOQVJZOgogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCIgRGF0YShiaW5hcnkpXG4iKTsKICAgICAgICAgICAgICAgIC8qIElzIHRoZXJlIGEgd2F5IG9mIHByaW50aW5nIHRoaXMgaW4gcmVhZGFibGUgZm9ybT8gKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiVW5rbm93biBkYXRhIHR5cGUgJWxkXG4iLCAqbHBkd1R5cGUpOwogICAgICAgIH0gLyogc3dpdGNoICovCiAgICB9IC8qIGlmICovCgogICAgLyogU2V0IHRoZSBhY3R1YWwgc2l6ZSAqLwogICAgKmxwY2JEYXRhID0gbHBrZXktPnZhbHVlc1tpXS5sZW47CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZTMyVyBbQURWQVBJMzIuMTU5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUzMlcoIEhLRVkgaGtleSwgTFBXU1RSIGxwc3pTdWJLZXksIExQV1NUUiBscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CglIS0VZCXhoa2V5OwoJRFdPUkQJcmV0LGxwZHdUeXBlOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGxwc3pEYXRhLAogICAgICAgICAgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIC8qIE9ubHkgb3BlbiBzdWJrZXksIGlmIHdlIHJlYWxseSBkbyBkZXNjZW5kICovCiAgICBpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewogICAgICAgIHJldCA9IFJlZ09wZW5LZXkzMlcoIGhrZXksIGxwc3pTdWJLZXksICZ4aGtleSApOwogICAgICAgIGlmIChyZXQgIT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgICAgICBXQVJOKHJlZywgIkNvdWxkIG5vdCBvcGVuICVzXG4iLCBkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICB9IGVsc2UKICAgICAgICB4aGtleSA9IGhrZXk7CgogICAgbHBkd1R5cGUgPSBSRUdfU1o7CiAgICByZXQgPSBSZWdRdWVyeVZhbHVlRXgzMlcoIHhoa2V5LCBOVUxMLCBOVUxMLCAmbHBkd1R5cGUsIChMUEJZVEUpbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwY2JEYXRhICk7CiAgICBpZiAoeGhrZXkgIT0gaGtleSkKICAgICAgICBSZWdDbG9zZUtleSh4aGtleSk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlRXgzMkEgW0FEVkFQSTMyLjE1N10KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXgzMkEoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBscGJEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBXU1RSCWxwc3pWYWx1ZU5hbWVXOwoJTFBCWVRFCWJ1ZjsKCURXT1JECXJldCxteXhsZW47CglEV09SRAkqbXlsZW47CglEV09SRAl0eXBlOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVwLCVwLCVsZClcbiIsIGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBscHN6VmFsdWVOYW1lVyA9IGxwc3pWYWx1ZU5hbWU/c3RyZHVwQTJXKGxwc3pWYWx1ZU5hbWUpOk5VTEw7CgogICAgLyogV2h5IHdvdWxkIHRoaXMgYmUgc2V0PyBJdCBpcyBqdXN0IGFuIG91dHB1dCAqLwogICAgaWYgKGxwZHdUeXBlKQogICAgICAgIHR5cGUgPSAqbHBkd1R5cGU7CgoJaWYgKGxwYkRhdGEpIHsKCQlteXhsZW4gID0gMDsKCQlteWxlbgk9ICZteXhsZW47CgkJYnVmCT0geG1hbGxvYyg0KTsKICAgICAgICAgICAgICAgIC8qIE9ubHkgZ2V0IHRoZSBzaXplIGZvciBub3cgKi8KCQlyZXQgPSBSZWdRdWVyeVZhbHVlRXgzMlcoIGhrZXksIGxwc3pWYWx1ZU5hbWVXLCBscGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0eXBlLCBidWYsIG15bGVuICk7CgkJZnJlZShidWYpOwoJCWlmIChyZXQ9PUVSUk9SX01PUkVfREFUQSkgewoJCQlidWYJPSAoTFBCWVRFKXhtYWxsb2MoKm15bGVuKTsKCQl9IGVsc2UgewoJCQlidWYJPSAoTFBCWVRFKXhtYWxsb2MoMiooKmxwY2JEYXRhKSk7CgkJCW15eGxlbiAgPSAyKigqbHBjYkRhdGEpOwoJCX0KCX0gZWxzZSB7CgkJLyogRGF0YSBpcyBub3QgcmVxdWlyZWQgKi8KCQlidWY9TlVMTDsKCQlpZiAobHBjYkRhdGEpIHsKCQkJbXl4bGVuCT0gKmxwY2JEYXRhKjI7CgkJCW15bGVuCT0gJm15eGxlbjsKCQl9IGVsc2UKCQkJbXlsZW4JPSBOVUxMOwoJfQoKICAgICAgICAvKiBOb3cgZ2V0IHRoZSBkYXRhICovCglyZXQgPSBSZWdRdWVyeVZhbHVlRXgzMlcoIGhrZXksIGxwc3pWYWx1ZU5hbWVXLCBscGR3UmVzZXJ2ZWQsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmLCBteWxlbiApOwoJaWYgKGxwZHdUeXBlKSAKCQkqbHBkd1R5cGU9dHlwZTsKCglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJaWYgKGJ1ZikgewoJCQlpZiAoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgewoJCQkJLyogY29udmVydCBVTklDT0RFIHRvIEFTQ0lJICovCgkJCQlsc3RyY3B5V3RvQShscGJEYXRhLChMUFdTVFIpYnVmKTsKCQkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJCQl9IGVsc2UgewoJCQkJaWYgKG15eGxlbj4qbHBjYkRhdGEpCgkJCQkJcmV0CT0gRVJST1JfTU9SRV9EQVRBOwoJCQkJZWxzZQoJCQkJCW1lbWNweShscGJEYXRhLGJ1ZixteXhsZW4pOwoKCQkJCSpscGNiRGF0YQk9IG15eGxlbjsKCQkJfQoJCX0gZWxzZSB7CgkJCWlmICgoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgJiYgbHBjYkRhdGEpCgkJCQkqbHBjYkRhdGEJPSBteXhsZW4vMjsKCQl9Cgl9IGVsc2UgewoJCWlmICgoVU5JQ09OVk1BU0sgJiAoMTw8KHR5cGUpKSkgJiYgbHBjYkRhdGEpCgkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJfQoKICAgIGlmKGJ1ZikgZnJlZShidWYpOwogICAgaWYobHBzelZhbHVlTmFtZVcpIGZyZWUobHBzelZhbHVlTmFtZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZUV4MTYgW0tFUk5FTC4yMjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgbHBiRGF0YSwgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVwLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeDMyQSggaGtleSwgbHBzelZhbHVlTmFtZSwgbHBkd1Jlc2VydmVkLCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwYkRhdGEsIGxwY2JEYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWUzMkEgW0FEVkFQSTMyLjE1Nl0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMzJBKCBIS0VZIGhrZXksIExQU1RSIGxwc3pTdWJLZXksIExQU1RSIGxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIEhLRVkgeGhrZXk7CiAgICBEV09SRCByZXQsIGR3VHlwZTsKCiAgICBUUkFDRShyZWcsIigleCwlcywlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxscHN6RGF0YSwKICAgICAgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewogICAgICAgIHJldCA9IFJlZ09wZW5LZXkxNiggaGtleSwgbHBzelN1YktleSwgJnhoa2V5ICk7CiAgICAgICAgaWYoIHJldCAhPSBFUlJPUl9TVUNDRVNTICkKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgIH0gZWxzZQogICAgICAgIHhoa2V5ID0gaGtleTsKCiAgICBkd1R5cGUgPSBSRUdfU1o7CiAgICByZXQgPSBSZWdRdWVyeVZhbHVlRXgzMkEoIHhoa2V5LCBOVUxMLE5VTEwsICZkd1R5cGUsIChMUEJZVEUpbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwY2JEYXRhICk7CiAgICBpZiggeGhrZXkgIT0gaGtleSApCiAgICAgICAgUmVnQ2xvc2VLZXkoIHhoa2V5ICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlMTYgW1NIRUxMLjZdIFtLRVJORUwuMjI0XQogKgogKiBOT1RFUwogKiAgICBJcyB0aGlzIEhBQ0sgc3RpbGwgYXBwbGljYWJsZT8KICoKICogSEFDSwogKiAgICBUaGUgMTZiaXQgUmVnUXVlcnlWYWx1ZSBkb2Vzbid0IGhhbmRsZSBzZWxlY3RvcmJsb2NrcyBhbnl3YXksIHNvIHdlIGp1c3QKICogICAgbWFzayBvdXQgdGhlIGhpZ2ggMTYgYml0LiAgVGhpcyAobm90IHNvIG11Y2ggaW5jaWRlbnRseSkgaG9wZWZ1bGx5IGZpeGVzCiAqICAgIEFsZHVzIEZINCkKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelN1YktleSwgTFBTVFIgbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxscHN6RGF0YSwKICAgICAgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBpZiAobHBjYkRhdGEpCiAgICAgICAgKmxwY2JEYXRhICY9IDB4RkZGRjsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlMzJBKGhrZXksbHBzelN1YktleSxscHN6RGF0YSxscGNiRGF0YSk7Cn0KCgovKgogKiBTZXR0aW5nIHZhbHVlcyBvZiBSZWdpc3RyeSBrZXlzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdTZXRWYWx1ZTE2IC0+IFJlZ1NldFZhbHVlMzJBIC0+IFJlZ1NldFZhbHVlRXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1NldFZhbHVlMzJXICAgLT4gUmVnU2V0VmFsdWVFeDMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgzMlcgW0FEVkFQSTMyLjE3MF0KICogU2V0cyB0aGUgZGF0YSBhbmQgdHlwZSBvZiBhIHZhbHVlIHVuZGVyIGEgcmVnaXN0ZXIga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgIFtJXSBIYW5kbGUgb2Yga2V5IHRvIHNldCB2YWx1ZSBmb3IKICogICAgbHBzelZhbHVlTmFtZSBbSV0gTmFtZSBvZiB2YWx1ZSB0byBzZXQKICogICAgZHdSZXNlcnZlZCAgICBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIHplcm8KICogICAgZHdUeXBlICAgICAgICBbSV0gRmxhZyBmb3IgdmFsdWUgdHlwZQogKiAgICBscGJEYXRhICAgICAgIFtJXSBBZGRyZXNzIG9mIHZhbHVlIGRhdGEKICogICAgY2JEYXRhICAgICAgICBbSV0gU2l6ZSBvZiB2YWx1ZSBkYXRhCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDMyVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzelZhbHVlTmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1Jlc2VydmVkLCBEV09SRCBkd1R5cGUsIExQQllURSBscGJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgY2JEYXRhKQp7CiAgICBMUEtFWVNUUlVDVCBscGtleTsKICAgIGludCBpOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuIiwgaGtleSwgZGVidWdzdHJfdyhscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsIGR3VHlwZSwgbHBiRGF0YSwgY2JEYXRhKTsKCiAgICBzd2l0Y2ggKGR3VHlwZSkgewogICAgICAgIGNhc2UgUkVHX1NaOgogICAgICAgICAgICBUUkFDRShyZWcsIiBEYXRhKHN6KT0lc1xuIiwgZGVidWdzdHJfdygoTFBDV1NUUilscGJEYXRhKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUkVHX0JJTkFSWToKICAgICAgICAgICAgVFJBQ0UocmVnLCIgRGF0YShiaW5hcnkpXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgICAgIFRSQUNFKHJlZywiIERhdGEoZHdvcmQpPSVseFxuIiwgKERXT1JEKWxwYkRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBUUkFDRShyZWcsIlVua25vd24gdHlwZTogJWxkXG4iLCBkd1R5cGUpOwogICAgfQoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKCWxwa2V5LT5mbGFncyB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgoJaWYgKGxwc3pWYWx1ZU5hbWU9PU5VTEwpIHsKICAgICAgICAgICAgIC8qIFNldHMgdHlwZSBhbmQgbmFtZSBmb3Iga2V5J3MgdW5uYW1lZCBvciBkZWZhdWx0IHZhbHVlICovCgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCX0gZWxzZSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmICgJbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmCgkJCQkhbHN0cmNtcGkzMlcobHBzelZhbHVlTmFtZSxscGtleS0+dmFsdWVzW2ldLm5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CgkJbHBrZXktPnZhbHVlcyA9IChMUEtFWVZBTFVFKXhyZWFsbG9jKAoJCQkJCWxwa2V5LT52YWx1ZXMsCgkJCQkJKGxwa2V5LT5ucm9mdmFsdWVzKzEpKnNpemVvZihLRVlWQUxVRSkKCQkJCSk7CgkJbHBrZXktPm5yb2Z2YWx1ZXMrKzsKCQltZW1zZXQobHBrZXktPnZhbHVlcytpLCdcMCcsc2l6ZW9mKEtFWVZBTFVFKSk7Cgl9CglpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCWlmIChscHN6VmFsdWVOYW1lKQoJCQlscGtleS0+dmFsdWVzW2ldLm5hbWUgPSBzdHJkdXBXKGxwc3pWYWx1ZU5hbWUpOwoJCWVsc2UKCQkJbHBrZXktPnZhbHVlc1tpXS5uYW1lID0gTlVMTDsKCWxwa2V5LT52YWx1ZXNbaV0ubGVuCT0gY2JEYXRhOwoJbHBrZXktPnZhbHVlc1tpXS50eXBlCT0gZHdUeXBlOwoJaWYgKGxwa2V5LT52YWx1ZXNbaV0uZGF0YSAhPU5VTEwpCgkJZnJlZShscGtleS0+dmFsdWVzW2ldLmRhdGEpOwoJbHBrZXktPnZhbHVlc1tpXS5kYXRhCT0gKExQQllURSl4bWFsbG9jKGNiRGF0YSk7CglscGtleS0+dmFsdWVzW2ldLmxhc3Rtb2RpZmllZCA9IHRpbWUoTlVMTCk7CgltZW1jcHkobHBrZXktPnZhbHVlc1tpXS5kYXRhLGxwYkRhdGEsY2JEYXRhKTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZUV4MzJBIFtBRFZBUEkzMi4xNjldCiAqCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDMyQSggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdSZXNlcnZlZCwgRFdPUkQgZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGNiRGF0YSApCnsKCUxQQllURQlidWY7CglMUFdTVFIJbHBzelZhbHVlTmFtZVc7CglEV09SRAlyZXQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsZHdUeXBlLGxwYkRhdGEsY2JEYXRhKTsKCglpZiAoKDE8PGR3VHlwZSkgJiBVTklDT05WTUFTSykgewoJCWJ1Zj0oTFBCWVRFKXN0cmR1cEEyVyhscGJEYXRhKTsKCQljYkRhdGE9MipzdHJsZW4obHBiRGF0YSkrMjsKCX0gZWxzZQoJCWJ1Zj1scGJEYXRhOwoJaWYgKGxwc3pWYWx1ZU5hbWUpCgkJbHBzelZhbHVlTmFtZVcgPSBzdHJkdXBBMlcobHBzelZhbHVlTmFtZSk7CgllbHNlCgkJbHBzelZhbHVlTmFtZVcgPSBOVUxMOwoJcmV0PVJlZ1NldFZhbHVlRXgzMlcoaGtleSxscHN6VmFsdWVOYW1lVyxkd1Jlc2VydmVkLGR3VHlwZSxidWYsY2JEYXRhKTsKCWlmIChscHN6VmFsdWVOYW1lVykKCQlmcmVlKGxwc3pWYWx1ZU5hbWVXKTsKCWlmIChidWYhPWxwYkRhdGEpCgkJZnJlZShidWYpOwoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWVFeDE2IFtLRVJORUwuMjI2XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXgxNiggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWVOYW1lLCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1R5cGUsIExQQllURSBscGJEYXRhLCBEV09SRCBjYkRhdGEgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlbGQsJWxkLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEpOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlRXgzMkEoIGhrZXksIGxwc3pWYWx1ZU5hbWUsIGR3UmVzZXJ2ZWQsIGR3VHlwZSwgbHBiRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYkRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWUzMlcJW0FEVkFQSTMyLjE3MV0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIGxwc3pEYXRhLCBEV09SRCBjYkRhdGEgKQp7CglIS0VZCXhoa2V5OwoJRFdPUkQJcmV0OwoKCVRSQUNFKHJlZywiKCV4LCVzLCVsZCwlcywlbGQpXG4iLAoJCWhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxkd1R5cGUsZGVidWdzdHJfdyhscHN6RGF0YSksY2JEYXRhCgkpOwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQ9UmVnQ3JlYXRlS2V5MzJXKGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleT1oa2V5OwoJaWYgKGR3VHlwZSE9UkVHX1NaKSB7CgkJVFJBQ0UocmVnLCJkd1R5cGU9JWxkIC0gQ2hhbmdpbmcgdG8gUkVHX1NaXG4iLGR3VHlwZSk7CgkJZHdUeXBlPVJFR19TWjsKCX0KCWlmIChjYkRhdGEhPTIqbHN0cmxlbjMyVyhscHN6RGF0YSkrMikgewoJCVRSQUNFKHJlZywiTGVuPSVsZCAhPSBzdHJsZW4oJXMpKzE9JWQhXG4iLAoJCQljYkRhdGEsZGVidWdzdHJfdyhscHN6RGF0YSksMipsc3RybGVuMzJXKGxwc3pEYXRhKSsyCgkJKTsKCQljYkRhdGE9Mipsc3RybGVuMzJXKGxwc3pEYXRhKSsyOwoJfQoJcmV0PVJlZ1NldFZhbHVlRXgzMlcoeGhrZXksTlVMTCwwLGR3VHlwZSwoTFBCWVRFKWxwc3pEYXRhLGNiRGF0YSk7CglpZiAoaGtleSE9eGhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWUzMkEgW0FEVkFQSTMyLjE2OF0KICoKICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgRFdPUkQgZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscHN6RGF0YSwgRFdPUkQgY2JEYXRhICkKewoJRFdPUkQJcmV0OwoJSEtFWQl4aGtleTsKCglUUkFDRShyZWcsIigleCwlcywlbGQsJXMsJWxkKVxuIixoa2V5LGxwc3pTdWJLZXksZHdUeXBlLGxwc3pEYXRhLGNiRGF0YSk7CglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldD1SZWdDcmVhdGVLZXkxNihoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXk9aGtleTsKCglpZiAoZHdUeXBlIT1SRUdfU1opIHsKCQlUUkFDRShyZWcsImR3VHlwZT0lbGQhXG4iLGR3VHlwZSk7CgkJZHdUeXBlPVJFR19TWjsKCX0KCWlmIChjYkRhdGEhPXN0cmxlbihscHN6RGF0YSkrMSkKCQljYkRhdGE9c3RybGVuKGxwc3pEYXRhKSsxOwoJcmV0PVJlZ1NldFZhbHVlRXgzMkEoeGhrZXksTlVMTCwwLGR3VHlwZSwoTFBCWVRFKWxwc3pEYXRhLGNiRGF0YSk7CglpZiAoeGhrZXkhPWhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWUxNiBbS0VSTkVMLjIyMV0gW1NIRUxMLjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgRFdPUkQJZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwc3pEYXRhLCBEV09SRCBjYkRhdGEgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlbGQsJXMsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSksZHdUeXBlLAogICAgICAgICAgZGVidWdzdHJfYShscHN6RGF0YSksY2JEYXRhKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZTMyQShoa2V5LGxwc3pTdWJLZXksZHdUeXBlLGxwc3pEYXRhLGNiRGF0YSk7Cn0KCgovKiAKICogS2V5IEVudW1lcmF0aW9uCiAqCiAqIENhbGxwYXRoOgogKiBSZWdFbnVtS2V5MTYgLT4gUmVnRW51bUtleTMyQSAtPiBSZWdFbnVtS2V5RXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdFbnVtS2V5MzJXICAgLT4gUmVnRW51bUtleUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleUV4MzJXIFtBRFZBUEkzMi4xMzldCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgW0ldIEhhbmRsZSB0byBrZXkgdG8gZW51bWVyYXRlCiAqICAgIGlTdWJLZXkgICAgICBbSV0gSW5kZXggb2Ygc3Via2V5IHRvIGVudW1lcmF0ZQogKiAgICBscHN6TmFtZSAgICAgW09dIEJ1ZmZlciBmb3Igc3Via2V5IG5hbWUKICogICAgbHBjY2hOYW1lICAgIFtPXSBTaXplIG9mIHN1YmtleSBidWZmZXIKICogICAgbHBkd1Jlc2VydmVkIFtJXSBSZXNlcnZlZAogKiAgICBscHN6Q2xhc3MgICAgW09dIEJ1ZmZlciBmb3IgY2xhc3Mgc3RyaW5nCiAqICAgIGxwY2NoQ2xhc3MgICBbT10gU2l6ZSBvZiBjbGFzcyBidWZmZXIKICogICAgZnQgICAgICAgICAgIFtPXSBUaW1lIGtleSBsYXN0IHdyaXR0ZW4gdG8KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5RXgzMlcoIEhLRVkgaGtleSwgRFdPUkQgaVN1YmtleSwgTFBXU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTmFtZSwgTFBEV09SRCBscGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBscHN6Q2xhc3MsIExQRFdPUkQgbHBjY2hDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVUSU1FICpmdCApCnsKCUxQS0VZU1RSVUNUCWxwa2V5LGxweGtleTsKCiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsCiAgICAgICAgICAqbHBjY2hOYW1lLGxwZHdSZXNlcnZlZCxscHN6Q2xhc3MsbHBjY2hDbGFzcyxmdCk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJaWYgKCFscGtleS0+bmV4dHN1YikKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCWxweGtleT1scGtleS0+bmV4dHN1YjsKCiAgICAvKiBUcmF2ZXJzZSB0aGUgc3Via2V5cyAqLwoJd2hpbGUgKGlTdWJrZXkgJiYgbHB4a2V5KSB7CgkJaVN1YmtleS0tOwoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9CgoJaWYgKGlTdWJrZXkgfHwgIWxweGtleSkKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCWlmICgyKmxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKSsyPipscGNjaE5hbWUpCgkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCW1lbWNweShscHN6TmFtZSxscHhrZXktPmtleW5hbWUsbHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpKjIrMik7CgogICAgICAgIGlmICgqbHBjY2hOYW1lKQogICAgICAgICAgICAqbHBjY2hOYW1lID0gbHN0cmxlbjMyVyhscHN6TmFtZSk7CgoJaWYgKGxwc3pDbGFzcykgewoJCS8qIEZJWE1FOiB3aGF0IHNob3VsZCB3ZSB3cml0ZSBpbnRvIGl0PyAqLwoJCSpscHN6Q2xhc3MJPSAwOwoJCSpscGNjaENsYXNzCT0gMjsKCX0KCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5MzJXIFtBRFZBUEkzMi4xNDBdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTMyVyggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFdTVFIgbHBzek5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbHBjY2hOYW1lICkKewogICAgRklMRVRJTUUJZnQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZSk7CiAgICByZXR1cm4gUmVnRW51bUtleUV4MzJXKGhrZXksaVN1YmtleSxscHN6TmFtZSwmbHBjY2hOYW1lLE5VTEwsTlVMTCxOVUxMLCZmdCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXlFeDMyQSBbQURWQVBJMzIuMTM4XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlFeDMyQSggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE5hbWUsIExQRFdPUkQgbHBkd1Jlc2VydmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgbHBzekNsYXNzLCBMUERXT1JEIGxwY2NoQ2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFVElNRSAqZnQgKQp7CglEV09SRAlyZXQsbHBjY2hOYW1lVyxscGNjaENsYXNzVzsKCUxQV1NUUglscHN6TmFtZVcsbHBzekNsYXNzVzsKCgoJVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZCwlcCwlcCwlcCwlcClcbiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLCpscGNjaE5hbWUsbHBkd1Jlc2VydmVkLGxwc3pDbGFzcyxscGNjaENsYXNzLGZ0CgkpOwoJaWYgKGxwc3pOYW1lKSB7CgkJbHBzek5hbWVXCT0gKExQV1NUUil4bWFsbG9jKCpscGNjaE5hbWUqMik7CgkJbHBjY2hOYW1lVwk9ICpscGNjaE5hbWUqMjsKCX0gZWxzZSB7CgkJbHBzek5hbWVXCT0gTlVMTDsKCQlscGNjaE5hbWVXIAk9IDA7Cgl9CglpZiAobHBzekNsYXNzKSB7CgkJbHBzekNsYXNzVwkJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoQ2xhc3MqMik7CgkJbHBjY2hDbGFzc1cJPSAqbHBjY2hDbGFzcyoyOwoJfSBlbHNlIHsKCQlscHN6Q2xhc3NXCT0wOwoJCWxwY2NoQ2xhc3NXPTA7Cgl9CglyZXQ9UmVnRW51bUtleUV4MzJXKAoJCWhrZXksCgkJaVN1YmtleSwKCQlscHN6TmFtZVcsCgkJJmxwY2NoTmFtZVcsCgkJbHBkd1Jlc2VydmVkLAoJCWxwc3pDbGFzc1csCgkJJmxwY2NoQ2xhc3NXLAoJCWZ0CgkpOwoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCWxzdHJjcHlXdG9BKGxwc3pOYW1lLGxwc3pOYW1lVyk7CgkJKmxwY2NoTmFtZT1zdHJsZW4obHBzek5hbWUpOwoJCWlmIChscHN6Q2xhc3NXKSB7CgkJCWxzdHJjcHlXdG9BKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCQkJKmxwY2NoQ2xhc3M9c3RybGVuKGxwc3pDbGFzcyk7CgkJfQoJfQoJaWYgKGxwc3pOYW1lVykKCQlmcmVlKGxwc3pOYW1lVyk7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleTMyQSBbQURWQVBJMzIuMTM3XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXkzMkEoIEhLRVkgaGtleSwgRFdPUkQgaVN1YmtleSwgTFBTVFIgbHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBGSUxFVElNRQlmdDsKCiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKICAgIHJldHVybiBSZWdFbnVtS2V5RXgzMkEoIGhrZXksIGlTdWJrZXksIGxwc3pOYW1lLCAmbHBjY2hOYW1lLCBOVUxMLCBOVUxMLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICZmdCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5MTYgW1NIRUxMLjddIFtLRVJORUwuMjE2XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXkxNiggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbHBjY2hOYW1lICkKewogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZSk7CiAgICByZXR1cm4gUmVnRW51bUtleTMyQSggaGtleSwgaVN1YmtleSwgbHBzek5hbWUsIGxwY2NoTmFtZSk7Cn0KCgovKiAKICogRW51bWVyYXRlIFJlZ2lzdHJ5IFZhbHVlcwogKgogKiBDYWxscGF0aDoKICogUmVnRW51bVZhbHVlMTYgLT4gUmVnRW51bVZhbHVlMzJBIC0+IFJlZ0VudW1WYWx1ZTMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1WYWx1ZTMyVyBbQURWQVBJMzIuMTQyXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgW0ldIEhhbmRsZSB0byBrZXkgdG8gcXVlcnkKICogICAgaVZhbHVlICAgICAgW0ldIEluZGV4IG9mIHZhbHVlIHRvIHF1ZXJ5CiAqICAgIGxwc3pWYWx1ZSAgIFtPXSBWYWx1ZSBzdHJpbmcKICogICAgbHBjY2hWYWx1ZSAgW09dIFNpemUgb2YgdmFsdWUgYnVmZmVyCiAqICAgIGxwZFJlc2VydmVkIFtJXSBSZXNlcnZlZAogKiAgICBscGR3VHlwZSAgICBbT10gVHlwZSBjb2RlCiAqICAgIGxwYkRhdGEgICAgIFtPXSBWYWx1ZSBkYXRhCiAqICAgIGxwY2JEYXRhICAgIFtPXSBTaXplIG9mIGRhdGEgYnVmZmVyCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMzJXKCBIS0VZIGhrZXksIERXT1JEIGlWYWx1ZSwgTFBXU1RSIGxwc3pWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaFZhbHVlLCBMUERXT1JEIGxwZFJlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsZGVidWdzdHJfdyhscHN6VmFsdWUpLAogICAgICAgICAgbHBjY2hWYWx1ZSxscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICAvKiBOb25lIGFza2VkIGZvciAqLwogICAgaWYgKCFpVmFsdWUpCiAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CgogICAgaWYgKGxwa2V5LT5ucm9mdmFsdWVzIDw9IGlWYWx1ZSkKICAgICAgICByZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCiAgICAvKiBGSVhNRTogU2hvdWxkIHRoaXMgYmUgbHBrZXktPnZhbHVlcyArIGlWYWx1ZSAqIHNpemVvZihLRVlWQUxVRSk/ICovCiAgICB2YWwgPSBscGtleS0+dmFsdWVzICsgaVZhbHVlOwoKCWlmICh2YWwtPm5hbWUpIHsKCQlpZiAobHN0cmxlbjMyVyh2YWwtPm5hbWUpKjIrMj4qbHBjY2hWYWx1ZSkgewoJCQkqbHBjY2hWYWx1ZSA9IGxzdHJsZW4zMlcodmFsLT5uYW1lKSoyKzI7CgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJfQoJCW1lbWNweShscHN6VmFsdWUsdmFsLT5uYW1lLDIqbHN0cmxlbjMyVyh2YWwtPm5hbWUpKzIpOwoJCSpscGNjaFZhbHVlPWxzdHJsZW4zMlcodmFsLT5uYW1lKSoyKzI7Cgl9IGVsc2UgewoJCSpscHN6VmFsdWUJPSAwOwoJCSpscGNjaFZhbHVlCT0gMDsKCX0KCiAgICAvKiBDYW4gYmUgTlVMTCBpZiB0aGUgdHlwZSBjb2RlIGlzIG5vdCByZXF1aXJlZCAqLwogICAgaWYgKGxwZHdUeXBlKQogICAgICAgICpscGR3VHlwZSA9IHZhbC0+dHlwZTsKCglpZiAobHBiRGF0YSkgewoJCWlmICh2YWwtPmxlbj4qbHBjYkRhdGEpCgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJbWVtY3B5KGxwYkRhdGEsdmFsLT5kYXRhLHZhbC0+bGVuKTsKCQkqbHBjYkRhdGEgPSB2YWwtPmxlbjsKCX0KCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUzMkEgW0FEVkFQSTMyLjE0MV0KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUzMkEoIEhLRVkgaGtleSwgRFdPUkQgaVZhbHVlLCBMUFNUUiBscHN6VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hWYWx1ZSwgTFBEV09SRCBscGRSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBXU1RSCWxwc3pWYWx1ZVc7CglMUEJZVEUJbHBiRGF0YVc7CglEV09SRAlyZXQsbHBjYkRhdGFXOwoJRFdPUkQgZHdUeXBlOwoKCVRSQUNFKHJlZywiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsCgkJbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YSk7CgoJbHBzelZhbHVlVyA9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hWYWx1ZSoyKTsKCWlmIChscGJEYXRhKSB7CgkJbHBiRGF0YVcgPSAoTFBCWVRFKXhtYWxsb2MoKmxwY2JEYXRhKjIpOwoJCWxwY2JEYXRhVyA9ICpscGNiRGF0YSoyOwoJfSBlbHNlCgkJbHBiRGF0YVcgPSBOVUxMOwoKCXJldCA9IFJlZ0VudW1WYWx1ZTMyVyggaGtleSwgaVZhbHVlLCBscHN6VmFsdWVXLCBscGNjaFZhbHVlLCAKCQkJCWxwZFJlc2VydmVkLCAmZHdUeXBlLCBscGJEYXRhVywgJmxwY2JEYXRhVyApOwoKCWlmIChscGR3VHlwZSkKCQkqbHBkd1R5cGUgPSBkd1R5cGU7CgoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCWxzdHJjcHlXdG9BKGxwc3pWYWx1ZSxscHN6VmFsdWVXKTsKCQlpZiAobHBiRGF0YSkgewoJCQlpZiAoKDE8PGR3VHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJbHN0cmNweVd0b0EobHBiRGF0YSwoTFBXU1RSKWxwYkRhdGFXKTsKCQkJfSBlbHNlIHsKCQkJCWlmIChscGNiRGF0YVcgPiAqbHBjYkRhdGEpCgkJCQkJcmV0CT0gRVJST1JfTU9SRV9EQVRBOwoJCQkJZWxzZQoJCQkJCW1lbWNweShscGJEYXRhLGxwYkRhdGFXLGxwY2JEYXRhVyk7CgkJCX0KCQkJKmxwY2JEYXRhID0gbHBjYkRhdGFXOwoJCX0KCX0KICAgIGlmIChscGJEYXRhVykgZnJlZShscGJEYXRhVyk7CiAgICBpZiAobHBzelZhbHVlVykgZnJlZShscHN6VmFsdWVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1WYWx1ZTE2IFtLRVJORUwuMjIzXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1WYWx1ZTE2KCBIS0VZIGhrZXksIERXT1JEIGlWYWx1ZSwgTFBTVFIgbHBzelZhbHVlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoVmFsdWUsIExQRFdPUkQgbHBkUmVzZXJ2ZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1R5cGUsIExQQllURSBscGJEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSwKICAgICAgICAgIGxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEpOwogICAgcmV0dXJuIFJlZ0VudW1WYWx1ZTMyQSggaGtleSwgaVZhbHVlLCBscHN6VmFsdWUsIGxwY2NoVmFsdWUsIGxwZFJlc2VydmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwZHdUeXBlLCBscGJEYXRhLCBscGNiRGF0YSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDbG9zZUtleSBbU0hFTEwuM10gW0tFUk5FTC4yMjBdIFtBRFZBUEkzMi4xMjZdCiAqIFJlbGVhc2VzIHRoZSBoYW5kbGUgb2YgdGhlIHNwZWNpZmllZCBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgW0ldIEhhbmRsZSBvZiBrZXkgdG8gY2xvc2UKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdDbG9zZUtleSggSEtFWSBoa2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgpXG4iLGhrZXkpOwoKICAgIC8qIFRoZSBzdGFuZGFyZCBoYW5kbGVzIGFyZSBhbGxvd2VkIHRvIHN1Y2NlZWQsIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIG5vdAogICAgICAgY2xvc2VkICovCiAgICBpZiAoaXNfc3RhbmRhcmRfaGtleShoa2V5KSkKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKCiAgICByZXR1cm4gcmVtb3ZlX2hhbmRsZShoa2V5KTsKfQoKCi8qIAogKiBEZWxldGUgcmVnaXN0cnkga2V5CiAqCiAqIENhbGxwYXRoOgogKiBSZWdEZWxldGVLZXkxNiAtPiBSZWdEZWxldGVLZXkzMkEgLT4gUmVnRGVsZXRlS2V5MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlS2V5MzJXIFtBRFZBUEkzMi4xMzRdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgIFtJXSBIYW5kbGUgdG8gb3BlbiBrZXkKICogICAgbHBzelN1YktleSBbSV0gTmFtZSBvZiBzdWJrZXkgdG8gZGVsZXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5MzJXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6U3ViS2V5ICkKewoJTFBLRVlTVFJVQ1QJKmxwbHBQcmV2S2V5LGxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIFN1YmtleSBwYXJhbSBjYW5ub3QgYmUgTlVMTCAqLwogICAgaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkKICAgICAgICByZXR1cm4gRVJST1JfQkFES0VZOwoKICAgIC8qIFdlIG5lZWQgdG8ga25vdyB0aGUgcHJldmlvdXMga2V5IGluIHRoZSBoaWVyLiAqLwoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7CglscHhrZXkJPSBscE5leHRLZXk7Cgl3aGlsZSAoaTx3cGMtMSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlUUkFDRShyZWcsICIgIFNjYW5uaW5nIFslc11cbiIsCgkJCQkgICAgIGRlYnVnc3RyX3cobHB4a2V5LT5rZXluYW1lKSk7CgkJCWlmICghbHN0cmNtcGkzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCQlicmVhazsKCQkJbHB4a2V5PWxweGtleS0+bmV4dDsKCQl9CgkJaWYgKCFscHhrZXkpIHsKCQkJRlJFRV9LRVlfUEFUSDsKCQkJVFJBQ0UocmVnLCAiICBOb3QgZm91bmQuXG4iKTsKCQkJLyogbm90IGZvdW5kIGlzIHN1Y2Nlc3MgKi8KCQkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CgkJfQoJCWkrKzsKCQlscE5leHRLZXkJPSBscHhrZXk7Cgl9CglscHhrZXkJPSBscE5leHRLZXktPm5leHRzdWI7CglscGxwUHJldktleSA9ICYobHBOZXh0S2V5LT5uZXh0c3ViKTsKCXdoaWxlIChscHhrZXkpIHsKCQlUUkFDRShyZWcsICIgIFNjYW5uaW5nIFslc11cbiIsCgkJCSAgICAgZGVidWdzdHJfdyhscHhrZXktPmtleW5hbWUpKTsKCQlpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQlicmVhazsKCQlscGxwUHJldktleQk9ICYobHB4a2V5LT5uZXh0KTsKCQlscHhrZXkJCT0gbHB4a2V5LT5uZXh0OwoJfQoKCWlmICghbHB4a2V5KSB7CgkJRlJFRV9LRVlfUEFUSDsKCQlXQVJOKHJlZyAsICIgIE5vdCBmb3VuZC5cbiIpOwoJCXJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsKCX0KCglpZiAobHB4a2V5LT5uZXh0c3ViKSB7CgkJRlJFRV9LRVlfUEFUSDsKCQlXQVJOKHJlZyAsICIgIE5vdCBlbXB0eS5cbiIpOwoJCXJldHVybiBFUlJPUl9DQU5UV1JJVEU7Cgl9CgkqbHBscFByZXZLZXkJPSBscHhrZXktPm5leHQ7CglmcmVlKGxweGtleS0+a2V5bmFtZSk7CglpZiAobHB4a2V5LT5jbGFzcykKCQlmcmVlKGxweGtleS0+Y2xhc3MpOwoJaWYgKGxweGtleS0+dmFsdWVzKQoJCWZyZWUobHB4a2V5LT52YWx1ZXMpOwoJZnJlZShscHhrZXkpOwoJRlJFRV9LRVlfUEFUSDsKCVRSQUNFKHJlZywgIiAgRG9uZS5cbiIpOwoJcmV0dXJuCUVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZUtleTMyQSBbQURWQVBJMzIuMTMzXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSApCnsKICAgIExQV1NUUiBscHN6U3ViS2V5VzsKICAgIERXT1JEICByZXQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSk7CiAgICBscHN6U3ViS2V5VyA9IGxwc3pTdWJLZXk/c3RyZHVwQTJXKGxwc3pTdWJLZXkpOk5VTEw7CiAgICByZXQgPSBSZWdEZWxldGVLZXkzMlcoIGhrZXksIGxwc3pTdWJLZXlXICk7CiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVLZXkxNiBbU0hFTEwuNF0gW0tFUk5FTC4yMTldCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXkgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpKTsKICAgIHJldHVybiBSZWdEZWxldGVLZXkzMkEoIGhrZXksIGxwc3pTdWJLZXkgKTsKfQoKCi8qIAogKiBEZWxldGUgcmVnaXN0cnkgdmFsdWUKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZVZhbHVlMTYgLT4gUmVnRGVsZXRlVmFsdWUzMkEgLT4gUmVnRGVsZXRlVmFsdWUzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVWYWx1ZTMyVyBbQURWQVBJMzIuMTM2XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgIFtJXQogKiAgICBscHN6VmFsdWUgW0ldCiAqCiAqIFJFVFVSTlMKICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTMyVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzelZhbHVlICkKewoJRFdPUkQJCWk7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelZhbHVlKSk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJaWYgKGxwc3pWYWx1ZSkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXBpMzJXKGxwa2V5LT52YWx1ZXNbaV0ubmFtZSxscHN6VmFsdWUpCgkJCSkKCQkJCWJyZWFrOwoJfSBlbHNlIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJfQoKICAgIGlmIChpID09IGxwa2V5LT5ucm9mdmFsdWVzKQogICAgICAgIHJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsKCgl2YWwJPSBscGtleS0+dmFsdWVzK2k7CglpZiAodmFsLT5uYW1lKSBmcmVlKHZhbC0+bmFtZSk7CglpZiAodmFsLT5kYXRhKSBmcmVlKHZhbC0+ZGF0YSk7CgltZW1jcHkoCQoJCWxwa2V5LT52YWx1ZXMraSwKCQlscGtleS0+dmFsdWVzK2krMSwKCQlzaXplb2YoS0VZVkFMVUUpKihscGtleS0+bnJvZnZhbHVlcy1pLTEpCgkpOwoJbHBrZXktPnZhbHVlcwk9IChMUEtFWVZBTFVFKXhyZWFsbG9jKAoJCQkJbHBrZXktPnZhbHVlcywKCQkJCShscGtleS0+bnJvZnZhbHVlcy0xKSpzaXplb2YoS0VZVkFMVUUpCgkJCSk7CglscGtleS0+bnJvZnZhbHVlcy0tOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZVZhbHVlMzJBIFtBRFZBUEkzMi4xMzVdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUzMkEoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlICkKewogICAgTFBXU1RSIGxwc3pWYWx1ZVc7CiAgICBEV09SRCAgcmV0OwoKICAgIFRSQUNFKHJlZywgIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZSkpOwogICAgbHBzelZhbHVlVyA9IGxwc3pWYWx1ZT9zdHJkdXBBMlcobHBzelZhbHVlKTpOVUxMOwogICAgcmV0ID0gUmVnRGVsZXRlVmFsdWUzMlcoIGhrZXksIGxwc3pWYWx1ZVcgKTsKICAgIGlmKGxwc3pWYWx1ZVcpIGZyZWUobHBzelZhbHVlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVWYWx1ZTE2IFtLRVJORUwuMjIyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLCBoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlKSk7CiAgICByZXR1cm4gUmVnRGVsZXRlVmFsdWUzMkEoIGhrZXksIGxwc3pWYWx1ZSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdGbHVzaEtleSBbS0VSTkVMLjIyN10gW0FEVkFQSTMyLjE0M10KICogV3JpdGVzIGtleSB0byByZWdpc3RyeQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byB3cml0ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0ZsdXNoS2V5KCBIS0VZIGhrZXkgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKICAgIEJPT0wzMiByZXQ7CgogICAgVFJBQ0UocmVnLCAiKCV4KVxuIiwgaGtleSk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRVJSKHJlZywgIldoYXQgaXMgdGhlIGNvcnJlY3QgZmlsZW5hbWU/XG4iKTsKCiAgICByZXQgPSBfc2F2ZXJlZyggbHBrZXksICJmb28uYmFyIiwgVFJVRSk7CgogICAgaWYoIHJldCApIHsKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKICAgIH0gZWxzZQogICAgICAgIHJldHVybiBFUlJPUl9VTktOT1dOOyAgLyogRklYTUUgKi8KfQoKCi8qIEZJWE1FOiBscGNjaFhYWFggLi4uIGlzIHRoaXMgY291bnRpbmcgaW4gV0NIQVJTIG9yIGluIEJZVEVzID8/ICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeUluZm9LZXkzMlcgW0FEVkFQSTMyLjE1M10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICAgICAgICAgW0ldIEhhbmRsZSB0byBrZXkgdG8gcXVlcnkKICogICAgbHBzekNsYXNzICAgICAgICAgICAgICBbT10gQnVmZmVyIGZvciBjbGFzcyBzdHJpbmcKICogICAgbHBjY2hDbGFzcyAgICAgICAgICAgICBbT10gU2l6ZSBvZiBjbGFzcyBzdHJpbmcgYnVmZmVyCiAqICAgIGxwZHdSZXNlcnZlZCAgICAgICAgICAgW0ldIFJlc2VydmVkCiAqICAgIGxwY1N1YktleXMgICAgICAgICAgICAgW0ldIEJ1ZmZlciBmb3IgbnVtYmVyIG9mIHN1YmtleXMKICogICAgbHBjY2hNYXhTdWJLZXkgICAgICAgICBbT10gQnVmZmVyIGZvciBsb25nZXN0IHN1YmtleSBuYW1lIGxlbmd0aAogKiAgICBscGNjaE1heENsYXNzICAgICAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3QgY2xhc3Mgc3RyaW5nIGxlbmd0aAogKiAgICBscGNWYWx1ZXMgICAgICAgICAgICAgIFtPXSBCdWZmZXIgZm9yIG51bWJlciBvZiB2YWx1ZSBlbnRyaWVzCiAqICAgIGxwY2NoTWF4VmFsdWVOYW1lICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCB2YWx1ZSBuYW1lIGxlbmd0aAogKiAgICBscGNjYk1heFZhbHVlRGF0YSAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3QgdmFsdWUgZGF0YSBsZW5ndGgKICogICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciBbT10gQnVmZmVyIGZvciBzZWN1cml0eSBkZXNjcmlwdG9yIGxlbmd0aAogKiAgICBmdAogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5SW5mb0tleTMyVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzekNsYXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaENsYXNzLCBMUERXT1JEIGxwZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNTdWJLZXlzLCBMUERXT1JEIGxwY2NoTWF4U3Via2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTWF4Q2xhc3MsIExQRFdPUkQgbHBjVmFsdWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTWF4VmFsdWVOYW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjYk1heFZhbHVlRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwgRklMRVRJTUUgKmZ0ICkKewoJTFBLRVlTVFJVQ1QJbHBrZXksbHB4a2V5OwoJaW50CQlucm9ma2V5cyxtYXhzdWJrZXksbWF4Y2xhc3MsbWF4dm5hbWUsbWF4dmRhdGE7CglpbnQJCWk7CgoJVFJBQ0UocmVnLCIoJXgsJXAsLi4uKVxuIixoa2V5LGxwc3pDbGFzcyk7CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscGtleSkKCQlyZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CglpZiAobHBzekNsYXNzKSB7CgkJaWYgKGxwa2V5LT5jbGFzcykgewoJCQlpZiAobHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjIrMj4qbHBjY2hDbGFzcykgewoJCQkJKmxwY2NoQ2xhc3M9bHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjI7CgkJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCQl9CgkJCSpscGNjaENsYXNzPWxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyOwoJCQltZW1jcHkobHBzekNsYXNzLGxwa2V5LT5jbGFzcyxsc3RybGVuMzJXKGxwa2V5LT5jbGFzcykpOwoJCX0gZWxzZSB7CgkJCSpscHN6Q2xhc3MJPSAwOwoJCQkqbHBjY2hDbGFzcwk9IDA7CgkJfQoJfSBlbHNlIHsKCQlpZiAobHBjY2hDbGFzcykKCQkJKmxwY2NoQ2xhc3MJPSBsc3RybGVuMzJXKGxwa2V5LT5jbGFzcykqMjsKCX0KCWxweGtleT1scGtleS0+bmV4dHN1YjsKCW5yb2ZrZXlzPW1heHN1YmtleT1tYXhjbGFzcz1tYXh2bmFtZT1tYXh2ZGF0YT0wOwoJd2hpbGUgKGxweGtleSkgewoJCW5yb2ZrZXlzKys7CgkJaWYgKGxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKT5tYXhzdWJrZXkpCgkJCW1heHN1YmtleT1sc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSk7CgkJaWYgKGxweGtleS0+Y2xhc3MgJiYgbHN0cmxlbjMyVyhscHhrZXktPmNsYXNzKT5tYXhjbGFzcykKCQkJbWF4Y2xhc3M9bHN0cmxlbjMyVyhscHhrZXktPmNsYXNzKTsKCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQlMUEtFWVZBTFVFCXZhbD1scGtleS0+dmFsdWVzK2k7CgoJCWlmICh2YWwtPm5hbWUgJiYgbHN0cmxlbjMyVyh2YWwtPm5hbWUpPm1heHZuYW1lKQoJCQltYXh2bmFtZT1sc3RybGVuMzJXKHZhbC0+bmFtZSk7CgkJaWYgKHZhbC0+bGVuPm1heHZkYXRhKQoJCQltYXh2ZGF0YT12YWwtPmxlbjsKCX0KCWlmICghbWF4Y2xhc3MpIG1heGNsYXNzCT0gMTsKCWlmICghbWF4dm5hbWUpIG1heHZuYW1lCT0gMTsKCWlmIChscGNWYWx1ZXMpCgkJKmxwY1ZhbHVlcwk9IGxwa2V5LT5ucm9mdmFsdWVzOwoJaWYgKGxwY1N1YktleXMpCgkJKmxwY1N1YktleXMJPSBucm9ma2V5czsKCWlmIChscGNjaE1heFN1YmtleSkKCQkqbHBjY2hNYXhTdWJrZXkJPSBtYXhzdWJrZXkqMjsKCWlmIChscGNjaE1heENsYXNzKQoJCSpscGNjaE1heENsYXNzCT0gbWF4Y2xhc3MqMjsKCWlmIChscGNjaE1heFZhbHVlTmFtZSkKCQkqbHBjY2hNYXhWYWx1ZU5hbWU9IG1heHZuYW1lOwoJaWYgKGxwY2NiTWF4VmFsdWVEYXRhKQoJCSpscGNjYk1heFZhbHVlRGF0YT0gbWF4dmRhdGE7CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlJbmZvS2V5MzJBIFtBRFZBUEkzMi4xNTJdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlJbmZvS2V5MzJBKCBIS0VZIGhrZXksIExQU1RSIGxwc3pDbGFzcywgTFBEV09SRCBscGNjaENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGNTdWJLZXlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTWF4U3Via2V5LCBMUERXT1JEIGxwY2NoTWF4Q2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjVmFsdWVzLCBMUERXT1JEIGxwY2NoTWF4VmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NiTWF4VmFsdWVEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yLCBGSUxFVElNRSAqZnQgKQp7CglMUFdTVFIJCWxwc3pDbGFzc1c7CglEV09SRAkJcmV0OwoKCVRSQUNFKHJlZywiKCV4LC4uLi4uLilcbiIsaGtleSk7CglpZiAobHBzekNsYXNzKSB7CgkJKmxwY2NoQ2xhc3MqPSAyOwoJCWxwc3pDbGFzc1cgID0gKExQV1NUUil4bWFsbG9jKCpscGNjaENsYXNzKTsKCgl9IGVsc2UKCQlscHN6Q2xhc3NXICA9IE5VTEw7CglyZXQ9UmVnUXVlcnlJbmZvS2V5MzJXKAoJCWhrZXksCgkJbHBzekNsYXNzVywKCQlscGNjaENsYXNzLAoJCWxwZHdSZXNlcnZlZCwKCQlscGNTdWJLZXlzLAoJCWxwY2NoTWF4U3Via2V5LAoJCWxwY2NoTWF4Q2xhc3MsCgkJbHBjVmFsdWVzLAoJCWxwY2NoTWF4VmFsdWVOYW1lLAoJCWxwY2NiTWF4VmFsdWVEYXRhLAoJCWxwY2JTZWN1cml0eURlc2NyaXB0b3IsCgkJZnQKCSk7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTICYmIGxwc3pDbGFzcykKCQlsc3RyY3B5V3RvQShscHN6Q2xhc3MsbHBzekNsYXNzVyk7CglpZiAobHBjY2hDbGFzcykKCQkqbHBjY2hDbGFzcy89MjsKCWlmIChscGNjaE1heFN1YmtleSkKCQkqbHBjY2hNYXhTdWJrZXkvPTI7CglpZiAobHBjY2hNYXhDbGFzcykKCQkqbHBjY2hNYXhDbGFzcy89MjsKCWlmIChscGNjaE1heFZhbHVlTmFtZSkKCQkqbHBjY2hNYXhWYWx1ZU5hbWUvPTI7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ29ubmVjdFJlZ2lzdHJ5MzJXIFtBRFZBUEkzMi4xMjhdCiAqCiAqIFBBUkFNUwogKiAgICBscE1hY2hpbmVOYW1lIFtJXSBBZGRyZXNzIG9mIG5hbWUgb2YgcmVtb3RlIGNvbXB1dGVyCiAqICAgIGhIZXkgICAgICAgICAgW0ldIFByZWRlZmluZWQgcmVnaXN0cnkgaGFuZGxlCiAqICAgIHBoa1Jlc3VsdCAgICAgW0ldIEFkZHJlc3Mgb2YgYnVmZmVyIGZvciByZW1vdGUgcmVnaXN0cnkgaGFuZGxlCiAqLwpMT05HIFdJTkFQSSBSZWdDb25uZWN0UmVnaXN0cnkzMlcoIExQQ1dTVFIgbHBNYWNoaW5lTmFtZSwgSEtFWSBoS2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEhLRVkgcGhrUmVzdWx0ICkKewogICAgVFJBQ0UocmVnLCIoJXMsJXgsJXApOiBzdHViXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSksaEtleSxwaGtSZXN1bHQpOwoKICAgIGlmICghbHBNYWNoaW5lTmFtZSB8fCAhKmxwTWFjaGluZU5hbWUpIHsKICAgICAgICAvKiBVc2UgdGhlIGxvY2FsIG1hY2hpbmUgbmFtZSAqLwogICAgICAgIHJldHVybiBSZWdPcGVuS2V5MTYoIGhLZXksICIiLCBwaGtSZXN1bHQgKTsKICAgIH0KCiAgICBGSVhNRShyZWcsIkNhbm5vdCBjb25uZWN0IHRvICVzXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSkpOwogICAgcmV0dXJuIEVSUk9SX0JBRF9ORVRQQVRIOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnkzMkEgW0FEVkFQSTMyLjEyN10KICovCkxPTkcgV0lOQVBJIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyQSggTFBDU1RSIG1hY2hpbmUsIEhLRVkgaGtleSwgTFBIS0VZIHJlc2tleSApCnsKICAgIERXT1JEIHJldDsKICAgIExQV1NUUiBtYWNoaW5lVyA9IHN0cmR1cEEyVyhtYWNoaW5lKTsKICAgIHJldCA9IFJlZ0Nvbm5lY3RSZWdpc3RyeTMyVyggbWFjaGluZVcsIGhrZXksIHJlc2tleSApOwogICAgZnJlZShtYWNoaW5lVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdHZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTQ0XQogKiBSZXRyaWV2ZXMgYSBjb3B5IG9mIHNlY3VyaXR5IGRlc2NyaXB0b3IgcHJvdGVjdGluZyB0aGUgcmVnaXN0cnkga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgICAgICAgIFtJXSAgIE9wZW4gaGFuZGxlIG9mIGtleSB0byBzZXQKICogICAgU2VjdXJpdHlJbmZvcm1hdGlvbiAgICBbSV0gICBEZXNjcmlwdG9yIGNvbnRlbnRzCiAqICAgIHBTZWN1cml0eURlc2NyaXB0b3IgICAgW09dICAgQWRkcmVzcyBvZiBkZXNjcmlwdG9yIGZvciBrZXkKICogICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciBbSS9PXSBBZGRyZXNzIG9mIHNpemUgb2YgYnVmZmVyIGFuZCBkZXNjcmlwdGlvbgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KTE9ORyBXSU5BUEkgUmVnR2V0S2V5U2VjdXJpdHkoIEhLRVkgaGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRUNVUklUWV9JTkZPUk1BVElPTiBTZWN1cml0eUluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9ERVNDUklQVE9SIHBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JTZWN1cml0eURlc2NyaXB0b3IgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LFNlY3VyaXR5SW5mb3JtYXRpb24scFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgIGxwY2JTZWN1cml0eURlc2NyaXB0b3I/KmxwY2JTZWN1cml0eURlc2NyaXB0b3I6MCk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgLyogRklYTUU6IENoZWNrIGZvciB2YWxpZCBTZWN1cml0eUluZm9ybWF0aW9uIHZhbHVlcyAqLwoKICAgIGlmICgqbHBjYlNlY3VyaXR5RGVzY3JpcHRvciA8IHNpemVvZigqcFNlY3VyaXR5RGVzY3JpcHRvcikpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVI7CgogICAgRklYTUUocmVnLCAiKCV4LCVsZCwlcCwlbGQpOiBzdHViXG4iLGhrZXksU2VjdXJpdHlJbmZvcm1hdGlvbiwKICAgICAgICAgIHBTZWN1cml0eURlc2NyaXB0b3IsbHBjYlNlY3VyaXR5RGVzY3JpcHRvcj8qbHBjYlNlY3VyaXR5RGVzY3JpcHRvcjowKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTG9hZEtleTMyVyBbQURWQVBJMzIuPz8/XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkKICogICAgbHBzekZpbGUgICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgcmVnaXN0cnkgaW5mb3JtYXRpb24KICovCkxPTkcgV0lOQVBJIFJlZ0xvYWRLZXkzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBMUENXU1RSIGxwc3pGaWxlICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CiAgICBUUkFDRShyZWcsIigleCwlcywlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGRlYnVnc3RyX3cobHBzekZpbGUpKTsKCiAgICAvKiBEbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSB8fCAhbHBzekZpbGUgfHwgISpscHN6RmlsZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUUocmVnLCIoJXgsJXMsJXMpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSwKICAgICAgICAgIGRlYnVnc3RyX3cobHBzekZpbGUpKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTG9hZEtleTMyQSBbQURWQVBJMzIuPz8/XQogKi8KTE9ORyBXSU5BUEkgUmVnTG9hZEtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBDU1RSIGxwc3pGaWxlICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBzelN1YktleVcgPSBzdHJkdXBBMlcobHBzelN1YktleSk7CiAgICBMUFdTVFIgbHBzekZpbGVXID0gc3RyZHVwQTJXKGxwc3pGaWxlKTsKICAgIHJldCA9IFJlZ0xvYWRLZXkzMlcoIGhrZXksIGxwc3pTdWJLZXlXLCBscHN6RmlsZVcgKTsKICAgIGlmKGxwc3pGaWxlVykgZnJlZShscHN6RmlsZVcpOwogICAgaWYobHBzelN1YktleVcpIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTm90aWZ5Q2hhbmdlS2V5VmFsdWUgW0FEVkFQSTMyLj8/P10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICBbSV0gSGFuZGxlIG9mIGtleSB0byB3YXRjaAogKiAgICBmV2F0Y2hTdWJUcmVlICAgW0ldIEZsYWcgZm9yIHN1YmtleSBub3RpZmljYXRpb24KICogICAgZmR3Tm90aWZ5RmlsdGVyIFtJXSBDaGFuZ2VzIHRvIGJlIHJlcG9ydGVkCiAqICAgIGhFdmVudCAgICAgICAgICBbSV0gSGFuZGxlIG9mIHNpZ25hbGVkIGV2ZW50CiAqICAgIGZBc3luYyAgICAgICAgICBbSV0gRmxhZyBmb3IgYXN5bmNocm9ub3VzIHJlcG9ydGluZwogKi8KTE9ORyBXSU5BUEkgUmVnTm90aWZ5Q2hhbmdlS2V5VmFsdWUoIEhLRVkgaGtleSwgQk9PTDMyIGZXYXRjaFN1YlRyZWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZmR3Tm90aWZ5RmlsdGVyLCBIQU5ETEUzMiBoRXZlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MMzIgZkFzeW5jICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CiAgICBUUkFDRShyZWcsIigleCwlaSwlbGQsJXgsJWkpXG4iLGhrZXksZldhdGNoU3ViVHJlZSxmZHdOb3RpZnlGaWx0ZXIsCiAgICAgICAgICBoRXZlbnQsZkFzeW5jKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsIigleCwlaSwlbGQsJXgsJWkpOiBzdHViXG4iLGhrZXksZldhdGNoU3ViVHJlZSxmZHdOb3RpZnlGaWx0ZXIsCiAgICAgICAgICBoRXZlbnQsZkFzeW5jKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnVW5Mb2FkS2V5MzJXIFtBRFZBUEkzMi4xNzNdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwU3ViS2V5IFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5IHRvIHVubG9hZAogKi8KTE9ORyBXSU5BUEkgUmVnVW5Mb2FkS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBTdWJLZXkgKQp7CiAgICBGSVhNRShyZWcsIigleCwlcyk6IHN0dWJcbiIsaGtleSwgZGVidWdzdHJfdyhscFN1YktleSkpOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1VuTG9hZEtleTMyQSBbQURWQVBJMzIuMTcyXQogKi8KTE9ORyBXSU5BUEkgUmVnVW5Mb2FkS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwU3ViS2V5VyA9IHN0cmR1cEEyVyhscFN1YktleSk7CiAgICByZXQgPSBSZWdVbkxvYWRLZXkzMlcoIGhrZXksIGxwU3ViS2V5VyApOwogICAgaWYobHBTdWJLZXlXKSBmcmVlKGxwU3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTY3XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICBbSV0gT3BlbiBoYW5kbGUgb2Yga2V5IHRvIHNldAogKiAgICBTZWN1cml0eUluZm8gIFtJXSBEZXNjcmlwdG9yIGNvbnRlbnRzCiAqICAgIHBTZWN1cml0eURlc2MgW0ldIEFkZHJlc3Mgb2YgZGVzY3JpcHRvciBmb3Iga2V5CiAqLwpMT05HIFdJTkFQSSBSZWdTZXRLZXlTZWN1cml0eSggSEtFWSBoa2V5LCBTRUNVUklUWV9JTkZPUk1BVElPTiBTZWN1cml0eUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzYyApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcClcbiIsaGtleSxTZWN1cml0eUluZm8scFNlY3VyaXR5RGVzYyk7CgogICAgLyogSXQgc2VlbXMgdG8gcGVyZm9ybSB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKChTZWN1cml0eUluZm8gJiBPV05FUl9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgR1JPVVBfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIERBQ0xfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIFNBQ0xfU0VDVVJJVFlfSU5GT1JNQVRJT04pKSB7CiAgICAgICAgLyogUGFyYW0gT0sgKi8KICAgIH0gZWxzZQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBpZiAoIXBTZWN1cml0eURlc2MpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywiOigleCwlbGQsJXApOiBzdHViXG4iLGhrZXksU2VjdXJpdHlJbmZvLHBTZWN1cml0eURlc2MpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTYXZlS2V5MzJXIFtBRFZBUEkzMi4xNjZdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgc2F2ZSBiZWdpbnMKICogICAgbHBGaWxlIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIHRvIHNhdmUgdG8KICogICAgc2EgICAgIFtJXSBBZGRyZXNzIG9mIHNlY3VyaXR5IHN0cnVjdHVyZQogKi8KTE9ORyBXSU5BUEkgUmVnU2F2ZUtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwRmlsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBzYSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFKHJlZywgIigleCwlcywlcClcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBGaWxlKSwgc2EpOwoKICAgIC8qIEl0IGFwcGVhcnMgdG8gZG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBGaWxlIHx8ICEqbHBGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsICIoJXgsJXMsJXApOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwRmlsZSksIHNhKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2F2ZUtleTMyQSBbQURWQVBJMzIuMTY1XQogKi8KTE9ORyBXSU5BUEkgUmVnU2F2ZUtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBGaWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIHNhICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBGaWxlVyA9IHN0cmR1cEEyVyhscEZpbGUpOwogICAgcmV0ID0gUmVnU2F2ZUtleTMyVyggaGtleSwgbHBGaWxlVywgc2EgKTsKICAgIGZyZWUobHBGaWxlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5MzJXIFtBRFZBUEkzMi4xNjRdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgIFtJXSBIYW5kbGUgb2Yga2V5IHdoZXJlIHJlc3RvcmUgYmVnaW5zCiAqICAgIGxwRmlsZSAgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgY29udGFpbmluZyBzYXZlZCB0cmVlCiAqICAgIGR3RmxhZ3MgW0ldIE9wdGlvbmFsIGZsYWdzCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCAiKCV4LCVzLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl93KGxwRmlsZSksZHdGbGFncyk7CgogICAgLyogSXQgc2VlbXMgdG8gZG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBGaWxlIHx8ICEqbHBGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsIigleCwlcywlbGQpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIENoZWNrIGZvciBmaWxlIGV4aXN0ZW5jZSAqLwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5MzJBIFtBRFZBUEkzMi4xNjNdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscEZpbGUsIERXT1JEIGR3RmxhZ3MgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscEZpbGVXID0gc3RyZHVwQTJXKGxwRmlsZSk7CiAgICByZXQgPSBSZWdSZXN0b3JlS2V5MzJXKCBoa2V5LCBscEZpbGVXLCBkd0ZsYWdzICk7CiAgICBpZihscEZpbGVXKSBmcmVlKGxwRmlsZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleTMyVyBbQURWQVBJMzIuMTYyXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBTdWJLZXkgIFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5CiAqICAgIGxwTmV3RmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgZmlsZSB3aXRoIG5ldyBkYXRhCiAqICAgIGxwT2xkRmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgYmFja3VwIGZpbGUKICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXkzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSwgTFBDV1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbHBPbGRGaWxlICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXMsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscFN1YktleSksCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsICIoJXgsJXMsJXMsJXMpOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwU3ViS2V5KSwgCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleTMyQSBbQURWQVBJMzIuMTYxXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXksIExQQ1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscE9sZEZpbGUgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscFN1YktleVcgPSBzdHJkdXBBMlcobHBTdWJLZXkpOwogICAgTFBXU1RSIGxwTmV3RmlsZVcgPSBzdHJkdXBBMlcobHBOZXdGaWxlKTsKICAgIExQV1NUUiBscE9sZEZpbGVXID0gc3RyZHVwQTJXKGxwT2xkRmlsZSk7CiAgICByZXQgPSBSZWdSZXBsYWNlS2V5MzJXKCBoa2V5LCBscFN1YktleVcsIGxwTmV3RmlsZVcsIGxwT2xkRmlsZVcgKTsKICAgIGZyZWUobHBPbGRGaWxlVyk7CiAgICBmcmVlKGxwTmV3RmlsZVcpOwogICAgZnJlZShscFN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoK