LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICoKICogRGVjZW1iZXIgMjEsIDE5OTcgLSBLZXZpbiBDb3plbnMKICogRml4ZWQgYnVncyBpbiB0aGUgX3c5NV9sb2FkcmVnKCkgZnVuY3Rpb24uIEFkZGVkIGV4dHJhIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyB0aGUgZm9ybWF0IG9mIHRoZSBXaW5kb3dzICc5NSByZWdpc3RyeSBmaWxlcy4KICoKICogTk9URVMKICogICAgV2hlbiBjaGFuZ2luZyB0aGlzIGZpbGUsIHBsZWFzZSByZS1ydW4gdGhlIHJlZ3Rlc3QgcHJvZ3JhbSB0byBlbnN1cmUKICogICAgdGhlIGNvbmRpdGlvbnMgYXJlIGhhbmRsZWQgcHJvcGVybHkuCiAqCiAqIFRPRE8KICogICAgU2VjdXJpdHkgYWNjZXNzCiAqICAgIE9wdGlvbiBoYW5kbGluZwogKiAgICBUaW1lIGZvciBSZWdFbnVtS2V5KiwgUmVnUXVlcnlJbmZvS2V5KgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPHN5cy9lcnJuby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxwd2QuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAid2luLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAiaGVhcC5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAid2ludmVyc2lvbi5oIgoKc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCh2b2lkKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCi8qIE5PVEU6IGRvIG5vdCBhcHBlbmQgYSAvLiBsaW51eCcgbWtkaXIoKSBXSUxMIEZBSUwgaWYgeW91IGRvIHRoYXQgKi8KI2RlZmluZSBXSU5FX1BSRUZJWAkJCSIvLndpbmUiCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUCQkiL3Vzci9sb2NhbC9ldGMvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUCSIvdXNyL2xvY2FsL2V0Yy93aW5lLnN5c3RlbXJlZyIKCi8qIHJlbGF0aXZlIGluIH51c2VyLy53aW5lLyA6ICovCiNkZWZpbmUgU0FWRV9DVVJSRU5UX1VTRVIJCSJ1c2VyLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX01BQ0hJTkUJCSJzeXN0ZW0ucmVnIgoKI2RlZmluZSBLRVlfUkVHSVNUUlkJIlNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeSIKI2RlZmluZSBWQUxfU0FWRVVQREFURUQJIlNhdmVPbmx5VXBkYXRlZEtleXMiCgovKiBvbmUgdmFsdWUgb2YgYSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZVkFMVUUKewogICAgTFBXU1RSICAgbmFtZTsgICAgICAgICAgLyogbmFtZSBvZiB2YWx1ZSAoVU5JQ09ERSkgb3IgTlVMTCBmb3Igd2luMzEgKi8KICAgIERXT1JEICAgIHR5cGU7ICAgICAgICAgIC8qIHR5cGUgb2YgdmFsdWUgKi8KICAgIERXT1JEICAgIGxlbjsgICAgICAgICAgIC8qIGxlbmd0aCBvZiBkYXRhIGluIEJZVEVzICovCiAgICBEV09SRCAgICBsYXN0bW9kaWZpZWQ7ICAvKiB0aW1lIG9mIHNlY29uZHMgc2luY2UgMS4xLjE5NzAgKi8KICAgIExQQllURSAgIGRhdGE7ICAgICAgICAgIC8qIGNvbnRlbnQsIG1heSBiZSBzdHJpbmdzLCBiaW5hcmllcywgZXRjLiAqLwp9IEtFWVZBTFVFLCpMUEtFWVZBTFVFOwoKLyogYSByZWdpc3RyeSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZU1RSVUNUCnsKICAgIExQV1NUUiAgICAgICAgICAgICAgIGtleW5hbWU7ICAgICAgIC8qIG5hbWUgb2YgVEhJUyBrZXkgKFVOSUNPREUpICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBmbGFnczsgICAgICAgICAvKiBmbGFncy4gKi8KICAgIExQV1NUUiAgICAgICAgICAgICAgIGNsYXNzOwogICAgLyogdmFsdWVzICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBucm9mdmFsdWVzOyAgICAvKiBuciBvZiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIExQS0VZVkFMVUUgICAgICAgICAgIHZhbHVlczsgICAgICAgIC8qIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgLyoga2V5IG1hbmFnZW1lbnQgcG9pbnRlcnMgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHQ7ICAgICAgICAgIC8qIG5leHQga2V5IG9uIHNhbWUgaGllcmFyY2h5ICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0c3ViOyAgICAgICAvKiBrZXlzIHRoYXQgaGFuZyBiZWxvdyBUSElTIGtleSAqLwp9IEtFWVNUUlVDVCwgKkxQS0VZU1RSVUNUOwoKCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jbGFzc2VzX3Jvb3Q9TlVMTDsJLyogd2luZG93cyAzLjEgZ2xvYmFsIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF91c2VyPU5VTEw7CS8qIHVzZXIgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9sb2NhbF9tYWNoaW5lPU5VTEw7LyogbWFjaGluZSBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3VzZXJzPU5VTEw7CS8qIGFsbCB1c2Vycz8gKi8KCi8qIGR5bmFtaWMsIG5vdCBzYXZlZCAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfcGVyZm9ybWFuY2VfZGF0YT1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF9jb25maWc9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2R5bl9kYXRhPU5VTEw7CgovKiB3aGF0IHZhbHVldHlwZXMgZG8gd2UgbmVlZCB0byBjb252ZXJ0PyAqLwojZGVmaW5lIFVOSUNPTlZNQVNLCSgoMTw8UkVHX1NaKXwoMTw8UkVHX01VTFRJX1NaKXwoMTw8UkVHX0VYUEFORF9TWikpCgoKc3RhdGljIHN0cnVjdCBvcGVuaGFuZGxlIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCVJFR1NBTQkJYWNjZXNzbWFzazsKfSAgKm9wZW5oYW5kbGVzPU5VTEw7CnN0YXRpYyBpbnQJbnJvZm9wZW5oYW5kbGVzPTA7Ci8qIFN0YXJ0cyBhZnRlciAxIGJlY2F1c2UgMCwxIGFyZSByZXNlcnZlZCBmb3IgV2luMTYgKi8KLyogTm90ZTogU2hvdWxkIGFsd2F5cyBiZSBldmVuLCBhcyBXaW45NSBBRFZBUEkzMi5ETEwgcmVzZXJ2ZXMgb2RkCiAgICAgICAgIEhLRVlzIGZvciByZW1vdGUgcmVnaXN0cnkgYWNjZXNzICovCnN0YXRpYyBpbnQJY3VycmVudGhhbmRsZT0yOwoKCi8qCiAqIFFVRVNUSU9OCiAqICAgQXJlIHRoZXNlIGRvaW5nIHRoZSBzYW1lIGFzIEhFQVBfc3RyZHVwQXRvVyBhbmQgSEVBUF9zdHJkdXBXdG9BPwogKiAgIElmIHNvLCBjYW4gd2UgcmVtb3ZlIHRoZW0/CiAqIEFOU1dFUgogKiAgIE5vLCB0aGUgbWVtb3J5IGhhbmRsaW5nIGZ1bmN0aW9ucyBhcmUgY2FsbGVkIHZlcnkgb2Z0ZW4gaW4gaGVyZSwgCiAqICAganVzdCByZXBsYWNpbmcgdGhlbSBieSBIZWFwQWxsb2MoU3lzdGVtSGVhcCwuLi4pIG1ha2VzIHJlZ2lzdHJ5CiAqICAgbG9hZGluZyAxMDAgdGltZXMgc2xvd2VyLiAtTU0KICovCnN0YXRpYyBMUFdTVFIgc3RyZHVwQTJXKExQQ1NUUiBzcmMpCnsKICAgIGlmKHNyYykgewoJTFBXU1RSIGRlc3Q9eG1hbGxvYygyKnN0cmxlbihzcmMpKzIpOwoJbHN0cmNweUF0b1coZGVzdCxzcmMpOwoJcmV0dXJuIGRlc3Q7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIExQV1NUUiBzdHJkdXBXKExQQ1dTVFIgYSkgewoJTFBXU1RSCWI7CglpbnQJbGVuOwoKICAgIGlmKGEpIHsKCWxlbj1zaXplb2YoV0NIQVIpKihsc3RybGVuMzJXKGEpKzEpOwoJYj0oTFBXU1RSKXhtYWxsb2MobGVuKTsKCW1lbWNweShiLGEsbGVuKTsKCXJldHVybiBiOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCkxQV1NUUiBzdHJjdnRBMlcoTFBDU1RSIHNyYywgaW50IG5jaGFycykKCnsKICAgTFBXU1RSIGRlc3QgPSB4bWFsbG9jICgyICogbmNoYXJzICsgMik7CgogICBsc3RyY3B5bkF0b1coZGVzdCxzcmMsbmNoYXJzKzEpOwogICBkZXN0W25jaGFyc10gPSAwOwogICByZXR1cm4gZGVzdDsKfQovKgogKiB3ZSBuZWVkIHRvIGNvbnZlcnQgQSB0byBXIHdpdGggJ1wwJyBpbiBzdHJpbmdzIChNVUxUSV9TWikgCiAqLwoKc3RhdGljIExQV1NUUiAgbG1lbWNweW5BdG9XKCBMUFdTVFIgZHN0LCBMUENTVFIgc3JjLCBJTlQzMiBuICkKewlMUFdTVFIgcCA9IGRzdDsKCglUUkFDRShyZWcsIlwiJXNcIiAlaVxuIixzcmMsIG4pOwoKCXdoaWxlIChuLS0gPiAwKSAqcCsrID0gKFdDSEFSKSh1bnNpZ25lZCBjaGFyKSpzcmMrKzsKCglyZXR1cm4gZHN0Owp9CnN0YXRpYyBMUFNUUiBsbWVtY3B5bld0b0EoIExQU1RSIGRzdCwgTFBDV1NUUiBzcmMsIElOVDMyIG4gKQp7CUxQU1RSIHAgPSBkc3Q7CgoJVFJBQ0Uoc3RyaW5nLCJMXCIlc1wiICVpXG4iLGRlYnVnc3RyX3coc3JjKSwgbik7CgoJd2hpbGUgKG4tLSA+IDApICpwKysgPSAoQ0hBUikqc3JjKys7CgoJcmV0dXJuIGRzdDsKfQoKc3RhdGljIHZvaWQgZGVidWdfcHJpbnRfdmFsdWUgKExQQllURSBscGJEYXRhLCBEV09SRCB0eXBlLCBEV09SRCBsZW4pCnsJaWYgKFRSQUNFX09OKHJlZykgJiYgbHBiRGF0YSkgCgl7IHN3aXRjaCh0eXBlKQoJICB7IGNhc2UgUkVHX1NaOgogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCIgRGF0YShzeik9JXNcbiIsZGVidWdzdHJfdygoTFBDV1NUUilscGJEYXRhKSk7CiAgICAgICAgICAgICAgICBicmVhazsKCgkgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsIiBEYXRhKGR3b3JkKT0weCUwOGx4XG4iLChEV09SRCkqbHBiRGF0YSk7CiAgICAgICAgICAgICAgICBicmVhazsKCQkKICAgICAgICAgICAgY2FzZSBSRUdfTVVMVElfU1o6CgkgICAgCXsgaW50IGk7CgkJICBMUENXU1RSIHB0ciA9IChMUENXU1RSKWxwYkRhdGE7CgkJICBmb3IgKGk9MDtwdHJbMF07aSsrKQoJCSAgeyBUUkFDRShyZWcsICIgTVVMVElfU1ooJWk9JXMpXG4iLCBpLCBkZWJ1Z3N0cl93KHB0cikpOwoJCSAgICBwdHIgKz0gbHN0cmxlbjMyVyhwdHIpKzE7CgkJICB9CgkJfQoJCWJyZWFrOwoKICAgICAgICAgICAgY2FzZSBSRUdfQklOQVJZOgogICAgICAgICAgICAgICAgeyBjaGFyIHN6VGVtcFsxMDBdOwkJCS8qIDMqMzIgKyAzICsgMSAqLwoJCSAgaW50IGk7CgkJICBmb3IgKCBpID0gMDsgaSA8IGxlbiA7IGkrKykJCSAgCgkJICB7IHNwcmludGYgKCYoc3pUZW1wW2kqM10pLCIlMDJ4ICIsIGxwYkRhdGFbaV0pOwoJCSAgICBpZiAoaT49MzEpCgkJICAgIHsgc3ByaW50ZiAoJihzelRlbXBbaSozKzNdKSwiLi4uIik7CgkJICAgICAgYnJlYWs7CgkJICAgIH0KCQkgIH0KCQkgIFRSQUNFKHJlZywiIERhdGEocmF3KT0oJXMpXG4iLCBzelRlbXApOyAgICAgICAgICAgICAgICAgIAoJCX0KICAgICAgICAgICAgICAgIGJyZWFrOwoJCQogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUocmVnLCAiIFVua25vd24gZGF0YSB0eXBlICVsZFxuIiwgdHlwZSk7CgkgIH0gLyogc3dpdGNoICovCgl9IC8qIGlmICovCn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBpc19zdGFuZGFyZF9oa2V5IFtJbnRlcm5hbF0KICogRGV0ZXJtaW5lcyBpZiBhIGhrZXkgaXMgYSBzdGFuZGFyZCBrZXkKICovCnN0YXRpYyBCT09MMzIgaXNfc3RhbmRhcmRfaGtleSggSEtFWSBoa2V5ICkKewogICAgc3dpdGNoKGhrZXkpIHsKICAgICAgICBjYXNlIDB4MDAwMDAwMDA6CiAgICAgICAgY2FzZSAweDAwMDAwMDAxOgogICAgICAgIGNhc2UgSEtFWV9DTEFTU0VTX1JPT1Q6CiAgICAgICAgY2FzZSBIS0VZX0NVUlJFTlRfQ09ORklHOgogICAgICAgIGNhc2UgSEtFWV9DVVJSRU5UX1VTRVI6CiAgICAgICAgY2FzZSBIS0VZX0xPQ0FMX01BQ0hJTkU6CiAgICAgICAgY2FzZSBIS0VZX1VTRVJTOgogICAgICAgIGNhc2UgSEtFWV9QRVJGT1JNQU5DRV9EQVRBOgogICAgICAgIGNhc2UgSEtFWV9EWU5fREFUQToKICAgICAgICAgICAgcmV0dXJuIFRSVUU7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGFkZF9oYW5kbGUgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgYWRkX2hhbmRsZSggSEtFWSBoa2V5LCBMUEtFWVNUUlVDVCBscGtleSwgUkVHU0FNIGFjY2Vzc21hc2sgKQp7CiAgICBpbnQgaTsKCiAgICBUUkFDRShyZWcsIigweCV4LCVwLDB4JWx4KVxuIixoa2V5LGxwa2V5LGFjY2Vzc21hc2spOwogICAgLyogQ2hlY2sgZm9yIGR1cGxpY2F0ZXMgKi8KICAgIGZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykgewogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5scGtleT09bHBrZXkpIHsKICAgICAgICAgICAgLyogVGhpcyBpcyBub3QgcmVhbGx5IGFuIGVycm9yIC0gdGhlIHVzZXIgaXMgYWxsb3dlZCB0byBjcmVhdGUKICAgICAgICAgICAgICAgdHdvIChvciBtb3JlKSBoYW5kbGVzIHRvIHRoZSBzYW1lIGtleSAqLwogICAgICAgICAgICAvKldBUk4ocmVnLCAiQWRkaW5nIGtleSAlcCB0d2ljZVxuIixscGtleSk7Ki8KICAgICAgICB9CiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpIHsKICAgICAgICAgICAgV0FSTihyZWcsICJBZGRpbmcgaGFuZGxlICV4IHR3aWNlXG4iLGhrZXkpOwogICAgICAgIH0KICAgIH0KICAgIG9wZW5oYW5kbGVzPXhyZWFsbG9jKCBvcGVuaGFuZGxlcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzKzEpKTsKCiAgICBvcGVuaGFuZGxlc1tpXS5scGtleSA9IGxwa2V5OwogICAgb3BlbmhhbmRsZXNbaV0uaGtleSA9IGhrZXk7CiAgICBvcGVuaGFuZGxlc1tpXS5hY2Nlc3NtYXNrID0gYWNjZXNzbWFzazsKICAgIG5yb2ZvcGVuaGFuZGxlcysrOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBnZXRfaGFuZGxlIFtJbnRlcm5hbF0KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBQb2ludGVyIHRvIGtleQogKiAgICBGYWlsdXJlOiBOVUxMCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgZ2V0X2hhbmRsZSggSEtFWSBoa2V5ICkKewogICAgaW50IGk7CgogICAgZm9yIChpPTA7IGk8bnJvZm9wZW5oYW5kbGVzOyBpKyspCiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXkgPT0gaGtleSkKICAgICAgICAgICAgcmV0dXJuIG9wZW5oYW5kbGVzW2ldLmxwa2V5OwogICAgV0FSTihyZWcsICJDb3VsZCBub3QgZmluZCBoYW5kbGUgMHgleFxuIixoa2V5KTsKICAgIHJldHVybiBOVUxMOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiByZW1vdmVfaGFuZGxlIFtJbnRlcm5hbF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgW0ldIEhhbmRsZSBvZiBrZXkgdG8gcmVtb3ZlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFUlJPUl9JTlZBTElEX0hBTkRMRQogKi8Kc3RhdGljIERXT1JEIHJlbW92ZV9oYW5kbGUoIEhLRVkgaGtleSApCnsKICAgIGludCBpOwoKICAgIGZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykKICAgICAgICBpZiAob3BlbmhhbmRsZXNbaV0uaGtleT09aGtleSkKICAgICAgICAgICAgYnJlYWs7CgogICAgaWYgKGkgPT0gbnJvZm9wZW5oYW5kbGVzKSB7CiAgICAgICAgV0FSTihyZWcsICJDb3VsZCBub3QgZmluZCBoYW5kbGUgMHgleFxuIixoa2V5KTsKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CiAgICB9CgogICAgbWVtY3B5KCBvcGVuaGFuZGxlcytpLAogICAgICAgICAgICBvcGVuaGFuZGxlcytpKzEsCiAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy1pLTEpCiAgICApOwogICAgb3BlbmhhbmRsZXM9eHJlYWxsb2Mob3BlbmhhbmRsZXMsc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLTEpKTsKICAgIG5yb2ZvcGVuaGFuZGxlcy0tOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogbG9va3VwX2hrZXkgW0ludGVybmFsXQogKiAKICogSnVzdCBhcyB0aGUgbmFtZSBzYXlzLiBDcmVhdGVzIHRoZSByb290IGtleXMgb24gZGVtYW5kLCBzbyB3ZSBjYW4gY2FsbCB0aGUKICogUmVnKiBmdW5jdGlvbnMgYXQgYW55IHRpbWUuCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogUG9pbnRlciB0byBrZXkgc3RydWN0dXJlCiAqICAgIEZhaWx1cmU6IE5VTEwKICovCiNkZWZpbmUgQUREX1JPT1RfS0VZKHh4KSBcCgl4eCA9IChMUEtFWVNUUlVDVCl4bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTtcCgltZW1zZXQoeHgsJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7XAoJeHgtPmtleW5hbWU9IHN0cmR1cEEyVygiPHNob3VsZF9ub3RfYXBwZWFyX2FueXdoZXJlPiIpOwoKc3RhdGljIExQS0VZU1RSVUNUIGxvb2t1cF9oa2V5KCBIS0VZIGhrZXkgKQp7Cglzd2l0Y2ggKGhrZXkpIHsKCS8qIDAgYW5kIDEgYXJlIHZhbGlkIHJvb3RrZXlzIGluIHdpbjE2IHNoZWxsLmRsbCBhbmQgYXJlIHVzZWQgYnkKCSAqIHNvbWUgcHJvZ3JhbXMuIERvIG5vdCByZW1vdmUgdGhvc2UgY2FzZXMuIC1NTQoJICovCiAgICAJY2FzZSAweDAwMDAwMDAwOgoJY2FzZSAweDAwMDAwMDAxOgoJY2FzZSBIS0VZX0NMQVNTRVNfUk9PVDogewoJCWlmICgha2V5X2NsYXNzZXNfcm9vdCkgewoJCQlIS0VZCWNsX3JfaGtleTsKCgkJCS8qIGNhbGxzIGxvb2t1cF9oa2V5IHJlY3Vyc2l2ZWx5LCBUV0lDRSAqLwoJCQlpZiAoUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJTT0ZUV0FSRVxcQ2xhc3NlcyIsJmNsX3JfaGtleSkhPUVSUk9SX1NVQ0NFU1MpIHsKCQkJCUVSUihyZWcsIkNvdWxkIG5vdCBjcmVhdGUgSEtMTVxcU09GVFdBUkVcXENsYXNzZXMuIFRoaXMgaXMgaW1wb3NzaWJsZS5cbiIpOwoJCQkJZXhpdCgxKTsKCQkJfQoJCQlrZXlfY2xhc3Nlc19yb290ID0gbG9va3VwX2hrZXkoY2xfcl9oa2V5KTsKCQl9CgkJcmV0dXJuIGtleV9jbGFzc2VzX3Jvb3Q7Cgl9CgljYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgoJCWlmICgha2V5X2N1cnJlbnRfdXNlcikgewoJCQlIS0VZCWNfdV9oa2V5OwoJCQlzdHJ1Y3QJcGFzc3dkCSpwd2Q7CgoJCQlwd2Q9Z2V0cHd1aWQoZ2V0dWlkKCkpOwoJCQkvKiBjYWxscyBsb29rdXBfaGtleSByZWN1cnNpdmVseSwgVFdJQ0UgKi8KCQkJaWYgKHB3ZCAmJiBwd2QtPnB3X25hbWUpIHsKCQkJCWlmIChSZWdDcmVhdGVLZXkxNihIS0VZX1VTRVJTLHB3ZC0+cHdfbmFtZSwmY191X2hrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJCQkJRVJSKHJlZywiQ291bGQgbm90IGNyZWF0ZSBIVVxcJXMuIFRoaXMgaXMgaW1wb3NzaWJsZS5cbiIscHdkLT5wd19uYW1lKTsKCQkJCQlleGl0KDEpOwoJCQkJfQoJCQkJa2V5X2N1cnJlbnRfdXNlciA9IGxvb2t1cF9oa2V5KGNfdV9oa2V5KTsKCQkJfSBlbHNlIHsKCQkJCS8qIG5vdGhpbmcgZm91bmQsIHVzZSBzdGFuZGFsb25lICovCgkJCQlBRERfUk9PVF9LRVkoa2V5X2N1cnJlbnRfdXNlcik7CgkJCX0KCQl9CgkJcmV0dXJuIGtleV9jdXJyZW50X3VzZXI7CgljYXNlIEhLRVlfTE9DQUxfTUFDSElORToKCQlpZiAoIWtleV9sb2NhbF9tYWNoaW5lKSB7CgkJCUFERF9ST09UX0tFWShrZXlfbG9jYWxfbWFjaGluZSk7CgkJCVJFR0lTVFJZX0luaXQoKTsKCQl9CgkJcmV0dXJuIGtleV9sb2NhbF9tYWNoaW5lOwoJY2FzZSBIS0VZX1VTRVJTOgoJCWlmICgha2V5X3VzZXJzKSB7CgkJCUFERF9ST09UX0tFWShrZXlfdXNlcnMpOwoJCX0KCQlyZXR1cm4ga2V5X3VzZXJzOwoJY2FzZSBIS0VZX1BFUkZPUk1BTkNFX0RBVEE6CgkJaWYgKCFrZXlfcGVyZm9ybWFuY2VfZGF0YSkgewoJCQlBRERfUk9PVF9LRVkoa2V5X3BlcmZvcm1hbmNlX2RhdGEpOwoJCX0KCQlyZXR1cm4ga2V5X3BlcmZvcm1hbmNlX2RhdGE7CgljYXNlIEhLRVlfRFlOX0RBVEE6CgkJaWYgKCFrZXlfZHluX2RhdGEpIHsKCQkJQUREX1JPT1RfS0VZKGtleV9keW5fZGF0YSk7CgkJfQoJCXJldHVybiBrZXlfZHluX2RhdGE7CgljYXNlIEhLRVlfQ1VSUkVOVF9DT05GSUc6CgkJaWYgKCFrZXlfY3VycmVudF9jb25maWcpIHsKCQkJQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X2NvbmZpZyk7CgkJfQoJCXJldHVybiBrZXlfY3VycmVudF9jb25maWc7CglkZWZhdWx0OgoJCXJldHVybiBnZXRfaGFuZGxlKGhrZXkpOwoJfQoJLypOT1RSRUFDSEVEKi8KfQojdW5kZWYgQUREX1JPT1RfS0VZCi8qIHNvIHdlIGRvbid0IGFjY2lkZW50bHkgYWNjZXNzIHRoZW0gLi4uICovCiNkZWZpbmUga2V5X2N1cnJlbnRfY29uZmlnIE5VTEwgTlVMTAojZGVmaW5lIGtleV9jdXJyZW50X3VzZXIgTlVMTCBOVUxMCiNkZWZpbmUga2V5X3VzZXJzIE5VTEwgTlVMTAojZGVmaW5lIGtleV9sb2NhbF9tYWNoaW5lIE5VTEwgTlVMTAojZGVmaW5lIGtleV9jbGFzc2VzX3Jvb3QgTlVMTCBOVUxMCiNkZWZpbmUga2V5X2R5bl9kYXRhIE5VTEwgTlVMTAojZGVmaW5lIGtleV9wZXJmb3JtYW5jZV9kYXRhIE5VTEwgTlVMTAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBzcGxpdF9rZXlwYXRoIFtJbnRlcm5hbF0KICogc3BsaXRzIHRoZSB1bmljb2RlIHN0cmluZyAnd3AnIGludG8gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KICogdGhlIGFycmF5IGlzIGFsbG9jYXRlZCBieSB0aGlzIGZ1bmN0aW9uLiAKICogRnJlZSB0aGUgYXJyYXkgdXNpbmcgRlJFRV9LRVlfUEFUSAogKgogKiBQQVJBTVMKICogICAgd3AgIFtJXSBTdHJpbmcgdG8gc3BsaXQgdXAKICogICAgd3B2IFtPXSBBcnJheSBvZiBwb2ludGVycyB0byBzdHJpbmdzCiAqICAgIHdwYyBbT10gTnVtYmVyIG9mIGNvbXBvbmVudHMKICovCnN0YXRpYyB2b2lkIHNwbGl0X2tleXBhdGgoIExQQ1dTVFIgd3AsIExQV1NUUiAqKndwdiwgaW50ICp3cGMpCnsKICAgIGludAlpLGosbGVuOwogICAgTFBXU1RSIHdzOwoKICAgIFRSQUNFKHJlZywiKCVzLCVwLCVwKVxuIixkZWJ1Z3N0cl93KHdwKSx3cHYsd3BjKTsKCiAgICB3cwk9IEhFQVBfc3RyZHVwVyggU3lzdGVtSGVhcCwgMCwgd3AgKTsKCiAgICAvKiBXZSBrbm93IHdlIGhhdmUgYXQgbGVhc3Qgb25lIHN1YnN0cmluZyAqLwogICAgKndwYyA9IDE7CgogICAgLyogUmVwbGFjZSBlYWNoIGJhY2tzbGFzaCB3aXRoIE5VTEwsIGFuZCBpbmNyZW1lbnQgdGhlIGNvdW50ICovCiAgICBmb3IgKGk9MDt3c1tpXTtpKyspIHsKICAgICAgICBpZiAod3NbaV09PSdcXCcpIHsKICAgICAgICAgICAgd3NbaV09MDsKICAgICAgICAgICAgKCp3cGMpKys7CiAgICAgICAgfQogICAgfQoKICAgIGxlbiA9IGk7CgogICAgLyogQWxsb2NhdGUgdGhlIHNwYWNlIGZvciB0aGUgYXJyYXkgb2YgcG9pbnRlcnMsIGxlYXZpbmcgcm9vbSBmb3IgdGhlCiAgICAgICBOVUxMIGF0IHRoZSBlbmQgKi8KICAgICp3cHYgPSAoTFBXU1RSKilIZWFwQWxsb2MoIFN5c3RlbUhlYXAsIDAsIHNpemVvZihMUFdTVFIpKigqd3BjKzIpKTsKICAgICgqd3B2KVswXT0gd3M7CgogICAgLyogQXNzaWduIGVhY2ggcG9pbnRlciB0byB0aGUgYXBwcm9wcmlhdGUgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcgKi8KICAgIGogPSAxOwogICAgZm9yIChpPTE7aTxsZW47aSsrKQogICAgICAgIGlmICh3c1tpLTFdPT0wKSB7CiAgICAgICAgICAgICgqd3B2KVtqKytdPXdzK2k7CiAgICAgICAgICAgIC8qIFRSQUNFKHJlZywgIiBTdWJpdGVtICVkID0gJXNcbiIsai0xLGRlYnVnc3RyX3coKCp3cHYpW2otMV0pKTsgKi8KICAgICAgICB9CgogICAgKCp3cHYpW2pdPU5VTEw7Cn0KI2RlZmluZSBGUkVFX0tFWV9QQVRIIEhlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHNbMF0pO0hlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHMpOwoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSRUdJU1RSWV9Jbml0IFtJbnRlcm5hbF0KICogUmVnaXN0cnkgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBzb21lIGRlZmF1bHQga2V5cy4gCiAqLwpzdGF0aWMgdm9pZCBSRUdJU1RSWV9Jbml0KHZvaWQpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJVFJBQ0UocmVnLCIodm9pZClcbiIpOwoKCVJlZ0NyZWF0ZUtleTE2KEhLRVlfRFlOX0RBVEEsIlBlcmZTdGF0c1xcU3RhdERhdGEiLCZoa2V5KTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKICAgICAgICAvKiBUaGlzIHdhcyBhbiBPcGVuLCBidXQgc2luY2UgaXQgaXMgY2FsbGVkIGJlZm9yZSB0aGUgcmVhbCByZWdpc3RyaWVzCiAgICAgICAgICAgYXJlIGxvYWRlZCwgaXQgd2FzIGNoYW5nZWQgdG8gYSBDcmVhdGUgLSBNVEIgOTgwNTA3Ki8KCVJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXgzMkEoaGtleSwiSWRlbnRpZmllciIsMCxSRUdfU1osIlN5c3RlbVR5cGUgV0lORSIsc3RybGVuKCJTeXN0ZW1UeXBlIFdJTkUiKSk7CglSZWdDbG9zZUtleShoa2V5KTsKCgkvKiBcXFNPRlRXQVJFXFxNaWNyb3NvZnRcXFdpbmRvdyBOVFxcQ3VycmVudFZlcnNpb24KCSAqCQkJCQkJQ3VycmVudFZlcnNpb24KCSAqCQkJCQkJQ3VycmVudEJ1aWxkTnVtYmVyCgkgKgkJCQkJCUN1cnJlbnRUeXBlCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPd25lcgoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3JnYW5pemF0aW9uCgkgKgoJICovCgkvKiBTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxTZXJ2aWNlc1xcU05NUFxcUGFyYW1ldGVyc1xcUkZDMTE1NkFnZW50CgkgKiAJCQkJCXN0cmluZwlTeXNDb250YWN0CgkgKiAJCQkJCXN0cmluZwlTeXNMb2NhdGlvbgoJICogCQkJCQkJU3lzU2VydmljZXMKCSAqLwkJCQkJCQoJaWYgKC0xIT1nZXRob3N0bmFtZShidWYsMjAwKSkgewoJCVJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcQ29tcHV0ZXJOYW1lXFxDb21wdXRlck5hbWUiLCZoa2V5KTsKCQlSZWdTZXRWYWx1ZUV4MTYoaGtleSwiQ29tcHV0ZXJOYW1lIiwwLFJFR19TWixidWYsc3RybGVuKGJ1ZikrMSk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqIFNBVkUgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgUkVHSVNUUllfU0FWRV9WRVJTSU9OCTB4MDAwMDAwMDEKCi8qIFJlZ2lzdHJ5IHNhdmVmb3JtYXQ6CiAqIElmIHlvdSBjaGFuZ2UgaXQsIGluY3JlYXNlIGFib3ZlIG51bWJlciBieSAxLCB3aGljaCB3aWxsIGZsdXNoCiAqIG9sZCByZWdpc3RyeSBkYXRhYmFzZSBmaWxlcy4KICogCiAqIEdsb2JhbDoKICogCSJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWQiCiAqIAlzdWJrZXlzLi4uLgogKiBTdWJrZXlzOgogKiAJa2V5bmFtZQogKgkJdmFsdWVuYW1lPWxhc3Rtb2RpZmllZCx0eXBlLGRhdGEKICoJCS4uLgogKgkJc3Via2V5cwogKgkuLi4KICoga2V5bmFtZSx2YWx1ZW5hbWUsc3RyaW5nZGF0YToKICoJdGhlIHVzdWFsIGFzY2lpIGNoYXJhY3RlcnMgZnJvbSAweDAwLTB4ZmYgKHdlbGwsIG5vdCAweDAwKQogKglhbmQgXHVYWFhYIGFzIFVOSUNPREUgdmFsdWUgWFhYWCB3aXRoIFhYWFg+MHhmZgogKgkoICI9XFxcdCIgZXNjYXBlZCBpbiBcdVhYWFggZm9ybS4pCiAqIHR5cGUsbGFzdG1vZGlmaWVkOiAKICoJaW50CiAqIAogKiBGSVhNRTogZG9lc24ndCBzYXZlICdjbGFzcycgKHdoYXQgZG9lcyBpdCBtZWFuIGFueXdheT8pLCBub3IgZmxhZ3MuCiAqCiAqIFtIS0VZX0NVUlJFTlRfVVNFUlxcU29mdHdhcmVcXFRoZSBXSU5FIHRlYW1cXFdJTkVcXFJlZ2lzdHJ5XQogKiBTYXZlT25seVVwZGF0ZWRLZXlzPXllcwogKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVfY2hlY2tfdGFpbnRlZCBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF9zYXZlX2NoZWNrX3RhaW50ZWQoIExQS0VZU1RSVUNUIGxwa2V5ICkKewoJaW50CQl0YWludGVkOwoKCWlmICghbHBrZXkpCgkJcmV0dXJuIDA7CglpZiAobHBrZXktPmZsYWdzICYgUkVHX09QVElPTl9UQUlOVEVEKQoJCXRhaW50ZWQgPSAxOwoJZWxzZQoJCXRhaW50ZWQgPSAwOwoJd2hpbGUgKGxwa2V5KSB7CgkJaWYgKF9zYXZlX2NoZWNrX3RhaW50ZWQobHBrZXktPm5leHRzdWIpKSB7CgkJCWxwa2V5LT5mbGFncyB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJCXRhaW50ZWQgPSAxOwoJCX0KCQlscGtleQk9IGxwa2V5LT5uZXh0OwoJfQoJcmV0dXJuIHRhaW50ZWQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVfVVNUUklORyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfc2F2ZV9VU1RSSU5HKCBGSUxFICpGLCBMUFdTVFIgd3N0ciwgaW50IGVzY2FwZWVxICkKewoJTFBXU1RSCXM7CglpbnQJZG9lc2NhcGU7CgoJaWYgKHdzdHI9PU5VTEwpCgkJcmV0dXJuOwoJcz13c3RyOwoJd2hpbGUgKCpzKSB7CgkJZG9lc2NhcGU9MDsKCQlpZiAoKnM+MHhmZikKCQkJZG9lc2NhcGUgPSAxOwoJCWlmICgqcz09J1xuJykKCQkJZG9lc2NhcGUgPSAxOwoJCWlmIChlc2NhcGVlcSAmJiAqcz09Jz0nKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKCpzPT0nXFwnKQogICAgICAgICAgICAgICAgICAgICAgICBmcHV0YygqcyxGKTsgLyogaWYgXFwgdGhlbiBwdXQgaXQgdHdpY2UuICovCgkJaWYgKGRvZXNjYXBlKQoJCQlmcHJpbnRmKEYsIlxcdSUwNHgiLCooKHVuc2lnbmVkIHNob3J0KilzKSk7CgkJZWxzZQoJCQlmcHV0YygqcyxGKTsKCQlzKys7Cgl9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVzdWJrZXkgW0ludGVybmFsXQogKgogKiBOT1RFUwogKiAgUkVHX01VTFRJX1NaIGlzIGhhbmRsZWQgYXMgYmluYXJ5IChsaWtlIGluIHdpbjk1KSAoanMpCiAqLwpzdGF0aWMgaW50IF9zYXZlc3Via2V5KCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGxldmVsLCBpbnQgYWxsICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlpLHRhYnMsajsKCglscHhrZXkJPSBscGtleTsKCXdoaWxlIChscHhrZXkpIHsKCQlpZiAoCSEobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVk9MQVRJTEUpICYmCgkJCShhbGwgfHwgKGxweGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1RBSU5URUQpKQoJCSkgewoJCQlmb3IgKHRhYnM9bGV2ZWw7dGFicy0tOykKCQkJCWZwdXRjKCdcdCcsRik7CgkJCV9zYXZlX1VTVFJJTkcoRixscHhrZXktPmtleW5hbWUsMSk7CgkJCWZwdXRzKCJcbiIsRik7CgkJCWZvciAoaT0wO2k8bHB4a2V5LT5ucm9mdmFsdWVzO2krKykgewoJCQkJTFBLRVlWQUxVRQl2YWw9bHB4a2V5LT52YWx1ZXMraTsKCgkJCQlmb3IgKHRhYnM9bGV2ZWwrMTt0YWJzLS07KQoJCQkJCWZwdXRjKCdcdCcsRik7CgkJCQlfc2F2ZV9VU1RSSU5HKEYsdmFsLT5uYW1lLDApOwoJCQkJZnB1dGMoJz0nLEYpOwoJCQkJZnByaW50ZihGLCIlbGQsJWxkLCIsdmFsLT50eXBlLHZhbC0+bGFzdG1vZGlmaWVkKTsKCQkJCWlmICggdmFsLT50eXBlID09IFJFR19TWiB8fCB2YWwtPnR5cGUgPT0gUkVHX0VYUEFORF9TWiApCgkJCQkJX3NhdmVfVVNUUklORyhGLChMUFdTVFIpdmFsLT5kYXRhLDApOwoJCQkJZWxzZQoJCQkJCWZvciAoaj0wO2o8dmFsLT5sZW47aisrKQoJCQkJCQlmcHJpbnRmKEYsIiUwMngiLCooKHVuc2lnbmVkIGNoYXIqKXZhbC0+ZGF0YStqKSk7CgkJCQlmcHV0cygiXG4iLEYpOwoJCQl9CgkJCS8qIGRlc2NlbmQgcmVjdXJzaXZlbHkgKi8KCQkJaWYgKCFfc2F2ZXN1YmtleShGLGxweGtleS0+bmV4dHN1YixsZXZlbCsxLGFsbCkpCgkJCQlyZXR1cm4gMDsKCQl9CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXN1YnJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF9zYXZlc3VicmVnKCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGFsbCApCnsKCWZwcmludGYoRiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkXG4iLFJFR0lTVFJZX1NBVkVfVkVSU0lPTik7Cglfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKTsKCXJldHVybiBfc2F2ZXN1YmtleShGLGxwa2V5LT5uZXh0c3ViLDAsYWxsKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIEJPT0wzMiBfc2F2ZXJlZyggTFBLRVlTVFJVQ1QgbHBrZXksIGNoYXIgKmZuLCBpbnQgYWxsICkKewoJRklMRQkqRjsKCglGPWZvcGVuKGZuLCJ3Iik7CglpZiAoRj09TlVMTCkgewoJCVdBUk4ocmVnLCJDb3VsZG4ndCBvcGVuICVzIGZvciB3cml0aW5nOiAlc1xuIiwKCQkJZm4sc3RyZXJyb3IoZXJybm8pCgkJKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglpZiAoIV9zYXZlc3VicmVnKEYsbHBrZXksYWxsKSkgewoJCWZjbG9zZShGKTsKCQl1bmxpbmsoZm4pOwoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gc2F2ZSBrZXlzLCBwZXJoYXBzIG5vIG1vcmUgZGlza3NwYWNlIGZvciAlcz9cbiIsZm4pOwoJCXJldHVybiBGQUxTRTsKCX0KCWZjbG9zZShGKTsKICAgICAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfU2F2ZVJlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnZvaWQgU0hFTExfU2F2ZVJlZ2lzdHJ5KCB2b2lkICkKewoJY2hhcgkqZm47CglzdHJ1Y3QJcGFzc3dkCSpwd2Q7CgljaGFyCWJ1Zls0XTsKCUhLRVkJaGtleTsKCWludAlhbGw7CgogICAgVFJBQ0UocmVnLCIodm9pZClcbiIpOwoKCWFsbD0wOwoJaWYgKFJlZ09wZW5LZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJc3RyY3B5KGJ1ZiwieWVzIik7Cgl9IGVsc2UgewoJCURXT1JEIGxlbixqdW5rLHR5cGU7CgoJCWxlbj00OwoJCWlmICgJKEVSUk9SX1NVQ0NFU1MhPVJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQkJCWhrZXksCgkJCQlWQUxfU0FWRVVQREFURUQsCgkJCQkmanVuaywKCQkJCSZ0eXBlLAoJCQkJYnVmLAoJCQkJJmxlbgoJCQkpKXx8ICh0eXBlIT1SRUdfU1opCgkJKQoJCQlzdHJjcHkoYnVmLCJ5ZXMiKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KCWlmIChsc3RyY21waTMyQShidWYsInllcyIpKQoJCWFsbD0xOwoJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCWlmIChwd2QhPU5VTEwgJiYgcHdkLT5wd19kaXIhPU5VTEwpCiAgICAgICAgewogICAgICAgICAgICAgICAgY2hhciAqdG1wOwoKCQlmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKHB3ZC0+cHdfZGlyKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikgKyAyICk7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgpOwoJCS8qIGNyZWF0ZSB0aGUgZGlyZWN0b3J5LiBkb24ndCBjYXJlIGFib3V0IGVycm9yY29kZXMuICovCgkJbWtkaXIoZm4sMDc1NSk7IC8qIGRyd3hyLXhyLXggKi8KCQlzdHJjYXQoZm4sIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwoJCXRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CgkJc3RyY3B5KHRtcCxmbik7c3RyY2F0KHRtcCwiLnRtcCIpOwoJCWlmIChfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUiksdG1wLGFsbCkpIHsKCQkJaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewoJCQkJcGVycm9yKCJyZW5hbWUgdG1wIHJlZ2lzdHJ5Iik7CgkJCQl1bmxpbmsodG1wKTsKCQkJfQoJCX0KCQlmcmVlKHRtcCk7CgkJZnJlZShmbik7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9NQUNISU5FKTsKCQl0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwoJCXN0cmNweSh0bXAsZm4pO3N0cmNhdCh0bXAsIi50bXAiKTsKCQlpZiAoX3NhdmVyZWcobG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSx0bXAsYWxsKSkgewoJCQlpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CgkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKCQkJCXVubGluayh0bXApOwoJCQl9CgkJfQoJCWZyZWUodG1wKTsKCQlmcmVlKGZuKTsKCX0gZWxzZQoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVkLlxuIixnZXR1aWQoKSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqIExPQUQgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmluZF9vcl9hZGRfa2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBMUEtFWVNUUlVDVCBfZmluZF9vcl9hZGRfa2V5KCBMUEtFWVNUUlVDVCBscGtleSwgTFBXU1RSIGtleW5hbWUgKQp7CglMUEtFWVNUUlVDVAlscHhrZXksKmxwbHBrZXk7CgoJaWYgKCgha2V5bmFtZSkgfHwgKGtleW5hbWVbMF09PTApKSB7CgkJZnJlZShrZXluYW1lKTsKCQlyZXR1cm4gbHBrZXk7Cgl9CglscGxwa2V5PSAmKGxwa2V5LT5uZXh0c3ViKTsKCWxweGtleQk9ICpscGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJKGxweGtleS0+a2V5bmFtZVswXT09a2V5bmFtZVswXSkgJiYgCgkJCSFsc3RyY21waTMyVyhscHhrZXktPmtleW5hbWUsa2V5bmFtZSkKCQkpCgkJCWJyZWFrOwoJCWxwbHBrZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7Cgl9CglpZiAobHB4a2V5PT1OVUxMKSB7CgkJKmxwbHBrZXkgPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7CgkJbWVtc2V0KGxweGtleSwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTsKCQlscHhrZXktPmtleW5hbWUJPSBrZXluYW1lOwoJfSBlbHNlCgkJZnJlZShrZXluYW1lKTsKCXJldHVybiBscHhrZXk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2ZpbmRfb3JfYWRkX3ZhbHVlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9maW5kX29yX2FkZF92YWx1ZSggTFBLRVlTVFJVQ1QgbHBrZXksIExQV1NUUiBuYW1lLCBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBkYXRhLCBEV09SRCBsZW4sIERXT1JEIGxhc3Rtb2RpZmllZCApCnsKCUxQS0VZVkFMVUUJdmFsPU5VTEw7CglpbnQJCWk7CgoJaWYgKG5hbWUgJiYgISpuYW1lKSB7LyogZW1wdHkgc3RyaW5nIGVxdWFscyBkZWZhdWx0IChOVUxMKSB2YWx1ZSAqLwoJCWZyZWUobmFtZSk7CgkJbmFtZSA9IE5VTEw7Cgl9CgoJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCWlmIChuYW1lPT1OVUxMKSB7CgkJCWlmICh2YWwtPm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCQl9IGVsc2UgewoJCQlpZiAoCXZhbC0+bmFtZSE9TlVMTCAmJiAKCQkJCXZhbC0+bmFtZVswXT09bmFtZVswXSAmJgoJCQkJIWxzdHJjbXBpMzJXKHZhbC0+bmFtZSxuYW1lKQoJCQkpCgkJCQlicmVhazsKCQl9Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0geHJlYWxsb2MoCgkJCWxwa2V5LT52YWx1ZXMsCgkJCSgrK2xwa2V5LT5ucm9mdmFsdWVzKSpzaXplb2YoS0VZVkFMVUUpCgkJKTsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCW1lbXNldCh2YWwsJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCQl2YWwtPm5hbWUgPSBuYW1lOwoJfSBlbHNlIHsKCQlpZiAobmFtZSkKCQkJZnJlZShuYW1lKTsKCX0KCWlmICh2YWwtPmxhc3Rtb2RpZmllZDxsYXN0bW9kaWZpZWQpIHsKCQl2YWwtPmxhc3Rtb2RpZmllZD1sYXN0bW9kaWZpZWQ7CgkJdmFsLT50eXBlID0gdHlwZTsKCQl2YWwtPmxlbiAgPSBsZW47CgkJaWYgKHZhbC0+ZGF0YSkgCgkJCWZyZWUodmFsLT5kYXRhKTsKCQl2YWwtPmRhdGEgPSBkYXRhOwoJfSBlbHNlCgkJZnJlZShkYXRhKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9saW5lIFtJbnRlcm5hbF0KICoKICogcmVhZHMgYSBsaW5lIGluY2x1ZGluZyBkeW5hbWljYWxseSBlbmxhcmdpbmcgdGhlIHJlYWRidWZmZXIgYW5kIHRocm93aW5nCiAqIGF3YXkgY29tbWVudHMKICovCnN0YXRpYyBpbnQgX3dpbmVfcmVhZF9saW5lKCBGSUxFICpGLCBjaGFyICoqYnVmLCBpbnQgKmxlbiApCnsKCWNoYXIJKnMsKmN1cnJlYWQ7CglpbnQJbXlsZW4sY3Vyb2ZmOwoKCWN1cnJlYWQJPSAqYnVmOwoJbXlsZW4JPSAqbGVuOwoJKipidWYJPSAnXDAnOwoJd2hpbGUgKDEpIHsKCQl3aGlsZSAoMSkgewoJCQlzPWZnZXRzKGN1cnJlYWQsbXlsZW4sRik7CgkJCWlmIChzPT1OVUxMKQoJCQkJcmV0dXJuIDA7IC8qIEVPRiAqLwoJCQlpZiAoTlVMTD09KHM9c3RyY2hyKGN1cnJlYWQsJ1xuJykpKSB7CgkJCQkvKiBidWZmZXIgd2Fzbid0IGxhcmdlIGVub3VnaCAqLwoJCQkJY3Vyb2ZmCT0gc3RybGVuKCpidWYpOwoJCQkJKmJ1Zgk9IHhyZWFsbG9jKCpidWYsKmxlbioyKTsKCQkJCWN1cnJlYWQJPSAqYnVmICsgY3Vyb2ZmOwoJCQkJbXlsZW4JPSAqbGVuOwkvKiB3ZSBmaWxsZWQgdXAgdGhlIGJ1ZmZlciBhbmQgCgkJCQkJCSAqIGdvdCBuZXcgJypsZW4nIGJ5dGVzIHRvIGZpbGwKCQkJCQkJICovCgkJCQkqbGVuCT0gKmxlbiAqIDI7CgkJCX0gZWxzZSB7CgkJCQkqcz0nXDAnOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLyogdGhyb3cgYXdheSBjb21tZW50cyAqLwoJCWlmICgqKmJ1Zj09JyMnIHx8ICoqYnVmPT0nOycpIHsKCQkJY3VycmVhZAk9ICpidWY7CgkJCW15bGVuCT0gKmxlbjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzKSAJLyogZ290IGVuZCBvZiBsaW5lICovCgkJCWJyZWFrOwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfVVNUUklORyBbSW50ZXJuYWxdCiAqCiAqIGNvbnZlcnRzIGEgY2hhciogaW50byBhIFVOSUNPREUgc3RyaW5nICh1cCB0byBhIHNwZWNpYWwgY2hhcikKICogYW5kIHJldHVybnMgdGhlIHBvc2l0aW9uIGV4YWN0bHkgYWZ0ZXIgdGhhdCBzdHJpbmcKICovCnN0YXRpYyBjaGFyKiBfd2luZV9yZWFkX1VTVFJJTkcoIGNoYXIgKmJ1ZiwgTFBXU1RSICpzdHIgKQp7CgljaGFyCSpzOwoJTFBXU1RSCXdzOwoKCS8qIHJlYWQgdXAgdG8gIj0iIG9yICJcMCIgb3IgIlxuIiAqLwoJcwk9IGJ1ZjsKCWlmICgqcyA9PSAnPScpIHsKCQkvKiBlbXB0eSBzdHJpbmcgaXMgdGhlIHdpbjMuMSBkZWZhdWx0IHZhbHVlKE5VTEwpKi8KCQkqc3RyCT0gTlVMTDsKCQlyZXR1cm4gczsKCX0KCSpzdHIJPSAoTFBXU1RSKXhtYWxsb2MoMipzdHJsZW4oYnVmKSsyKTsKCXdzCT0gKnN0cjsKCXdoaWxlICgqcyAmJiAoKnMhPSdcbicpICYmICgqcyE9Jz0nKSkgewoJCWlmICgqcyE9J1xcJykKCQkJKndzKys9KigodW5zaWduZWQgY2hhciopcysrKTsKCQllbHNlIHsKCQkJcysrOwoJCQlpZiAoISpzKSB7CgkJCQkvKiBEYW5nbGluZyBcIC4uLiBtYXkgb25seSBoYXBwZW4gaWYgYSByZWdpc3RyeQoJCQkJICogd3JpdGUgd2FzIHNob3J0LiBGSVhNRTogV2hhdCBkbyB0bz8KCQkJCSAqLwoJCQkJIGJyZWFrOwoJCQl9CgkJCWlmICgqcz09J1xcJykgewoJCQkJKndzKys9J1xcJzsKCQkJCXMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWlmICgqcyE9J3UnKSB7CgkJCQlXQVJOKHJlZywiTm9uIHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlIFxcJWMgZm91bmQgaW4gfCVzfFxuIiwqcyxidWYpOwoJCQkJKndzKys9J1xcJzsKCQkJCSp3cysrPSpzKys7CgkJCX0gZWxzZSB7CgkJCQljaGFyCXhidWZbNV07CgkJCQlpbnQJd2M7CgoJCQkJcysrOwoJCQkJbWVtY3B5KHhidWYscyw0KTt4YnVmWzRdPSdcMCc7CgkJCQlpZiAoIXNzY2FuZih4YnVmLCIleCIsJndjKSkKCQkJCQlXQVJOKHJlZywiU3RyYW5nZSBlc2NhcGUgc2VxdWVuY2UgJXMgZm91bmQgaW4gfCVzfFxuIix4YnVmLGJ1Zik7CgkJCQlzKz00OwoJCQkJKndzKysJPSh1bnNpZ25lZCBzaG9ydCl3YzsKCQkJfQoJCX0KCX0KCSp3cwk9IDA7Cgl3cwk9ICpzdHI7CglpZiAoKndzKQoJCSpzdHIJPSBzdHJkdXBXKCpzdHIpOwoJZWxzZQoJCSpzdHIJPSBOVUxMOwoJZnJlZSh3cyk7CglyZXR1cm4gczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHN1YmtleSBbSW50ZXJuYWxdCiAqCiAqIE5PVEVTCiAqICAgIEl0IHNlZW1zIGxpa2UgdGhpcyBpcyByZXR1cm5pbmcgYSBib29sZWFuLiAgU2hvdWxkIGl0PwogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IDEKICogICAgRmFpbHVyZTogMAogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3Via2V5KCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGxldmVsLCBjaGFyICoqYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqYnVmbGVuLCBEV09SRCBvcHRmbGFnICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlpOwoJY2hhcgkJKnM7CglMUFdTVFIJCW5hbWU7CgogICAgVFJBQ0UocmVnLCIoJXAsJXAsJWQsJXMsJWQsJWx4KVxuIiwgRiwgbHBrZXksIGxldmVsLCBkZWJ1Z3N0cl9hKCpidWYpLAogICAgICAgICAgKmJ1Zmxlbiwgb3B0ZmxhZyk7CgogICAgbHBrZXktPmZsYWdzIHw9IG9wdGZsYWc7CgogICAgLyogR29vZC4gIFdlIGFscmVhZHkgZ290IGEgbGluZSBoZXJlIC4uLiBzbyBwYXJzZSBpdCAqLwogICAgbHB4a2V5ID0gTlVMTDsKICAgIHdoaWxlICgxKSB7CiAgICAgICAgaT0wO3M9KmJ1ZjsKICAgICAgICB3aGlsZSAoKnM9PSdcdCcpIHsKICAgICAgICAgICAgcysrOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQogICAgICAgIGlmIChpPmxldmVsKSB7CiAgICAgICAgICAgIGlmIChscHhrZXk9PU5VTEwpIHsKICAgICAgICAgICAgICAgIFdBUk4ocmVnLCJHb3QgYSBzdWJoaWVyYXJjaHkgd2l0aG91dCByZXNwLiBrZXk/XG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF93aW5lX2xvYWRzdWJrZXkoRixscHhrZXksbGV2ZWwrMSxidWYsYnVmbGVuLG9wdGZsYWcpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoJCS8qIGxldCB0aGUgY2FsbGVyIGhhbmRsZSB0aGlzIGxpbmUgKi8KCQlpZiAoaTxsZXZlbCB8fCAqKmJ1Zj09J1wwJykKCQkJcmV0dXJuIDE7CgoJCS8qIGl0IGNhbiBiZTogYSB2YWx1ZSBvciBhIGtleW5hbWUuIFBhcnNlIHRoZSBuYW1lIGZpcnN0ICovCgkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywmbmFtZSk7CgoJCS8qIHN3aXRjaCgpIGRlZmF1bHQ6IGhhY2sgdG8gYXZvaWQgZ290b3MgKi8KCQlzd2l0Y2ggKDApIHsKCQlkZWZhdWx0OgoJCQlpZiAoKnM9PSdcMCcpIHsKCQkJCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoJCQl9IGVsc2UgewoJCQkJTFBCWVRFCQlkYXRhOwoJCQkJaW50CQlsZW4sbGFzdG1vZGlmaWVkLHR5cGU7CgoJCQkJaWYgKCpzIT0nPScpIHsKCQkJCQlXQVJOKHJlZywiVW5leHBlY3RlZCBjaGFyYWN0ZXI6ICVjXG4iLCpzKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCXMrKzsKCQkJCWlmICgyIT1zc2NhbmYocywiJWQsJWQsIiwmdHlwZSwmbGFzdG1vZGlmaWVkKSkgewoJCQkJCVdBUk4ocmVnLCJIYXZlbid0IHVuZGVyc3Rvb2QgcG9zc2libGUgdmFsdWUgaW4gfCVzfCwgc2tpcHBpbmcuXG4iLCpidWYpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJLyogc2tpcCB0aGUgMiAsICovCgkJCQlzPXN0cmNocihzLCcsJyk7cysrOwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCWlmICh0eXBlID09IFJFR19TWiB8fCB0eXBlID09IFJFR19FWFBBTkRfU1opIHsKCQkJCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLChMUFdTVFIqKSZkYXRhKTsKCQkJCQlpZiAoZGF0YSkKCQkJCQkJbGVuID0gbHN0cmxlbjMyVygoTFBXU1RSKWRhdGEpKjIrMjsKCQkJCQllbHNlCQoJCQkJCQlsZW4gPSAwOwoJCQkJfSBlbHNlIHsKCQkJCQlsZW49c3RybGVuKHMpLzI7CgkJCQkJZGF0YSA9IChMUEJZVEUpeG1hbGxvYyhsZW4rMSk7CgkJCQkJZm9yIChpPTA7aTxsZW47aSsrKSB7CgkJCQkJCWRhdGFbaV09MDsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV09KCpzLScwJyk8PDQ7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nYScrJ1x4YScpPDw0OwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ0EnKydceGEnKTw8NDsKCQkJCQkJcysrOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXXw9KnMtJzAnOwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ2EnKydceGEnOwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ0EnKydceGEnOwoJCQkJCQlzKys7CgkJCQkJfQoJCQkJfQoJCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKGxwa2V5LG5hbWUsdHlwZSxkYXRhLGxlbixsYXN0bW9kaWZpZWQpOwoJCQl9CgkJfQoJCS8qIHJlYWQgdGhlIG5leHQgbGluZSAqLwoJCWlmICghX3dpbmVfcmVhZF9saW5lKEYsYnVmLGJ1ZmxlbikpCgkJCXJldHVybiAxOwogICAgfQogICAgcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3VicmVnKCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgRFdPUkQgb3B0ZmxhZyApCnsKCWludAl2ZXI7CgljaGFyCSpidWY7CglpbnQJYnVmbGVuOwoKCWJ1Zj14bWFsbG9jKDEwKTtidWZsZW49MTA7CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXNzY2FuZihidWYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAodmVyIT1SRUdJU1RSWV9TQVZFX1ZFUlNJT04pIHsKCQlUUkFDRShyZWcsIk9sZCBmb3JtYXQgKCVkKSByZWdpc3RyeSBmb3VuZCwgaWdub3JpbmcgaXQuIChidWYgd2FzICVzKS5cbiIsdmVyLGJ1Zik7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9sb2Fkc3Via2V5KEYsbHBrZXksMCwmYnVmLCZidWZsZW4sb3B0ZmxhZykpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglmcmVlKGJ1Zik7CglyZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfd2luZV9sb2FkcmVnKCBMUEtFWVNUUlVDVCBscGtleSwgY2hhciAqZm4sIERXT1JEIG9wdGZsYWcgKQp7CiAgICBGSUxFICpGOwoKICAgIFRSQUNFKHJlZywiKCVwLCVzLCVseClcbiIsbHBrZXksZGVidWdzdHJfYShmbiksb3B0ZmxhZyk7CgogICAgRiA9IGZvcGVuKGZuLCJyYiIpOwogICAgaWYgKEY9PU5VTEwpIHsKICAgICAgICBXQVJOKHJlZywiQ291bGRuJ3Qgb3BlbiAlcyBmb3IgcmVhZGluZzogJXNcbiIsZm4sc3RyZXJyb3IoZXJybm8pICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKCFfd2luZV9sb2Fkc3VicmVnKEYsbHBrZXksb3B0ZmxhZykpIHsKICAgICAgICBmY2xvc2UoRik7CiAgICAgICAgdW5saW5rKGZuKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmY2xvc2UoRik7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9jb3B5X3JlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9jb3B5X3JlZ2lzdHJ5KCBMUEtFWVNUUlVDVCBmcm9tLCBMUEtFWVNUUlVDVCB0byApCnsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJajsKCUxQS0VZVkFMVUUJdmFsZnJvbTsKCglmcm9tPWZyb20tPm5leHRzdWI7Cgl3aGlsZSAoZnJvbSkgewoJCWxweGtleSA9IF9maW5kX29yX2FkZF9rZXkodG8sc3RyZHVwVyhmcm9tLT5rZXluYW1lKSk7CgoJCWZvciAoaj0wO2o8ZnJvbS0+bnJvZnZhbHVlcztqKyspIHsKCQkJTFBXU1RSCW5hbWU7CgkJCUxQQllURQlkYXRhOwoKCQkJdmFsZnJvbSA9IGZyb20tPnZhbHVlcytqOwoJCQluYW1lPXZhbGZyb20tPm5hbWU7CgkJCWlmIChuYW1lKSBuYW1lPXN0cmR1cFcobmFtZSk7CgkJCWRhdGE9KExQQllURSl4bWFsbG9jKHZhbGZyb20tPmxlbik7CgkJCW1lbWNweShkYXRhLHZhbGZyb20tPmRhdGEsdmFsZnJvbS0+bGVuKTsKCgkJCV9maW5kX29yX2FkZF92YWx1ZSgKCQkJCWxweGtleSwKCQkJCW5hbWUsCgkJCQl2YWxmcm9tLT50eXBlLAoJCQkJZGF0YSwKCQkJCXZhbGZyb20tPmxlbiwKCQkJCXZhbGZyb20tPmxhc3Rtb2RpZmllZAoJCQkpOwoJCX0KCQlfY29weV9yZWdpc3RyeShmcm9tLGxweGtleSk7CgkJZnJvbSA9IGZyb20tPm5leHQ7Cgl9Cn0KCgovKiBXSU5ET1dTIDk1IFJFR0lTVFJZIExPQURFUiAqLwovKiAKICogU3RydWN0dXJlIG9mIGEgd2luOTUgcmVnaXN0cnkgZGF0YWJhc2UuCiAqIG1haW4gaGVhZGVyOgogKiAwIDoJIkNSRUciCS0gbWFnaWMKICogNCA6CURXT1JEIHZlcnNpb24KICogOCA6CURXT1JEIG9mZnNldF9vZl9SR0RCX3BhcnQKICogMEMuLjBGOgk/IChzb21lb25lIGZpbGwgaW4gcGxlYXNlKQogKiAxMDogIFdPUkQJbnVtYmVyIG9mIFJHREIgYmxvY2tzCiAqIDEyOiAgV09SRAk/CiAqIDE0OiAgV09SRAlhbHdheXMgMDAwMD8KICogMTY6ICBXT1JECWFsd2F5cyAwMDAxPwogKiAxOC4uMUY6CT8gKHNvbWVvbmUgZmlsbCBpbiBwbGVhc2UpCiAqCiAqIDIwOiBSR0tOX3NlY3Rpb246CiAqICAgaGVhZGVyOgogKiAJMCA6CQkiUkdLTiIJLSBtYWdpYwogKiAgICAgIDQgOiBEV09SRAlvZmZzZXQgdG8gZmlyc3QgUkdEQiBzZWN0aW9uCiAqICAgICAgOCA6IERXT1JECW9mZnNldCB0byB0aGUgcm9vdCByZWNvcmQKICogCUMuLjB4MUI6IAk/IChmaWxsIGluKQogKiAgICAgIDB4MjAgLi4uIG9mZnNldF9vZl9SR0RCX3BhcnQ6IERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZXMKICoKICogICBEaXNrIEtleSBFbnRyeSBTdHJ1Y3R1cmU6CiAqCTAwOiBEV09SRAktIEZyZWUgZW50cnkgaW5kaWNhdG9yKD8pCiAqCTA0OiBEV09SRAktIEhhc2ggPSBzdW0gb2YgYnl0ZXMgb2Yga2V5bmFtZQogKgkwODogRFdPUkQJLSBSb290IGtleSBpbmRpY2F0b3I/IHVua25vd24sIGJ1dCB1c3VhbGx5IDB4RkZGRkZGRkYgb24gd2luOTUgc3lzdGVtcwogKgkwQzogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgUHJldmlvdXNMZXZlbCBLZXkuCiAqCTEwOiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBOZXh0IFN1YmxldmVsIEtleS4KICoJMTQ6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIE5leHQgS2V5IChvbiBzYW1lIGxldmVsKS4KICogREtFUD4xODogV09SRAktIE5yLCBMb3cgU2lnbmlmaWNhbnQgcGFydC4KICoJMUE6IFdPUkQJLSBOciwgSGlnaCBTaWduaWZpY2FudCBwYXJ0LgogKgogKiBUaGUgZGlzayBhZGRyZXNzIGFsd2F5cyBwb2ludHMgdG8gdGhlIG5yIHBhcnQgb2YgdGhlIHByZXZpb3VzIGtleSBlbnRyeSAKICogb2YgdGhlIHJlZmVyZW5jZWQga2V5LiBEb24ndCBhc2sgbWUgd2h5LCBvciBldmVuIGlmIEkgZ290IHRoaXMgY29ycmVjdAogKiBmcm9tIHN0YXJpbmcgYXQgMWtnIG9mIGhleGR1bXBzLiAoREtFUCkKICoKICogVGhlIEhpZ2ggc2lnbmlmaWNhbnQgcGFydCBvZiB0aGUgc3RydWN0dXJlIHNlZW1zIHRvIGVxdWFsIHRoZSBudW1iZXIKICogb2YgdGhlIFJHREIgc2VjdGlvbi4gVGhlIGxvdyBzaWduaWZpY2FudCBwYXJ0IGlzIGEgdW5pcXVlIElEIHdpdGhpbgogKiB0aGF0IFJHREIgc2VjdGlvbgogKgogKiBUaGVyZSBhcmUgdHdvIG1pbm9yIGNvcnJlY3Rpb25zIHRvIHRoZSBwb3NpdGlvbiBvZiB0aGF0IHN0cnVjdHVyZS4KICogMS4gSWYgdGhlIGFkZHJlc3MgaXMgeHh4MDE0IG9yIHh4eDAxOCBpdCB3aWxsIGJlIGFsaWduZWQgdG8geHh4MDFjIEFORCAKICogICAgdGhlIERLRSByZXJlYWQgZnJvbSB0aGVyZS4KICogMi4gSWYgdGhlIGFkZHJlc3MgaXMgeHh4RkZ4IGl0IHdpbGwgYmUgYWxpZ25lZCB0byAoeHh4KzEpMDAwLgogKiBDUFMgLSBJIGhhdmUgbm90IGV4cGVyaWVuY2VkIHRoZSBhYm92ZSBwaGVub21lbm9uIGluIG15IHJlZ2lzdHJ5IGZpbGVzCiAqCiAqIFJHREJfc2VjdGlvbjoKICogCTAwOgkJIlJHREIiCS0gbWFnaWMKICoJMDQ6IERXT1JECW9mZnNldCB0byBuZXh0IFJHREIgc2VjdGlvbgogKgkwODogRFdPUkQJPwogKgkwQzogV09SRAlhbHdheXMgMDAwZD8KICoJMEU6IFdPUkQJUkdEQiBibG9jayBudW1iZXIKICoJMTA6CURXT1JECT8gKGVxdWFscyB2YWx1ZSBhdCBvZmZzZXQgNCAtIHZhbHVlIGF0IG9mZnNldCA4KQogKgkxNC4uMUY6CQk/CiAqCTIwLi4uLi46CWRpc2sga2V5cwogKgogKiBkaXNrIGtleToKICogCTAwOiAJRFdPUkQJbmV4dGtleW9mZnNldAktIG9mZnNldCB0byB0aGUgbmV4dCBkaXNrIGtleSBzdHJ1Y3R1cmUKICoJMDg6IAlXT1JECW5yTFMJCS0gbG93IHNpZ25pZmljYW50IHBhcnQgb2YgTlIKICoJMEE6IAlXT1JECW5ySFMJCS0gaGlnaCBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBDOiAJRFdPUkQJYnl0ZXN1c2VkCS0gYnl0ZXMgdXNlZCBpbiB0aGlzIHN0cnVjdHVyZS4KICoJMTA6IAlXT1JECW5hbWVfbGVuCS0gbGVuZ3RoIG9mIG5hbWUgaW4gYnl0ZXMuIHdpdGhvdXQgXDAKICoJMTI6IAlXT1JECW5yX29mX3ZhbHVlcwktIG51bWJlciBvZiB2YWx1ZXMuCiAqCTE0OiAJY2hhcgluYW1lW25hbWVfbGVuXQktIG5hbWUgc3RyaW5nLiBObyBcMC4KICoJMTQrbmFtZV9sZW46IGRpc2sgdmFsdWVzCiAqCW5leHRrZXlvZmZzZXQ6IC4uLiBuZXh0IGRpc2sga2V5CiAqCiAqIGRpc2sgdmFsdWU6CiAqCTAwOglEV09SRAl0eXBlCQktIHZhbHVlIHR5cGUgKGhtbSwgY291bGQgYmUgV09SRCB0b28pCiAqCTA0OglEV09SRAkJCS0gdW5rbm93biwgdXN1YWxseSAwCiAqCTA4OglXT1JECW5hbWVsZW4JCS0gbGVuZ3RoIG9mIE5hbWUuIDAgbWVhbnMgbmFtZT1OVUxMCiAqCTBDOglXT1JECWRhdGFsZW4JCS0gbGVuZ3RoIG9mIERhdGEuCiAqCTEwOgljaGFyCW5hbWVbbmFtZWxlbl0JLSBuYW1lLCBubyBcMAogKgkxMCtuYW1lbGVuOiBCWVRFCWRhdGFbZGF0YWxlbl0gLSBkYXRhLCB3aXRob3V0IFwwIGlmIHN0cmluZwogKgkxMCtuYW1lbGVuK2RhdGFsZW46IG5leHQgdmFsdWVzIG9yIGRpc2sga2V5CiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuckhTIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKiByZXBlYXQgdW50aWwgZW5kIG9mIGZpbGUuCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgdmFsdWUgYXQgb2Zmc2V0CiAqIDEwIGVxdWFscyB0aGUgdmFsdWUgYXQgb2Zmc2V0IDQgbWludXMgdGhlIHZhbHVlIGF0IG9mZnNldCA4LiBJIGhhdmUgbm8KICogaWRlYSBhdCB0aGUgbW9tZW50IHdoYXQgdGhpcyBtZWFucy4gIChLZXZpbiBDb3plbnMpCiAqCiAqIEZJWE1FOiB0aGlzIGRlc2NyaXB0aW9uIG5lZWRzIHNvbWUgc2VyaW91cyBoZWxwLCB5ZXMuCiAqLwoKc3RydWN0CV93OTVrZXl2YWx1ZSB7Cgl1bnNpZ25lZCBsb25nCQl0eXBlOwoJdW5zaWduZWQgc2hvcnQJCWRhdGFsZW47CgljaGFyCQkJKm5hbWU7Cgl1bnNpZ25lZCBjaGFyCQkqZGF0YTsKCXVuc2lnbmVkIGxvbmcJCXgxOwoJaW50CQkJbGFzdG1vZGlmaWVkOwp9OwoKc3RydWN0IAlfdzk1a2V5IHsKCWNoYXIJCQkqbmFtZTsKCWludAkJCW5yb2Z2YWxzOwoJc3RydWN0CV93OTVrZXl2YWx1ZQkqdmFsdWVzOwoJc3RydWN0IF93OTVrZXkJCSpwcmV2bHZsOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0c3ViOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0Owp9OwoKCnN0cnVjdCBfdzk1X2luZm8gewogIGNoYXIgKnJna25idWZmZXI7CiAgaW50ICByZ2tuc2l6ZTsKICBjaGFyICpyZ2RiYnVmZmVyOwogIGludCAgcmdkYnNpemU7CiAgaW50ICBkZXB0aDsKICBpbnQgIGxhc3Rtb2RpZmllZDsKfTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfcHJvY2Vzc0tleSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgX3c5NV9wcm9jZXNzS2V5ICggTFBLRVlTVFJVQ1QgbHBrZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuckxTLCBpbnQgbnJNUywgc3RydWN0IF93OTVfaW5mbyAqaW5mbyApCgp7CiAgLyogRGlzayBLZXkgSGVhZGVyIHN0cnVjdHVyZSAoUkdEQiBwYXJ0KSAqLwoJc3RydWN0CWRraCB7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nCQluZXh0a2V5b2ZmOyAKCQl1bnNpZ25lZCBzaG9ydAkJbnJMUzsKCQl1bnNpZ25lZCBzaG9ydAkJbnJNUzsKCQl1bnNpZ25lZCBsb25nCQlieXRlc3VzZWQ7CgkJdW5zaWduZWQgc2hvcnQJCWtleW5hbWVsZW47CgkJdW5zaWduZWQgc2hvcnQJCXZhbHVlczsKCQl1bnNpZ25lZCBsb25nCQl4eDE7CgkJLyoga2V5bmFtZSAqLwoJCS8qIGRpc2sga2V5IHZhbHVlcyBvciBub3RoaW5nICovCgl9OwoJLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlICovCglzdHJ1Y3QJZGt2IHsKCQl1bnNpZ25lZCBsb25nCQl0eXBlOwoJCXVuc2lnbmVkIGxvbmcJCXgxOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxuYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxkYXRhbGVuOwoJCS8qIHZhbG5hbWUsIHZhbGRhdGEgKi8KCX07CgoJCglzdHJ1Y3QJZGtoIGRraDsKCWludAlieXRlc3JlYWQgPSAwOwoJY2hhciAgICAqcmdkYmRhdGEgPSBpbmZvLT5yZ2RiYnVmZmVyOwoJaW50ICAgICBuYnl0ZXMgPSBpbmZvLT5yZ2Ric2l6ZTsKCWNoYXIgICAgKmN1cmRhdGEgPSByZ2RiZGF0YTsKCWNoYXIgICAgKmVuZCA9IHJnZGJkYXRhICsgbmJ5dGVzOwoJaW50ICAgICBvZmZfbmV4dF9yZ2RiOwoJY2hhciAgICAqbmV4dCA9IHJnZGJkYXRhOwoJaW50ICAgICBucmdkYiwgaTsKCUxQS0VZU1RSVUNUCWxweGtleTsKCQoJZG8gewoJICBjdXJkYXRhID0gbmV4dDsKCSAgaWYgKHN0cm5jbXAoY3VyZGF0YSwgIlJHREIiLCA0KSkgcmV0dXJuIChOVUxMKTsKCSAgICAKCSAgbWVtY3B5KCZvZmZfbmV4dF9yZ2RiLGN1cmRhdGErNCw0KTsKCSAgbmV4dCA9IGN1cmRhdGEgKyBvZmZfbmV4dF9yZ2RiOwoJICBucmdkYiA9IChpbnQpICooKHNob3J0ICopY3VyZGF0YSArIDcpOwoKCX0gd2hpbGUgKG5yZ2RiICE9IG5yTVMgJiYgKG5leHQgPCBlbmQpKTsKCgkvKiBjdXJkYXRhIG5vdyBwb2ludHMgdG8gdGhlIHN0YXJ0IG9mIHRoZSByaWdodCBSR0RCIHNlY3Rpb24gKi8KCWN1cmRhdGEgKz0gMHgyMDsKCiNkZWZpbmUgWFJFQUQod2hlcmV0byxsZW4pIFwKCWlmICgoY3VyZGF0YSArIGxlbikgPGVuZCkge1wKCQltZW1jcHkod2hlcmV0byxjdXJkYXRhLGxlbik7XAoJCWN1cmRhdGErPWxlbjtcCgkJYnl0ZXNyZWFkKz1sZW47XAoJfQoKCXdoaWxlIChjdXJkYXRhIDwgbmV4dCkgewoJICBzdHJ1Y3QJZGtoICp4ZGtoID0gKHN0cnVjdCBka2gqKWN1cmRhdGE7CgoJICBieXRlc3JlYWQgKz0gc2l6ZW9mKGRraCk7IC8qIEZJWE1FLi4uIG5leHRrZXlvZmY/ICovCgkgIGlmICh4ZGtoLT5uckxTID09IG5yTFMpIHsKCSAgCW1lbWNweSgmZGtoLHhka2gsc2l6ZW9mKGRraCkpOwoJICAJY3VyZGF0YSArPSBzaXplb2YoZGtoKTsKCSAgCWJyZWFrOwoJICB9CgkgIGN1cmRhdGEgKz0geGRraC0+bmV4dGtleW9mZjsKCX07CgoJaWYgKGRraC5uckxTICE9IG5yTFMpIHJldHVybiAoTlVMTCk7CgoJaWYgKG5yZ2RiICE9IGRraC5uck1TKQoJICByZXR1cm4gKE5VTEwpOwoKICAgICAgICBhc3NlcnQoKGRraC5rZXluYW1lbGVuPDIpIHx8IGN1cmRhdGFbMF0pOwoJbHB4a2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksc3RyY3Z0QTJXKGN1cmRhdGEsIGRraC5rZXluYW1lbGVuKSk7CgljdXJkYXRhICs9IGRraC5rZXluYW1lbGVuOwoKCWZvciAoaT0wO2k8IGRraC52YWx1ZXM7IGkrKykgewoJICBzdHJ1Y3QgZGt2IGRrdjsKCSAgTFBCWVRFIGRhdGE7CgkgIGludCBsZW47CgkgIExQV1NUUiBuYW1lOwoKCSAgWFJFQUQoJmRrdixzaXplb2YoZGt2KSk7CgoJICBuYW1lID0gc3RyY3Z0QTJXKGN1cmRhdGEsIGRrdi52YWxuYW1lbGVuKTsKCSAgY3VyZGF0YSArPSBka3YudmFsbmFtZWxlbjsKCgkgIGlmICgoMSA8PCBka3YudHlwZSkgJiBVTklDT05WTUFTSykgewoJICAgIGRhdGEgPSAoTFBCWVRFKSBzdHJjdnRBMlcoY3VyZGF0YSwgZGt2LnZhbGRhdGFsZW4pOwoJICAgIGxlbiA9IDIqKGRrdi52YWxkYXRhbGVuICsgMSk7CgkgIH0gZWxzZSB7CgkgICAgLyogSSBkb24ndCB0aGluayB3ZSB3YW50IHRvIE5VTEwgdGVybWluYXRlIGFsbCBkYXRhICovCgkgICAgZGF0YSA9IHhtYWxsb2MoZGt2LnZhbGRhdGFsZW4pOwoJICAgIG1lbWNweSAoZGF0YSwgY3VyZGF0YSwgZGt2LnZhbGRhdGFsZW4pOwoJICAgIGxlbiA9IGRrdi52YWxkYXRhbGVuOwoJICB9CgoJICBjdXJkYXRhICs9IGRrdi52YWxkYXRhbGVuOwoJICAKCSAgX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJCQkgICAgIGxweGtleSwKCQkJICAgICBuYW1lLAoJCQkgICAgIGRrdi50eXBlLAoJCQkgICAgIGRhdGEsCgkJCSAgICAgbGVuLAoJCQkgICAgIGluZm8tPmxhc3Rtb2RpZmllZAoJCQkgICAgICk7Cgl9CglyZXR1cm4gKGxweGtleSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV93YWxrcmdrbiBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfdzk1X3dhbGtyZ2tuKCBMUEtFWVNUUlVDVCBwcmV2a2V5LCBjaGFyICpvZmYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgX3c5NV9pbmZvICppbmZvICkKCnsKICAvKiBEaXNrIEtleSBFbnRyeSBzdHJ1Y3R1cmUgKFJHS04gcGFydCkgKi8KICBzdHJ1Y3QJZGtlIHsKICAgIHVuc2lnbmVkIGxvbmcJCXgxOwogICAgdW5zaWduZWQgbG9uZwkJeDI7CiAgICB1bnNpZ25lZCBsb25nCQl4MzsvKnVzdWFsbHkgMHhGRkZGRkZGRiAqLwogICAgdW5zaWduZWQgbG9uZwkJcHJldmx2bDsKICAgIHVuc2lnbmVkIGxvbmcJCW5leHRzdWI7CiAgICB1bnNpZ25lZCBsb25nCQluZXh0OwogICAgdW5zaWduZWQgc2hvcnQJCW5yTFM7CiAgICB1bnNpZ25lZCBzaG9ydAkJbnJNUzsKICB9ICpka2UgPSAoc3RydWN0IGRrZSAqKW9mZjsKICBMUEtFWVNUUlVDVCAgbHB4a2V5OwoKICBpZiAoZGtlID09IE5VTEwpIHsKICAgIGRrZSA9IChzdHJ1Y3QgZGtlICopICgoY2hhciAqKWluZm8tPnJna25idWZmZXIpOwogIH0KCiAgbHB4a2V5ID0gX3c5NV9wcm9jZXNzS2V5KHByZXZrZXksIGRrZS0+bnJMUywgZGtlLT5uck1TLCBpbmZvKTsKICAvKiBYWFggPC0tIFRoaXMgaXMgYSBoYWNrKi8KICBpZiAoIWxweGtleSkgewogICAgbHB4a2V5ID0gcHJldmtleTsKICB9CgogIGlmIChka2UtPm5leHRzdWIgIT0gLTEgJiYgCiAgICAgICgoZGtlLT5uZXh0c3ViIC0gMHgyMCkgPCBpbmZvLT5yZ2tuc2l6ZSkgCiAgICAgICYmIChka2UtPm5leHRzdWIgPiAweDIwKSkgewogICAgCiAgICBfdzk1X3dhbGtyZ2tuKGxweGtleSwgCgkJICBpbmZvLT5yZ2tuYnVmZmVyICsgZGtlLT5uZXh0c3ViIC0gMHgyMCwgCgkJICBpbmZvKTsKICB9CiAgCiAgaWYgKGRrZS0+bmV4dCAhPSAtMSAmJiAKICAgICAgKChka2UtPm5leHQgLSAweDIwKSA8IGluZm8tPnJna25zaXplKSAmJiAKICAgICAgKGRrZS0+bmV4dCA+IDB4MjApKSB7CiAgICBfdzk1X3dhbGtyZ2tuKHByZXZrZXksICAKCQkgIGluZm8tPnJna25idWZmZXIgKyBka2UtPm5leHQgLSAweDIwLAoJCSAgaW5mbyk7CiAgfQoKICByZXR1cm47Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfdzk1X2xvYWRyZWcoIGNoYXIqIGZuLCBMUEtFWVNUUlVDVCBscGtleSApCnsKCUhGSUxFMzIJCWhmZDsKCWNoYXIJCW1hZ2ljWzVdOwoJdW5zaWduZWQgbG9uZwl3aGVyZSx2ZXJzaW9uLHJnZGJzZWN0aW9uLGVuZDsKCXN0cnVjdCAgICAgICAgICBfdzk1X2luZm8gaW5mbzsKCU9GU1RSVUNUCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmZGluZm87CgoJVFJBQ0UocmVnLCJMb2FkaW5nIFdpbjk1IHJlZ2lzdHJ5IGRhdGFiYXNlICclcydcbiIsZm4pOwoJaGZkPU9wZW5GaWxlMzIoZm4sJm9mcyxPRl9SRUFEKTsKCWlmIChoZmQ9PUhGSUxFX0VSUk9SMzIpCgkJcmV0dXJuOwoJbWFnaWNbNF09MDsKCWlmICg0IT1fbHJlYWQzMihoZmQsbWFnaWMsNCkpCgkJcmV0dXJuOwoJaWYgKHN0cmNtcChtYWdpYywiQ1JFRyIpKSB7CgkJV0FSTihyZWcsIiVzIGlzIG5vdCBhIHc5NSByZWdpc3RyeS5cbiIsZm4pOwoJCXJldHVybjsKCX0KCWlmICg0IT1fbHJlYWQzMihoZmQsJnZlcnNpb24sNCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZDMyKGhmZCwmcmdkYnNlY3Rpb24sNCkpCgkJcmV0dXJuOwoJaWYgKC0xPT1fbGxzZWVrMzIoaGZkLDB4MjAsU0VFS19TRVQpKQoJCXJldHVybjsKCWlmICg0IT1fbHJlYWQzMihoZmQsbWFnaWMsNCkpCgkJcmV0dXJuOwoJaWYgKHN0cmNtcChtYWdpYywiUkdLTiIpKSB7CgkJV0FSTihyZWcsICJzZWNvbmQgSUZGIGhlYWRlciBub3QgUkdLTiwgYnV0ICVzXG4iLCBtYWdpYyk7CgkJcmV0dXJuOwoJfQoKCS8qIFNURVAgMTogS2V5bGluayBzdHJ1Y3R1cmVzICovCglpZiAoLTE9PV9sbHNlZWszMihoZmQsMHg0MCxTRUVLX1NFVCkpCgkJcmV0dXJuOwoJd2hlcmUJPSAweDQwOwoJZW5kCT0gcmdkYnNlY3Rpb247CgoJaW5mby5yZ2tuc2l6ZSA9IGVuZCAtIHdoZXJlOwoJaW5mby5yZ2tuYnVmZmVyID0gKGNoYXIqKXhtYWxsb2MoaW5mby5yZ2tuc2l6ZSk7CglpZiAoaW5mby5yZ2tuc2l6ZSAhPSBfbHJlYWQzMihoZmQsaW5mby5yZ2tuYnVmZmVyLGluZm8ucmdrbnNpemUpKQoJCXJldHVybjsKCglpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmZCwmaGZkaW5mbykpCgkJcmV0dXJuOwoKCWVuZCA9IGhmZGluZm8ubkZpbGVTaXplTG93OwoJaW5mby5sYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmZGluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoKCWlmICgtMT09X2xsc2VlazMyKGhmZCxyZ2Ric2VjdGlvbixTRUVLX1NFVCkpCgkJcmV0dXJuOwoKCWluZm8ucmdkYmJ1ZmZlciA9IChjaGFyKil4bWFsbG9jKGVuZC1yZ2Ric2VjdGlvbik7CglpbmZvLnJnZGJzaXplID0gZW5kIC0gcmdkYnNlY3Rpb247CgoJaWYgKGluZm8ucmdkYnNpemUgIT1fbHJlYWQzMihoZmQsaW5mby5yZ2RiYnVmZmVyLGluZm8ucmdkYnNpemUpKQoJCXJldHVybjsKCV9sY2xvc2UzMihoZmQpOwoKCV93OTVfd2Fsa3Jna24obHBrZXksIE5VTEwsICZpbmZvKTsKCglmcmVlIChpbmZvLnJnZGJidWZmZXIpOwoJZnJlZSAoaW5mby5yZ2tuYnVmZmVyKTsKfQoKCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCgovKgogICAgcmVnaGFjayAtIHdpbmRvd3MgMy4xMSByZWdpc3RyeSBkYXRhIGZvcm1hdCBkZW1vIHByb2dyYW0uCgogICAgVGhlIHJlZy5kYXQgZmlsZSBoYXMgMyBwYXJ0cywgYSBoZWFkZXIsIGEgdGFibGUgb2YgOC1ieXRlIGVudHJpZXMgdGhhdCBpcwogICAgYSBjb21iaW5lZCBoYXNoIHRhYmxlIGFuZCB0cmVlIGRlc2NyaXB0aW9uLCBhbmQgZmluYWxseSBhIHRleHQgdGFibGUuCgogICAgVGhlIGhlYWRlciBpcyBvYnZpb3VzIGZyb20gdGhlIHN0cnVjdCBoZWFkZXIuIFRoZSB0YWJvZmYxIGFuZCB0YWJvZmYyCiAgICBmaWVsZHMgYXJlIGFsd2F5cyAweDIwLCBhbmQgdGhlaXIgdXNhZ2UgaXMgdW5rbm93bi4KCiAgICBUaGUgOC1ieXRlIGVudHJ5IHRhYmxlIGhhcyB2YXJpb3VzIGVudHJ5IHR5cGVzLgoKICAgIHRhYmVudFswXSBpcyBhIHJvb3QgaW5kZXguIFRoZSBzZWNvbmQgd29yZCBoYXMgdGhlIGluZGV4IG9mIHRoZSByb290IG9mCiAgICAgICAgICAgIHRoZSBkaXJlY3RvcnkuCiAgICB0YWJlbnRbMS4uaGFzaHNpemVdIGlzIGEgaGFzaCB0YWJsZS4gVGhlIGZpcnN0IHdvcmQgaW4gdGhlIGhhc2ggZW50cnkgaXMKICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBrZXkvdmFsdWUgdGhhdCBoYXMgdGhhdCBoYXNoLiBEYXRhIHdpdGggdGhlIHNhbWUKICAgICAgICAgICAgaGFzaCB2YWx1ZSBhcmUgb24gYSBjaXJjdWxhciBsaXN0LiBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlCiAgICAgICAgICAgIGhhc2ggZW50cnkgYXJlIGFsd2F5cyB6ZXJvLgogICAgdGFiZW50W2hhc2hzaXplLi50YWJjbnRdIGlzIHRoZSB0cmVlIHN0cnVjdHVyZS4gVGhlcmUgYXJlIHR3byBraW5kcyBvZgogICAgICAgICAgICBlbnRyeTogZGlyZW50IGFuZCBrZXllbnQvdmFsZW50LiBUaGV5IGFyZSBpZGVudGlmaWVkIGJ5IGNvbnRleHQuCiAgICB0YWJlbnRbZnJlZWlkeF0gaXMgdGhlIGZpcnN0IGZyZWUgZW50cnkuIFRoZSBmaXJzdCB3b3JkIGluIGEgZnJlZSBlbnRyeQogICAgICAgICAgICBpcyB0aGUgaW5kZXggb2YgdGhlIG5leHQgZnJlZSBlbnRyeS4gVGhlIGxhc3QgaGFzIDAgYXMgYSBsaW5rLgogICAgICAgICAgICBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlIGZyZWUgbGlzdCBhcmUgcHJvYmFibHkgaXJyZWxldmFudC4KCiAgICBFbnRyaWVzIGluIHRleHQgdGFibGUgYXJlIHByZWNlZWRlZCBieSBhIHdvcmQgYXQgb2Zmc2V0LTIuIFRoaXMgd29yZAogICAgaGFzIHRoZSB2YWx1ZSAoMippbmRleCkrMSwgd2hlcmUgaW5kZXggaXMgdGhlIHJlZmVycmluZyBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBpbiB0aGUgdGFibGUuIEkgaGF2ZSBubyBzdWdnZXN0aW9uIGZvciB0aGUgMiogYW5kIHRoZSArMS4KICAgIEZvbGxvd2luZyB0aGUgd29yZCwgdGhlcmUgYXJlIE4gYnl0ZXMgb2YgZGF0YSwgYXMgcGVyIHRoZSBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBsZW5ndGguIFRoZSBvZmZzZXQgb2YgdGhlIGtleWVudC92YWxlbnQgZW50cnkgaXMgZnJvbSB0aGUgc3RhcnQKICAgIG9mIHRoZSB0ZXh0IHRhYmxlIHRvIHRoZSBmaXJzdCBkYXRhIGJ5dGUuCgogICAgVGhpcyBpbmZvcm1hdGlvbiBpcyBub3QgYXZhaWxhYmxlIGZyb20gTWljcm9zb2Z0LiBUaGUgZGF0YSBmb3JtYXQgaXMKICAgIGRlZHVjZWQgZnJvbSB0aGUgcmVnLmRhdCBmaWxlIGJ5IG1lLiBNaXN0YWtlcyBtYXkKICAgIGhhdmUgYmVlbiBtYWRlLiBJIGNsYWltIG5vIHJpZ2h0cyBhbmQgZ2l2ZSBubyBndWFyYW50ZWVzIGZvciB0aGlzIHByb2dyYW0uCgogICAgVG9yIFNq+HdhbGwsIHRvckBzbi5ubwoqLwoKLyogcmVnLmRhdCBoZWFkZXIgZm9ybWF0ICovCnN0cnVjdCBfdzMxX2hlYWRlciB7CgljaGFyCQljb29raWVbOF07CS8qICdTSENDMy4xMCcgKi8KCXVuc2lnbmVkIGxvbmcJdGFib2ZmMTsJLyogb2Zmc2V0IG9mIGhhc2ggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFib2ZmMjsJLyogb2Zmc2V0IG9mIGluZGV4IHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYmNudDsJCS8qIG51bWJlciBvZiBlbnRyaWVzIGluIGluZGV4IHRhYmxlICovCgl1bnNpZ25lZCBsb25nCXRleHRvZmY7CS8qIG9mZnNldCBvZiB0ZXh0IHBhcnQgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dHNpemU7CS8qIGJ5dGUgc2l6ZSBvZiB0ZXh0IHBhcnQgKi8KCXVuc2lnbmVkIHNob3J0CWhhc2hzaXplOwkvKiBoYXNoIHNpemUgKi8KCXVuc2lnbmVkIHNob3J0CWZyZWVpZHg7CS8qIGZyZWUgaW5kZXggKi8KfTsKCi8qIGdlbmVyaWMgZm9ybWF0IG9mIHRhYmxlIGVudHJpZXMgKi8Kc3RydWN0IF93MzFfdGFiZW50IHsKCXVuc2lnbmVkIHNob3J0IHcwLCB3MSwgdzIsIHczOwp9OwoKLyogZGlyZWN0b3J5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfZGlyZW50IHsKCXVuc2lnbmVkIHNob3J0CXNpYmxpbmdfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBzaWJsaW5nIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJY2hpbGRfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBjaGlsZCBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWtleV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGtleSBrZXllbnQgKi8KCXVuc2lnbmVkIHNob3J0CXZhbHVlX2lkeDsJLyogdGFibGUgaW5kZXggb2YgdmFsdWUgdmFsZW50ICovCn07CgovKiBrZXkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9rZXllbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHZhbHVlIHRhYmVudDogKi8Kc3RydWN0IF93MzFfdmFsZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiByZWN1cnNpdmUgaGVscGVyIGZ1bmN0aW9uIHRvIGRpc3BsYXkgYSBkaXJlY3RvcnkgdHJlZSAqLwp2b2lkCl9fdzMxX2R1bXB0cmVlKAl1bnNpZ25lZCBzaG9ydCBpZHgsCgkJdW5zaWduZWQgY2hhciAqdHh0LAoJCXN0cnVjdCBfdzMxX3RhYmVudCAqdGFiLAoJCXN0cnVjdCBfdzMxX2hlYWRlciAqaGVhZCwKCQlMUEtFWVNUUlVDVAlscGtleSwKCQl0aW1lX3QJCWxhc3Rtb2RpZmllZCwKCQlpbnQJCWxldmVsCikgewoJc3RydWN0IF93MzFfZGlyZW50CSpkaXI7CglzdHJ1Y3QgX3czMV9rZXllbnQJKmtleTsKCXN0cnVjdCBfdzMxX3ZhbGVudAkqdmFsOwoJTFBLRVlTVFJVQ1QJCXhscGtleSA9IE5VTEw7CglMUFdTVFIJCQluYW1lLHZhbHVlOwoJc3RhdGljIGNoYXIJCXRhaWxbNDAwXTsKCgl3aGlsZSAoaWR4IT0wKSB7CgkJZGlyPShzdHJ1Y3QgX3czMV9kaXJlbnQqKSZ0YWJbaWR4XTsKCgkJaWYgKGRpci0+a2V5X2lkeCkgewoJCQlrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgoJCQltZW1jcHkodGFpbCwmdHh0W2tleS0+c3RyaW5nX29mZl0sa2V5LT5sZW5ndGgpOwoJCQl0YWlsW2tleS0+bGVuZ3RoXT0nXDAnOwoJCQkvKiBhbGwgdG9wbGV2ZWwgZW50cmllcyBBTkQgdGhlIGVudHJpZXMgaW4gdGhlIAoJCQkgKiB0b3BsZXZlbCBzdWJkaXJlY3RvcnkgYmVsb25nIHRvIFxTT0ZUV0FSRVxDbGFzc2VzCgkJCSAqLwoJCQlpZiAoIWxldmVsICYmICFsc3RyY21wMzJBKHRhaWwsIi5jbGFzc2VzIikpIHsKCQkJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxscGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJCQlpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCW5hbWU9c3RyZHVwQTJXKHRhaWwpOwoKCQkJeGxwa2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksbmFtZSk7CgoJCQkvKiBvbmx5IGFkZCBpZiBsZWFmIG5vZGUgb3IgdmFsdWVkIG5vZGUgKi8KCQkJaWYgKGRpci0+dmFsdWVfaWR4IT0wfHxkaXItPmNoaWxkX2lkeD09MCkgewoJCQkJaWYgKGRpci0+dmFsdWVfaWR4KSB7CgkJCQkJdmFsPShzdHJ1Y3QgX3czMV92YWxlbnQqKSZ0YWJbZGlyLT52YWx1ZV9pZHhdOwoJCQkJCW1lbWNweSh0YWlsLCZ0eHRbdmFsLT5zdHJpbmdfb2ZmXSx2YWwtPmxlbmd0aCk7CgkJCQkJdGFpbFt2YWwtPmxlbmd0aF09J1wwJzsKCQkJCQl2YWx1ZT1zdHJkdXBBMlcodGFpbCk7CgkJCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKHhscGtleSxOVUxMLFJFR19TWiwoTFBCWVRFKXZhbHVlLGxzdHJsZW4zMlcodmFsdWUpKjIrMixsYXN0bW9kaWZpZWQpOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJVFJBQ0UocmVnLCJzdHJhbmdlOiBubyBkaXJlY3Rvcnkga2V5IG5hbWUsIGlkeD0lMDR4XG4iLCBpZHgpOwoJCX0KCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQseGxwa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQlpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3czMV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnZvaWQgX3czMV9sb2FkcmVnKHZvaWQpIHsKCUhGSUxFMzIJCQloZjsKCXN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwoJc3RydWN0IF93MzFfdGFiZW50CSp0YWI7Cgl1bnNpZ25lZCBjaGFyCQkqdHh0OwoJaW50CQkJbGVuOwoJT0ZTVFJVQ1QJCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmaW5mbzsKCXRpbWVfdAkJCWxhc3Rtb2RpZmllZDsKCUxQS0VZU1RSVUNUCQlscGtleTsKCglUUkFDRShyZWcsIih2b2lkKVxuIik7CgoJaGYgPSBPcGVuRmlsZTMyKCJyZWcuZGF0Iiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmPT1IRklMRV9FUlJPUjMyKQoJCXJldHVybjsKCgkvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KCWlmIChzaXplb2YoaGVhZCkhPV9scmVhZDMyKGhmLCZoZWFkLHNpemVvZihoZWFkKSkpIHsKCQlFUlIocmVnLCAicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCWlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpIT0wKSB7CgkJRVJSKHJlZywgInJlZy5kYXQgaGFzIGJhZCBzaWduYXR1cmUuXG4iKTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCglsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwoJLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwoJdGFiID0geG1hbGxvYyhsZW4pOwoJaWYgKGxlbiE9X2xyZWFkMzIoaGYsdGFiLGxlbikpIHsKCQlFUlIocmVnLCJjb3VsZG4ndCByZWFkICVkIGJ5dGVzLlxuIixsZW4pOyAKCQlmcmVlKHRhYik7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CgoJLyogcmVhZCB0ZXh0ICovCgl0eHQgPSB4bWFsbG9jKGhlYWQudGV4dHNpemUpOwoJaWYgKC0xPT1fbGxzZWVrMzIoaGYsaGVhZC50ZXh0b2ZmLFNFRUtfU0VUKSkgewoJCUVSUihyZWcsImNvdWxkbid0IHNlZWsgdG8gdGV4dGJsb2NrLlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAoaGVhZC50ZXh0c2l6ZSE9X2xyZWFkMzIoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CgkJRVJSKHJlZywidGV4dGJsb2NrIHRvbyBzaG9ydCAoJWQgaW5zdGVhZCBvZiAlbGQpLlxuIixsZW4saGVhZC50ZXh0c2l6ZSk7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZiwmaGZpbmZvKSkgewoJCUVSUihyZWcsIkdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlIGZhaWxlZD8uXG4iKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCWxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoSEtFWV9DTEFTU0VTX1JPT1QpOwoJX193MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLDApOwoJZnJlZSh0YWIpOwoJZnJlZSh0eHQpOwoJX2xjbG9zZTMyKGhmKTsKCXJldHVybjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX0xvYWRSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwp2b2lkIFNIRUxMX0xvYWRSZWdpc3RyeSggdm9pZCApCnsKCWNoYXIJKmZuOwoJc3RydWN0CXBhc3N3ZAkqcHdkOwoJTFBLRVlTVFJVQ1QJbHBrZXk7CglIS0VZCQloa2V5OwoKCVRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCgkvKiBMb2FkIHdpbmRvd3MgMy4xIGVudHJpZXMgKi8KCV93MzFfbG9hZHJlZygpOwoJLyogTG9hZCB3aW5kb3dzIDk1IGVudHJpZXMgKi8KCV93OTVfbG9hZHJlZygiQzpcXHN5c3RlbS4xc3QiLAlsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpKTsKCV93OTVfbG9hZHJlZygic3lzdGVtLmRhdCIsCWxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSkpOwoJX3c5NV9sb2FkcmVnKCJ1c2VyLmRhdCIsCWxvb2t1cF9oa2V5KEhLRVlfVVNFUlMpKTsKCgkvKiB0aGUgZ2xvYmFsIHVzZXIgZGVmYXVsdCBpcyBsb2FkZWQgdW5kZXIgSEtFWV9VU0VSU1xcLkRlZmF1bHQgKi8KCVJlZ0NyZWF0ZUtleTE2KEhLRVlfVVNFUlMsIi5EZWZhdWx0IiwmaGtleSk7CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgICAgIGlmKCFscGtleSkKICAgICAgICAgICAgV0FSTihyZWcsIkNvdWxkIG5vdCBjcmVhdGUgZ2xvYmFsIHVzZXIgZGVmYXVsdCBrZXlcbiIpOwoJX3dpbmVfbG9hZHJlZyhscGtleSxTQVZFX1VTRVJTX0RFRkFVTFQsMCk7CgoJLyogSEtFWV9VU0VSU1xcLkRlZmF1bHQgaXMgY29waWVkIHRvIEhLRVlfQ1VSUkVOVF9VU0VSICovCglfY29weV9yZWdpc3RyeShscGtleSxsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogdGhlIGdsb2JhbCBtYWNoaW5lIGRlZmF1bHRzICovCglfd2luZV9sb2FkcmVnKGxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSksU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQsMCk7CgoJLyogbG9hZCB0aGUgdXNlciBzYXZlZCByZWdpc3RyaWVzICovCgoJLyogRklYTUU6IHVzZSBnZXRlbnYoIkhPTUUiKSBvciBnZXRwd3VpZChnZXR1aWQoKSktPnB3X2RpciA/PyAqLwoKCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CglpZiAocHdkIT1OVUxMICYmIHB3ZC0+cHdfZGlyIT1OVUxMKSB7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0NVUlJFTlRfVVNFUik7CgkJX3dpbmVfbG9hZHJlZyhsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUiksZm4sUkVHX09QVElPTl9UQUlOVEVEKTsKCQlmcmVlKGZuKTsKCQlmbj0oY2hhciopeG1hbGxvYyhzdHJsZW4ocHdkLT5wd19kaXIpK3N0cmxlbihXSU5FX1BSRUZJWCkrc3RybGVuKFNBVkVfTE9DQUxfTUFDSElORSkrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwoJCV93aW5lX2xvYWRyZWcobG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSxmbixSRUdfT1BUSU9OX1RBSU5URUQpOwoJCWZyZWUoZm4pOwoJfSBlbHNlCgkJV0FSTihyZWcsIkZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWQuXG4iLGdldHVpZCgpKTsKCWlmIChFUlJPUl9TVUNDRVNTPT1SZWdDcmVhdGVLZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpKSB7CgkJRFdPUkQJanVuayx0eXBlLGxlbjsKCQljaGFyCWRhdGFbNV07CgoJCWxlbj00OwoJCWlmICgoCVJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQkJCWhrZXksCgkJCQlWQUxfU0FWRVVQREFURUQsCgkJCQkmanVuaywKCQkJCSZ0eXBlLAoJCQkJZGF0YSwKCQkJCSZsZW4KCQkJKSE9RVJST1JfU1VDQ0VTUykgfHwKCQkJdHlwZSAhPSBSRUdfU1oKCQkpCgkJCVJlZ1NldFZhbHVlRXgzMkEoaGtleSxWQUxfU0FWRVVQREFURUQsMCxSRUdfU1osInllcyIsNCk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIEFQSSBGVU5DVElPTlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKgogKiBPcGVuIEtleXMuCiAqCiAqIEFsbCBmdW5jdGlvbnMgYXJlIHN0dWJzIHRvIFJlZ09wZW5LZXlFeDMyVyB3aGVyZSBhbGwgdGhlCiAqIG1hZ2ljIGhhcHBlbnMuIAogKgogKiBDYWxscGF0aDoKICogUmVnT3BlbktleTE2IC0+IFJlZ09wZW5LZXkzMkEgLT4gUmVnT3BlbktleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnT3BlbktleTMyVyAgIC0+IFJlZ09wZW5LZXlFeDMyVyAKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5RXgzMlcgW0FEVkFQSTMyLjE1MF0KICogT3BlbnMgdGhlIHNwZWNpZmllZCBrZXkKICoKICogVW5saWtlIFJlZ0NyZWF0ZUtleUV4LCB0aGlzIGRvZXMgbm90IGNyZWF0ZSB0aGUga2V5IGlmIGl0IGRvZXMgbm90IGV4aXN0LgogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIE5hbWUgb2Ygc3Via2V5IHRvIG9wZW4KICogICAgZHdSZXNlcnZlZCBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIHplcm8KICogICAgc2FtRGVzaXJlZCBbSV0gU2VjdXJpdHkgYWNjZXNzIG1hc2sKICogICAgcmV0a2V5ICAgICBbT10gQWRkcmVzcyBvZiBoYW5kbGUgb2Ygb3BlbiBrZXkKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5RXgzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdTQU0gc2FtRGVzaXJlZCwgTFBIS0VZIHJldGtleSApCnsKCUxQS0VZU1RSVUNUCWxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKICAgIFRSQUNFKHJlZywiKDB4JXgsJXMsJWxkLCVseCwlcClcbiIsIGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxkd1Jlc2VydmVkLAogICAgICAgICAgc2FtRGVzaXJlZCxyZXRrZXkpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkgewogICAgICAgIC8qIEVpdGhlciBOVUxMIG9yIHBvaW50ZXIgdG8gZW1wdHkgc3RyaW5nLCBzbyByZXR1cm4gYSBuZXcgaGFuZGxlCiAgICAgICAgICAgdG8gdGhlIG9yaWdpbmFsIGhrZXkgKi8KICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CiAgICAgICAgYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKICAgICAgICAqcmV0a2V5PWN1cnJlbnRoYW5kbGU7CiAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CiAgICB9CgogICAgaWYgKGxwc3pTdWJLZXlbMF0gPT0gJ1xcJykgewogICAgICAgIFdBUk4ocmVnLCJTdWJrZXkgJXMgbXVzdCBub3QgYmVnaW4gd2l0aCBiYWNrc2xhc2guXG4iLGRlYnVnc3RyX3cobHBzelN1YktleSkpOwogICAgICAgIHJldHVybiBFUlJPUl9CQURfUEFUSE5BTUU7CiAgICB9CgoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpID0gMDsKCXdoaWxlICgoaTx3cGMpICYmICh3cHNbaV1bMF09PSdcMCcpKSBpKys7CglscHhrZXkgPSBscE5leHRLZXk7CgogICAgd2hpbGUgKHdwc1tpXSkgewogICAgICAgIGxweGtleT1scE5leHRLZXktPm5leHRzdWI7CiAgICAgICAgd2hpbGUgKGxweGtleSkgewogICAgICAgICAgICBpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBscHhrZXk9bHB4a2V5LT5uZXh0OwogICAgICAgIH0KCiAgICAgICAgaWYgKCFscHhrZXkpIHsKICAgICAgICAgICAgVFJBQ0UocmVnLCJDb3VsZCBub3QgZmluZCBzdWJrZXkgJXNcbiIsZGVidWdzdHJfdyh3cHNbaV0pKTsKICAgICAgICAgICAgRlJFRV9LRVlfUEFUSDsKICAgICAgICAgICAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwogICAgICAgIH0KICAgICAgICBpKys7CiAgICAgICAgbHBOZXh0S2V5ID0gbHB4a2V5OwogICAgfQoKICAgIGN1cnJlbnRoYW5kbGUgKz0gMjsKICAgIGFkZF9oYW5kbGUoY3VycmVudGhhbmRsZSxscHhrZXksc2FtRGVzaXJlZCk7CiAgICAqcmV0a2V5ID0gY3VycmVudGhhbmRsZTsKICAgIFRSQUNFKHJlZywiICBSZXR1cm5pbmcgJXhcbiIsIGN1cnJlbnRoYW5kbGUpOwogICAgRlJFRV9LRVlfUEFUSDsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5RXgzMkEgW0FEVkFQSTMyLjE0OV0KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5RXgzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR1NBTSBzYW1EZXNpcmVkLCBMUEhLRVkgcmV0a2V5ICkKewogICAgTFBXU1RSIGxwc3pTdWJLZXlXID0gc3RyZHVwQTJXKGxwc3pTdWJLZXkpOwogICAgRFdPUkQgcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbHgsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxkd1Jlc2VydmVkLAogICAgICAgICAgc2FtRGVzaXJlZCxyZXRrZXkpOwogICAgcmV0ID0gUmVnT3BlbktleUV4MzJXKCBoa2V5LCBscHN6U3ViS2V5VywgZHdSZXNlcnZlZCwgc2FtRGVzaXJlZCwgcmV0a2V5ICk7CiAgICBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXkzMlcgW0FEVkFQSTMyLjE1MV0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5IFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5IHRvIG9wZW4KICogICAgcmV0a2V5ICAgICBbT10gQWRkcmVzcyBvZiBoYW5kbGUgb2Ygb3BlbiBrZXkKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdPcGVuS2V5RXgzMlcoIGhrZXksIGxwc3pTdWJLZXksIDAsIEtFWV9BTExfQUNDRVNTLCByZXRrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleTMyQSBbQURWQVBJMzIuMTQ4XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBEV09SRCByZXQ7CiAgICBMUFdTVFIgbHBzelN1YktleVcgPSBzdHJkdXBBMlcobHBzelN1YktleSk7CiAgICBUUkFDRShyZWcsIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICByZXQgPSAgUmVnT3BlbktleTMyVyggaGtleSwgbHBzelN1YktleVcsIHJldGtleSApOwogICAgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5MTYgW1NIRUxMLjFdIFtLRVJORUwuMjE3XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdPcGVuS2V5MzJBKCBoa2V5LCBscHN6U3ViS2V5LCByZXRrZXkgKTsKfQoKCi8qIAogKiBDcmVhdGUga2V5cwogKiAKICogQWxsIHRob3NlIGZ1bmN0aW9ucyBjb252ZXJ0IHRoZWlyIHJlc3BlY3RpdmUgCiAqIGFyZ3VtZW50cyBhbmQgY2FsbCBSZWdDcmVhdGVLZXlFeFcgYXQgdGhlIGVuZC4KICoKICogV2Ugc3RheSBhd2F5IGZyb20gdGhlIEV4IGZ1bmN0aW9ucyBhcyBsb25nIGFzIHBvc3NpYmxlIGJlY2F1c2UgdGhlcmUgYXJlCiAqIGRpZmZlcmVuY2VzIGluIHRoZSByZXR1cm4gdmFsdWVzCiAqCiAqIENhbGxwYXRoOgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnQ3JlYXRlS2V5RXgzMkEgXAogKiBSZWdDcmVhdGVLZXkxNiAtPiBSZWdDcmVhdGVLZXkzMkEgLT4gUmVnQ3JlYXRlS2V5MzJXICAgLT4gUmVnQ3JlYXRlS2V5RXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXlFeDMyVyBbQURWQVBJMzIuMTMxXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgIFtJXSBIYW5kbGUgb2YgYW4gb3BlbiBrZXkKICogICAgbHBzelN1YktleSAgIFtJXSBBZGRyZXNzIG9mIHN1YmtleSBuYW1lCiAqICAgIGR3UmVzZXJ2ZWQgICBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIDAKICogICAgbHBzekNsYXNzICAgIFtJXSBBZGRyZXNzIG9mIGNsYXNzIHN0cmluZwogKiAgICBmZHdPcHRpb25zICAgW0ldIFNwZWNpYWwgb3B0aW9ucyBmbGFnCiAqICAgIHNhbURlc2lyZWQgICBbSV0gRGVzaXJlZCBzZWN1cml0eSBhY2Nlc3MKICogICAgbHBTZWNBdHRyaWJzIFtJXSBBZGRyZXNzIG9mIGtleSBzZWN1cml0eSBzdHJ1Y3R1cmUKICogICAgcmV0a2V5ICAgICAgIFtPXSBBZGRyZXNzIG9mIGJ1ZmZlciBmb3Igb3BlbmVkIGhhbmRsZQogKiAgICBscERpc3BvcyAgICAgW09dIFJlY2VpdmVzIFJFR19DUkVBVEVEX05FV19LRVkgb3IgUkVHX09QRU5FRF9FWElTVElOR19LRVkKICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXlFeDMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3UmVzZXJ2ZWQsIExQV1NUUiBscHN6Q2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGZkd09wdGlvbnMsIFJFR1NBTSBzYW1EZXNpcmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBscFNlY0F0dHJpYnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSByZXRrZXksIExQRFdPUkQgbHBEaXNwb3MgKQp7CglMUEtFWVNUUlVDVAkqbHBscFByZXZLZXksbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVseCwlbHgsJXAsJXAsJXApXG4iLCBoa2V5LAoJCWRlYnVnc3RyX3cobHBzelN1YktleSksIGR3UmVzZXJ2ZWQsIGRlYnVnc3RyX3cobHBzekNsYXNzKSwKCQlmZHdPcHRpb25zLCBzYW1EZXNpcmVkLCBscFNlY0F0dHJpYnMsIHJldGtleSwgbHBEaXNwb3MpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIENoZWNrIGZvciB2YWxpZCBvcHRpb25zICovCiAgICBzd2l0Y2goZmR3T3B0aW9ucykgewogICAgICAgIGNhc2UgUkVHX09QVElPTl9OT05fVk9MQVRJTEU6CiAgICAgICAgY2FzZSBSRUdfT1BUSU9OX1ZPTEFUSUxFOgogICAgICAgIGNhc2UgUkVHX09QVElPTl9CQUNLVVBfUkVTVE9SRToKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwogICAgfQoKICAgIC8qIFNhbSBoYXMgdG8gYmUgYSBjb21iaW5hdGlvbiBvZiB0aGUgZm9sbG93aW5nICovCiAgICBpZiAoIShzYW1EZXNpcmVkICYgCiAgICAgICAgICAoS0VZX0FMTF9BQ0NFU1MgfCBLRVlfQ1JFQVRFX0xJTksgfCBLRVlfQ1JFQVRFX1NVQl9LRVkgfCAKICAgICAgICAgICBLRVlfRU5VTUVSQVRFX1NVQl9LRVlTIHwgS0VZX0VYRUNVVEUgfCBLRVlfTk9USUZZIHwKICAgICAgICAgICBLRVlfUVVFUllfVkFMVUUgfCBLRVlfUkVBRCB8IEtFWV9TRVRfVkFMVUUgfCBLRVlfV1JJVEUpKSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgoJaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkgewogICAgICAgICAgICAgICAgY3VycmVudGhhbmRsZSArPSAyOwoJCWFkZF9oYW5kbGUoY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgkJKnJldGtleT1jdXJyZW50aGFuZGxlOwogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCQlscE5leHRLZXktPmZsYWdzfD1SRUdfT1BUSU9OX1RBSU5URUQ7CgkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgl9CgogICAgaWYgKGxwc3pTdWJLZXlbMF0gPT0gJ1xcJykgewogICAgICAgIFdBUk4ocmVnLCJTdWJrZXkgJXMgbXVzdCBub3QgYmVnaW4gd2l0aCBiYWNrc2xhc2guXG4iLGRlYnVnc3RyX3cobHBzelN1YktleSkpOwogICAgICAgIHJldHVybiBFUlJPUl9CQURfUEFUSE5BTUU7CiAgICB9CgoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7Cgl3aGlsZSAoKGk8d3BjKSAmJiAod3BzW2ldWzBdPT0nXDAnKSkgaSsrOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKHdwc1tpXSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KQoJCQlicmVhazsKCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJaWYgKGxweGtleSkgewogICAgICAgICAgICAgICAgY3VycmVudGhhbmRsZSArPSAyOwoJCWFkZF9oYW5kbGUoY3VycmVudGhhbmRsZSxscHhrZXksc2FtRGVzaXJlZCk7CgkJbHB4a2V5LT5mbGFncyAgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoJCSpyZXRrZXkJCT0gY3VycmVudGhhbmRsZTsKICAgICAgICAgICAgICAgIFRSQUNFKHJlZywgIlJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CgkJaWYgKGxwRGlzcG9zKQoJCQkqbHBEaXNwb3MJPSBSRUdfT1BFTkVEX0VYSVNUSU5HX0tFWTsKCQlGUkVFX0tFWV9QQVRIOwoJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJfQoKCS8qIEdvb2QuICBOb3cgdGhlIGhhcmQgcGFydCAqLwoJd2hpbGUgKHdwc1tpXSkgewoJCWxwbHBQcmV2S2V5CT0gJihscE5leHRLZXktPm5leHRzdWIpOwoJCWxweGtleQkJPSAqbHBscFByZXZLZXk7CgkJd2hpbGUgKGxweGtleSkgewoJCQlscGxwUHJldktleQk9ICYobHB4a2V5LT5uZXh0KTsKCQkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl9CgkJKmxwbHBQcmV2S2V5PW1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJaWYgKCEqbHBscFByZXZLZXkpIHsKCQkJRlJFRV9LRVlfUEFUSDsKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nIE9VVE9GTUVNT1JZXG4iKTsKCQkJcmV0dXJuIEVSUk9SX09VVE9GTUVNT1JZOwoJCX0KCQltZW1zZXQoKmxwbHBQcmV2S2V5LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpOwogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCJBZGRpbmcgJXNcbiIsIGRlYnVnc3RyX3cod3BzW2ldKSk7CgkJKCpscGxwUHJldktleSktPmtleW5hbWUJPSBzdHJkdXBXKHdwc1tpXSk7CgkJKCpscGxwUHJldktleSktPm5leHQJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5uZXh0c3ViCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+dmFsdWVzCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+bnJvZnZhbHVlcyA9IDA7CgkJKCpscGxwUHJldktleSktPmZsYWdzIAk9IFJFR19PUFRJT05fVEFJTlRFRDsKCQlpZiAobHBzekNsYXNzKQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBzdHJkdXBXKGxwc3pDbGFzcyk7CgkJZWxzZQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBOVUxMOwoJCWxwTmV4dEtleQk9ICpscGxwUHJldktleTsKCQlpKys7Cgl9CiAgICAgICAgY3VycmVudGhhbmRsZSArPSAyOwoJYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKCgkvKkZJWE1FOiBmbGFnIGhhbmRsaW5nIGNvcnJlY3Q/ICovCglscE5leHRLZXktPmZsYWdzPSBmZHdPcHRpb25zIHxSRUdfT1BUSU9OX1RBSU5URUQ7CglpZiAobHBzekNsYXNzKQoJCWxwTmV4dEtleS0+Y2xhc3MgPSBzdHJkdXBXKGxwc3pDbGFzcyk7CgllbHNlCgkJbHBOZXh0S2V5LT5jbGFzcyA9IE5VTEw7CgkqcmV0a2V5CQk9IGN1cnJlbnRoYW5kbGU7CiAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCWlmIChscERpc3BvcykKCQkqbHBEaXNwb3MJPSBSRUdfQ1JFQVRFRF9ORVdfS0VZOwoJRlJFRV9LRVlfUEFUSDsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXlFeDMyQSBbQURWQVBJMzIuMTMwXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleUV4MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGxwc3pDbGFzcywgRFdPUkQgZmR3T3B0aW9ucywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHU0FNIHNhbURlc2lyZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBscFNlY0F0dHJpYnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSByZXRrZXksIExQRFdPUkQgbHBEaXNwb3MgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVcsIGxwc3pDbGFzc1c7CiAgICBEV09SRCAgcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlcywlbHgsJWx4LCVwLCVwLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSksCiAgICAgICAgICBkd1Jlc2VydmVkLGRlYnVnc3RyX2EobHBzekNsYXNzKSxmZHdPcHRpb25zLHNhbURlc2lyZWQsbHBTZWNBdHRyaWJzLAogICAgICAgICAgcmV0a2V5LGxwRGlzcG9zKTsKCiAgICBscHN6U3ViS2V5VyA9IGxwc3pTdWJLZXk/c3RyZHVwQTJXKGxwc3pTdWJLZXkpOk5VTEw7CiAgICBscHN6Q2xhc3NXID0gbHBzekNsYXNzP3N0cmR1cEEyVyhscHN6Q2xhc3MpOk5VTEw7CgogICAgcmV0ID0gUmVnQ3JlYXRlS2V5RXgzMlcoIGhrZXksIGxwc3pTdWJLZXlXLCBkd1Jlc2VydmVkLCBscHN6Q2xhc3NXLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZHdPcHRpb25zLCBzYW1EZXNpcmVkLCBscFNlY0F0dHJpYnMsIHJldGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBEaXNwb3MgKTsKCiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICBpZihscHN6Q2xhc3NXKSBmcmVlKGxwc3pDbGFzc1cpOwoKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleTMyVyBbQURWQVBJMzIuMTMyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBEV09SRCBqdW5rOwogICAgTFBLRVlTVFJVQ1QJbHBOZXh0S2V5OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIiwgaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLHJldGtleSk7CgogICAgLyogVGhpcyBjaGVjayBpcyBoZXJlIGJlY2F1c2UgdGhlIHJldHVybiB2YWx1ZSBpcyBkaWZmZXJlbnQgdGhhbiB0aGUKICAgICAgIG9uZSBmcm9tIHRoZSBFeCBmdW5jdGlvbnMgKi8KICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0JBREtFWTsKCiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5RXgzMlcoIGhrZXksIGxwc3pTdWJLZXksIDAsIE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX0FMTF9BQ0NFU1MsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldGtleSwgJmp1bmspOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXkzMkEgW0FEVkFQSTMyLjEyOV0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBEV09SRCByZXQ7CiAgICBMUFdTVFIgbHBzelN1YktleVc7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgbHBzelN1YktleVcgPSBscHN6U3ViS2V5P3N0cmR1cEEyVyhscHN6U3ViS2V5KTpOVUxMOwogICAgcmV0ID0gUmVnQ3JlYXRlS2V5MzJXKCBoa2V5LCBscHN6U3ViS2V5VywgcmV0a2V5ICk7CiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXkxNiBbU0hFTEwuMl0gW0tFUk5FTC4yMThdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5MzJBKCBoa2V5LCBscHN6U3ViS2V5LCByZXRrZXkgKTsKfQoKCi8qIAogKiBRdWVyeSBWYWx1ZSBGdW5jdGlvbnMKICogV2luMzIgZGlmZmVycyBiZXR3ZWVuIGtleW5hbWVzIGFuZCB2YWx1ZW5hbWVzLiAKICogbXVsdGlwbGUgdmFsdWVzIG1heSBiZWxvbmcgdG8gb25lIGtleSwgdGhlIHNwZWNpYWwgdmFsdWUKICogd2l0aCBuYW1lIE5VTEwgaXMgdGhlIGRlZmF1bHQgdmFsdWUgdXNlZCBieSB0aGUgd2luMzEKICogY29tcGF0IGZ1bmN0aW9ucy4KICoKICogQ2FsbHBhdGg6CiAqIFJlZ1F1ZXJ5VmFsdWUxNiAtPiBSZWdRdWVyeVZhbHVlMzJBIC0+IFJlZ1F1ZXJ5VmFsdWVFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUzMlcgLT4gUmVnUXVlcnlWYWx1ZUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZUV4MzJXIFtBRFZBUEkzMi4xNThdCiAqIFJldHJpZXZlcyB0eXBlIGFuZCBkYXRhIGZvciBhIHNwZWNpZmllZCBuYW1lIGFzc29jaWF0ZWQgd2l0aCBhbiBvcGVuIGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICBbSV0gICBIYW5kbGUgb2Yga2V5IHRvIHF1ZXJ5CiAqICAgIGxwVmFsdWVOYW1lICAgW0ldICAgTmFtZSBvZiB2YWx1ZSB0byBxdWVyeQogKiAgICBscGR3UmVzZXJ2ZWQgIFtJXSAgIFJlc2VydmVkIC0gbXVzdCBiZSBOVUxMCiAqICAgIGxwZHdUeXBlICAgICAgW09dICAgQWRkcmVzcyBvZiBidWZmZXIgZm9yIHZhbHVlIHR5cGUuICBJZiBOVUxMLCB0aGUgdHlwZQogKiAgICAgICAgICAgICAgICAgICAgICAgIGlzIG5vdCByZXF1aXJlZC4KICogICAgbHBiRGF0YSAgICAgICBbT10gICBBZGRyZXNzIG9mIGRhdGEgYnVmZmVyLiAgSWYgTlVMTCwgdGhlIGFjdHVhbCBkYXRhIGlzCiAqICAgICAgICAgICAgICAgICAgICAgICAgbm90IHJlcXVpcmVkLgogKiAgICBscGNiRGF0YSAgICAgIFtJL09dIEFkZHJlc3Mgb2YgZGF0YSBidWZmZXIgc2l6ZQogKgogKiBSRVRVUk5TIAogKiAgICBFUlJPUl9TVUNDRVNTOiAgIFN1Y2Nlc3MKICogICAgRVJST1JfTU9SRV9EQVRBOiAhISEgaWYgdGhlIHNwZWNpZmllZCBidWZmZXIgaXMgbm90IGJpZyBlbm91Z2ggdG8gaG9sZCB0aGUgZGF0YQogKiAJCSAgICAgICBidWZmZXIgaXMgbGVmdCB1bnRvdWNoZWQuIFRoZSBNUy1kb2N1bWVudGF0aW9uIGlzIHdyb25nIChqcykgISEhCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MzJXKCBIS0VZIGhrZXksIExQV1NUUiBscFZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBscGJEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglpbnQJCWk7CglEV09SRAkJcmV0OwoKCVRSQUNFKHJlZywiKDB4JXgsJXMsJXAsJXAsJXAsJXA9JWxkKVxuIiwgaGtleSwgZGVidWdzdHJfdyhscFZhbHVlTmFtZSksCiAgICAgICAgICBscGR3UmVzZXJ2ZWQsIGxwZHdUeXBlLCBscGJEYXRhLCBscGNiRGF0YSwgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CgoJaWYgKCFscGtleSkKCSAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKCWlmICgobHBiRGF0YSAmJiAhIGxwY2JEYXRhKSB8fCBscGR3UmVzZXJ2ZWQpCgkgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCgkvKiBBbiBlbXB0eSBuYW1lIHN0cmluZyBpcyBlcXVpdmFsZW50IHRvIE5VTEwgKi8KCWlmIChscFZhbHVlTmFtZSAmJiAhKmxwVmFsdWVOYW1lKQoJICBscFZhbHVlTmFtZSA9IE5VTEw7CgoJaWYgKGxwVmFsdWVOYW1lPT1OVUxMKSAKCXsgLyogVXNlIGtleSdzIHVubmFtZWQgb3IgZGVmYXVsdCB2YWx1ZSwgaWYgYW55ICovCgkgIGZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJICAgIGlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkgICAgICBicmVhazsKCX0gCgllbHNlIAoJeyAvKiBTZWFyY2ggZm9yIHRoZSBrZXkgbmFtZSAqLwoJICBmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCSAgICBpZiAoIGxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJiAhbHN0cmNtcGkzMlcobHBWYWx1ZU5hbWUsbHBrZXktPnZhbHVlc1tpXS5uYW1lKSkKCSAgICAgIGJyZWFrOwoJfQoKCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgCgl7IFRSQUNFKHJlZywiIEtleSBub3QgZm91bmRcbiIpOwoJICBpZiAobHBWYWx1ZU5hbWU9PU5VTEwpIAoJICB7IC8qIEVtcHR5IGtleW5hbWUgbm90IGZvdW5kICovCgkgICAgaWYgKGxwYkRhdGEpIAoJICAgIHsgKihXQ0hBUiopbHBiRGF0YSA9IDA7CgkgICAgICAqbHBjYkRhdGEJPSAyOwoJICAgIH0KCSAgICBpZiAobHBkd1R5cGUpCgkgICAgICAqbHBkd1R5cGUJPSBSRUdfU1o7CgkgICAgVFJBQ0UocmVnLCAiIFJldHVybmluZyBhbiBlbXB0eSBzdHJpbmdcbiIpOwoJICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwoJICB9CgkgIHJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsKCX0KCglyZXQgPSBFUlJPUl9TVUNDRVNTOwoKCWlmIChscGR3VHlwZSkgCQkJCQkvKiB0eXBlIHJlcXVpcmVkID8qLwoJICAqbHBkd1R5cGUgPSBscGtleS0+dmFsdWVzW2ldLnR5cGU7CgoJaWYgKGxwYkRhdGEpCQkJCQkvKiBkYXRhIHJlcXVpcmVkID8qLwoJeyBpZiAoKmxwY2JEYXRhID49IGxwa2V5LT52YWx1ZXNbaV0ubGVuKQkvKiBidWZmZXIgbGFyZ2UgZW5vdWdodCA/Ki8KCSAgICBtZW1jcHkobHBiRGF0YSxscGtleS0+dmFsdWVzW2ldLmRhdGEsbHBrZXktPnZhbHVlc1tpXS5sZW4pOwoJICBlbHNlCgkgICAgcmV0ID0gRVJST1JfTU9SRV9EQVRBOwoJfQoKCWlmIChscGNiRGF0YSkgCQkJCQkvKiBzaXplIHJlcXVpcmVkID8qLwoJeyAqbHBjYkRhdGEgPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKCX0KCglkZWJ1Z19wcmludF92YWx1ZSAoIGxwYkRhdGEsIGxwa2V5LT52YWx1ZXNbaV0udHlwZSwgbHBrZXktPnZhbHVlc1tpXS5sZW4pOwoKCVRSQUNFKHJlZywiIChyZXQ9JWx4LCB0eXBlPSVseCwgbGVuPSVsZClcbiIsIHJldCwgbHBkd1R5cGU/KmxwZHdUeXBlOjAsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWUzMlcgW0FEVkFQSTMyLjE1OV0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMzJXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6U3ViS2V5LCBMUFdTVFIgbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewoJSEtFWQl4aGtleTsKCURXT1JECXJldCxscGR3VHlwZTsKCiAgICBUUkFDRShyZWcsIigleCwlcywlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxscHN6RGF0YSwKICAgICAgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICAvKiBPbmx5IG9wZW4gc3Via2V5LCBpZiB3ZSByZWFsbHkgZG8gZGVzY2VuZCAqLwogICAgaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKICAgICAgICByZXQgPSBSZWdPcGVuS2V5MzJXKCBoa2V5LCBscHN6U3ViS2V5LCAmeGhrZXkgKTsKICAgICAgICBpZiAocmV0ICE9IEVSUk9SX1NVQ0NFU1MpIHsKICAgICAgICAgICAgV0FSTihyZWcsICJDb3VsZCBub3Qgb3BlbiAlc1xuIiwgZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgfSBlbHNlCiAgICAgICAgeGhrZXkgPSBoa2V5OwoKICAgIGxwZHdUeXBlID0gUkVHX1NaOwogICAgcmV0ID0gUmVnUXVlcnlWYWx1ZUV4MzJXKCB4aGtleSwgTlVMTCwgTlVMTCwgJmxwZHdUeXBlLCAoTFBCWVRFKWxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscGNiRGF0YSApOwogICAgaWYgKHhoa2V5ICE9IGhrZXkpCiAgICAgICAgUmVnQ2xvc2VLZXkoeGhrZXkpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZUV4MzJBIFtBRFZBUEkzMi4xNTddCiAqCiAqIE5PVEVTOgogKiB0aGUgZG9jdW1hbnRhdGlvbiBpcyB3cm9uZzogaWYgdGhlIGJ1ZmZlciBpcyB0byBzbWFsbCBpdCByZW1haW5zIHVudG91Y2hlZCAKICoKICogRklYTUU6IGNoZWNrIHJldHVybnZhbHVlIChsZW4pIGZvciBhbiBlbXB0eSBrZXkKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXgzMkEoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBscGJEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBXU1RSCWxwc3pWYWx1ZU5hbWVXOwoJTFBCWVRFCW15YnVmID0gTlVMTDsKCURXT1JECXJldCwgbXl0eXBlLCBteWxlbiA9IDA7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJXAsJXAsJXAsJXA9JWxkKVxuIiwgaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKCWlmICghbHBjYkRhdGEgJiYgbHBiRGF0YSkJCQkvKiBidWZmZXIgd2l0aG91dCBzaXplIGlzIGlsbGVnYWwgKi8KCXsgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCX0KCglscHN6VmFsdWVOYW1lVyA9IGxwc3pWYWx1ZU5hbWUgPyBzdHJkdXBBMlcobHBzelZhbHVlTmFtZSkgOiBOVUxMOwkKCQoJLyogZ2V0IGp1c3QgdGhlIHR5cGUgZmlyc3QgKi8KCXJldCA9IFJlZ1F1ZXJ5VmFsdWVFeDMyVyggaGtleSwgbHBzelZhbHVlTmFtZVcsIGxwZHdSZXNlcnZlZCwgJm15dHlwZSwgTlVMTCwgTlVMTCApOwoJCglpZiAoIHJldCAhPSBFUlJPUl9TVUNDRVNTICkJCQkvKiBmYWlsZWQgPz8gKi8KCXsgaWYobHBzelZhbHVlTmFtZVcpIGZyZWUobHBzelZhbHVlTmFtZVcpOwoJICByZXR1cm4gcmV0OwoJfQoJCglpZiAobHBjYkRhdGEpCQkJCQkvKiBhdCBsZWFzdCBsZW5ndGggcmVxdWVzdGVkPyAqLwoJeyBpZiAoVU5JQ09OVk1BU0sgJiAoMTw8KG15dHlwZSkpKQkJLyogc3RyaW5nIHJlcXVlc3RlZD8gKi8KCSAgeyBpZiAobHBiRGF0YSApCQkJCS8qIHZhbHVlIHJlcXVlc3RlZD8gKi8KCSAgICB7IG15bGVuID0gMiooICpscGNiRGF0YSApOwoJICAgICAgbXlidWYgPSAoTFBCWVRFKXhtYWxsb2MoIG15bGVuICk7CgkgICAgfQoKCSAgICByZXQgPSBSZWdRdWVyeVZhbHVlRXgzMlcoIGhrZXksIGxwc3pWYWx1ZU5hbWVXLCBscGR3UmVzZXJ2ZWQsIGxwZHdUeXBlLCBteWJ1ZiwgJm15bGVuICk7CgoJICAgIGlmIChyZXQgPT0gRVJST1JfU1VDQ0VTUyApCgkgICAgeyBpZiAoIGxwYkRhdGEgKQoJICAgICAgeyBsbWVtY3B5bld0b0EobHBiRGF0YSwgKExQV1NUUilteWJ1ZiwgbXlsZW4vMik7CgkgICAgICB9CgkgICAgfQoKCSAgICAqbHBjYkRhdGEgPSBteWxlbi8yOwkJCS8qIHNpemUgaXMgaW4gYnl0ZSEgKi8KCSAgfQoJICBlbHNlCQkJCQkJLyogbm8gc3RyaW5ncywgY2FsbCBpdCBzdHJhaWdodCAqLwoJICB7IHJldCA9IFJlZ1F1ZXJ5VmFsdWVFeDMyVyggaGtleSwgbHBzelZhbHVlTmFtZVcsIGxwZHdSZXNlcnZlZCwgbHBkd1R5cGUsIGxwYkRhdGEsIGxwY2JEYXRhICk7CgkgIH0KCX0KCQoJaWYgKGxwZHdUeXBlKQkJCQkJLyogdHlwZSB3aGVuIHJlcXVlc3RlZCAqLwoJeyAqbHBkd1R5cGUgPSBteXR5cGU7Cgl9CgoJVFJBQ0UocmVnLCIgKHJldD0lbHgsdHlwZT0lbHgsIGxlbj0lbGQpXG4iLCByZXQsbXl0eXBlLGxwY2JEYXRhPypscGNiRGF0YTowKTsKCQoJaWYobXlidWYpIGZyZWUobXlidWYpOwoJaWYobHBzelZhbHVlTmFtZVcpIGZyZWUobHBzelZhbHVlTmFtZVcpOwoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZUV4MTYgW0tFUk5FTC4yMjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgbHBiRGF0YSwgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVwLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeDMyQSggaGtleSwgbHBzelZhbHVlTmFtZSwgbHBkd1Jlc2VydmVkLCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwYkRhdGEsIGxwY2JEYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWUzMkEgW0FEVkFQSTMyLjE1Nl0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMzJBKCBIS0VZIGhrZXksIExQU1RSIGxwc3pTdWJLZXksIExQU1RSIGxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIEhLRVkgeGhrZXk7CiAgICBEV09SRCByZXQsIGR3VHlwZTsKCiAgICBUUkFDRShyZWcsIigleCwlcywlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxscHN6RGF0YSwKICAgICAgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewogICAgICAgIHJldCA9IFJlZ09wZW5LZXkxNiggaGtleSwgbHBzelN1YktleSwgJnhoa2V5ICk7CiAgICAgICAgaWYoIHJldCAhPSBFUlJPUl9TVUNDRVNTICkKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgIH0gZWxzZQogICAgICAgIHhoa2V5ID0gaGtleTsKCiAgICBkd1R5cGUgPSBSRUdfU1o7CiAgICByZXQgPSBSZWdRdWVyeVZhbHVlRXgzMkEoIHhoa2V5LCBOVUxMLE5VTEwsICZkd1R5cGUsIChMUEJZVEUpbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwY2JEYXRhICk7CiAgICBpZiggeGhrZXkgIT0gaGtleSApCiAgICAgICAgUmVnQ2xvc2VLZXkoIHhoa2V5ICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlMTYgW1NIRUxMLjZdIFtLRVJORUwuMjI0XQogKgogKiBOT1RFUwogKiAgICBJcyB0aGlzIEhBQ0sgc3RpbGwgYXBwbGljYWJsZT8KICoKICogSEFDSwogKiAgICBUaGUgMTZiaXQgUmVnUXVlcnlWYWx1ZSBkb2Vzbid0IGhhbmRsZSBzZWxlY3RvcmJsb2NrcyBhbnl3YXksIHNvIHdlIGp1c3QKICogICAgbWFzayBvdXQgdGhlIGhpZ2ggMTYgYml0LiAgVGhpcyAobm90IHNvIG11Y2ggaW5jaWRlbnRseSkgaG9wZWZ1bGx5IGZpeGVzCiAqICAgIEFsZHVzIEZINCkKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelN1YktleSwgTFBTVFIgbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxscHN6RGF0YSwKICAgICAgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBpZiAobHBjYkRhdGEpCiAgICAgICAgKmxwY2JEYXRhICY9IDB4RkZGRjsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlMzJBKGhrZXksbHBzelN1YktleSxscHN6RGF0YSxscGNiRGF0YSk7Cn0KCgovKgogKiBTZXR0aW5nIHZhbHVlcyBvZiBSZWdpc3RyeSBrZXlzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdTZXRWYWx1ZTE2IC0+IFJlZ1NldFZhbHVlMzJBIC0+IFJlZ1NldFZhbHVlRXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1NldFZhbHVlMzJXICAgLT4gUmVnU2V0VmFsdWVFeDMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgzMlcgW0FEVkFQSTMyLjE3MF0KICogU2V0cyB0aGUgZGF0YSBhbmQgdHlwZSBvZiBhIHZhbHVlIHVuZGVyIGEgcmVnaXN0ZXIga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgIFtJXSBIYW5kbGUgb2Yga2V5IHRvIHNldCB2YWx1ZSBmb3IKICogICAgbHBzelZhbHVlTmFtZSBbSV0gTmFtZSBvZiB2YWx1ZSB0byBzZXQKICogICAgZHdSZXNlcnZlZCAgICBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIHplcm8KICogICAgZHdUeXBlICAgICAgICBbSV0gRmxhZyBmb3IgdmFsdWUgdHlwZQogKiAgICBscGJEYXRhICAgICAgIFtJXSBBZGRyZXNzIG9mIHZhbHVlIGRhdGEKICogICAgY2JEYXRhICAgICAgICBbSV0gU2l6ZSBvZiB2YWx1ZSBkYXRhCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqCiAqIE5PVEVTCiAqICAgd2luOTUgZG9lcyBub3QgY2FyZSBhYm91dCBjYkRhdGEgZm9yIFJFR19TWiBhbmQgZmluZHMgb3V0IHRoZSBsZW4gYnkgaXRzZWxmIChqcykgCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDMyVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzelZhbHVlTmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1Jlc2VydmVkLCBEV09SRCBkd1R5cGUsIExQQllURSBscGJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgY2JEYXRhKQp7CglMUEtFWVNUUlVDVCBscGtleTsKCWludCBpOwoKCVRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuIiwgaGtleSwgZGVidWdzdHJfdyhscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsIGR3VHlwZSwgbHBiRGF0YSwgY2JEYXRhKTsKCglkZWJ1Z19wcmludF92YWx1ZSAoIGxwYkRhdGEsIGR3VHlwZSwgY2JEYXRhICk7CgoJbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwoKCWlmICghbHBrZXkpCiAgICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCglpZiAobHBzelZhbHVlTmFtZT09TlVMTCkgewogICAgICAgICAgICAgLyogU2V0cyB0eXBlIGFuZCBuYW1lIGZvciBrZXkncyB1bm5hbWVkIG9yIGRlZmF1bHQgdmFsdWUgKi8KCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJfSBlbHNlIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKAlscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYKCQkJCSFsc3RyY21waTMyVyhscHN6VmFsdWVOYW1lLGxwa2V5LT52YWx1ZXNbaV0ubmFtZSkKCQkJKQoJCQkJYnJlYWs7Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0gKExQS0VZVkFMVUUpeHJlYWxsb2MoCgkJCQkJbHBrZXktPnZhbHVlcywKCQkJCQkobHBrZXktPm5yb2Z2YWx1ZXMrMSkqc2l6ZW9mKEtFWVZBTFVFKQoJCQkJKTsKCQlscGtleS0+bnJvZnZhbHVlcysrOwoJCW1lbXNldChscGtleS0+dmFsdWVzK2ksJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCX0KCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpIHsKCQlpZiAobHBzelZhbHVlTmFtZSkKCQkJbHBrZXktPnZhbHVlc1tpXS5uYW1lID0gc3RyZHVwVyhscHN6VmFsdWVOYW1lKTsKCQllbHNlCgkJCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSA9IE5VTEw7Cgl9CgoJaWYgKGR3VHlwZSA9PSBSRUdfU1opCgkgIGNiRGF0YSA9IDIgKiAobHN0cmxlbjMyVyAoKExQQ1dTVFIpbHBiRGF0YSkgKyAxKTsKCSAgCglscGtleS0+dmFsdWVzW2ldLmxlbgk9IGNiRGF0YTsKCWxwa2V5LT52YWx1ZXNbaV0udHlwZQk9IGR3VHlwZTsKCWlmIChscGtleS0+dmFsdWVzW2ldLmRhdGEgIT1OVUxMKQoJCWZyZWUobHBrZXktPnZhbHVlc1tpXS5kYXRhKTsKCWxwa2V5LT52YWx1ZXNbaV0uZGF0YQk9IChMUEJZVEUpeG1hbGxvYyhjYkRhdGEpOwoJbHBrZXktPnZhbHVlc1tpXS5sYXN0bW9kaWZpZWQgPSB0aW1lKE5VTEwpOwoJbWVtY3B5KGxwa2V5LT52YWx1ZXNbaV0uZGF0YSxscGJEYXRhLGNiRGF0YSk7CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWVFeDMyQSBbQURWQVBJMzIuMTY5XQogKgogKiBOT1RFUwogKiAgIHdpbjk1IGRvZXMgbm90IGNhcmUgYWJvdXQgY2JEYXRhIGZvciBSRUdfU1ogYW5kIGZpbmRzIG91dCB0aGUgbGVuIGJ5IGl0c2VsZiAoanMpIAogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXgzMkEoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3UmVzZXJ2ZWQsIERXT1JEIGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBjYkRhdGEgKQp7CglMUEJZVEUJYnVmOwoJTFBXU1RSCWxwc3pWYWx1ZU5hbWVXOwoJRFdPUkQJcmV0OwoKCWlmICghbHBiRGF0YSkKCQlyZXR1cm4gKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKCQkKCVRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlTmFtZSksCiAgICAgICAgICBkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YSk7CgoJaWYgKCgxPDxkd1R5cGUpICYgVU5JQ09OVk1BU0spIAoJeyBpZiAoZHdUeXBlID09IFJFR19TWikKCSAgICBjYkRhdGEgPSBzdHJsZW4gKChMUENTVFIpbHBiRGF0YSkrMTsKCgkgIGJ1ZiA9IChMUEJZVEUpeG1hbGxvYyggY2JEYXRhICoyICk7CgkgIGxtZW1jcHluQXRvVyAoKExQVk9JRClidWYsIGxwYkRhdGEsIGNiRGF0YSApOwoJICBjYkRhdGE9MipjYkRhdGE7Cgl9IAoJZWxzZQoJICBidWY9bHBiRGF0YTsKCglpZiAobHBzelZhbHVlTmFtZSkKCSAgbHBzelZhbHVlTmFtZVcgPSBzdHJkdXBBMlcobHBzelZhbHVlTmFtZSk7CgllbHNlCgkgIGxwc3pWYWx1ZU5hbWVXID0gTlVMTDsKCglyZXQ9UmVnU2V0VmFsdWVFeDMyVyhoa2V5LGxwc3pWYWx1ZU5hbWVXLGR3UmVzZXJ2ZWQsZHdUeXBlLGJ1ZixjYkRhdGEpOwoKCWlmIChscHN6VmFsdWVOYW1lVykKCSAgZnJlZShscHN6VmFsdWVOYW1lVyk7CgoJaWYgKGJ1ZiE9bHBiRGF0YSkKCSAgZnJlZShidWYpOwoKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgxNiBbS0VSTkVMLjIyNl0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgRFdPUkQgY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsZHdUeXBlLGxwYkRhdGEsY2JEYXRhKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUV4MzJBKCBoa2V5LCBscHN6VmFsdWVOYW1lLCBkd1Jlc2VydmVkLCBkd1R5cGUsIGxwYkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2JEYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMzJXCVtBRFZBUEkzMi4xNzFdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBscHN6RGF0YSwgRFdPUkQgY2JEYXRhICkKewoJSEtFWQl4aGtleTsKCURXT1JECXJldDsKCglUUkFDRShyZWcsIigleCwlcywlbGQsJXMsJWxkKVxuIiwKCQloa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksZHdUeXBlLGRlYnVnc3RyX3cobHBzekRhdGEpLGNiRGF0YQoJKTsKCWlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CgkJcmV0PVJlZ0NyZWF0ZUtleTMyVyhoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXk9aGtleTsKCWlmIChkd1R5cGUhPVJFR19TWikgewoJCVRSQUNFKHJlZywiZHdUeXBlPSVsZCAtIENoYW5naW5nIHRvIFJFR19TWlxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT0yKmxzdHJsZW4zMlcobHBzekRhdGEpKzIpIHsKCQlUUkFDRShyZWcsIkxlbj0lbGQgIT0gc3RybGVuKCVzKSsxPSVkIVxuIiwKCQkJY2JEYXRhLGRlYnVnc3RyX3cobHBzekRhdGEpLDIqbHN0cmxlbjMyVyhscHN6RGF0YSkrMgoJCSk7CgkJY2JEYXRhPTIqbHN0cmxlbjMyVyhscHN6RGF0YSkrMjsKCX0KCXJldD1SZWdTZXRWYWx1ZUV4MzJXKHhoa2V5LE5VTEwsMCxkd1R5cGUsKExQQllURSlscHN6RGF0YSxjYkRhdGEpOwoJaWYgKGhrZXkhPXhoa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMzJBIFtBRFZBUEkzMi4xNjhdCiAqCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBzekRhdGEsIERXT1JEIGNiRGF0YSApCnsKCURXT1JECXJldDsKCUhLRVkJeGhrZXk7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEpOwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQ9UmVnQ3JlYXRlS2V5MTYoaGtleSxscHN6U3ViS2V5LCZ4aGtleSk7CgkJaWYgKHJldCE9RVJST1JfU1VDQ0VTUykKCQkJcmV0dXJuIHJldDsKCX0gZWxzZQoJCXhoa2V5PWhrZXk7CgoJaWYgKGR3VHlwZSE9UkVHX1NaKSB7CgkJVFJBQ0UocmVnLCJkd1R5cGU9JWxkIVxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT1zdHJsZW4obHBzekRhdGEpKzEpCgkJY2JEYXRhPXN0cmxlbihscHN6RGF0YSkrMTsKCXJldD1SZWdTZXRWYWx1ZUV4MzJBKHhoa2V5LE5VTEwsMCxkd1R5cGUsKExQQllURSlscHN6RGF0YSxjYkRhdGEpOwoJaWYgKHhoa2V5IT1oa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMTYgW0tFUk5FTC4yMjFdIFtTSEVMTC41XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JECWR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscHN6RGF0YSwgRFdPUkQgY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGR3VHlwZSwKICAgICAgICAgIGRlYnVnc3RyX2EobHBzekRhdGEpLGNiRGF0YSk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWUzMkEoaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEpOwp9CgoKLyogCiAqIEtleSBFbnVtZXJhdGlvbgogKgogKiBDYWxscGF0aDoKICogUmVnRW51bUtleTE2IC0+IFJlZ0VudW1LZXkzMkEgLT4gUmVnRW51bUtleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnRW51bUtleTMyVyAgIC0+IFJlZ0VudW1LZXlFeDMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXlFeDMyVyBbQURWQVBJMzIuMTM5XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgIFtJXSBIYW5kbGUgdG8ga2V5IHRvIGVudW1lcmF0ZQogKiAgICBpU3ViS2V5ICAgICAgW0ldIEluZGV4IG9mIHN1YmtleSB0byBlbnVtZXJhdGUKICogICAgbHBzek5hbWUgICAgIFtPXSBCdWZmZXIgZm9yIHN1YmtleSBuYW1lCiAqICAgIGxwY2NoTmFtZSAgICBbT10gU2l6ZSBvZiBzdWJrZXkgYnVmZmVyCiAqICAgIGxwZHdSZXNlcnZlZCBbSV0gUmVzZXJ2ZWQKICogICAgbHBzekNsYXNzICAgIFtPXSBCdWZmZXIgZm9yIGNsYXNzIHN0cmluZwogKiAgICBscGNjaENsYXNzICAgW09dIFNpemUgb2YgY2xhc3MgYnVmZmVyCiAqICAgIGZ0ICAgICAgICAgICBbT10gVGltZSBrZXkgbGFzdCB3cml0dGVuIHRvCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleUV4MzJXKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQV1NUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE5hbWUsIExQRFdPUkQgbHBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgbHBzekNsYXNzLCBMUERXT1JEIGxwY2NoQ2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFVElNRSAqZnQgKQp7CglMUEtFWVNUUlVDVAlscGtleSxscHhrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZCwlcCwlcCwlcCwlcClcbiIsaGtleSxpU3Via2V5LGxwc3pOYW1lLAogICAgICAgICAgKmxwY2NoTmFtZSxscGR3UmVzZXJ2ZWQsbHBzekNsYXNzLGxwY2NoQ2xhc3MsZnQpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKCWlmICghbHBrZXktPm5leHRzdWIpCgkJcmV0dXJuIEVSUk9SX05PX01PUkVfSVRFTVM7CglscHhrZXk9bHBrZXktPm5leHRzdWI7CgogICAgLyogVHJhdmVyc2UgdGhlIHN1YmtleXMgKi8KCXdoaWxlIChpU3Via2V5ICYmIGxweGtleSkgewoJCWlTdWJrZXktLTsKCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoKCWlmIChpU3Via2V5IHx8ICFscHhrZXkpCgkJcmV0dXJuIEVSUk9SX05PX01PUkVfSVRFTVM7CglpZiAobHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpKzE+KmxwY2NoTmFtZSkKCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJbWVtY3B5KGxwc3pOYW1lLGxweGtleS0+a2V5bmFtZSxsc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSkqMisyKTsKCiAgICAgICAgaWYgKCpscGNjaE5hbWUpCiAgICAgICAgICAgICpscGNjaE5hbWUgPSBsc3RybGVuMzJXKGxwc3pOYW1lKTsKCglpZiAobHBzekNsYXNzKSB7CgkJLyogRklYTUU6IHdoYXQgc2hvdWxkIHdlIHdyaXRlIGludG8gaXQ/ICovCgkJKmxwc3pDbGFzcwk9IDA7CgkJKmxwY2NoQ2xhc3MJPSAyOwoJfQoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXkzMlcgW0FEVkFQSTMyLjE0MF0KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MzJXKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQV1NUUiBscHN6TmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBGSUxFVElNRQlmdDsKCiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKICAgIHJldHVybiBSZWdFbnVtS2V5RXgzMlcoaGtleSxpU3Via2V5LGxwc3pOYW1lLCZscGNjaE5hbWUsTlVMTCxOVUxMLE5VTEwsJmZ0KTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleUV4MzJBIFtBRFZBUEkzMi4xMzhdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleUV4MzJBKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTmFtZSwgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiBscHN6Q2xhc3MsIExQRFdPUkQgbHBjY2hDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVUSU1FICpmdCApCnsKCURXT1JECXJldCxscGNjaE5hbWVXLGxwY2NoQ2xhc3NXOwoJTFBXU1RSCWxwc3pOYW1lVyxscHN6Q2xhc3NXOwoKCglUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlTdWJrZXksbHBzek5hbWUsKmxwY2NoTmFtZSxscGR3UmVzZXJ2ZWQsbHBzekNsYXNzLGxwY2NoQ2xhc3MsZnQKCSk7CglpZiAobHBzek5hbWUpIHsKCQlscHN6TmFtZVcJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoTmFtZSoyKTsKCQlscGNjaE5hbWVXCT0gKmxwY2NoTmFtZTsKCX0gZWxzZSB7CgkJbHBzek5hbWVXCT0gTlVMTDsKCQlscGNjaE5hbWVXIAk9IDA7Cgl9CglpZiAobHBzekNsYXNzKSB7CgkJbHBzekNsYXNzVwkJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoQ2xhc3MqMik7CgkJbHBjY2hDbGFzc1cJPSAqbHBjY2hDbGFzczsKCX0gZWxzZSB7CgkJbHBzekNsYXNzVwk9MDsKCQlscGNjaENsYXNzVz0wOwoJfQoJcmV0PVJlZ0VudW1LZXlFeDMyVygKCQloa2V5LAoJCWlTdWJrZXksCgkJbHBzek5hbWVXLAoJCSZscGNjaE5hbWVXLAoJCWxwZHdSZXNlcnZlZCwKCQlscHN6Q2xhc3NXLAoJCSZscGNjaENsYXNzVywKCQlmdAoJKTsKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MpIHsKCQlsc3RyY3B5V3RvQShscHN6TmFtZSxscHN6TmFtZVcpOwoJCSpscGNjaE5hbWU9c3RybGVuKGxwc3pOYW1lKTsKCQlpZiAobHBzekNsYXNzVykgewoJCQlsc3RyY3B5V3RvQShscHN6Q2xhc3MsbHBzekNsYXNzVyk7CgkJCSpscGNjaENsYXNzPXN0cmxlbihscHN6Q2xhc3MpOwoJCX0KCX0KCWlmIChscHN6TmFtZVcpCgkJZnJlZShscHN6TmFtZVcpOwoJaWYgKGxwc3pDbGFzc1cpCgkJZnJlZShscHN6Q2xhc3NXKTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXkzMkEgW0FEVkFQSTMyLjEzN10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MzJBKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbHBjY2hOYW1lICkKewogICAgRklMRVRJTUUJZnQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZSk7CiAgICByZXR1cm4gUmVnRW51bUtleUV4MzJBKCBoa2V5LCBpU3Via2V5LCBscHN6TmFtZSwgJmxwY2NoTmFtZSwgTlVMTCwgTlVMTCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAmZnQgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleTE2IFtTSEVMTC43XSBbS0VSTkVMLjIxNl0KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MTYoIEhLRVkgaGtleSwgRFdPUkQgaVN1YmtleSwgTFBTVFIgbHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGxwY2NoTmFtZSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwogICAgcmV0dXJuIFJlZ0VudW1LZXkzMkEoIGhrZXksIGlTdWJrZXksIGxwc3pOYW1lLCBscGNjaE5hbWUpOwp9CgoKLyogCiAqIEVudW1lcmF0ZSBSZWdpc3RyeSBWYWx1ZXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0VudW1WYWx1ZTE2IC0+IFJlZ0VudW1WYWx1ZTMyQSAtPiBSZWdFbnVtVmFsdWUzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUzMlcgW0FEVkFQSTMyLjE0Ml0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgIFtJXSBIYW5kbGUgdG8ga2V5IHRvIHF1ZXJ5CiAqICAgIGlWYWx1ZSAgICAgIFtJXSBJbmRleCBvZiB2YWx1ZSB0byBxdWVyeQogKiAgICBscHN6VmFsdWUgICBbT10gVmFsdWUgc3RyaW5nCiAqICAgIGxwY2NoVmFsdWUgIFtJL09dIFNpemUgb2YgdmFsdWUgYnVmZmVyIChpbiB3Y2hhcnMpCiAqICAgIGxwZFJlc2VydmVkIFtJXSBSZXNlcnZlZAogKiAgICBscGR3VHlwZSAgICBbT10gVHlwZSBjb2RlCiAqICAgIGxwYkRhdGEgICAgIFtPXSBWYWx1ZSBkYXRhCiAqICAgIGxwY2JEYXRhICAgIFtJL09dIFNpemUgb2YgZGF0YSBidWZmZXIgKGluIGJ5dGVzKQogKgogKiBOb3RlOiAgd2lkZSBjaGFyYWN0ZXIgZnVuY3Rpb25zIHRoYXQgdGFrZSBhbmQvb3IgcmV0dXJuICJjaGFyYWN0ZXIgY291bnRzIgogKiAgdXNlIFRDSEFSICh0aGF0IGlzIHVuc2lnbmVkIHNob3J0IG9yIGNoYXIpIG5vdCBieXRlIGNvdW50cy4KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUzMlcoIEhLRVkgaGtleSwgRFdPUkQgaVZhbHVlLCBMUFdTVFIgbHBzelZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoVmFsdWUsIExQRFdPUkQgbHBkUmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1R5cGUsIExQQllURSBscGJEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJTFBLRVlWQUxVRQl2YWw7CgoJVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlWYWx1ZSxkZWJ1Z3N0cl93KGxwc3pWYWx1ZSksCiAgICAgICAgICBscGNjaFZhbHVlLGxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEpOwoKCWxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKCQoJaWYgKCFscGNiRGF0YSAmJiBscGJEYXRhKQoJCXJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCQkKCWlmICghbHBrZXkpCgkJcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKCWlmIChscGtleS0+bnJvZnZhbHVlcyA8PSBpVmFsdWUpCgkJcmV0dXJuIEVSUk9SX05PX01PUkVfSVRFTVM7CgoJdmFsID0gJihscGtleS0+dmFsdWVzW2lWYWx1ZV0pOwoKCWlmICh2YWwtPm5hbWUpIHsKCSAgICAgICAgaWYgKGxzdHJsZW4zMlcodmFsLT5uYW1lKSsxPipscGNjaFZhbHVlKSB7CgkJCSpscGNjaFZhbHVlID0gbHN0cmxlbjMyVyh2YWwtPm5hbWUpKzE7CgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJfQoJCW1lbWNweShscHN6VmFsdWUsdmFsLT5uYW1lLDIgKiAobHN0cmxlbjMyVyh2YWwtPm5hbWUpKzEpICk7CgkJKmxwY2NoVmFsdWU9bHN0cmxlbjMyVyh2YWwtPm5hbWUpOwoJfSBlbHNlIHsKCQkqbHBzelZhbHVlCT0gMDsKCQkqbHBjY2hWYWx1ZQk9IDA7Cgl9CgoJLyogQ2FuIGJlIE5VTEwgaWYgdGhlIHR5cGUgY29kZSBpcyBub3QgcmVxdWlyZWQgKi8KCWlmIChscGR3VHlwZSkKCQkqbHBkd1R5cGUgPSB2YWwtPnR5cGU7CgoJaWYgKGxwYkRhdGEpIHsKCQlpZiAodmFsLT5sZW4+KmxwY2JEYXRhKQoJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCW1lbWNweShscGJEYXRhLHZhbC0+ZGF0YSx2YWwtPmxlbik7CgkJKmxwY2JEYXRhID0gdmFsLT5sZW47Cgl9CgoJZGVidWdfcHJpbnRfdmFsdWUgKCB2YWwtPmRhdGEsIHZhbC0+dHlwZSwgdmFsLT5sZW4gKTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUzMkEgW0FEVkFQSTMyLjE0MV0KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUzMkEoIEhLRVkgaGtleSwgRFdPUkQgaVZhbHVlLCBMUFNUUiBscHN6VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hWYWx1ZSwgTFBEV09SRCBscGRSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBXU1RSCWxwc3pWYWx1ZVc7CglMUEJZVEUJbHBiRGF0YVc7CglEV09SRAlyZXQsbHBjYkRhdGFXOwoJRFdPUkQgZHdUeXBlOwoKCVRSQUNFKHJlZywiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsCgkJbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YSk7CgoJbHBzelZhbHVlVyA9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hWYWx1ZSoyKTsKCWlmIChscGJEYXRhKSB7CgkJbHBiRGF0YVcgPSAoTFBCWVRFKXhtYWxsb2MoKmxwY2JEYXRhKjIpOwoJCWxwY2JEYXRhVyA9ICpscGNiRGF0YTsKCX0gZWxzZQoJCWxwYkRhdGFXID0gTlVMTDsKCglyZXQgPSBSZWdFbnVtVmFsdWUzMlcoIGhrZXksIGlWYWx1ZSwgbHBzelZhbHVlVywgbHBjY2hWYWx1ZSwgCgkJCQlscGRSZXNlcnZlZCwgJmR3VHlwZSwgbHBiRGF0YVcsICZscGNiRGF0YVcgKTsKCglpZiAobHBkd1R5cGUpCgkJKmxwZHdUeXBlID0gZHdUeXBlOwoKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MpIHsKCQlsc3RyY3B5V3RvQShscHN6VmFsdWUsbHBzelZhbHVlVyk7CgkJaWYgKGxwYkRhdGEpIHsKCQkJaWYgKCgxPDxkd1R5cGUpICYgVU5JQ09OVk1BU0spIHsKCQkJCWxzdHJjcHlXdG9BKGxwYkRhdGEsKExQV1NUUilscGJEYXRhVyk7CgkJCX0gZWxzZSB7CgkJCQlpZiAobHBjYkRhdGFXID4gKmxwY2JEYXRhKQoJCQkJCXJldAk9IEVSUk9SX01PUkVfREFUQTsKCQkJCWVsc2UKCQkJCQltZW1jcHkobHBiRGF0YSxscGJEYXRhVyxscGNiRGF0YVcpOwoJCQl9CgkJCSpscGNiRGF0YSA9IGxwY2JEYXRhVzsKCQl9Cgl9CiAgICBpZiAobHBiRGF0YVcpIGZyZWUobHBiRGF0YVcpOwogICAgaWYgKGxwc3pWYWx1ZVcpIGZyZWUobHBzelZhbHVlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUxNiBbS0VSTkVMLjIyM10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUxNiggSEtFWSBoa2V5LCBEV09SRCBpVmFsdWUsIExQU1RSIGxwc3pWYWx1ZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaFZhbHVlLCBMUERXT1JEIGxwZFJlc2VydmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsCiAgICAgICAgICBscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhKTsKICAgIHJldHVybiBSZWdFbnVtVmFsdWUzMkEoIGhrZXksIGlWYWx1ZSwgbHBzelZhbHVlLCBscGNjaFZhbHVlLCBscGRSZXNlcnZlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBscGR3VHlwZSwgbHBiRGF0YSwgbHBjYkRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ2xvc2VLZXkgW1NIRUxMLjNdIFtLRVJORUwuMjIwXSBbQURWQVBJMzIuMTI2XQogKiBSZWxlYXNlcyB0aGUgaGFuZGxlIG9mIHRoZSBzcGVjaWZpZWQga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIGNsb3NlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnQ2xvc2VLZXkoIEhLRVkgaGtleSApCnsKICAgIFRSQUNFKHJlZywiKCV4KVxuIixoa2V5KTsKCiAgICAvKiBUaGUgc3RhbmRhcmQgaGFuZGxlcyBhcmUgYWxsb3dlZCB0byBzdWNjZWVkLCBldmVuIHRob3VnaCB0aGV5IGFyZSBub3QKICAgICAgIGNsb3NlZCAqLwogICAgaWYgKGlzX3N0YW5kYXJkX2hrZXkoaGtleSkpCiAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CgogICAgcmV0dXJuIHJlbW92ZV9oYW5kbGUoaGtleSk7Cn0KCgovKiAKICogRGVsZXRlIHJlZ2lzdHJ5IGtleQogKgogKiBDYWxscGF0aDoKICogUmVnRGVsZXRlS2V5MTYgLT4gUmVnRGVsZXRlS2V5MzJBIC0+IFJlZ0RlbGV0ZUtleTMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZUtleTMyVyBbQURWQVBJMzIuMTM0XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIHRvIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIE5hbWUgb2Ygc3Via2V5IHRvIGRlbGV0ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTMyVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzelN1YktleSApCnsKCUxQS0VZU1RSVUNUCSpscGxwUHJldktleSxscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCiAgICBUUkFDRShyZWcsIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpKTsKCiAgICBscE5leHRLZXkgPSBsb29rdXBfaGtleShoa2V5KTsKICAgIGlmICghbHBOZXh0S2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICAvKiBTdWJrZXkgcGFyYW0gY2Fubm90IGJlIE5VTEwgKi8KICAgIGlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0JBREtFWTsKCiAgICAvKiBXZSBuZWVkIHRvIGtub3cgdGhlIHByZXZpb3VzIGtleSBpbiB0aGUgaGllci4gKi8KCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKGk8d3BjLTEpIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJVFJBQ0UocmVnLCAiICBTY2FubmluZyBbJXNdXG4iLAoJCQkJICAgICBkZWJ1Z3N0cl93KGxweGtleS0+a2V5bmFtZSkpOwoJCQlpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KSB7CgkJCUZSRUVfS0VZX1BBVEg7CgkJCVRSQUNFKHJlZywgIiAgTm90IGZvdW5kLlxuIik7CgkJCS8qIG5vdCBmb3VuZCBpcyBzdWNjZXNzICovCgkJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJCX0KCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJbHB4a2V5CT0gbHBOZXh0S2V5LT5uZXh0c3ViOwoJbHBscFByZXZLZXkgPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7Cgl3aGlsZSAobHB4a2V5KSB7CgkJVFJBQ0UocmVnLCAiICBTY2FubmluZyBbJXNdXG4iLAoJCQkgICAgIGRlYnVnc3RyX3cobHB4a2V5LT5rZXluYW1lKSk7CgkJaWYgKCFsc3RyY21waTMyVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJYnJlYWs7CgkJbHBscFByZXZLZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJbHB4a2V5CQk9IGxweGtleS0+bmV4dDsKCX0KCglpZiAoIWxweGtleSkgewoJCUZSRUVfS0VZX1BBVEg7CgkJV0FSTihyZWcgLCAiICBOb3QgZm91bmQuXG4iKTsKCQlyZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7Cgl9CgoJaWYgKGxweGtleS0+bmV4dHN1YikgewoJCUZSRUVfS0VZX1BBVEg7CgkJV0FSTihyZWcgLCAiICBOb3QgZW1wdHkuXG4iKTsKCQlyZXR1cm4gRVJST1JfQ0FOVFdSSVRFOwoJfQoJKmxwbHBQcmV2S2V5CT0gbHB4a2V5LT5uZXh0OwoJZnJlZShscHhrZXktPmtleW5hbWUpOwoJaWYgKGxweGtleS0+Y2xhc3MpCgkJZnJlZShscHhrZXktPmNsYXNzKTsKCWlmIChscHhrZXktPnZhbHVlcykKCQlmcmVlKGxweGtleS0+dmFsdWVzKTsKCWZyZWUobHB4a2V5KTsKCUZSRUVfS0VZX1BBVEg7CglUUkFDRShyZWcsICIgIERvbmUuXG4iKTsKCXJldHVybglFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVLZXkzMkEgW0FEVkFQSTMyLjEzM10KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXkgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVc7CiAgICBEV09SRCAgcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkpOwogICAgbHBzelN1YktleVcgPSBscHN6U3ViS2V5P3N0cmR1cEEyVyhscHN6U3ViS2V5KTpOVUxMOwogICAgcmV0ID0gUmVnRGVsZXRlS2V5MzJXKCBoa2V5LCBscHN6U3ViS2V5VyApOwogICAgaWYobHBzelN1YktleVcpIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlS2V5MTYgW1NIRUxMLjRdIFtLRVJORUwuMjE5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSk7CiAgICByZXR1cm4gUmVnRGVsZXRlS2V5MzJBKCBoa2V5LCBscHN6U3ViS2V5ICk7Cn0KCgovKiAKICogRGVsZXRlIHJlZ2lzdHJ5IHZhbHVlCiAqCiAqIENhbGxwYXRoOgogKiBSZWdEZWxldGVWYWx1ZTE2IC0+IFJlZ0RlbGV0ZVZhbHVlMzJBIC0+IFJlZ0RlbGV0ZVZhbHVlMzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlVmFsdWUzMlcgW0FEVkFQSTMyLjEzNl0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICBbSV0KICogICAgbHBzelZhbHVlIFtJXQogKgogKiBSRVRVUk5TCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUzMlcoIEhLRVkgaGtleSwgTFBXU1RSIGxwc3pWYWx1ZSApCnsKCURXT1JECQlpOwoJTFBLRVlTVFJVQ1QJbHBrZXk7CglMUEtFWVZBTFVFCXZhbDsKCiAgICBUUkFDRShyZWcsIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pWYWx1ZSkpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKCWlmIChscHN6VmFsdWUpIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKAlscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYKCQkJCSFsc3RyY21waTMyVyhscGtleS0+dmFsdWVzW2ldLm5hbWUsbHBzelZhbHVlKQoJCQkpCgkJCQlicmVhazsKCX0gZWxzZSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCX0KCiAgICBpZiAoaSA9PSBscGtleS0+bnJvZnZhbHVlcykKICAgICAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7CgoJdmFsCT0gbHBrZXktPnZhbHVlcytpOwoJaWYgKHZhbC0+bmFtZSkgZnJlZSh2YWwtPm5hbWUpOwoJaWYgKHZhbC0+ZGF0YSkgZnJlZSh2YWwtPmRhdGEpOwoJbWVtY3B5KAkKCQlscGtleS0+dmFsdWVzK2ksCgkJbHBrZXktPnZhbHVlcytpKzEsCgkJc2l6ZW9mKEtFWVZBTFVFKSoobHBrZXktPm5yb2Z2YWx1ZXMtaS0xKQoJKTsKCWxwa2V5LT52YWx1ZXMJPSAoTFBLRVlWQUxVRSl4cmVhbGxvYygKCQkJCWxwa2V5LT52YWx1ZXMsCgkJCQkobHBrZXktPm5yb2Z2YWx1ZXMtMSkqc2l6ZW9mKEtFWVZBTFVFKQoJCQkpOwoJbHBrZXktPm5yb2Z2YWx1ZXMtLTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVWYWx1ZTMyQSBbQURWQVBJMzIuMTM1XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMzJBKCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZSApCnsKICAgIExQV1NUUiBscHN6VmFsdWVXOwogICAgRFdPUkQgIHJldDsKCiAgICBUUkFDRShyZWcsICIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWUpKTsKICAgIGxwc3pWYWx1ZVcgPSBscHN6VmFsdWU/c3RyZHVwQTJXKGxwc3pWYWx1ZSk6TlVMTDsKICAgIHJldCA9IFJlZ0RlbGV0ZVZhbHVlMzJXKCBoa2V5LCBscHN6VmFsdWVXICk7CiAgICBpZihscHN6VmFsdWVXKSBmcmVlKGxwc3pWYWx1ZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlVmFsdWUxNiBbS0VSTkVMLjIyMl0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTE2KCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIiwgaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZSkpOwogICAgcmV0dXJuIFJlZ0RlbGV0ZVZhbHVlMzJBKCBoa2V5LCBscHN6VmFsdWUgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRmx1c2hLZXkgW0tFUk5FTC4yMjddIFtBRFZBUEkzMi4xNDNdCiAqIFdyaXRlcyBrZXkgdG8gcmVnaXN0cnkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgW0ldIEhhbmRsZSBvZiBrZXkgdG8gd3JpdGUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdGbHVzaEtleSggSEtFWSBoa2V5ICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CiAgICBCT09MMzIgcmV0OwoKICAgIFRSQUNFKHJlZywgIigleClcbiIsIGhrZXkpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0JBREtFWTsKCiAgICBFUlIocmVnLCAiV2hhdCBpcyB0aGUgY29ycmVjdCBmaWxlbmFtZT9cbiIpOwoKICAgIHJldCA9IF9zYXZlcmVnKCBscGtleSwgImZvby5iYXIiLCBUUlVFKTsKCiAgICBpZiggcmV0ICkgewogICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwogICAgfSBlbHNlCiAgICAgICAgcmV0dXJuIEVSUk9SX1VOS05PV047ICAvKiBGSVhNRSAqLwp9CgoKLyogRklYTUU6IGxwY2NoWFhYWCAuLi4gaXMgdGhpcyBjb3VudGluZyBpbiBXQ0hBUlMgb3IgaW4gQllURXMgPz8gKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5SW5mb0tleTMyVyBbQURWQVBJMzIuMTUzXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgICAgICAgICBbSV0gSGFuZGxlIHRvIGtleSB0byBxdWVyeQogKiAgICBscHN6Q2xhc3MgICAgICAgICAgICAgIFtPXSBCdWZmZXIgZm9yIGNsYXNzIHN0cmluZwogKiAgICBscGNjaENsYXNzICAgICAgICAgICAgIFtPXSBTaXplIG9mIGNsYXNzIHN0cmluZyBidWZmZXIKICogICAgbHBkd1Jlc2VydmVkICAgICAgICAgICBbSV0gUmVzZXJ2ZWQKICogICAgbHBjU3ViS2V5cyAgICAgICAgICAgICBbSV0gQnVmZmVyIGZvciBudW1iZXIgb2Ygc3Via2V5cwogKiAgICBscGNjaE1heFN1YktleSAgICAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3Qgc3Via2V5IG5hbWUgbGVuZ3RoCiAqICAgIGxwY2NoTWF4Q2xhc3MgICAgICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCBjbGFzcyBzdHJpbmcgbGVuZ3RoCiAqICAgIGxwY1ZhbHVlcyAgICAgICAgICAgICAgW09dIEJ1ZmZlciBmb3IgbnVtYmVyIG9mIHZhbHVlIGVudHJpZXMKICogICAgbHBjY2hNYXhWYWx1ZU5hbWUgICAgICBbT10gQnVmZmVyIGZvciBsb25nZXN0IHZhbHVlIG5hbWUgbGVuZ3RoCiAqICAgIGxwY2NiTWF4VmFsdWVEYXRhICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCB2YWx1ZSBkYXRhIGxlbmd0aAogKiAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yIFtPXSBCdWZmZXIgZm9yIHNlY3VyaXR5IGRlc2NyaXB0b3IgbGVuZ3RoCiAqICAgIGZ0CiAqIC0gd2luOTUgYWxsb3dzIGxwc3pDbGFzcyB0byBiZSB2YWxpZCBhbmQgbHBjY2hDbGFzcyB0byBiZSBOVUxMIAogKiAtIHdpbm50IHJldHVybnMgRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgaWYgbHBzekNsYXNzIGlzIHZhbGlkIGFuZAogKiAgIGxwY2NoQ2xhc3MgaXMgTlVMTAogKiAtIGJvdGggYWxsb3cgbHBzekNsYXNzIHRvIGJlIE5VTEwgYW5kIGxwY2NoQ2xhc3MgdG8gYmUgTlVMTCAKICogKGl0J3MgaGFyZCB0byB0ZXN0IHZhbGlkaXR5LCBzbyB0ZXN0ICFOVUxMIGluc3RlYWQpCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlJbmZvS2V5MzJXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6Q2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoQ2xhc3MsIExQRFdPUkQgbHBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY1N1YktleXMsIExQRFdPUkQgbHBjY2hNYXhTdWJrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hNYXhDbGFzcywgTFBEV09SRCBscGNWYWx1ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hNYXhWYWx1ZU5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NiTWF4VmFsdWVEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yLCBGSUxFVElNRSAqZnQgKQp7CglMUEtFWVNUUlVDVAlscGtleSxscHhrZXk7CglpbnQJCW5yb2ZrZXlzLG1heHN1YmtleSxtYXhjbGFzcyxtYXh2bmFtZSxtYXh2ZGF0YTsKCWludAkJaTsKCglUUkFDRShyZWcsIigleCwlcCwuLi4pXG4iLGhrZXksbHBzekNsYXNzKTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCWlmIChscHN6Q2xhc3MpIHsKICAgCSAgICAgICAgaWYgKFZFUlNJT05fR2V0VmVyc2lvbigpID09IE5UNDAgJiYgbHBjY2hDbGFzcyA9PSBOVUxMKSB7CgkJICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCQl9CgkJLyogZWl0aGVyIGxwY2NoQ2xhc3MgaXMgdmFsaWQgb3IgdGhpcyBpcyB3aW45NSBhbmQgbHBjY2hDbGFzcwoJCSAgIGNvdWxkIGJlIGludmFsaWQgKi8KCQlpZiAobHBrZXktPmNsYXNzKSB7CgkJICAgICAgICBEV09SRCBjbGFzc0xlbiA9IGxzdHJsZW4zMlcobHBrZXktPmNsYXNzKTsKCgkJCWlmIChscGNjaENsYXNzICYmIGNsYXNzTGVuKzE+KmxwY2NoQ2xhc3MpIHsKCQkJCSpscGNjaENsYXNzPWNsYXNzTGVuKzE7CgkJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCQl9CgkJCWlmIChscGNjaENsYXNzKQoJCQkgICAgKmxwY2NoQ2xhc3M9Y2xhc3NMZW47CgkJCW1lbWNweShscHN6Q2xhc3MsbHBrZXktPmNsYXNzLCBjbGFzc0xlbioyICsgMik7CgkJfSBlbHNlIHsKCQkJKmxwc3pDbGFzcwk9IDA7CgkJCWlmIChscGNjaENsYXNzKQoJCQkgICAgKmxwY2NoQ2xhc3MJPSAwOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGxwY2NoQ2xhc3MpCgkJCSpscGNjaENsYXNzCT0gbHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpOwoJfQoJbHB4a2V5PWxwa2V5LT5uZXh0c3ViOwoJbnJvZmtleXM9bWF4c3Via2V5PW1heGNsYXNzPW1heHZuYW1lPW1heHZkYXRhPTA7Cgl3aGlsZSAobHB4a2V5KSB7CgkJbnJvZmtleXMrKzsKCQlpZiAobHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpPm1heHN1YmtleSkKCQkJbWF4c3Via2V5PWxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKTsKCQlpZiAobHB4a2V5LT5jbGFzcyAmJiBsc3RybGVuMzJXKGxweGtleS0+Y2xhc3MpPm1heGNsYXNzKQoJCQltYXhjbGFzcz1sc3RybGVuMzJXKGxweGtleS0+Y2xhc3MpOwoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9Cglmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykgewoJCUxQS0VZVkFMVUUJdmFsPWxwa2V5LT52YWx1ZXMraTsKCgkJaWYgKHZhbC0+bmFtZSAmJiBsc3RybGVuMzJXKHZhbC0+bmFtZSk+bWF4dm5hbWUpCgkJCW1heHZuYW1lPWxzdHJsZW4zMlcodmFsLT5uYW1lKTsKCQlpZiAodmFsLT5sZW4+bWF4dmRhdGEpCgkJCW1heHZkYXRhPXZhbC0+bGVuOwoJfQoJaWYgKCFtYXhjbGFzcykgbWF4Y2xhc3MJPSAxOwoJaWYgKCFtYXh2bmFtZSkgbWF4dm5hbWUJPSAxOwoJaWYgKGxwY1ZhbHVlcykKCQkqbHBjVmFsdWVzCT0gbHBrZXktPm5yb2Z2YWx1ZXM7CglpZiAobHBjU3ViS2V5cykKCQkqbHBjU3ViS2V5cwk9IG5yb2ZrZXlzOwoJaWYgKGxwY2NoTWF4U3Via2V5KQoJCSpscGNjaE1heFN1YmtleQk9IG1heHN1YmtleTsKCWlmIChscGNjaE1heENsYXNzKQoJCSpscGNjaE1heENsYXNzCT0gbWF4Y2xhc3M7CglpZiAobHBjY2hNYXhWYWx1ZU5hbWUpCgkJKmxwY2NoTWF4VmFsdWVOYW1lPSBtYXh2bmFtZTsKCWlmIChscGNjYk1heFZhbHVlRGF0YSkKCQkqbHBjY2JNYXhWYWx1ZURhdGE9IG1heHZkYXRhOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5SW5mb0tleTMyQSBbQURWQVBJMzIuMTUyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5SW5mb0tleTMyQSggSEtFWSBoa2V5LCBMUFNUUiBscHN6Q2xhc3MsIExQRFdPUkQgbHBjY2hDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBjU3ViS2V5cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE1heFN1YmtleSwgTFBEV09SRCBscGNjaE1heENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY1ZhbHVlcywgTFBEV09SRCBscGNjaE1heFZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjYk1heFZhbHVlRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwgRklMRVRJTUUgKmZ0ICkKewoJTFBXU1RSCQlscHN6Q2xhc3NXID0gTlVMTDsKCURXT1JECQlyZXQ7CgoJVFJBQ0UocmVnLCIoJXgsJXAsJXAuLi4uLi4pXG4iLGhrZXksIGxwc3pDbGFzcywgbHBjY2hDbGFzcyk7CglpZiAobHBzekNsYXNzKSB7CgkJaWYgKGxwY2NoQ2xhc3MpIHsKCQkgICAgbHBzekNsYXNzVyAgPSAoTFBXU1RSKXhtYWxsb2MoKCpscGNjaENsYXNzKSAqIDIpOwoJCX0gZWxzZSBpZiAoVkVSU0lPTl9HZXRWZXJzaW9uKCkgPT0gV0lOOTUpIHsKCQkgICAgLyogd2luOTUgIGFsbG93cyBscGNjaENsYXNzIHRvIGJlIG51bGwgKi8KCQkgICAgLyogd2UgZG9uJ3Qga25vdyBob3cgYmlnIGxwc3pDbGFzcyBpcywgd291bGQgCgkJICAgICAgIE1BWF9QQVRITkFNRV9MRU4gYmUgdGhlIGNvcnJlY3QgZGVmYXVsdD8gKi8KCQkgICAgbHBzekNsYXNzVyAgPSAoTFBXU1RSKXhtYWxsb2MoTUFYX1BBVEhOQU1FX0xFTioyKTsgCgkJfQoKCX0gZWxzZQoJCWxwc3pDbGFzc1cgID0gTlVMTDsKCXJldD1SZWdRdWVyeUluZm9LZXkzMlcoCgkJaGtleSwKCQlscHN6Q2xhc3NXLAoJCWxwY2NoQ2xhc3MsCgkJbHBkd1Jlc2VydmVkLAoJCWxwY1N1YktleXMsCgkJbHBjY2hNYXhTdWJrZXksCgkJbHBjY2hNYXhDbGFzcywKCQlscGNWYWx1ZXMsCgkJbHBjY2hNYXhWYWx1ZU5hbWUsCgkJbHBjY2JNYXhWYWx1ZURhdGEsCgkJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCQlmdAoJKTsKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MgJiYgbHBzekNsYXNzKQoJCWxzdHJjcHlXdG9BKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnkzMlcgW0FEVkFQSTMyLjEyOF0KICoKICogUEFSQU1TCiAqICAgIGxwTWFjaGluZU5hbWUgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiByZW1vdGUgY29tcHV0ZXIKICogICAgaEhleSAgICAgICAgICBbSV0gUHJlZGVmaW5lZCByZWdpc3RyeSBoYW5kbGUKICogICAgcGhrUmVzdWx0ICAgICBbSV0gQWRkcmVzcyBvZiBidWZmZXIgZm9yIHJlbW90ZSByZWdpc3RyeSBoYW5kbGUKICovCkxPTkcgV0lOQVBJIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyVyggTFBDV1NUUiBscE1hY2hpbmVOYW1lLCBIS0VZIGhLZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSBwaGtSZXN1bHQgKQp7CiAgICBUUkFDRShyZWcsIiglcywleCwlcCk6IHN0dWJcbiIsZGVidWdzdHJfdyhscE1hY2hpbmVOYW1lKSxoS2V5LHBoa1Jlc3VsdCk7CgogICAgaWYgKCFscE1hY2hpbmVOYW1lIHx8ICEqbHBNYWNoaW5lTmFtZSkgewogICAgICAgIC8qIFVzZSB0aGUgbG9jYWwgbWFjaGluZSBuYW1lICovCiAgICAgICAgcmV0dXJuIFJlZ09wZW5LZXkxNiggaEtleSwgIiIsIHBoa1Jlc3VsdCApOwogICAgfQoKICAgIEZJWE1FKHJlZywiQ2Fubm90IGNvbm5lY3QgdG8gJXNcbiIsZGVidWdzdHJfdyhscE1hY2hpbmVOYW1lKSk7CiAgICByZXR1cm4gRVJST1JfQkFEX05FVFBBVEg7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyQSBbQURWQVBJMzIuMTI3XQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5MzJBKCBMUENTVFIgbWFjaGluZSwgSEtFWSBoa2V5LCBMUEhLRVkgcmVza2V5ICkKewogICAgRFdPUkQgcmV0OwogICAgTFBXU1RSIG1hY2hpbmVXID0gc3RyZHVwQTJXKG1hY2hpbmUpOwogICAgcmV0ID0gUmVnQ29ubmVjdFJlZ2lzdHJ5MzJXKCBtYWNoaW5lVywgaGtleSwgcmVza2V5ICk7CiAgICBmcmVlKG1hY2hpbmVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0dldEtleVNlY3VyaXR5IFtBRFZBUEkzMi4xNDRdCiAqIFJldHJpZXZlcyBhIGNvcHkgb2Ygc2VjdXJpdHkgZGVzY3JpcHRvciBwcm90ZWN0aW5nIHRoZSByZWdpc3RyeSBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICAgICAgICAgW0ldICAgT3BlbiBoYW5kbGUgb2Yga2V5IHRvIHNldAogKiAgICBTZWN1cml0eUluZm9ybWF0aW9uICAgIFtJXSAgIERlc2NyaXB0b3IgY29udGVudHMKICogICAgcFNlY3VyaXR5RGVzY3JpcHRvciAgICBbT10gICBBZGRyZXNzIG9mIGRlc2NyaXB0b3IgZm9yIGtleQogKiAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yIFtJL09dIEFkZHJlc3Mgb2Ygc2l6ZSBvZiBidWZmZXIgYW5kIGRlc2NyaXB0aW9uCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpMT05HIFdJTkFQSSBSZWdHZXRLZXlTZWN1cml0eSggSEtFWSBoa2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFQ1VSSVRZX0lORk9STUFUSU9OIFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU0VDVVJJVFlfREVTQ1JJUFRPUiBwU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxTZWN1cml0eUluZm9ybWF0aW9uLHBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yPypscGNiU2VjdXJpdHlEZXNjcmlwdG9yOjApOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIEZJWE1FOiBDaGVjayBmb3IgdmFsaWQgU2VjdXJpdHlJbmZvcm1hdGlvbiB2YWx1ZXMgKi8KCiAgICBpZiAoKmxwY2JTZWN1cml0eURlc2NyaXB0b3IgPCBzaXplb2YoKnBTZWN1cml0eURlc2NyaXB0b3IpKQogICAgICAgIHJldHVybiBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSOwoKICAgIEZJWE1FKHJlZywgIigleCwlbGQsJXAsJWxkKTogc3R1YlxuIixoa2V5LFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICBwU2VjdXJpdHlEZXNjcmlwdG9yLGxwY2JTZWN1cml0eURlc2NyaXB0b3I/KmxwY2JTZWN1cml0eURlc2NyaXB0b3I6MCk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0xvYWRLZXkzMlcgW0FEVkFQSTMyLj8/P10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5IFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5CiAqICAgIGxwc3pGaWxlICAgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIHJlZ2lzdHJ5IGluZm9ybWF0aW9uCiAqLwpMT05HIFdJTkFQSSBSZWdMb2FkS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBDV1NUUiBscHN6RmlsZSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxkZWJ1Z3N0cl93KGxwc3pGaWxlKSk7CgogICAgLyogRG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkgfHwgIWxwc3pGaWxlIHx8ICEqbHBzekZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywiKCV4LCVzLCVzKTogc3R1YlxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwc3pGaWxlKSk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0xvYWRLZXkzMkEgW0FEVkFQSTMyLj8/P10KICovCkxPTkcgV0lOQVBJIFJlZ0xvYWRLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQQ1NUUiBscHN6RmlsZSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwc3pTdWJLZXlXID0gc3RyZHVwQTJXKGxwc3pTdWJLZXkpOwogICAgTFBXU1RSIGxwc3pGaWxlVyA9IHN0cmR1cEEyVyhscHN6RmlsZSk7CiAgICByZXQgPSBSZWdMb2FkS2V5MzJXKCBoa2V5LCBscHN6U3ViS2V5VywgbHBzekZpbGVXICk7CiAgICBpZihscHN6RmlsZVcpIGZyZWUobHBzekZpbGVXKTsKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlIFtBRFZBUEkzMi4/Pz9dCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgW0ldIEhhbmRsZSBvZiBrZXkgdG8gd2F0Y2gKICogICAgZldhdGNoU3ViVHJlZSAgIFtJXSBGbGFnIGZvciBzdWJrZXkgbm90aWZpY2F0aW9uCiAqICAgIGZkd05vdGlmeUZpbHRlciBbSV0gQ2hhbmdlcyB0byBiZSByZXBvcnRlZAogKiAgICBoRXZlbnQgICAgICAgICAgW0ldIEhhbmRsZSBvZiBzaWduYWxlZCBldmVudAogKiAgICBmQXN5bmMgICAgICAgICAgW0ldIEZsYWcgZm9yIGFzeW5jaHJvbm91cyByZXBvcnRpbmcKICovCkxPTkcgV0lOQVBJIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlKCBIS0VZIGhrZXksIEJPT0wzMiBmV2F0Y2hTdWJUcmVlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGZkd05vdGlmeUZpbHRlciwgSEFORExFMzIgaEV2ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTDMyIGZBc3luYyApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwogICAgVFJBQ0UocmVnLCIoJXgsJWksJWxkLCV4LCVpKVxuIixoa2V5LGZXYXRjaFN1YlRyZWUsZmR3Tm90aWZ5RmlsdGVyLAogICAgICAgICAgaEV2ZW50LGZBc3luYyk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUUocmVnLCIoJXgsJWksJWxkLCV4LCVpKTogc3R1YlxuIixoa2V5LGZXYXRjaFN1YlRyZWUsZmR3Tm90aWZ5RmlsdGVyLAogICAgICAgICAgaEV2ZW50LGZBc3luYyk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1VuTG9hZEtleTMyVyBbQURWQVBJMzIuMTczXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscFN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleSB0byB1bmxvYWQKICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwU3ViS2V5ICkKewogICAgRklYTUUocmVnLCIoJXgsJXMpOiBzdHViXG4iLGhrZXksIGRlYnVnc3RyX3cobHBTdWJLZXkpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXkzMkEgW0FEVkFQSTMyLjE3Ml0KICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXkgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscFN1YktleVcgPSBzdHJkdXBBMlcobHBTdWJLZXkpOwogICAgcmV0ID0gUmVnVW5Mb2FkS2V5MzJXKCBoa2V5LCBscFN1YktleVcgKTsKICAgIGlmKGxwU3ViS2V5VykgZnJlZShscFN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0S2V5U2VjdXJpdHkgW0FEVkFQSTMyLjE2N10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldIE9wZW4gaGFuZGxlIG9mIGtleSB0byBzZXQKICogICAgU2VjdXJpdHlJbmZvICBbSV0gRGVzY3JpcHRvciBjb250ZW50cwogKiAgICBwU2VjdXJpdHlEZXNjIFtJXSBBZGRyZXNzIG9mIGRlc2NyaXB0b3IgZm9yIGtleQogKi8KTE9ORyBXSU5BUEkgUmVnU2V0S2V5U2VjdXJpdHkoIEhLRVkgaGtleSwgU0VDVVJJVFlfSU5GT1JNQVRJT04gU2VjdXJpdHlJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzYyApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcClcbiIsaGtleSxTZWN1cml0eUluZm8scFNlY3VyaXR5RGVzYyk7CgogICAgLyogSXQgc2VlbXMgdG8gcGVyZm9ybSB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKChTZWN1cml0eUluZm8gJiBPV05FUl9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgR1JPVVBfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIERBQ0xfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIFNBQ0xfU0VDVVJJVFlfSU5GT1JNQVRJT04pKSB7CiAgICAgICAgLyogUGFyYW0gT0sgKi8KICAgIH0gZWxzZQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBpZiAoIXBTZWN1cml0eURlc2MpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywiOigleCwlbGQsJXApOiBzdHViXG4iLGhrZXksU2VjdXJpdHlJbmZvLHBTZWN1cml0eURlc2MpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTYXZlS2V5MzJXIFtBRFZBUEkzMi4xNjZdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgc2F2ZSBiZWdpbnMKICogICAgbHBGaWxlIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIHRvIHNhdmUgdG8KICogICAgc2EgICAgIFtJXSBBZGRyZXNzIG9mIHNlY3VyaXR5IHN0cnVjdHVyZQogKi8KTE9ORyBXSU5BUEkgUmVnU2F2ZUtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwRmlsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBzYSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFKHJlZywgIigleCwlcywlcClcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBGaWxlKSwgc2EpOwoKICAgIC8qIEl0IGFwcGVhcnMgdG8gZG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBGaWxlIHx8ICEqbHBGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsICIoJXgsJXMsJXApOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwRmlsZSksIHNhKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2F2ZUtleTMyQSBbQURWQVBJMzIuMTY1XQogKi8KTE9ORyBXSU5BUEkgUmVnU2F2ZUtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBGaWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIHNhICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBGaWxlVyA9IHN0cmR1cEEyVyhscEZpbGUpOwogICAgcmV0ID0gUmVnU2F2ZUtleTMyVyggaGtleSwgbHBGaWxlVywgc2EgKTsKICAgIGZyZWUobHBGaWxlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5MzJXIFtBRFZBUEkzMi4xNjRdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgIFtJXSBIYW5kbGUgb2Yga2V5IHdoZXJlIHJlc3RvcmUgYmVnaW5zCiAqICAgIGxwRmlsZSAgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgY29udGFpbmluZyBzYXZlZCB0cmVlCiAqICAgIGR3RmxhZ3MgW0ldIE9wdGlvbmFsIGZsYWdzCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCAiKCV4LCVzLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl93KGxwRmlsZSksZHdGbGFncyk7CgogICAgLyogSXQgc2VlbXMgdG8gZG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBGaWxlIHx8ICEqbHBGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsIigleCwlcywlbGQpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIENoZWNrIGZvciBmaWxlIGV4aXN0ZW5jZSAqLwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5MzJBIFtBRFZBUEkzMi4xNjNdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscEZpbGUsIERXT1JEIGR3RmxhZ3MgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscEZpbGVXID0gc3RyZHVwQTJXKGxwRmlsZSk7CiAgICByZXQgPSBSZWdSZXN0b3JlS2V5MzJXKCBoa2V5LCBscEZpbGVXLCBkd0ZsYWdzICk7CiAgICBpZihscEZpbGVXKSBmcmVlKGxwRmlsZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleTMyVyBbQURWQVBJMzIuMTYyXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBTdWJLZXkgIFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5CiAqICAgIGxwTmV3RmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgZmlsZSB3aXRoIG5ldyBkYXRhCiAqICAgIGxwT2xkRmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgYmFja3VwIGZpbGUKICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXkzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSwgTFBDV1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbHBPbGRGaWxlICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXMsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscFN1YktleSksCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsICIoJXgsJXMsJXMsJXMpOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwU3ViS2V5KSwgCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleTMyQSBbQURWQVBJMzIuMTYxXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXksIExQQ1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscE9sZEZpbGUgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscFN1YktleVcgPSBzdHJkdXBBMlcobHBTdWJLZXkpOwogICAgTFBXU1RSIGxwTmV3RmlsZVcgPSBzdHJkdXBBMlcobHBOZXdGaWxlKTsKICAgIExQV1NUUiBscE9sZEZpbGVXID0gc3RyZHVwQTJXKGxwT2xkRmlsZSk7CiAgICByZXQgPSBSZWdSZXBsYWNlS2V5MzJXKCBoa2V5LCBscFN1YktleVcsIGxwTmV3RmlsZVcsIGxwT2xkRmlsZVcgKTsKICAgIGZyZWUobHBPbGRGaWxlVyk7CiAgICBmcmVlKGxwTmV3RmlsZVcpOwogICAgZnJlZShscFN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoK