LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICoKICogRGVjZW1iZXIgMjEsIDE5OTcgLSBLZXZpbiBDb3plbnMKICogRml4ZWQgYnVncyBpbiB0aGUgX3c5NV9sb2FkcmVnKCkgZnVuY3Rpb24uIEFkZGVkIGV4dHJhIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyB0aGUgZm9ybWF0IG9mIHRoZSBXaW5kb3dzICc5NSByZWdpc3RyeSBmaWxlcy4KICoKICogTk9URVMKICogICAgV2hlbiBjaGFuZ2luZyB0aGlzIGZpbGUsIHBsZWFzZSByZS1ydW4gdGhlIHJlZ3Rlc3QgcHJvZ3JhbSB0byBlbnN1cmUKICogICAgdGhlIGNvbmRpdGlvbnMgYXJlIGhhbmRsZWQgcHJvcGVybHkuCiAqCiAqIFRPRE8KICogICAgU2VjdXJpdHkgYWNjZXNzCiAqICAgIE9wdGlvbiBoYW5kbGluZwogKiAgICBUaW1lIGZvciBSZWdFbnVtS2V5KiwgUmVnUXVlcnlJbmZvS2V5KgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL2ZjbnRsLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8cHdkLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJ4bWFsbG9jLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCnN0YXRpYyB2b2lkIFJFR0lTVFJZX0luaXQoKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCi8qIE5PVEU6IGRvIG5vdCBhcHBlbmQgYSAvLiBsaW51eCcgbWtkaXIoKSBXSUxMIEZBSUwgaWYgeW91IGRvIHRoYXQgKi8KI2RlZmluZSBXSU5FX1BSRUZJWAkJCSIvLndpbmUiCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUCQkiL3Vzci9sb2NhbC9ldGMvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUCSIvdXNyL2xvY2FsL2V0Yy93aW5lLnN5c3RlbXJlZyIKCi8qIHJlbGF0aXZlIGluIH51c2VyLy53aW5lLyA6ICovCiNkZWZpbmUgU0FWRV9DVVJSRU5UX1VTRVIJCSJ1c2VyLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX01BQ0hJTkUJCSJzeXN0ZW0ucmVnIgoKI2RlZmluZSBLRVlfUkVHSVNUUlkJIlNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeSIKI2RlZmluZSBWQUxfU0FWRVVQREFURUQJIlNhdmVPbmx5VXBkYXRlZEtleXMiCgovKiBvbmUgdmFsdWUgb2YgYSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZVkFMVUUKewogICAgTFBXU1RSICAgbmFtZTsgICAgICAgICAgLyogbmFtZSBvZiB2YWx1ZSAoVU5JQ09ERSkgb3IgTlVMTCBmb3Igd2luMzEgKi8KICAgIERXT1JEICAgIHR5cGU7ICAgICAgICAgIC8qIHR5cGUgb2YgdmFsdWUgKi8KICAgIERXT1JEICAgIGxlbjsgICAgICAgICAgIC8qIGxlbmd0aCBvZiBkYXRhIGluIEJZVEVzICovCiAgICBEV09SRCAgICBsYXN0bW9kaWZpZWQ7ICAvKiB0aW1lIG9mIHNlY29uZHMgc2luY2UgMS4xLjE5NzAgKi8KICAgIExQQllURSAgIGRhdGE7ICAgICAgICAgIC8qIGNvbnRlbnQsIG1heSBiZSBzdHJpbmdzLCBiaW5hcmllcywgZXRjLiAqLwp9IEtFWVZBTFVFLCpMUEtFWVZBTFVFOwoKLyogYSByZWdpc3RyeSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZU1RSVUNUCnsKICAgIExQV1NUUiAgICAgICAgICAgICAgIGtleW5hbWU7ICAgICAgIC8qIG5hbWUgb2YgVEhJUyBrZXkgKFVOSUNPREUpICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBmbGFnczsgICAgICAgICAvKiBmbGFncy4gKi8KICAgIExQV1NUUiAgICAgICAgICAgICAgIGNsYXNzOwogICAgLyogdmFsdWVzICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBucm9mdmFsdWVzOyAgICAvKiBuciBvZiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIExQS0VZVkFMVUUgICAgICAgICAgIHZhbHVlczsgICAgICAgIC8qIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgLyoga2V5IG1hbmFnZW1lbnQgcG9pbnRlcnMgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHQ7ICAgICAgICAgIC8qIG5leHQga2V5IG9uIHNhbWUgaGllcmFyY2h5ICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0c3ViOyAgICAgICAvKiBrZXlzIHRoYXQgaGFuZyBiZWxvdyBUSElTIGtleSAqLwp9IEtFWVNUUlVDVCwgKkxQS0VZU1RSVUNUOwoKCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jbGFzc2VzX3Jvb3Q9TlVMTDsJLyogd2luZG93cyAzLjEgZ2xvYmFsIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF91c2VyPU5VTEw7CS8qIHVzZXIgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9sb2NhbF9tYWNoaW5lPU5VTEw7LyogbWFjaGluZSBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3VzZXJzPU5VTEw7CS8qIGFsbCB1c2Vycz8gKi8KCi8qIGR5bmFtaWMsIG5vdCBzYXZlZCAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfcGVyZm9ybWFuY2VfZGF0YT1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF9jb25maWc9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2R5bl9kYXRhPU5VTEw7CgovKiB3aGF0IHZhbHVldHlwZXMgZG8gd2UgbmVlZCB0byBjb252ZXJ0PyAqLwojZGVmaW5lIFVOSUNPTlZNQVNLCSgoMTw8UkVHX1NaKXwoMTw8UkVHX01VTFRJX1NaKXwoMTw8UkVHX0VYUEFORF9TWikpCgoKc3RhdGljIHN0cnVjdCBvcGVuaGFuZGxlIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCVJFR1NBTQkJYWNjZXNzbWFzazsKfSAgKm9wZW5oYW5kbGVzPU5VTEw7CnN0YXRpYyBpbnQJbnJvZm9wZW5oYW5kbGVzPTA7Ci8qIFN0YXJ0cyBhZnRlciAxIGJlY2F1c2UgMCwxIGFyZSByZXNlcnZlZCBmb3IgV2luMTYgKi8KLyogTm90ZTogU2hvdWxkIGFsd2F5cyBiZSBldmVuLCBhcyBXaW45NSBBRFZBUEkzMi5ETEwgcmVzZXJ2ZXMgb2RkCiAgICAgICAgIEhLRVlzIGZvciByZW1vdGUgcmVnaXN0cnkgYWNjZXNzICovCnN0YXRpYyBpbnQJY3VycmVudGhhbmRsZT0yOwoKCi8qCiAqIFFVRVNUSU9OCiAqICAgQXJlIHRoZXNlIGRvaW5nIHRoZSBzYW1lIGFzIEhFQVBfc3RyZHVwQXRvVyBhbmQgSEVBUF9zdHJkdXBXdG9BPwogKiAgIElmIHNvLCBjYW4gd2UgcmVtb3ZlIHRoZW0/CiAqIEFOU1dFUgogKiAgIE5vLCB0aGUgbWVtb3J5IGhhbmRsaW5nIGZ1bmN0aW9ucyBhcmUgY2FsbGVkIHZlcnkgb2Z0ZW4gaW4gaGVyZSwgCiAqICAganVzdCByZXBsYWNpbmcgdGhlbSBieSBIZWFwQWxsb2MoU3lzdGVtSGVhcCwuLi4pIG1ha2VzIHJlZ2lzdHJ5CiAqICAgbG9hZGluZyAxMDAgdGltZXMgc2xvd2VyLiAtTU0KICovCnN0YXRpYyBMUFdTVFIgc3RyZHVwQTJXKExQQ1NUUiBzcmMpCnsKICAgIGlmKHNyYykgewoJTFBXU1RSIGRlc3Q9eG1hbGxvYygyKnN0cmxlbihzcmMpKzIpOwoJbHN0cmNweUF0b1coZGVzdCxzcmMpOwoJcmV0dXJuIGRlc3Q7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIExQV1NUUiBzdHJkdXBXKExQQ1dTVFIgYSkgewoJTFBXU1RSCWI7CglpbnQJbGVuOwoKICAgIGlmKGEpIHsKCWxlbj1zaXplb2YoV0NIQVIpKihsc3RybGVuMzJXKGEpKzEpOwoJYj0oTFBXU1RSKXhtYWxsb2MobGVuKTsKCW1lbWNweShiLGEsbGVuKTsKCXJldHVybiBiOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCkxQV1NUUiBzdHJjdnRBMlcoTFBDU1RSIHNyYywgaW50IG5jaGFycykKCnsKICAgTFBXU1RSIGRlc3QgPSB4bWFsbG9jICgyICogbmNoYXJzICsgMik7CgogICBsc3RyY3B5bkF0b1coZGVzdCxzcmMsbmNoYXJzKzEpOwogICBkZXN0W25jaGFyc10gPSAwOwogICByZXR1cm4gZGVzdDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogaXNfc3RhbmRhcmRfaGtleSBbSW50ZXJuYWxdCiAqIERldGVybWluZXMgaWYgYSBoa2V5IGlzIGEgc3RhbmRhcmQga2V5CiAqLwpzdGF0aWMgQk9PTDMyIGlzX3N0YW5kYXJkX2hrZXkoIEhLRVkgaGtleSApCnsKICAgIHN3aXRjaChoa2V5KSB7CiAgICAgICAgY2FzZSAweDAwMDAwMDAwOgogICAgICAgIGNhc2UgMHgwMDAwMDAwMToKICAgICAgICBjYXNlIEhLRVlfQ0xBU1NFU19ST09UOgogICAgICAgIGNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKICAgICAgICBjYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgogICAgICAgIGNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgogICAgICAgIGNhc2UgSEtFWV9VU0VSUzoKICAgICAgICBjYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKICAgICAgICBjYXNlIEhLRVlfRFlOX0RBVEE6CiAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBhZGRfaGFuZGxlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIGFkZF9oYW5kbGUoIEhLRVkgaGtleSwgTFBLRVlTVFJVQ1QgbHBrZXksIFJFR1NBTSBhY2Nlc3NtYXNrICkKewogICAgaW50IGk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXAsJWx4KVxuIixoa2V5LGxwa2V5LGFjY2Vzc21hc2spOwogICAgLyogQ2hlY2sgZm9yIGR1cGxpY2F0ZXMgKi8KICAgIGZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykgewogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5scGtleT09bHBrZXkpIHsKICAgICAgICAgICAgLyogVGhpcyBpcyBub3QgcmVhbGx5IGFuIGVycm9yIC0gdGhlIHVzZXIgaXMgYWxsb3dlZCB0byBjcmVhdGUKICAgICAgICAgICAgICAgdHdvIChvciBtb3JlKSBoYW5kbGVzIHRvIHRoZSBzYW1lIGtleSAqLwogICAgICAgICAgICAvKldBUk4ocmVnLCAiQWRkaW5nIGtleSAlcCB0d2ljZVxuIixscGtleSk7Ki8KICAgICAgICB9CiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpIHsKICAgICAgICAgICAgV0FSTihyZWcsICJBZGRpbmcgaGFuZGxlICV4IHR3aWNlXG4iLGhrZXkpOwogICAgICAgIH0KICAgIH0KICAgIG9wZW5oYW5kbGVzPXhyZWFsbG9jKCBvcGVuaGFuZGxlcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzKzEpKTsKCiAgICBvcGVuaGFuZGxlc1tpXS5scGtleSA9IGxwa2V5OwogICAgb3BlbmhhbmRsZXNbaV0uaGtleSA9IGhrZXk7CiAgICBvcGVuaGFuZGxlc1tpXS5hY2Nlc3NtYXNrID0gYWNjZXNzbWFzazsKICAgIG5yb2ZvcGVuaGFuZGxlcysrOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBnZXRfaGFuZGxlIFtJbnRlcm5hbF0KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBQb2ludGVyIHRvIGtleQogKiAgICBGYWlsdXJlOiBOVUxMCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgZ2V0X2hhbmRsZSggSEtFWSBoa2V5ICkKewogICAgaW50IGk7CgogICAgZm9yIChpPTA7IGk8bnJvZm9wZW5oYW5kbGVzOyBpKyspCiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXkgPT0gaGtleSkKICAgICAgICAgICAgcmV0dXJuIG9wZW5oYW5kbGVzW2ldLmxwa2V5OwogICAgV0FSTihyZWcsICJDb3VsZCBub3QgZmluZCBoYW5kbGUgJXhcbiIsaGtleSk7CiAgICByZXR1cm4gTlVMTDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogcmVtb3ZlX2hhbmRsZSBbSW50ZXJuYWxdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHJlbW92ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRVJST1JfSU5WQUxJRF9IQU5ETEUKICovCnN0YXRpYyBEV09SRCByZW1vdmVfaGFuZGxlKCBIS0VZIGhrZXkgKQp7CiAgICBpbnQgaTsKCiAgICBmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspCiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpCiAgICAgICAgICAgIGJyZWFrOwoKICAgIGlmIChpID09IG5yb2ZvcGVuaGFuZGxlcykgewogICAgICAgIFdBUk4ocmVnLCAiQ291bGQgbm90IGZpbmQgaGFuZGxlICV4XG4iLGhrZXkpOwogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKICAgIH0KCiAgICBtZW1jcHkoIG9wZW5oYW5kbGVzK2ksCiAgICAgICAgICAgIG9wZW5oYW5kbGVzK2krMSwKICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLWktMSkKICAgICk7CiAgICBvcGVuaGFuZGxlcz14cmVhbGxvYyhvcGVuaGFuZGxlcyxzaXplb2Yoc3RydWN0IG9wZW5oYW5kbGUpKihucm9mb3BlbmhhbmRsZXMtMSkpOwogICAgbnJvZm9wZW5oYW5kbGVzLS07CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBsb29rdXBfaGtleSBbSW50ZXJuYWxdCiAqIAogKiBKdXN0IGFzIHRoZSBuYW1lIHNheXMuIENyZWF0ZXMgdGhlIHJvb3Qga2V5cyBvbiBkZW1hbmQsIHNvIHdlIGNhbiBjYWxsIHRoZQogKiBSZWcqIGZ1bmN0aW9ucyBhdCBhbnkgdGltZS4KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBQb2ludGVyIHRvIGtleSBzdHJ1Y3R1cmUKICogICAgRmFpbHVyZTogTlVMTAogKi8KI2RlZmluZSBBRERfUk9PVF9LRVkoeHgpIFwKCXh4ID0gKExQS0VZU1RSVUNUKXhtYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpO1wKCW1lbXNldCh4eCwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTtcCgl4eC0+a2V5bmFtZT0gc3RyZHVwQTJXKCI8c2hvdWxkX25vdF9hcHBlYXJfYW55d2hlcmU+Iik7CgpzdGF0aWMgTFBLRVlTVFJVQ1QgbG9va3VwX2hrZXkoIEhLRVkgaGtleSApCnsKCXN3aXRjaCAoaGtleSkgewoJLyogMCBhbmQgMSBhcmUgdmFsaWQgcm9vdGtleXMgaW4gd2luMTYgc2hlbGwuZGxsIGFuZCBhcmUgdXNlZCBieQoJICogc29tZSBwcm9ncmFtcy4gRG8gbm90IHJlbW92ZSB0aG9zZSBjYXNlcy4gLU1NCgkgKi8KICAgIAljYXNlIDB4MDAwMDAwMDA6CgljYXNlIDB4MDAwMDAwMDE6CgljYXNlIEhLRVlfQ0xBU1NFU19ST09UOiB7CgkJaWYgKCFrZXlfY2xhc3Nlc19yb290KSB7CgkJCUhLRVkJY2xfcl9oa2V5OwoKCQkJLyogY2FsbHMgbG9va3VwX2hrZXkgcmVjdXJzaXZlbHksIFRXSUNFICovCgkJCWlmIChSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlNPRlRXQVJFXFxDbGFzc2VzIiwmY2xfcl9oa2V5KSE9RVJST1JfU1VDQ0VTUykgewoJCQkJRVJSKHJlZywiQ291bGQgbm90IGNyZWF0ZSBIS0xNXFxTT0ZUV0FSRVxcQ2xhc3Nlcy4gVGhpcyBpcyBpbXBvc3NpYmxlLlxuIik7CgkJCQlleGl0KDEpOwoJCQl9CgkJCWtleV9jbGFzc2VzX3Jvb3QgPSBsb29rdXBfaGtleShjbF9yX2hrZXkpOwoJCX0KCQlyZXR1cm4ga2V5X2NsYXNzZXNfcm9vdDsKCX0KCWNhc2UgSEtFWV9DVVJSRU5UX1VTRVI6CgkJaWYgKCFrZXlfY3VycmVudF91c2VyKSB7CgkJCUhLRVkJY191X2hrZXk7CgkJCXN0cnVjdAlwYXNzd2QJKnB3ZDsKCgkJCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CgkJCS8qIGNhbGxzIGxvb2t1cF9oa2V5IHJlY3Vyc2l2ZWx5LCBUV0lDRSAqLwoJCQlpZiAocHdkICYmIHB3ZC0+cHdfbmFtZSkgewoJCQkJaWYgKFJlZ0NyZWF0ZUtleTE2KEhLRVlfVVNFUlMscHdkLT5wd19uYW1lLCZjX3VfaGtleSkhPUVSUk9SX1NVQ0NFU1MpIHsKCQkJCQlFUlIocmVnLCJDb3VsZCBub3QgY3JlYXRlIEhVXFwlcy4gVGhpcyBpcyBpbXBvc3NpYmxlLlxuIixwd2QtPnB3X25hbWUpOwoJCQkJCWV4aXQoMSk7CgkJCQl9CgkJCQlrZXlfY3VycmVudF91c2VyID0gbG9va3VwX2hrZXkoY191X2hrZXkpOwoJCQl9IGVsc2UgewoJCQkJLyogbm90aGluZyBmb3VuZCwgdXNlIHN0YW5kYWxvbmUgKi8KCQkJCUFERF9ST09UX0tFWShrZXlfY3VycmVudF91c2VyKTsKCQkJfQoJCX0KCQlyZXR1cm4ga2V5X2N1cnJlbnRfdXNlcjsKCWNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgoJCWlmICgha2V5X2xvY2FsX21hY2hpbmUpIHsKCQkJQUREX1JPT1RfS0VZKGtleV9sb2NhbF9tYWNoaW5lKTsKCQkJUkVHSVNUUllfSW5pdCgpOwoJCX0KCQlyZXR1cm4ga2V5X2xvY2FsX21hY2hpbmU7CgljYXNlIEhLRVlfVVNFUlM6CgkJaWYgKCFrZXlfdXNlcnMpIHsKCQkJQUREX1JPT1RfS0VZKGtleV91c2Vycyk7CgkJfQoJCXJldHVybiBrZXlfdXNlcnM7CgljYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKCQlpZiAoIWtleV9wZXJmb3JtYW5jZV9kYXRhKSB7CgkJCUFERF9ST09UX0tFWShrZXlfcGVyZm9ybWFuY2VfZGF0YSk7CgkJfQoJCXJldHVybiBrZXlfcGVyZm9ybWFuY2VfZGF0YTsKCWNhc2UgSEtFWV9EWU5fREFUQToKCQlpZiAoIWtleV9keW5fZGF0YSkgewoJCQlBRERfUk9PVF9LRVkoa2V5X2R5bl9kYXRhKTsKCQl9CgkJcmV0dXJuIGtleV9keW5fZGF0YTsKCWNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKCQlpZiAoIWtleV9jdXJyZW50X2NvbmZpZykgewoJCQlBRERfUk9PVF9LRVkoa2V5X2N1cnJlbnRfY29uZmlnKTsKCQl9CgkJcmV0dXJuIGtleV9jdXJyZW50X2NvbmZpZzsKCWRlZmF1bHQ6CgkJcmV0dXJuIGdldF9oYW5kbGUoaGtleSk7Cgl9CgkvKk5PVFJFQUNIRUQqLwp9CiN1bmRlZiBBRERfUk9PVF9LRVkKLyogc28gd2UgZG9uJ3QgYWNjaWRlbnRseSBhY2Nlc3MgdGhlbSAuLi4gKi8KI2RlZmluZSBrZXlfY3VycmVudF9jb25maWcgTlVMTCBOVUxMCiNkZWZpbmUga2V5X2N1cnJlbnRfdXNlciBOVUxMIE5VTEwKI2RlZmluZSBrZXlfdXNlcnMgTlVMTCBOVUxMCiNkZWZpbmUga2V5X2xvY2FsX21hY2hpbmUgTlVMTCBOVUxMCiNkZWZpbmUga2V5X2NsYXNzZXNfcm9vdCBOVUxMIE5VTEwKI2RlZmluZSBrZXlfZHluX2RhdGEgTlVMTCBOVUxMCiNkZWZpbmUga2V5X3BlcmZvcm1hbmNlX2RhdGEgTlVMTCBOVUxMCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIHNwbGl0X2tleXBhdGggW0ludGVybmFsXQogKiBzcGxpdHMgdGhlIHVuaWNvZGUgc3RyaW5nICd3cCcgaW50byBhbiBhcnJheSBvZiBzdHJpbmdzLgogKiB0aGUgYXJyYXkgaXMgYWxsb2NhdGVkIGJ5IHRoaXMgZnVuY3Rpb24uIAogKiBGcmVlIHRoZSBhcnJheSB1c2luZyBGUkVFX0tFWV9QQVRICiAqCiAqIFBBUkFNUwogKiAgICB3cCAgW0ldIFN0cmluZyB0byBzcGxpdCB1cAogKiAgICB3cHYgW09dIEFycmF5IG9mIHBvaW50ZXJzIHRvIHN0cmluZ3MKICogICAgd3BjIFtPXSBOdW1iZXIgb2YgY29tcG9uZW50cwogKi8Kc3RhdGljIHZvaWQgc3BsaXRfa2V5cGF0aCggTFBDV1NUUiB3cCwgTFBXU1RSICoqd3B2LCBpbnQgKndwYykKewogICAgaW50CWksaixsZW47CiAgICBMUFdTVFIgd3M7CgogICAgVFJBQ0UocmVnLCIoJXMsJXAsJXApXG4iLGRlYnVnc3RyX3cod3ApLHdwdix3cGMpOwoKICAgIHdzCT0gSEVBUF9zdHJkdXBXKCBTeXN0ZW1IZWFwLCAwLCB3cCApOwoKICAgIC8qIFdlIGtub3cgd2UgaGF2ZSBhdCBsZWFzdCBvbmUgc3Vic3RyaW5nICovCiAgICAqd3BjID0gMTsKCiAgICAvKiBSZXBsYWNlIGVhY2ggYmFja3NsYXNoIHdpdGggTlVMTCwgYW5kIGluY3JlbWVudCB0aGUgY291bnQgKi8KICAgIGZvciAoaT0wO3dzW2ldO2krKykgewogICAgICAgIGlmICh3c1tpXT09J1xcJykgewogICAgICAgICAgICB3c1tpXT0wOwogICAgICAgICAgICAoKndwYykrKzsKICAgICAgICB9CiAgICB9CgogICAgbGVuID0gaTsKCiAgICAvKiBBbGxvY2F0ZSB0aGUgc3BhY2UgZm9yIHRoZSBhcnJheSBvZiBwb2ludGVycywgbGVhdmluZyByb29tIGZvciB0aGUKICAgICAgIE5VTEwgYXQgdGhlIGVuZCAqLwogICAgKndwdiA9IChMUFdTVFIqKUhlYXBBbGxvYyggU3lzdGVtSGVhcCwgMCwgc2l6ZW9mKExQV1NUUikqKCp3cGMrMikpOwogICAgKCp3cHYpWzBdPSB3czsKCiAgICAvKiBBc3NpZ24gZWFjaCBwb2ludGVyIHRvIHRoZSBhcHByb3ByaWF0ZSBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZyAqLwogICAgaiA9IDE7CiAgICBmb3IgKGk9MTtpPGxlbjtpKyspCiAgICAgICAgaWYgKHdzW2ktMV09PTApIHsKICAgICAgICAgICAgKCp3cHYpW2orK109d3MraTsKICAgICAgICAgICAgLyogVFJBQ0UocmVnLCAiIFN1Yml0ZW0gJWQgPSAlc1xuIixqLTEsZGVidWdzdHJfdygoKndwdilbai0xXSkpOyAqLwogICAgICAgIH0KCiAgICAoKndwdilbal09TlVMTDsKfQojZGVmaW5lIEZSRUVfS0VZX1BBVEggSGVhcEZyZWUoU3lzdGVtSGVhcCwwLHdwc1swXSk7SGVhcEZyZWUoU3lzdGVtSGVhcCwwLHdwcyk7CgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJFR0lTVFJZX0luaXQgW0ludGVybmFsXQogKiBSZWdpc3RyeSBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIHNvbWUgZGVmYXVsdCBrZXlzLiAKICovCnN0YXRpYyB2b2lkIFJFR0lTVFJZX0luaXQoKSB7CglIS0VZCWhrZXk7CgljaGFyCWJ1ZlsyMDBdOwoKCVRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCglSZWdDcmVhdGVLZXkxNihIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIkhBUkRXQVJFXFxERVNDUklQVElPTlxcU3lzdGVtIiwmaGtleSk7CglSZWdTZXRWYWx1ZUV4MzJBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3cgTlRcXEN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRCdWlsZE51bWJlcgoJICoJCQkJCQlDdXJyZW50VHlwZQoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3duZXIKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE9yZ2FuaXphdGlvbgoJICoKCSAqLwoJLyogU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXFNOTVBcXFBhcmFtZXRlcnNcXFJGQzExNTZBZ2VudAoJICogCQkJCQlzdHJpbmcJU3lzQ29udGFjdAoJICogCQkJCQlzdHJpbmcJU3lzTG9jYXRpb24KCSAqIAkJCQkJCVN5c1NlcnZpY2VzCgkgKi8JCQkJCQkKCWlmICgtMSE9Z2V0aG9zdG5hbWUoYnVmLDIwMCkpIHsKCQlSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXENvbnRyb2xcXENvbXB1dGVyTmFtZVxcQ29tcHV0ZXJOYW1lIiwmaGtleSk7CgkJUmVnU2V0VmFsdWVFeDE2KGhrZXksIkNvbXB1dGVyTmFtZSIsMCxSRUdfU1osYnVmLHN0cmxlbihidWYpKzEpOwoJCVJlZ0Nsb3NlS2V5KGhrZXkpOwoJfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKiBTQVZFIFJlZ2lzdHJ5IEZ1bmN0aW9uICoqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIFJFR0lTVFJZX1NBVkVfVkVSU0lPTgkweDAwMDAwMDAxCgovKiBSZWdpc3RyeSBzYXZlZm9ybWF0OgogKiBJZiB5b3UgY2hhbmdlIGl0LCBpbmNyZWFzZSBhYm92ZSBudW1iZXIgYnkgMSwgd2hpY2ggd2lsbCBmbHVzaAogKiBvbGQgcmVnaXN0cnkgZGF0YWJhc2UgZmlsZXMuCiAqIAogKiBHbG9iYWw6CiAqIAkiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIgogKiAJc3Via2V5cy4uLi4KICogU3Via2V5czoKICogCWtleW5hbWUKICoJCXZhbHVlbmFtZT1sYXN0bW9kaWZpZWQsdHlwZSxkYXRhCiAqCQkuLi4KICoJCXN1YmtleXMKICoJLi4uCiAqIGtleW5hbWUsdmFsdWVuYW1lLHN0cmluZ2RhdGE6CiAqCXRoZSB1c3VhbCBhc2NpaSBjaGFyYWN0ZXJzIGZyb20gMHgwMC0weGZmICh3ZWxsLCBub3QgMHgwMCkKICoJYW5kIFx1WFhYWCBhcyBVTklDT0RFIHZhbHVlIFhYWFggd2l0aCBYWFhYPjB4ZmYKICoJKCAiPVxcXHQiIGVzY2FwZWQgaW4gXHVYWFhYIGZvcm0uKQogKiB0eXBlLGxhc3Rtb2RpZmllZDogCiAqCWludAogKiAKICogRklYTUU6IGRvZXNuJ3Qgc2F2ZSAnY2xhc3MnICh3aGF0IGRvZXMgaXQgbWVhbiBhbnl3YXk/KSwgbm9yIGZsYWdzLgogKgogKiBbSEtFWV9DVVJSRU5UX1VTRVJcXFNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeV0KICogU2F2ZU9ubHlVcGRhdGVkS2V5cz15ZXMKICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlX2NoZWNrX3RhaW50ZWQgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfc2F2ZV9jaGVja190YWludGVkKCBMUEtFWVNUUlVDVCBscGtleSApCnsKCWludAkJdGFpbnRlZDsKCglpZiAoIWxwa2V5KQoJCXJldHVybiAwOwoJaWYgKGxwa2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkKCQl0YWludGVkID0gMTsKCWVsc2UKCQl0YWludGVkID0gMDsKCXdoaWxlIChscGtleSkgewoJCWlmIChfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKSkgewoJCQlscGtleS0+ZmxhZ3MgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoJCQl0YWludGVkID0gMTsKCQl9CgkJbHBrZXkJPSBscGtleS0+bmV4dDsKCX0KCXJldHVybiB0YWludGVkOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlX1VTVFJJTkcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3NhdmVfVVNUUklORyggRklMRSAqRiwgTFBXU1RSIHdzdHIsIGludCBlc2NhcGVlcSApCnsKCUxQV1NUUglzOwoJaW50CWRvZXNjYXBlOwoKCWlmICh3c3RyPT1OVUxMKQoJCXJldHVybjsKCXM9d3N0cjsKCXdoaWxlICgqcykgewoJCWRvZXNjYXBlPTA7CgkJaWYgKCpzPjB4ZmYpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoKnM9PSdcbicpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoZXNjYXBlZXEgJiYgKnM9PSc9JykKCQkJZG9lc2NhcGUgPSAxOwoJCWlmICgqcz09J1xcJykKICAgICAgICAgICAgICAgICAgICAgICAgZnB1dGMoKnMsRik7IC8qIGlmIFxcIHRoZW4gcHV0IGl0IHR3aWNlLiAqLwoJCWlmIChkb2VzY2FwZSkKCQkJZnByaW50ZihGLCJcXHUlMDR4IiwqKCh1bnNpZ25lZCBzaG9ydCopcykpOwoJCWVsc2UKCQkJZnB1dGMoKnMsRik7CgkJcysrOwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlc3Via2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3NhdmVzdWJrZXkoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgbGV2ZWwsIGludCBhbGwgKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWksdGFicyxqOwoKCWxweGtleQk9IGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJIShscHhrZXktPmZsYWdzICYgUkVHX09QVElPTl9WT0xBVElMRSkgJiYKCQkJKGFsbCB8fCAobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkpCgkJKSB7CgkJCWZvciAodGFicz1sZXZlbDt0YWJzLS07KQoJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJX3NhdmVfVVNUUklORyhGLGxweGtleS0+a2V5bmFtZSwxKTsKCQkJZnB1dHMoIlxuIixGKTsKCQkJZm9yIChpPTA7aTxscHhrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJCQlMUEtFWVZBTFVFCXZhbD1scHhrZXktPnZhbHVlcytpOwoKCQkJCWZvciAodGFicz1sZXZlbCsxO3RhYnMtLTspCgkJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJCV9zYXZlX1VTVFJJTkcoRix2YWwtPm5hbWUsMCk7CgkJCQlmcHV0YygnPScsRik7CgkJCQlmcHJpbnRmKEYsIiVsZCwlbGQsIix2YWwtPnR5cGUsdmFsLT5sYXN0bW9kaWZpZWQpOwoJCQkJaWYgKCgxPDx2YWwtPnR5cGUpICYgVU5JQ09OVk1BU0spCgkJCQkJX3NhdmVfVVNUUklORyhGLChMUFdTVFIpdmFsLT5kYXRhLDApOwoJCQkJZWxzZQoJCQkJCWZvciAoaj0wO2o8dmFsLT5sZW47aisrKQoJCQkJCQlmcHJpbnRmKEYsIiUwMngiLCooKHVuc2lnbmVkIGNoYXIqKXZhbC0+ZGF0YStqKSk7CgkJCQlmcHV0cygiXG4iLEYpOwoJCQl9CgkJCS8qIGRlc2NlbmQgcmVjdXJzaXZlbHkgKi8KCQkJaWYgKCFfc2F2ZXN1YmtleShGLGxweGtleS0+bmV4dHN1YixsZXZlbCsxLGFsbCkpCgkJCQlyZXR1cm4gMDsKCQl9CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXN1YnJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF9zYXZlc3VicmVnKCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGFsbCApCnsKCWZwcmludGYoRiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkXG4iLFJFR0lTVFJZX1NBVkVfVkVSU0lPTik7Cglfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKTsKCXJldHVybiBfc2F2ZXN1YmtleShGLGxwa2V5LT5uZXh0c3ViLDAsYWxsKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIEJPT0wzMiBfc2F2ZXJlZyggTFBLRVlTVFJVQ1QgbHBrZXksIGNoYXIgKmZuLCBpbnQgYWxsICkKewoJRklMRQkqRjsKCglGPWZvcGVuKGZuLCJ3Iik7CglpZiAoRj09TlVMTCkgewoJCVdBUk4ocmVnLCJDb3VsZG4ndCBvcGVuICVzIGZvciB3cml0aW5nOiAlc1xuIiwKCQkJZm4sc3RyZXJyb3IoZXJybm8pCgkJKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglpZiAoIV9zYXZlc3VicmVnKEYsbHBrZXksYWxsKSkgewoJCWZjbG9zZShGKTsKCQl1bmxpbmsoZm4pOwoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gc2F2ZSBrZXlzLCBwZXJoYXBzIG5vIG1vcmUgZGlza3NwYWNlIGZvciAlcz9cbiIsZm4pOwoJCXJldHVybiBGQUxTRTsKCX0KCWZjbG9zZShGKTsKICAgICAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfU2F2ZVJlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnZvaWQgU0hFTExfU2F2ZVJlZ2lzdHJ5KCB2b2lkICkKewoJY2hhcgkqZm47CglzdHJ1Y3QJcGFzc3dkCSpwd2Q7CgljaGFyCWJ1Zls0XTsKCUhLRVkJaGtleTsKCWludAlhbGw7CgogICAgVFJBQ0UocmVnLCIodm9pZClcbiIpOwoKCWFsbD0wOwoJaWYgKFJlZ09wZW5LZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJc3RyY3B5KGJ1ZiwieWVzIik7Cgl9IGVsc2UgewoJCURXT1JEIGxlbixqdW5rLHR5cGU7CgoJCWxlbj00OwoJCWlmICgJKEVSUk9SX1NVQ0NFU1MhPVJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQkJCWhrZXksCgkJCQlWQUxfU0FWRVVQREFURUQsCgkJCQkmanVuaywKCQkJCSZ0eXBlLAoJCQkJYnVmLAoJCQkJJmxlbgoJCQkpKXx8ICh0eXBlIT1SRUdfU1opCgkJKQoJCQlzdHJjcHkoYnVmLCJ5ZXMiKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KCWlmIChsc3RyY21waTMyQShidWYsInllcyIpKQoJCWFsbD0xOwoJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCWlmIChwd2QhPU5VTEwgJiYgcHdkLT5wd19kaXIhPU5VTEwpCiAgICAgICAgewogICAgICAgICAgICAgICAgY2hhciAqdG1wOwoKCQlmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKHB3ZC0+cHdfZGlyKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikgKyAyICk7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgpOwoJCS8qIGNyZWF0ZSB0aGUgZGlyZWN0b3J5LiBkb24ndCBjYXJlIGFib3V0IGVycm9yY29kZXMuICovCgkJbWtkaXIoZm4sMDc1NSk7IC8qIGRyd3hyLXhyLXggKi8KCQlzdHJjYXQoZm4sIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwoJCXRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CgkJc3RyY3B5KHRtcCxmbik7c3RyY2F0KHRtcCwiLnRtcCIpOwoJCWlmIChfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUiksdG1wLGFsbCkpIHsKCQkJaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewoJCQkJcGVycm9yKCJyZW5hbWUgdG1wIHJlZ2lzdHJ5Iik7CgkJCQl1bmxpbmsodG1wKTsKCQkJfQoJCX0KCQlmcmVlKHRtcCk7CgkJZnJlZShmbik7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9NQUNISU5FKTsKCQl0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwoJCXN0cmNweSh0bXAsZm4pO3N0cmNhdCh0bXAsIi50bXAiKTsKCQlpZiAoX3NhdmVyZWcobG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSx0bXAsYWxsKSkgewoJCQlpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CgkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKCQkJCXVubGluayh0bXApOwoJCQl9CgkJfQoJCWZyZWUodG1wKTsKCQlmcmVlKGZuKTsKCX0gZWxzZQoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVkLlxuIixnZXR1aWQoKSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqIExPQUQgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmluZF9vcl9hZGRfa2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBMUEtFWVNUUlVDVCBfZmluZF9vcl9hZGRfa2V5KCBMUEtFWVNUUlVDVCBscGtleSwgTFBXU1RSIGtleW5hbWUgKQp7CglMUEtFWVNUUlVDVAlscHhrZXksKmxwbHBrZXk7CgoJaWYgKCgha2V5bmFtZSkgfHwgKGtleW5hbWVbMF09PTApKSB7CgkJZnJlZShrZXluYW1lKTsKCQlyZXR1cm4gbHBrZXk7Cgl9CglscGxwa2V5PSAmKGxwa2V5LT5uZXh0c3ViKTsKCWxweGtleQk9ICpscGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJKGxweGtleS0+a2V5bmFtZVswXT09a2V5bmFtZVswXSkgJiYgCgkJCSFsc3RyY21waTMyVyhscHhrZXktPmtleW5hbWUsa2V5bmFtZSkKCQkpCgkJCWJyZWFrOwoJCWxwbHBrZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7Cgl9CglpZiAobHB4a2V5PT1OVUxMKSB7CgkJKmxwbHBrZXkgPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7CgkJbWVtc2V0KGxweGtleSwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTsKCQlscHhrZXktPmtleW5hbWUJPSBrZXluYW1lOwoJfSBlbHNlCgkJZnJlZShrZXluYW1lKTsKCXJldHVybiBscHhrZXk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2ZpbmRfb3JfYWRkX3ZhbHVlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9maW5kX29yX2FkZF92YWx1ZSggTFBLRVlTVFJVQ1QgbHBrZXksIExQV1NUUiBuYW1lLCBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBkYXRhLCBEV09SRCBsZW4sIERXT1JEIGxhc3Rtb2RpZmllZCApCnsKCUxQS0VZVkFMVUUJdmFsPU5VTEw7CglpbnQJCWk7CgoJaWYgKG5hbWUgJiYgISpuYW1lKSB7LyogZW1wdHkgc3RyaW5nIGVxdWFscyBkZWZhdWx0IChOVUxMKSB2YWx1ZSAqLwoJCWZyZWUobmFtZSk7CgkJbmFtZSA9IE5VTEw7Cgl9CgoJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCWlmIChuYW1lPT1OVUxMKSB7CgkJCWlmICh2YWwtPm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCQl9IGVsc2UgewoJCQlpZiAoCXZhbC0+bmFtZSE9TlVMTCAmJiAKCQkJCXZhbC0+bmFtZVswXT09bmFtZVswXSAmJgoJCQkJIWxzdHJjbXBpMzJXKHZhbC0+bmFtZSxuYW1lKQoJCQkpCgkJCQlicmVhazsKCQl9Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0geHJlYWxsb2MoCgkJCWxwa2V5LT52YWx1ZXMsCgkJCSgrK2xwa2V5LT5ucm9mdmFsdWVzKSpzaXplb2YoS0VZVkFMVUUpCgkJKTsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCW1lbXNldCh2YWwsJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCQl2YWwtPm5hbWUgPSBuYW1lOwoJfSBlbHNlIHsKCQlpZiAobmFtZSkKCQkJZnJlZShuYW1lKTsKCX0KCWlmICh2YWwtPmxhc3Rtb2RpZmllZDxsYXN0bW9kaWZpZWQpIHsKCQl2YWwtPmxhc3Rtb2RpZmllZD1sYXN0bW9kaWZpZWQ7CgkJdmFsLT50eXBlID0gdHlwZTsKCQl2YWwtPmxlbiAgPSBsZW47CgkJaWYgKHZhbC0+ZGF0YSkgCgkJCWZyZWUodmFsLT5kYXRhKTsKCQl2YWwtPmRhdGEgPSBkYXRhOwoJfSBlbHNlCgkJZnJlZShkYXRhKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9saW5lIFtJbnRlcm5hbF0KICoKICogcmVhZHMgYSBsaW5lIGluY2x1ZGluZyBkeW5hbWljYWxseSBlbmxhcmdpbmcgdGhlIHJlYWRidWZmZXIgYW5kIHRocm93aW5nCiAqIGF3YXkgY29tbWVudHMKICovCnN0YXRpYyBpbnQgX3dpbmVfcmVhZF9saW5lKCBGSUxFICpGLCBjaGFyICoqYnVmLCBpbnQgKmxlbiApCnsKCWNoYXIJKnMsKmN1cnJlYWQ7CglpbnQJbXlsZW4sY3Vyb2ZmOwoKCWN1cnJlYWQJPSAqYnVmOwoJbXlsZW4JPSAqbGVuOwoJKipidWYJPSAnXDAnOwoJd2hpbGUgKDEpIHsKCQl3aGlsZSAoMSkgewoJCQlzPWZnZXRzKGN1cnJlYWQsbXlsZW4sRik7CgkJCWlmIChzPT1OVUxMKQoJCQkJcmV0dXJuIDA7IC8qIEVPRiAqLwoJCQlpZiAoTlVMTD09KHM9c3RyY2hyKGN1cnJlYWQsJ1xuJykpKSB7CgkJCQkvKiBidWZmZXIgd2Fzbid0IGxhcmdlIGVub3VnaCAqLwoJCQkJY3Vyb2ZmCT0gc3RybGVuKCpidWYpOwoJCQkJKmJ1Zgk9IHhyZWFsbG9jKCpidWYsKmxlbioyKTsKCQkJCWN1cnJlYWQJPSAqYnVmICsgY3Vyb2ZmOwoJCQkJbXlsZW4JPSAqbGVuOwkvKiB3ZSBmaWxsZWQgdXAgdGhlIGJ1ZmZlciBhbmQgCgkJCQkJCSAqIGdvdCBuZXcgJypsZW4nIGJ5dGVzIHRvIGZpbGwKCQkJCQkJICovCgkJCQkqbGVuCT0gKmxlbiAqIDI7CgkJCX0gZWxzZSB7CgkJCQkqcz0nXDAnOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLyogdGhyb3cgYXdheSBjb21tZW50cyAqLwoJCWlmICgqKmJ1Zj09JyMnIHx8ICoqYnVmPT0nOycpIHsKCQkJY3VycmVhZAk9ICpidWY7CgkJCW15bGVuCT0gKmxlbjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzKSAJLyogZ290IGVuZCBvZiBsaW5lICovCgkJCWJyZWFrOwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfVVNUUklORyBbSW50ZXJuYWxdCiAqCiAqIGNvbnZlcnRzIGEgY2hhciogaW50byBhIFVOSUNPREUgc3RyaW5nICh1cCB0byBhIHNwZWNpYWwgY2hhcikKICogYW5kIHJldHVybnMgdGhlIHBvc2l0aW9uIGV4YWN0bHkgYWZ0ZXIgdGhhdCBzdHJpbmcKICovCnN0YXRpYyBjaGFyKiBfd2luZV9yZWFkX1VTVFJJTkcoIGNoYXIgKmJ1ZiwgTFBXU1RSICpzdHIgKQp7CgljaGFyCSpzOwoJTFBXU1RSCXdzOwoKCS8qIHJlYWQgdXAgdG8gIj0iIG9yICJcMCIgb3IgIlxuIiAqLwoJcwk9IGJ1ZjsKCWlmICgqcyA9PSAnPScpIHsKCQkvKiBlbXB0eSBzdHJpbmcgaXMgdGhlIHdpbjMuMSBkZWZhdWx0IHZhbHVlKE5VTEwpKi8KCQkqc3RyCT0gTlVMTDsKCQlyZXR1cm4gczsKCX0KCSpzdHIJPSAoTFBXU1RSKXhtYWxsb2MoMipzdHJsZW4oYnVmKSsyKTsKCXdzCT0gKnN0cjsKCXdoaWxlICgqcyAmJiAoKnMhPSdcbicpICYmICgqcyE9Jz0nKSkgewoJCWlmICgqcyE9J1xcJykKCQkJKndzKys9KigodW5zaWduZWQgY2hhciopcysrKTsKCQllbHNlIHsKCQkJcysrOwoJCQlpZiAoKnM9PSdcXCcpIHsKCQkJCSp3cysrPSdcXCc7CgkJCQlzKys7CgkJCQljb250aW51ZTsKCQkJfQoJCQlpZiAoKnMhPSd1JykgewoJCQkJV0FSTihyZWcsIk5vbiB1bmljb2RlIGVzY2FwZSBzZXF1ZW5jZSBcXCVjIGZvdW5kIGluIHwlc3xcbiIsKnMsYnVmKTsKCQkJCSp3cysrPSdcXCc7CgkJCQkqd3MrKz0qcysrOwoJCQl9IGVsc2UgewoJCQkJY2hhcgl4YnVmWzVdOwoJCQkJaW50CXdjOwoKCQkJCXMrKzsKCQkJCW1lbWNweSh4YnVmLHMsNCk7eGJ1Zls0XT0nXDAnOwoJCQkJaWYgKCFzc2NhbmYoeGJ1ZiwiJXgiLCZ3YykpCgkJCQkJV0FSTihyZWcsIlN0cmFuZ2UgZXNjYXBlIHNlcXVlbmNlICVzIGZvdW5kIGluIHwlc3xcbiIseGJ1ZixidWYpOwoJCQkJcys9NDsKCQkJCSp3cysrCT0odW5zaWduZWQgc2hvcnQpd2M7CgkJCX0KCQl9Cgl9Cgkqd3MJPSAwOwoJd3MJPSAqc3RyOwoJaWYgKCp3cykKCQkqc3RyCT0gc3RyZHVwVygqc3RyKTsKCWVsc2UKCQkqc3RyCT0gTlVMTDsKCWZyZWUod3MpOwoJcmV0dXJuIHM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJrZXkgW0ludGVybmFsXQogKgogKiBOT1RFUwogKiAgICBJdCBzZWVtcyBsaWtlIHRoaXMgaXMgcmV0dXJuaW5nIGEgYm9vbGVhbi4gIFNob3VsZCBpdD8KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiAxCiAqICAgIEZhaWx1cmU6IDAKICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YmtleSggRklMRSAqRiwgTFBLRVlTVFJVQ1QgbHBrZXksIGludCBsZXZlbCwgY2hhciAqKmJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKmJ1ZmxlbiwgRFdPUkQgb3B0ZmxhZyApCnsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJaTsKCWNoYXIJCSpzOwoJTFBXU1RSCQluYW1lOwoKICAgIFRSQUNFKHJlZywiKCVwLCVwLCVkLCVzLCVkLCVseClcbiIsIEYsIGxwa2V5LCBsZXZlbCwgZGVidWdzdHJfYSgqYnVmKSwKICAgICAgICAgICpidWZsZW4sIG9wdGZsYWcpOwoKICAgIGxwa2V5LT5mbGFncyB8PSBvcHRmbGFnOwoKICAgIC8qIEdvb2QuICBXZSBhbHJlYWR5IGdvdCBhIGxpbmUgaGVyZSAuLi4gc28gcGFyc2UgaXQgKi8KICAgIGxweGtleSA9IE5VTEw7CiAgICB3aGlsZSAoMSkgewogICAgICAgIGk9MDtzPSpidWY7CiAgICAgICAgd2hpbGUgKCpzPT0nXHQnKSB7CiAgICAgICAgICAgIHMrKzsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KICAgICAgICBpZiAoaT5sZXZlbCkgewogICAgICAgICAgICBpZiAobHB4a2V5PT1OVUxMKSB7CiAgICAgICAgICAgICAgICBXQVJOKHJlZywiR290IGEgc3ViaGllcmFyY2h5IHdpdGhvdXQgcmVzcC4ga2V5P1xuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBfd2luZV9sb2Fkc3Via2V5KEYsbHB4a2V5LGxldmVsKzEsYnVmLGJ1ZmxlbixvcHRmbGFnKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKCQkvKiBsZXQgdGhlIGNhbGxlciBoYW5kbGUgdGhpcyBsaW5lICovCgkJaWYgKGk8bGV2ZWwgfHwgKipidWY9PSdcMCcpCgkJCXJldHVybiAxOwoKCQkvKiBpdCBjYW4gYmU6IGEgdmFsdWUgb3IgYSBrZXluYW1lLiBQYXJzZSB0aGUgbmFtZSBmaXJzdCAqLwoJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsJm5hbWUpOwoKCQkvKiBzd2l0Y2goKSBkZWZhdWx0OiBoYWNrIHRvIGF2b2lkIGdvdG9zICovCgkJc3dpdGNoICgwKSB7CgkJZGVmYXVsdDoKCQkJaWYgKCpzPT0nXDAnKSB7CgkJCQlscHhrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxuYW1lKTsKCQkJfSBlbHNlIHsKCQkJCUxQQllURQkJZGF0YTsKCQkJCWludAkJbGVuLGxhc3Rtb2RpZmllZCx0eXBlOwoKCQkJCWlmICgqcyE9Jz0nKSB7CgkJCQkJV0FSTihyZWcsIlVuZXhwZWN0ZWQgY2hhcmFjdGVyOiAlY1xuIiwqcyk7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlzKys7CgkJCQlpZiAoMiE9c3NjYW5mKHMsIiVkLCVkLCIsJnR5cGUsJmxhc3Rtb2RpZmllZCkpIHsKCQkJCQlXQVJOKHJlZywiSGF2ZW4ndCB1bmRlcnN0b29kIHBvc3NpYmxlIHZhbHVlIGluIHwlc3wsIHNraXBwaW5nLlxuIiwqYnVmKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCS8qIHNraXAgdGhlIDIgLCAqLwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlpZiAoKDE8PHR5cGUpICYgVU5JQ09OVk1BU0spIHsKCQkJCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLChMUFdTVFIqKSZkYXRhKTsKCQkJCQlpZiAoZGF0YSkKCQkJCQkJbGVuID0gbHN0cmxlbjMyVygoTFBXU1RSKWRhdGEpKjIrMjsKCQkJCQllbHNlCQoJCQkJCQlsZW4gPSAwOwoJCQkJfSBlbHNlIHsKCQkJCQlsZW49c3RybGVuKHMpLzI7CgkJCQkJZGF0YSA9IChMUEJZVEUpeG1hbGxvYyhsZW4rMSk7CgkJCQkJZm9yIChpPTA7aTxsZW47aSsrKSB7CgkJCQkJCWRhdGFbaV09MDsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV09KCpzLScwJyk8PDQ7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nYScrJ1x4YScpPDw0OwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ0EnKydceGEnKTw8NDsKCQkJCQkJcysrOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXXw9KnMtJzAnOwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ2EnKydceGEnOwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ0EnKydceGEnOwoJCQkJCQlzKys7CgkJCQkJfQoJCQkJfQoJCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKGxwa2V5LG5hbWUsdHlwZSxkYXRhLGxlbixsYXN0bW9kaWZpZWQpOwoJCQl9CgkJfQoJCS8qIHJlYWQgdGhlIG5leHQgbGluZSAqLwoJCWlmICghX3dpbmVfcmVhZF9saW5lKEYsYnVmLGJ1ZmxlbikpCgkJCXJldHVybiAxOwogICAgfQogICAgcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3VicmVnKCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgRFdPUkQgb3B0ZmxhZyApCnsKCWludAl2ZXI7CgljaGFyCSpidWY7CglpbnQJYnVmbGVuOwoKCWJ1Zj14bWFsbG9jKDEwKTtidWZsZW49MTA7CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXNzY2FuZihidWYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAodmVyIT1SRUdJU1RSWV9TQVZFX1ZFUlNJT04pIHsKCQlUUkFDRShyZWcsIk9sZCBmb3JtYXQgKCVkKSByZWdpc3RyeSBmb3VuZCwgaWdub3JpbmcgaXQuIChidWYgd2FzICVzKS5cbiIsdmVyLGJ1Zik7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9sb2Fkc3Via2V5KEYsbHBrZXksMCwmYnVmLCZidWZsZW4sb3B0ZmxhZykpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglmcmVlKGJ1Zik7CglyZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfd2luZV9sb2FkcmVnKCBMUEtFWVNUUlVDVCBscGtleSwgY2hhciAqZm4sIERXT1JEIG9wdGZsYWcgKQp7CiAgICBGSUxFICpGOwoKICAgIFRSQUNFKHJlZywiKCVwLCVzLCVseClcbiIsbHBrZXksZGVidWdzdHJfYShmbiksb3B0ZmxhZyk7CgogICAgRiA9IGZvcGVuKGZuLCJyYiIpOwogICAgaWYgKEY9PU5VTEwpIHsKICAgICAgICBXQVJOKHJlZywiQ291bGRuJ3Qgb3BlbiAlcyBmb3IgcmVhZGluZzogJXNcbiIsZm4sc3RyZXJyb3IoZXJybm8pICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKCFfd2luZV9sb2Fkc3VicmVnKEYsbHBrZXksb3B0ZmxhZykpIHsKICAgICAgICBmY2xvc2UoRik7CiAgICAgICAgdW5saW5rKGZuKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmY2xvc2UoRik7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9jb3B5X3JlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9jb3B5X3JlZ2lzdHJ5KCBMUEtFWVNUUlVDVCBmcm9tLCBMUEtFWVNUUlVDVCB0byApCnsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJajsKCUxQS0VZVkFMVUUJdmFsZnJvbTsKCglmcm9tPWZyb20tPm5leHRzdWI7Cgl3aGlsZSAoZnJvbSkgewoJCWxweGtleSA9IF9maW5kX29yX2FkZF9rZXkodG8sc3RyZHVwVyhmcm9tLT5rZXluYW1lKSk7CgoJCWZvciAoaj0wO2o8ZnJvbS0+bnJvZnZhbHVlcztqKyspIHsKCQkJTFBXU1RSCW5hbWU7CgkJCUxQQllURQlkYXRhOwoKCQkJdmFsZnJvbSA9IGZyb20tPnZhbHVlcytqOwoJCQluYW1lPXZhbGZyb20tPm5hbWU7CgkJCWlmIChuYW1lKSBuYW1lPXN0cmR1cFcobmFtZSk7CgkJCWRhdGE9KExQQllURSl4bWFsbG9jKHZhbGZyb20tPmxlbik7CgkJCW1lbWNweShkYXRhLHZhbGZyb20tPmRhdGEsdmFsZnJvbS0+bGVuKTsKCgkJCV9maW5kX29yX2FkZF92YWx1ZSgKCQkJCWxweGtleSwKCQkJCW5hbWUsCgkJCQl2YWxmcm9tLT50eXBlLAoJCQkJZGF0YSwKCQkJCXZhbGZyb20tPmxlbiwKCQkJCXZhbGZyb20tPmxhc3Rtb2RpZmllZAoJCQkpOwoJCX0KCQlfY29weV9yZWdpc3RyeShmcm9tLGxweGtleSk7CgkJZnJvbSA9IGZyb20tPm5leHQ7Cgl9Cn0KCgovKiBXSU5ET1dTIDk1IFJFR0lTVFJZIExPQURFUiAqLwovKiAKICogU3RydWN0dXJlIG9mIGEgd2luOTUgcmVnaXN0cnkgZGF0YWJhc2UuCiAqIG1haW4gaGVhZGVyOgogKiAwIDoJIkNSRUciCS0gbWFnaWMKICogNCA6CURXT1JEIHZlcnNpb24KICogOCA6CURXT1JEIG9mZnNldF9vZl9SR0RCX3BhcnQKICogMEMuLjBGOgk/IChzb21lb25lIGZpbGwgaW4gcGxlYXNlKQogKiAxMDogIFdPUkQJbnVtYmVyIG9mIFJHREIgYmxvY2tzCiAqIDEyOiAgV09SRAk/CiAqIDE0OiAgV09SRAlhbHdheXMgMDAwMD8KICogMTY6ICBXT1JECWFsd2F5cyAwMDAxPwogKiAxOC4uMUY6CT8gKHNvbWVvbmUgZmlsbCBpbiBwbGVhc2UpCiAqCiAqIDIwOiBSR0tOX3NlY3Rpb246CiAqICAgaGVhZGVyOgogKiAJMCA6CQkiUkdLTiIJLSBtYWdpYwogKiAgICAgIDQgOiBEV09SRAlvZmZzZXQgdG8gZmlyc3QgUkdEQiBzZWN0aW9uCiAqICAgICAgOCA6IERXT1JECW9mZnNldCB0byB0aGUgcm9vdCByZWNvcmQKICogCUMuLjB4MUI6IAk/IChmaWxsIGluKQogKiAgICAgIDB4MjAgLi4uIG9mZnNldF9vZl9SR0RCX3BhcnQ6IERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZXMKICoKICogICBEaXNrIEtleSBFbnRyeSBTdHJ1Y3R1cmU6CiAqCTAwOiBEV09SRAktIEZyZWUgZW50cnkgaW5kaWNhdG9yKD8pCiAqCTA0OiBEV09SRAktIEhhc2ggPSBzdW0gb2YgYnl0ZXMgb2Yga2V5bmFtZQogKgkwODogRFdPUkQJLSBSb290IGtleSBpbmRpY2F0b3I/IHVua25vd24sIGJ1dCB1c3VhbGx5IDB4RkZGRkZGRkYgb24gd2luOTUgc3lzdGVtcwogKgkwQzogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgUHJldmlvdXNMZXZlbCBLZXkuCiAqCTEwOiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBOZXh0IFN1YmxldmVsIEtleS4KICoJMTQ6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIE5leHQgS2V5IChvbiBzYW1lIGxldmVsKS4KICogREtFUD4xODogV09SRAktIE5yLCBMb3cgU2lnbmlmaWNhbnQgcGFydC4KICoJMUE6IFdPUkQJLSBOciwgSGlnaCBTaWduaWZpY2FudCBwYXJ0LgogKgogKiBUaGUgZGlzayBhZGRyZXNzIGFsd2F5cyBwb2ludHMgdG8gdGhlIG5yIHBhcnQgb2YgdGhlIHByZXZpb3VzIGtleSBlbnRyeSAKICogb2YgdGhlIHJlZmVyZW5jZWQga2V5LiBEb24ndCBhc2sgbWUgd2h5LCBvciBldmVuIGlmIEkgZ290IHRoaXMgY29ycmVjdAogKiBmcm9tIHN0YXJpbmcgYXQgMWtnIG9mIGhleGR1bXBzLiAoREtFUCkKICoKICogVGhlIEhpZ2ggc2lnbmlmaWNhbnQgcGFydCBvZiB0aGUgc3RydWN0dXJlIHNlZW1zIHRvIGVxdWFsIHRoZSBudW1iZXIKICogb2YgdGhlIFJHREIgc2VjdGlvbi4gVGhlIGxvdyBzaWduaWZpY2FudCBwYXJ0IGlzIGEgdW5pcXVlIElEIHdpdGhpbgogKiB0aGF0IFJHREIgc2VjdGlvbgogKgogKiBUaGVyZSBhcmUgdHdvIG1pbm9yIGNvcnJlY3Rpb25zIHRvIHRoZSBwb3NpdGlvbiBvZiB0aGF0IHN0cnVjdHVyZS4KICogMS4gSWYgdGhlIGFkZHJlc3MgaXMgeHh4MDE0IG9yIHh4eDAxOCBpdCB3aWxsIGJlIGFsaWduZWQgdG8geHh4MDFjIEFORCAKICogICAgdGhlIERLRSByZXJlYWQgZnJvbSB0aGVyZS4KICogMi4gSWYgdGhlIGFkZHJlc3MgaXMgeHh4RkZ4IGl0IHdpbGwgYmUgYWxpZ25lZCB0byAoeHh4KzEpMDAwLgogKiBDUFMgLSBJIGhhdmUgbm90IGV4cGVyaWVuY2VkIHRoZSBhYm92ZSBwaGVub21lbm9uIGluIG15IHJlZ2lzdHJ5IGZpbGVzCiAqCiAqIFJHREJfc2VjdGlvbjoKICogCTAwOgkJIlJHREIiCS0gbWFnaWMKICoJMDQ6IERXT1JECW9mZnNldCB0byBuZXh0IFJHREIgc2VjdGlvbgogKgkwODogRFdPUkQJPwogKgkwQzogV09SRAlhbHdheXMgMDAwZD8KICoJMEU6IFdPUkQJUkdEQiBibG9jayBudW1iZXIKICoJMTA6CURXT1JECT8gKGVxdWFscyB2YWx1ZSBhdCBvZmZzZXQgNCAtIHZhbHVlIGF0IG9mZnNldCA4KQogKgkxNC4uMUY6CQk/CiAqCTIwLi4uLi46CWRpc2sga2V5cwogKgogKiBkaXNrIGtleToKICogCTAwOiAJRFdPUkQJbmV4dGtleW9mZnNldAktIG9mZnNldCB0byB0aGUgbmV4dCBkaXNrIGtleSBzdHJ1Y3R1cmUKICoJMDg6IAlXT1JECW5yTFMJCS0gbG93IHNpZ25pZmljYW50IHBhcnQgb2YgTlIKICoJMEE6IAlXT1JECW5ySFMJCS0gaGlnaCBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBDOiAJRFdPUkQJYnl0ZXN1c2VkCS0gYnl0ZXMgdXNlZCBpbiB0aGlzIHN0cnVjdHVyZS4KICoJMTA6IAlXT1JECW5hbWVfbGVuCS0gbGVuZ3RoIG9mIG5hbWUgaW4gYnl0ZXMuIHdpdGhvdXQgXDAKICoJMTI6IAlXT1JECW5yX29mX3ZhbHVlcwktIG51bWJlciBvZiB2YWx1ZXMuCiAqCTE0OiAJY2hhcgluYW1lW25hbWVfbGVuXQktIG5hbWUgc3RyaW5nLiBObyBcMC4KICoJMTQrbmFtZV9sZW46IGRpc2sgdmFsdWVzCiAqCW5leHRrZXlvZmZzZXQ6IC4uLiBuZXh0IGRpc2sga2V5CiAqCiAqIGRpc2sgdmFsdWU6CiAqCTAwOglEV09SRAl0eXBlCQktIHZhbHVlIHR5cGUgKGhtbSwgY291bGQgYmUgV09SRCB0b28pCiAqCTA0OglEV09SRAkJCS0gdW5rbm93biwgdXN1YWxseSAwCiAqCTA4OglXT1JECW5hbWVsZW4JCS0gbGVuZ3RoIG9mIE5hbWUuIDAgbWVhbnMgbmFtZT1OVUxMCiAqCTBDOglXT1JECWRhdGFsZW4JCS0gbGVuZ3RoIG9mIERhdGEuCiAqCTEwOgljaGFyCW5hbWVbbmFtZWxlbl0JLSBuYW1lLCBubyBcMAogKgkxMCtuYW1lbGVuOiBCWVRFCWRhdGFbZGF0YWxlbl0gLSBkYXRhLCB3aXRob3V0IFwwIGlmIHN0cmluZwogKgkxMCtuYW1lbGVuK2RhdGFsZW46IG5leHQgdmFsdWVzIG9yIGRpc2sga2V5CiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuckhTIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKiByZXBlYXQgdW50aWwgZW5kIG9mIGZpbGUuCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgdmFsdWUgYXQgb2Zmc2V0CiAqIDEwIGVxdWFscyB0aGUgdmFsdWUgYXQgb2Zmc2V0IDQgbWludXMgdGhlIHZhbHVlIGF0IG9mZnNldCA4LiBJIGhhdmUgbm8KICogaWRlYSBhdCB0aGUgbW9tZW50IHdoYXQgdGhpcyBtZWFucy4gIChLZXZpbiBDb3plbnMpCiAqCiAqIEZJWE1FOiB0aGlzIGRlc2NyaXB0aW9uIG5lZWRzIHNvbWUgc2VyaW91cyBoZWxwLCB5ZXMuCiAqLwoKc3RydWN0CV93OTVrZXl2YWx1ZSB7Cgl1bnNpZ25lZCBsb25nCQl0eXBlOwoJdW5zaWduZWQgc2hvcnQJCWRhdGFsZW47CgljaGFyCQkJKm5hbWU7Cgl1bnNpZ25lZCBjaGFyCQkqZGF0YTsKCXVuc2lnbmVkIGxvbmcJCXgxOwoJaW50CQkJbGFzdG1vZGlmaWVkOwp9OwoKc3RydWN0IAlfdzk1a2V5IHsKCWNoYXIJCQkqbmFtZTsKCWludAkJCW5yb2Z2YWxzOwoJc3RydWN0CV93OTVrZXl2YWx1ZQkqdmFsdWVzOwoJc3RydWN0IF93OTVrZXkJCSpwcmV2bHZsOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0c3ViOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0Owp9OwoKCnN0cnVjdCBfdzk1X2luZm8gewogIGNoYXIgKnJna25idWZmZXI7CiAgaW50ICByZ2tuc2l6ZTsKICBjaGFyICpyZ2RiYnVmZmVyOwogIGludCAgcmdkYnNpemU7CiAgaW50ICBkZXB0aDsKICBpbnQgIGxhc3Rtb2RpZmllZDsKfTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfcHJvY2Vzc0tleSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgX3c5NV9wcm9jZXNzS2V5ICggTFBLRVlTVFJVQ1QgbHBrZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuckxTLCBpbnQgbnJNUywgc3RydWN0IF93OTVfaW5mbyAqaW5mbyApCgp7CiAgLyogRGlzayBLZXkgSGVhZGVyIHN0cnVjdHVyZSAoUkdEQiBwYXJ0KSAqLwoJc3RydWN0CWRraCB7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nCQluZXh0a2V5b2ZmOyAKCQl1bnNpZ25lZCBzaG9ydAkJbnJMUzsKCQl1bnNpZ25lZCBzaG9ydAkJbnJNUzsKCQl1bnNpZ25lZCBsb25nCQlieXRlc3VzZWQ7CgkJdW5zaWduZWQgc2hvcnQJCWtleW5hbWVsZW47CgkJdW5zaWduZWQgc2hvcnQJCXZhbHVlczsKCQl1bnNpZ25lZCBsb25nCQl4eDE7CgkJLyoga2V5bmFtZSAqLwoJCS8qIGRpc2sga2V5IHZhbHVlcyBvciBub3RoaW5nICovCgl9OwoJLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlICovCglzdHJ1Y3QJZGt2IHsKCQl1bnNpZ25lZCBsb25nCQl0eXBlOwoJCXVuc2lnbmVkIGxvbmcJCXgxOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxuYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxkYXRhbGVuOwoJCS8qIHZhbG5hbWUsIHZhbGRhdGEgKi8KCX07CgoJCglzdHJ1Y3QJZGtoIGRraDsKCWludAlieXRlc3JlYWQgPSAwOwoJY2hhciAgICAqcmdkYmRhdGEgPSBpbmZvLT5yZ2RiYnVmZmVyOwoJaW50ICAgICBuYnl0ZXMgPSBpbmZvLT5yZ2Ric2l6ZTsKCWNoYXIgICAgKmN1cmRhdGEgPSByZ2RiZGF0YTsKCWNoYXIgICAgKmVuZCA9IHJnZGJkYXRhICsgbmJ5dGVzOwoJaW50ICAgICBvZmZfbmV4dF9yZ2RiOwoJY2hhciAgICAqbmV4dCA9IHJnZGJkYXRhOwoJaW50ICAgICBucmdkYiwgaTsKCUxQS0VZU1RSVUNUCWxweGtleTsKCQoJZG8gewoJICBjdXJkYXRhID0gbmV4dDsKCSAgaWYgKHN0cm5jbXAoY3VyZGF0YSwgIlJHREIiLCA0KSkgcmV0dXJuIChOVUxMKTsKCSAgICAKCSAgbWVtY3B5KCZvZmZfbmV4dF9yZ2RiLGN1cmRhdGErNCw0KTsKCSAgbmV4dCA9IGN1cmRhdGEgKyBvZmZfbmV4dF9yZ2RiOwoJICBucmdkYiA9IChpbnQpICooKHNob3J0ICopY3VyZGF0YSArIDcpOwoKCX0gd2hpbGUgKG5yZ2RiICE9IG5yTVMgJiYgKG5leHQgPCBlbmQpKTsKCgkvKiBjdXJkYXRhIG5vdyBwb2ludHMgdG8gdGhlIHN0YXJ0IG9mIHRoZSByaWdodCBSR0RCIHNlY3Rpb24gKi8KCWN1cmRhdGEgKz0gMHgyMDsKCiNkZWZpbmUgWFJFQUQod2hlcmV0byxsZW4pIFwKCWlmICgoY3VyZGF0YSArIGxlbikgPGVuZCkge1wKCQltZW1jcHkod2hlcmV0byxjdXJkYXRhLGxlbik7XAoJCWN1cmRhdGErPWxlbjtcCgkJYnl0ZXNyZWFkKz1sZW47XAoJfQoKCXdoaWxlIChjdXJkYXRhIDwgbmV4dCkgewoJICBzdHJ1Y3QJZGtoICp4ZGtoID0gY3VyZGF0YTsKCgkgIGJ5dGVzcmVhZCArPSBzaXplb2YoZGtoKTsgLyogRklYTUUuLi4gbmV4dGtleW9mZj8gKi8KCSAgaWYgKHhka2gtPm5yTFMgPT0gbnJMUykgewoJICAJbWVtY3B5KCZka2gseGRraCxzaXplb2YoZGtoKSk7CgkgIAljdXJkYXRhICs9IHNpemVvZihka2gpOwoJICAJYnJlYWs7CgkgIH0KCSAgY3VyZGF0YSArPSB4ZGtoLT5uZXh0a2V5b2ZmOwoJfTsKCglpZiAoZGtoLm5yTFMgIT0gbnJMUykgcmV0dXJuIChOVUxMKTsKCglpZiAobnJnZGIgIT0gZGtoLm5yTVMpCgkgIHJldHVybiAoTlVMTCk7CgogICAgICAgIGFzc2VydCgoZGtoLmtleW5hbWVsZW48MikgfHwgY3VyZGF0YVswXSk7CglscHhrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxzdHJjdnRBMlcoY3VyZGF0YSwgZGtoLmtleW5hbWVsZW4pKTsKCWN1cmRhdGEgKz0gZGtoLmtleW5hbWVsZW47CgoJZm9yIChpPTA7aTwgZGtoLnZhbHVlczsgaSsrKSB7CgkgIHN0cnVjdCBka3YgZGt2OwoJICBMUEJZVEUgZGF0YTsKCSAgaW50IGxlbjsKCSAgTFBXU1RSIG5hbWU7CgoJICBYUkVBRCgmZGt2LHNpemVvZihka3YpKTsKCgkgIG5hbWUgPSBzdHJjdnRBMlcoY3VyZGF0YSwgZGt2LnZhbG5hbWVsZW4pOwoJICBjdXJkYXRhICs9IGRrdi52YWxuYW1lbGVuOwoKCSAgaWYgKCgxIDw8IGRrdi50eXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkgICAgZGF0YSA9IChMUEJZVEUpIHN0cmN2dEEyVyhjdXJkYXRhLCBka3YudmFsZGF0YWxlbik7CgkgICAgbGVuID0gMiooZGt2LnZhbGRhdGFsZW4gKyAxKTsKCSAgfSBlbHNlIHsKCSAgICAvKiBJIGRvbid0IHRoaW5rIHdlIHdhbnQgdG8gTlVMTCB0ZXJtaW5hdGUgYWxsIGRhdGEgKi8KCSAgICBkYXRhID0geG1hbGxvYyhka3YudmFsZGF0YWxlbik7CgkgICAgbWVtY3B5IChkYXRhLCBjdXJkYXRhLCBka3YudmFsZGF0YWxlbik7CgkgICAgbGVuID0gZGt2LnZhbGRhdGFsZW47CgkgIH0KCgkgIGN1cmRhdGEgKz0gZGt2LnZhbGRhdGFsZW47CgkgIAoJICBfZmluZF9vcl9hZGRfdmFsdWUoCgkJCSAgICAgbHB4a2V5LAoJCQkgICAgIG5hbWUsCgkJCSAgICAgZGt2LnR5cGUsCgkJCSAgICAgZGF0YSwKCQkJICAgICBsZW4sCgkJCSAgICAgaW5mby0+bGFzdG1vZGlmaWVkCgkJCSAgICAgKTsKCX0KCXJldHVybiAobHB4a2V5KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X3dhbGtyZ2tuIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93OTVfd2Fsa3Jna24oIExQS0VZU1RSVUNUIHByZXZrZXksIGNoYXIgKm9mZiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBfdzk1X2luZm8gKmluZm8gKQoKewogIC8qIERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZSAoUkdLTiBwYXJ0KSAqLwogIHN0cnVjdAlka2UgewogICAgdW5zaWduZWQgbG9uZwkJeDE7CiAgICB1bnNpZ25lZCBsb25nCQl4MjsKICAgIHVuc2lnbmVkIGxvbmcJCXgzOy8qdXN1YWxseSAweEZGRkZGRkZGICovCiAgICB1bnNpZ25lZCBsb25nCQlwcmV2bHZsOwogICAgdW5zaWduZWQgbG9uZwkJbmV4dHN1YjsKICAgIHVuc2lnbmVkIGxvbmcJCW5leHQ7CiAgICB1bnNpZ25lZCBzaG9ydAkJbnJMUzsKICAgIHVuc2lnbmVkIHNob3J0CQluck1TOwogIH0gKmRrZSA9IChzdHJ1Y3QgZGtlICopb2ZmOwogIExQS0VZU1RSVUNUICBscHhrZXk7CgogIGlmIChka2UgPT0gTlVMTCkgewogICAgZGtlID0gKHN0cnVjdCBka2UgKikgKChjaGFyICopaW5mby0+cmdrbmJ1ZmZlcik7CiAgfQoKICBscHhrZXkgPSBfdzk1X3Byb2Nlc3NLZXkocHJldmtleSwgZGtlLT5uckxTLCBka2UtPm5yTVMsIGluZm8pOwogIC8qIFhYWCA8LS0gVGhpcyBpcyBhIGhhY2sqLwogIGlmICghbHB4a2V5KSB7CiAgICBscHhrZXkgPSBwcmV2a2V5OwogIH0KCiAgaWYgKGRrZS0+bmV4dHN1YiAhPSAtMSAmJiAKICAgICAgKChka2UtPm5leHRzdWIgLSAweDIwKSA8IGluZm8tPnJna25zaXplKSAKICAgICAgJiYgKGRrZS0+bmV4dHN1YiA+IDB4MjApKSB7CiAgICAKICAgIF93OTVfd2Fsa3Jna24obHB4a2V5LCAKCQkgIGluZm8tPnJna25idWZmZXIgKyBka2UtPm5leHRzdWIgLSAweDIwLCAKCQkgIGluZm8pOwogIH0KICAKICBpZiAoZGtlLT5uZXh0ICE9IC0xICYmIAogICAgICAoKGRrZS0+bmV4dCAtIDB4MjApIDwgaW5mby0+cmdrbnNpemUpICYmIAogICAgICAoZGtlLT5uZXh0ID4gMHgyMCkpIHsKICAgIF93OTVfd2Fsa3Jna24ocHJldmtleSwgIAoJCSAgaW5mby0+cmdrbmJ1ZmZlciArIGRrZS0+bmV4dCAtIDB4MjAsCgkJICBpbmZvKTsKICB9CgogIHJldHVybjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93OTVfbG9hZHJlZyggY2hhciogZm4sIExQS0VZU1RSVUNUIGxwa2V5ICkKewoJSEZJTEUzMgkJaGZkOwoJY2hhcgkJbWFnaWNbNV07Cgl1bnNpZ25lZCBsb25nCXdoZXJlLHZlcnNpb24scmdkYnNlY3Rpb24sZW5kOwoJc3RydWN0ICAgICAgICAgIF93OTVfaW5mbyBpbmZvOwoJT0ZTVFJVQ1QJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZkaW5mbzsKCglUUkFDRShyZWcsIkxvYWRpbmcgV2luOTUgcmVnaXN0cnkgZGF0YWJhc2UgJyVzJ1xuIixmbik7CgloZmQ9T3BlbkZpbGUzMihmbiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmZD09SEZJTEVfRVJST1IzMikKCQlyZXR1cm47CgltYWdpY1s0XT0wOwoJaWYgKDQhPV9scmVhZDMyKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJDUkVHIikpIHsKCQlXQVJOKHJlZywiJXMgaXMgbm90IGEgdzk1IHJlZ2lzdHJ5LlxuIixmbik7CgkJcmV0dXJuOwoJfQoJaWYgKDQhPV9scmVhZDMyKGhmZCwmdmVyc2lvbiw0KSkKCQlyZXR1cm47CglpZiAoNCE9X2xyZWFkMzIoaGZkLCZyZ2Ric2VjdGlvbiw0KSkKCQlyZXR1cm47CglpZiAoLTE9PV9sbHNlZWszMihoZmQsMHgyMCxTRUVLX1NFVCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZDMyKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJSR0tOIikpIHsKCQlXQVJOKHJlZywgInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJXNcbiIsIG1hZ2ljKTsKCQlyZXR1cm47Cgl9CgoJLyogU1RFUCAxOiBLZXlsaW5rIHN0cnVjdHVyZXMgKi8KCWlmICgtMT09X2xsc2VlazMyKGhmZCwweDQwLFNFRUtfU0VUKSkKCQlyZXR1cm47Cgl3aGVyZQk9IDB4NDA7CgllbmQJPSByZ2Ric2VjdGlvbjsKCglpbmZvLnJna25zaXplID0gZW5kIC0gd2hlcmU7CglpbmZvLnJna25idWZmZXIgPSAoY2hhciopeG1hbGxvYyhpbmZvLnJna25zaXplKTsKCWlmIChpbmZvLnJna25zaXplICE9IF9scmVhZDMyKGhmZCxpbmZvLnJna25idWZmZXIsaW5mby5yZ2tuc2l6ZSkpCgkJcmV0dXJuOwoKCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGZkLCZoZmRpbmZvKSkKCQlyZXR1cm47CgoJZW5kID0gaGZkaW5mby5uRmlsZVNpemVMb3c7CglpbmZvLmxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZkaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CgoJaWYgKC0xPT1fbGxzZWVrMzIoaGZkLHJnZGJzZWN0aW9uLFNFRUtfU0VUKSkKCQlyZXR1cm47CgoJaW5mby5yZ2RiYnVmZmVyID0gKGNoYXIqKXhtYWxsb2MoZW5kLXJnZGJzZWN0aW9uKTsKCWluZm8ucmdkYnNpemUgPSBlbmQgLSByZ2Ric2VjdGlvbjsKCglpZiAoaW5mby5yZ2Ric2l6ZSAhPV9scmVhZDMyKGhmZCxpbmZvLnJnZGJidWZmZXIsaW5mby5yZ2Ric2l6ZSkpCgkJcmV0dXJuOwoJX2xjbG9zZTMyKGhmZCk7CgoJX3c5NV93YWxrcmdrbihscGtleSwgTlVMTCwgJmluZm8pOwoKCWZyZWUgKGluZm8ucmdkYmJ1ZmZlcik7CglmcmVlIChpbmZvLnJna25idWZmZXIpOwp9CgoKLyogV0lORE9XUyAzMSBSRUdJU1RSWSBMT0FERVIsIHN1cHBsaWVkIGJ5IFRvciBTavh3YWxsLCB0b3JAc24ubm8gKi8KCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VlZGVkIGJ5IGEgd29yZCBhdCBvZmZzZXQtMi4gVGhpcyB3b3JkCiAgICBoYXMgdGhlIHZhbHVlICgyKmluZGV4KSsxLCB3aGVyZSBpbmRleCBpcyB0aGUgcmVmZXJyaW5nIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGluIHRoZSB0YWJsZS4gSSBoYXZlIG5vIHN1Z2dlc3Rpb24gZm9yIHRoZSAyKiBhbmQgdGhlICsxLgogICAgRm9sbG93aW5nIHRoZSB3b3JkLCB0aGVyZSBhcmUgTiBieXRlcyBvZiBkYXRhLCBhcyBwZXIgdGhlIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGxlbmd0aC4gVGhlIG9mZnNldCBvZiB0aGUga2V5ZW50L3ZhbGVudCBlbnRyeSBpcyBmcm9tIHRoZSBzdGFydAogICAgb2YgdGhlIHRleHQgdGFibGUgdG8gdGhlIGZpcnN0IGRhdGEgYnl0ZS4KCiAgICBUaGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbSBNaWNyb3NvZnQuIFRoZSBkYXRhIGZvcm1hdCBpcwogICAgZGVkdWNlZCBmcm9tIHRoZSByZWcuZGF0IGZpbGUgYnkgbWUuIE1pc3Rha2VzIG1heQogICAgaGF2ZSBiZWVuIG1hZGUuIEkgY2xhaW0gbm8gcmlnaHRzIGFuZCBnaXZlIG5vIGd1YXJhbnRlZXMgZm9yIHRoaXMgcHJvZ3JhbS4KCiAgICBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vCiovCgovKiByZWcuZGF0IGhlYWRlciBmb3JtYXQgKi8Kc3RydWN0IF93MzFfaGVhZGVyIHsKCWNoYXIJCWNvb2tpZVs4XTsJLyogJ1NIQ0MzLjEwJyAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYxOwkvKiBvZmZzZXQgb2YgaGFzaCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYyOwkvKiBvZmZzZXQgb2YgaW5kZXggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFiY250OwkJLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gaW5kZXggdGFibGUgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dG9mZjsJLyogb2Zmc2V0IG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0c2l6ZTsJLyogYnl0ZSBzaXplIG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgc2hvcnQJaGFzaHNpemU7CS8qIGhhc2ggc2l6ZSAqLwoJdW5zaWduZWQgc2hvcnQJZnJlZWlkeDsJLyogZnJlZSBpbmRleCAqLwp9OwoKLyogZ2VuZXJpYyBmb3JtYXQgb2YgdGFibGUgZW50cmllcyAqLwpzdHJ1Y3QgX3czMV90YWJlbnQgewoJdW5zaWduZWQgc2hvcnQgdzAsIHcxLCB3MiwgdzM7Cn07CgovKiBkaXJlY3RvcnkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9kaXJlbnQgewoJdW5zaWduZWQgc2hvcnQJc2libGluZ19pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHNpYmxpbmcgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAljaGlsZF9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGNoaWxkIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJa2V5X2lkeDsJLyogdGFibGUgaW5kZXggb2Yga2V5IGtleWVudCAqLwoJdW5zaWduZWQgc2hvcnQJdmFsdWVfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiB2YWx1ZSB2YWxlbnQgKi8KfTsKCi8qIGtleSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2tleWVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogdmFsdWUgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV92YWxlbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdG8gZGlzcGxheSBhIGRpcmVjdG9yeSB0cmVlICovCnZvaWQKX193MzFfZHVtcHRyZWUoCXVuc2lnbmVkIHNob3J0IGlkeCwKCQl1bnNpZ25lZCBjaGFyICp0eHQsCgkJc3RydWN0IF93MzFfdGFiZW50ICp0YWIsCgkJc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAoJCUxQS0VZU1RSVUNUCWxwa2V5LAoJCXRpbWVfdAkJbGFzdG1vZGlmaWVkLAoJCWludAkJbGV2ZWwKKSB7CglzdHJ1Y3QgX3czMV9kaXJlbnQJKmRpcjsKCXN0cnVjdCBfdzMxX2tleWVudAkqa2V5OwoJc3RydWN0IF93MzFfdmFsZW50CSp2YWw7CglMUEtFWVNUUlVDVAkJeGxwa2V5ID0gTlVMTDsKCUxQV1NUUgkJCW5hbWUsdmFsdWU7CglzdGF0aWMgY2hhcgkJdGFpbFs0MDBdOwoKCXdoaWxlIChpZHghPTApIHsKCQlkaXI9KHN0cnVjdCBfdzMxX2RpcmVudCopJnRhYltpZHhdOwoKCQlpZiAoZGlyLT5rZXlfaWR4KSB7CgkJCWtleSA9IChzdHJ1Y3QgX3czMV9rZXllbnQqKSZ0YWJbZGlyLT5rZXlfaWR4XTsKCgkJCW1lbWNweSh0YWlsLCZ0eHRba2V5LT5zdHJpbmdfb2ZmXSxrZXktPmxlbmd0aCk7CgkJCXRhaWxba2V5LT5sZW5ndGhdPSdcMCc7CgkJCS8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUgCgkJCSAqIHRvcGxldmVsIHN1YmRpcmVjdG9yeSBiZWxvbmcgdG8gXFNPRlRXQVJFXENsYXNzZXMKCQkJICovCgkJCWlmICghbGV2ZWwgJiYgIWxzdHJjbXAzMkEodGFpbCwiLmNsYXNzZXMiKSkgewoJCQkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLGxwa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQkJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJCQkJY29udGludWU7CgkJCX0KCQkJbmFtZT1zdHJkdXBBMlcodGFpbCk7CgoJCQl4bHBrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxuYW1lKTsKCgkJCS8qIG9ubHkgYWRkIGlmIGxlYWYgbm9kZSBvciB2YWx1ZWQgbm9kZSAqLwoJCQlpZiAoZGlyLT52YWx1ZV9pZHghPTB8fGRpci0+Y2hpbGRfaWR4PT0wKSB7CgkJCQlpZiAoZGlyLT52YWx1ZV9pZHgpIHsKCQkJCQl2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CgkJCQkJbWVtY3B5KHRhaWwsJnR4dFt2YWwtPnN0cmluZ19vZmZdLHZhbC0+bGVuZ3RoKTsKCQkJCQl0YWlsW3ZhbC0+bGVuZ3RoXT0nXDAnOwoJCQkJCXZhbHVlPXN0cmR1cEEyVyh0YWlsKTsKCQkJCQlfZmluZF9vcl9hZGRfdmFsdWUoeGxwa2V5LE5VTEwsUkVHX1NaLChMUEJZVEUpdmFsdWUsbHN0cmxlbjMyVyh2YWx1ZSkqMisyLGxhc3Rtb2RpZmllZCk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQlUUkFDRShyZWcsInN0cmFuZ2U6IG5vIGRpcmVjdG9yeSBrZXkgbmFtZSwgaWR4PSUwNHhcbiIsIGlkeCk7CgkJfQoJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCx4bHBrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzMxX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kdm9pZCBfdzMxX2xvYWRyZWcoKSB7CglIRklMRTMyCQkJaGY7CglzdHJ1Y3QgX3czMV9oZWFkZXIJaGVhZDsKCXN0cnVjdCBfdzMxX3RhYmVudAkqdGFiOwoJdW5zaWduZWQgY2hhcgkJKnR4dDsKCWludAkJCWxlbjsKCU9GU1RSVUNUCQlvZnM7CglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmluZm87Cgl0aW1lX3QJCQlsYXN0bW9kaWZpZWQ7CglMUEtFWVNUUlVDVAkJbHBrZXk7CgoJVFJBQ0UocmVnLCIodm9pZClcbiIpOwoKCWhmID0gT3BlbkZpbGUzMigicmVnLmRhdCIsJm9mcyxPRl9SRUFEKTsKCWlmIChoZj09SEZJTEVfRVJST1IzMikKCQlyZXR1cm47CgoJLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCglpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQzMihoZiwmaGVhZCxzaXplb2YoaGVhZCkpKSB7CgkJRVJSKHJlZywgInJlZy5kYXQgaXMgdG9vIHNob3J0LlxuIik7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSE9MCkgewoJCUVSUihyZWcsICJyZWcuZGF0IGhhcyBiYWQgc2lnbmF0dXJlLlxuIik7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CgoJbGVuID0gaGVhZC50YWJjbnQgKiBzaXplb2Yoc3RydWN0IF93MzFfdGFiZW50KTsKCS8qIHJlYWQgYW5kIGR1bXAgaW5kZXggdGFibGUgKi8KCXRhYiA9IHhtYWxsb2MobGVuKTsKCWlmIChsZW4hPV9scmVhZDMyKGhmLHRhYixsZW4pKSB7CgkJRVJSKHJlZywiY291bGRuJ3QgcmVhZCAlZCBieXRlcy5cbiIsbGVuKTsgCgkJZnJlZSh0YWIpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoKCS8qIHJlYWQgdGV4dCAqLwoJdHh0ID0geG1hbGxvYyhoZWFkLnRleHRzaXplKTsKCWlmICgtMT09X2xsc2VlazMyKGhmLGhlYWQudGV4dG9mZixTRUVLX1NFVCkpIHsKCQlFUlIocmVnLCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoJaWYgKGhlYWQudGV4dHNpemUhPV9scmVhZDMyKGhmLHR4dCxoZWFkLnRleHRzaXplKSkgewoJCUVSUihyZWcsInRleHRibG9jayB0b28gc2hvcnQgKCVkIGluc3RlYWQgb2YgJWxkKS5cbiIsbGVuLGhlYWQudGV4dHNpemUpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoKCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGYsJmhmaW5mbykpIHsKCQlFUlIocmVnLCJHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CglsYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CglscGtleSA9IGxvb2t1cF9oa2V5KEhLRVlfQ0xBU1NFU19ST09UKTsKCV9fdzMxX2R1bXB0cmVlKHRhYlswXS53MSx0eHQsdGFiLCZoZWFkLGxwa2V5LGxhc3Rtb2RpZmllZCwwKTsKCWZyZWUodGFiKTsKCWZyZWUodHh0KTsKCV9sY2xvc2UzMihoZik7CglyZXR1cm47Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEVMTF9Mb2FkUmVnaXN0cnkgW0ludGVybmFsXQogKi8Kdm9pZCBTSEVMTF9Mb2FkUmVnaXN0cnkoIHZvaWQgKQp7CgljaGFyCSpmbjsKCXN0cnVjdAlwYXNzd2QJKnB3ZDsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCglUUkFDRShyZWcsIih2b2lkKVxuIik7CgoJLyogTG9hZCB3aW5kb3dzIDMuMSBlbnRyaWVzICovCglfdzMxX2xvYWRyZWcoKTsKCS8qIExvYWQgd2luZG93cyA5NSBlbnRyaWVzICovCglfdzk1X2xvYWRyZWcoIkM6XFxzeXN0ZW0uMXN0IiwJbG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSk7Cglfdzk1X2xvYWRyZWcoInN5c3RlbS5kYXQiLAlsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpKTsKCV93OTVfbG9hZHJlZygidXNlci5kYXQiLAlsb29rdXBfaGtleShIS0VZX1VTRVJTKSk7CgoJLyogdGhlIGdsb2JhbCB1c2VyIGRlZmF1bHQgaXMgbG9hZGVkIHVuZGVyIEhLRVlfVVNFUlNcXC5EZWZhdWx0ICovCglSZWdDcmVhdGVLZXkxNihIS0VZX1VTRVJTLCIuRGVmYXVsdCIsJmhrZXkpOwoJbHBrZXkgPSBsb29rdXBfaGtleShoa2V5KTsKICAgICAgICBpZighbHBrZXkpCiAgICAgICAgICAgIFdBUk4ocmVnLCJDb3VsZCBub3QgY3JlYXRlIGdsb2JhbCB1c2VyIGRlZmF1bHQga2V5XG4iKTsKCV93aW5lX2xvYWRyZWcobHBrZXksU0FWRV9VU0VSU19ERUZBVUxULDApOwoKCS8qIEhLRVlfVVNFUlNcXC5EZWZhdWx0IGlzIGNvcGllZCB0byBIS0VZX0NVUlJFTlRfVVNFUiAqLwoJX2NvcHlfcmVnaXN0cnkobHBrZXksbG9va3VwX2hrZXkoSEtFWV9DVVJSRU5UX1VTRVIpKTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKCS8qIHRoZSBnbG9iYWwgbWFjaGluZSBkZWZhdWx0cyAqLwoJX3dpbmVfbG9hZHJlZyhsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpLFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxULDApOwoKCS8qIGxvYWQgdGhlIHVzZXIgc2F2ZWQgcmVnaXN0cmllcyAqLwoKCS8qIEZJWE1FOiB1c2UgZ2V0ZW52KCJIT01FIikgb3IgZ2V0cHd1aWQoZ2V0dWlkKCkpLT5wd19kaXIgPz8gKi8KCglwd2Q9Z2V0cHd1aWQoZ2V0dWlkKCkpOwoJaWYgKHB3ZCE9TlVMTCAmJiBwd2QtPnB3X2RpciE9TlVMTCkgewoJCWZuPShjaGFyKil4bWFsbG9jKHN0cmxlbihwd2QtPnB3X2Rpcikrc3RybGVuKFdJTkVfUFJFRklYKStzdHJsZW4oU0FWRV9DVVJSRU5UX1VTRVIpKzIpOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwoJCV93aW5lX2xvYWRyZWcobG9va3VwX2hrZXkoSEtFWV9DVVJSRU5UX1VTRVIpLGZuLFJFR19PUFRJT05fVEFJTlRFRCk7CgkJZnJlZShmbik7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9NQUNISU5FKTsKCQlfd2luZV9sb2FkcmVnKGxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSksZm4sUkVHX09QVElPTl9UQUlOVEVEKTsKCQlmcmVlKGZuKTsKCX0gZWxzZQoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVkLlxuIixnZXR1aWQoKSk7CglpZiAoRVJST1JfU1VDQ0VTUz09UmVnQ3JlYXRlS2V5MTYoSEtFWV9DVVJSRU5UX1VTRVIsS0VZX1JFR0lTVFJZLCZoa2V5KSkgewoJCURXT1JECWp1bmssdHlwZSxsZW47CgkJY2hhcglkYXRhWzVdOwoKCQlsZW49NDsKCQlpZiAoKAlSZWdRdWVyeVZhbHVlRXgzMkEoCgkJCQloa2V5LAoJCQkJVkFMX1NBVkVVUERBVEVELAoJCQkJJmp1bmssCgkJCQkmdHlwZSwKCQkJCWRhdGEsCgkJCQkmbGVuCgkJCSkhPUVSUk9SX1NVQ0NFU1MpIHx8CgkJCXR5cGUgIT0gUkVHX1NaCgkJKQoJCQlSZWdTZXRWYWx1ZUV4MzJBKGhrZXksVkFMX1NBVkVVUERBVEVELDAsUkVHX1NaLCJ5ZXMiLDQpOwoJCVJlZ0Nsb3NlS2V5KGhrZXkpOwoJfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKiBBUEkgRlVOQ1RJT05TICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoKICogT3BlbiBLZXlzLgogKgogKiBBbGwgZnVuY3Rpb25zIGFyZSBzdHVicyB0byBSZWdPcGVuS2V5RXgzMlcgd2hlcmUgYWxsIHRoZQogKiBtYWdpYyBoYXBwZW5zLiAKICoKICogQ2FsbHBhdGg6CiAqIFJlZ09wZW5LZXkxNiAtPiBSZWdPcGVuS2V5MzJBIC0+IFJlZ09wZW5LZXlFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ09wZW5LZXkzMlcgICAtPiBSZWdPcGVuS2V5RXgzMlcgCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleUV4MzJXIFtBRFZBUEkzMi4xNTBdCiAqIE9wZW5zIHRoZSBzcGVjaWZpZWQga2V5CiAqCiAqIFVubGlrZSBSZWdDcmVhdGVLZXlFeCwgdGhpcyBkb2VzIG5vdCBjcmVhdGUgdGhlIGtleSBpZiBpdCBkb2VzIG5vdCBleGlzdC4KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5IFtJXSBOYW1lIG9mIHN1YmtleSB0byBvcGVuCiAqICAgIGR3UmVzZXJ2ZWQgW0ldIFJlc2VydmVkIC0gbXVzdCBiZSB6ZXJvCiAqICAgIHNhbURlc2lyZWQgW0ldIFNlY3VyaXR5IGFjY2VzcyBtYXNrCiAqICAgIHJldGtleSAgICAgW09dIEFkZHJlc3Mgb2YgaGFuZGxlIG9mIG9wZW4ga2V5CiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleUV4MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHU0FNIHNhbURlc2lyZWQsIExQSEtFWSByZXRrZXkgKQp7CglMUEtFWVNUUlVDVAlscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCiAgICBUUkFDRShyZWcsIigleCwlcywlbGQsJWx4LCVwKVxuIiwgaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGR3UmVzZXJ2ZWQsCiAgICAgICAgICBzYW1EZXNpcmVkLHJldGtleSk7CgogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBOZXh0S2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KSB7CiAgICAgICAgLyogRWl0aGVyIE5VTEwgb3IgcG9pbnRlciB0byBlbXB0eSBzdHJpbmcsIHNvIHJldHVybiBhIG5ldyBoYW5kbGUKICAgICAgICAgICB0byB0aGUgb3JpZ2luYWwgaGtleSAqLwogICAgICAgIGN1cnJlbnRoYW5kbGUgKz0gMjsKICAgICAgICBhZGRfaGFuZGxlKGN1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwogICAgICAgICpyZXRrZXk9Y3VycmVudGhhbmRsZTsKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAobHBzelN1YktleVswXSA9PSAnXFwnKSB7CiAgICAgICAgV0FSTihyZWcsIlN1YmtleSAlcyBtdXN0IG5vdCBiZWdpbiB3aXRoIGJhY2tzbGFzaC5cbiIsZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CiAgICAgICAgcmV0dXJuIEVSUk9SX0JBRF9QQVRITkFNRTsKICAgIH0KCglzcGxpdF9rZXlwYXRoKGxwc3pTdWJLZXksJndwcywmd3BjKTsKCWkgPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleSA9IGxwTmV4dEtleTsKCiAgICB3aGlsZSAod3BzW2ldKSB7CiAgICAgICAgbHB4a2V5PWxwTmV4dEtleS0+bmV4dHN1YjsKICAgICAgICB3aGlsZSAobHB4a2V5KSB7CiAgICAgICAgICAgIGlmICghbHN0cmNtcGkzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxweGtleT1scHhrZXktPm5leHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWxweGtleSkgewogICAgICAgICAgICBUUkFDRShyZWcsIkNvdWxkIG5vdCBmaW5kIHN1YmtleSAlc1xuIixkZWJ1Z3N0cl93KHdwc1tpXSkpOwogICAgICAgICAgICBGUkVFX0tFWV9QQVRIOwogICAgICAgICAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7CiAgICAgICAgfQogICAgICAgIGkrKzsKICAgICAgICBscE5leHRLZXkgPSBscHhrZXk7CiAgICB9CgogICAgY3VycmVudGhhbmRsZSArPSAyOwogICAgYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKICAgICpyZXRrZXkgPSBjdXJyZW50aGFuZGxlOwogICAgVFJBQ0UocmVnLCIgIFJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CiAgICBGUkVFX0tFWV9QQVRIOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXlFeDMyQSBbQURWQVBJMzIuMTQ5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXlFeDMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHU0FNIHNhbURlc2lyZWQsIExQSEtFWSByZXRrZXkgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVcgPSBzdHJkdXBBMlcobHBzelN1YktleSk7CiAgICBEV09SRCByZXQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVseCwlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGR3UmVzZXJ2ZWQsCiAgICAgICAgICBzYW1EZXNpcmVkLHJldGtleSk7CiAgICByZXQgPSBSZWdPcGVuS2V5RXgzMlcoIGhrZXksIGxwc3pTdWJLZXlXLCBkd1Jlc2VydmVkLCBzYW1EZXNpcmVkLCByZXRrZXkgKTsKICAgIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleTMyVyBbQURWQVBJMzIuMTUxXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkgdG8gb3BlbgogKiAgICByZXRrZXkgICAgIFtPXSBBZGRyZXNzIG9mIGhhbmRsZSBvZiBvcGVuIGtleQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0dXJuIFJlZ09wZW5LZXlFeDMyVyggaGtleSwgbHBzelN1YktleSwgMCwgS0VZX0FMTF9BQ0NFU1MsIHJldGtleSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5MzJBIFtBRFZBUEkzMi4xNDhdCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIERXT1JEIHJldDsKICAgIExQV1NUUiBscHN6U3ViS2V5VyA9IHN0cmR1cEEyVyhscHN6U3ViS2V5KTsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldCA9ICBSZWdPcGVuS2V5MzJXKCBoa2V5LCBscHN6U3ViS2V5VywgcmV0a2V5ICk7CiAgICBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXkxNiBbU0hFTEwuMV0gW0tFUk5FTC4yMTddCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0dXJuIFJlZ09wZW5LZXkzMkEoIGhrZXksIGxwc3pTdWJLZXksIHJldGtleSApOwp9CgoKLyogCiAqIENyZWF0ZSBrZXlzCiAqIAogKiBBbGwgdGhvc2UgZnVuY3Rpb25zIGNvbnZlcnQgdGhlaXIgcmVzcGVjdGl2ZSAKICogYXJndW1lbnRzIGFuZCBjYWxsIFJlZ0NyZWF0ZUtleUV4VyBhdCB0aGUgZW5kLgogKgogKiBXZSBzdGF5IGF3YXkgZnJvbSB0aGUgRXggZnVuY3Rpb25zIGFzIGxvbmcgYXMgcG9zc2libGUgYmVjYXVzZSB0aGVyZSBhcmUKICogZGlmZmVyZW5jZXMgaW4gdGhlIHJldHVybiB2YWx1ZXMKICoKICogQ2FsbHBhdGg6CiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdDcmVhdGVLZXlFeDMyQSBcCiAqIFJlZ0NyZWF0ZUtleTE2IC0+IFJlZ0NyZWF0ZUtleTMyQSAtPiBSZWdDcmVhdGVLZXkzMlcgICAtPiBSZWdDcmVhdGVLZXlFeDMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleUV4MzJXIFtBRFZBUEkzMi4xMzFdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgW0ldIEhhbmRsZSBvZiBhbiBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5ICAgW0ldIEFkZHJlc3Mgb2Ygc3Via2V5IG5hbWUKICogICAgZHdSZXNlcnZlZCAgIFtJXSBSZXNlcnZlZCAtIG11c3QgYmUgMAogKiAgICBscHN6Q2xhc3MgICAgW0ldIEFkZHJlc3Mgb2YgY2xhc3Mgc3RyaW5nCiAqICAgIGZkd09wdGlvbnMgICBbSV0gU3BlY2lhbCBvcHRpb25zIGZsYWcKICogICAgc2FtRGVzaXJlZCAgIFtJXSBEZXNpcmVkIHNlY3VyaXR5IGFjY2VzcwogKiAgICBscFNlY0F0dHJpYnMgW0ldIEFkZHJlc3Mgb2Yga2V5IHNlY3VyaXR5IHN0cnVjdHVyZQogKiAgICByZXRrZXkgICAgICAgW09dIEFkZHJlc3Mgb2YgYnVmZmVyIGZvciBvcGVuZWQgaGFuZGxlCiAqICAgIGxwRGlzcG9zICAgICBbT10gUmVjZWl2ZXMgUkVHX0NSRUFURURfTkVXX0tFWSBvciBSRUdfT1BFTkVEX0VYSVNUSU5HX0tFWQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleUV4MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdSZXNlcnZlZCwgTFBXU1RSIGxwc3pDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZmR3T3B0aW9ucywgUkVHU0FNIHNhbURlc2lyZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIGxwU2VjQXR0cmlicywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBIS0VZIHJldGtleSwgTFBEV09SRCBscERpc3BvcyApCnsKCUxQS0VZU1RSVUNUCSpscGxwUHJldktleSxscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCiAgICBUUkFDRShyZWcsIigleCwlcywlbGQsJXMsJWx4LCVseCwlcCwlcCwlcClcbiIsIGhrZXksCgkJZGVidWdzdHJfdyhscHN6U3ViS2V5KSwgZHdSZXNlcnZlZCwgZGVidWdzdHJfdyhscHN6Q2xhc3MpLAoJCWZkd09wdGlvbnMsIHNhbURlc2lyZWQsIGxwU2VjQXR0cmlicywgcmV0a2V5LCBscERpc3Bvcyk7CgogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgLyogQ2hlY2sgZm9yIHZhbGlkIG9wdGlvbnMgKi8KICAgIHN3aXRjaChmZHdPcHRpb25zKSB7CiAgICAgICAgY2FzZSBSRUdfT1BUSU9OX05PTl9WT0xBVElMRToKICAgICAgICBjYXNlIFJFR19PUFRJT05fVk9MQVRJTEU6CiAgICAgICAgY2FzZSBSRUdfT1BUSU9OX0JBQ0tVUF9SRVNUT1JFOgogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CiAgICB9CgogICAgLyogU2FtIGhhcyB0byBiZSBhIGNvbWJpbmF0aW9uIG9mIHRoZSBmb2xsb3dpbmcgKi8KICAgIGlmICghKHNhbURlc2lyZWQgJiAKICAgICAgICAgIChLRVlfQUxMX0FDQ0VTUyB8IEtFWV9DUkVBVEVfTElOSyB8IEtFWV9DUkVBVEVfU1VCX0tFWSB8IAogICAgICAgICAgIEtFWV9FTlVNRVJBVEVfU1VCX0tFWVMgfCBLRVlfRVhFQ1VURSB8IEtFWV9OT1RJRlkgfAogICAgICAgICAgIEtFWV9RVUVSWV9WQUxVRSB8IEtFWV9SRUFEIHwgS0VZX1NFVF9WQUxVRSB8IEtFWV9XUklURSkpKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCglpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KSB7CiAgICAgICAgICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CgkJYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKCQkqcmV0a2V5PWN1cnJlbnRoYW5kbGU7CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsICJSZXR1cm5pbmcgJXhcbiIsIGN1cnJlbnRoYW5kbGUpOwoJCWxwTmV4dEtleS0+ZmxhZ3N8PVJFR19PUFRJT05fVEFJTlRFRDsKCQlyZXR1cm4gRVJST1JfU1VDQ0VTUzsKCX0KCiAgICBpZiAobHBzelN1YktleVswXSA9PSAnXFwnKSB7CiAgICAgICAgV0FSTihyZWcsIlN1YmtleSAlcyBtdXN0IG5vdCBiZWdpbiB3aXRoIGJhY2tzbGFzaC5cbiIsZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CiAgICAgICAgcmV0dXJuIEVSUk9SX0JBRF9QQVRITkFNRTsKICAgIH0KCglzcGxpdF9rZXlwYXRoKGxwc3pTdWJLZXksJndwcywmd3BjKTsKCWkgCT0gMDsKCXdoaWxlICgoaTx3cGMpICYmICh3cHNbaV1bMF09PSdcMCcpKSBpKys7CglscHhrZXkJPSBscE5leHRLZXk7Cgl3aGlsZSAod3BzW2ldKSB7CgkJbHB4a2V5PWxwTmV4dEtleS0+bmV4dHN1YjsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCWlmICghbHN0cmNtcGkzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCQlicmVhazsKCQkJbHB4a2V5PWxweGtleS0+bmV4dDsKCQl9CgkJaWYgKCFscHhrZXkpCgkJCWJyZWFrOwoJCWkrKzsKCQlscE5leHRLZXkJPSBscHhrZXk7Cgl9CglpZiAobHB4a2V5KSB7CiAgICAgICAgICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CgkJYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKCQlscHhrZXktPmZsYWdzICB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCQlpZiAobHBEaXNwb3MpCgkJCSpscERpc3Bvcwk9IFJFR19PUEVORURfRVhJU1RJTkdfS0VZOwoJCUZSRUVfS0VZX1BBVEg7CgkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgl9CgoJLyogR29vZC4gIE5vdyB0aGUgaGFyZCBwYXJ0ICovCgl3aGlsZSAod3BzW2ldKSB7CgkJbHBscFByZXZLZXkJPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7CgkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCQlscHhrZXkJCT0gKmxwbHBQcmV2S2V5OwoJCX0KCQkqbHBscFByZXZLZXk9bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTsKCQlpZiAoISpscGxwUHJldktleSkgewoJCQlGUkVFX0tFWV9QQVRIOwogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRShyZWcsICJSZXR1cm5pbmcgT1VUT0ZNRU1PUllcbiIpOwoJCQlyZXR1cm4gRVJST1JfT1VUT0ZNRU1PUlk7CgkJfQoJCW1lbXNldCgqbHBscFByZXZLZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsIkFkZGluZyAlc1xuIiwgZGVidWdzdHJfdyh3cHNbaV0pKTsKCQkoKmxwbHBQcmV2S2V5KS0+a2V5bmFtZQk9IHN0cmR1cFcod3BzW2ldKTsKCQkoKmxwbHBQcmV2S2V5KS0+bmV4dAk9IE5VTEw7CgkJKCpscGxwUHJldktleSktPm5leHRzdWIJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT52YWx1ZXMJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5ucm9mdmFsdWVzID0gMDsKCQkoKmxwbHBQcmV2S2V5KS0+ZmxhZ3MgCT0gUkVHX09QVElPTl9UQUlOVEVEOwoJCWlmIChscHN6Q2xhc3MpCgkJCSgqbHBscFByZXZLZXkpLT5jbGFzcyA9IHN0cmR1cFcobHBzekNsYXNzKTsKCQllbHNlCgkJCSgqbHBscFByZXZLZXkpLT5jbGFzcyA9IE5VTEw7CgkJbHBOZXh0S2V5CT0gKmxwbHBQcmV2S2V5OwoJCWkrKzsKCX0KICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CglhZGRfaGFuZGxlKGN1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwoKCS8qRklYTUU6IGZsYWcgaGFuZGxpbmcgY29ycmVjdD8gKi8KCWxwTmV4dEtleS0+ZmxhZ3M9IGZkd09wdGlvbnMgfFJFR19PUFRJT05fVEFJTlRFRDsKCWlmIChscHN6Q2xhc3MpCgkJbHBOZXh0S2V5LT5jbGFzcyA9IHN0cmR1cFcobHBzekNsYXNzKTsKCWVsc2UKCQlscE5leHRLZXktPmNsYXNzID0gTlVMTDsKCSpyZXRrZXkJCT0gY3VycmVudGhhbmRsZTsKICAgICAgICBUUkFDRShyZWcsICJSZXR1cm5pbmcgJXhcbiIsIGN1cnJlbnRoYW5kbGUpOwoJaWYgKGxwRGlzcG9zKQoJCSpscERpc3Bvcwk9IFJFR19DUkVBVEVEX05FV19LRVk7CglGUkVFX0tFWV9QQVRIOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleUV4MzJBIFtBRFZBUEkzMi4xMzBdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5RXgzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgbHBzekNsYXNzLCBEV09SRCBmZHdPcHRpb25zLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdTQU0gc2FtRGVzaXJlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIGxwU2VjQXR0cmlicywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBIS0VZIHJldGtleSwgTFBEV09SRCBscERpc3BvcyApCnsKICAgIExQV1NUUiBscHN6U3ViS2V5VywgbHBzekNsYXNzVzsKICAgIERXT1JEICByZXQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVseCwlbHgsJXAsJXAsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsZGVidWdzdHJfYShscHN6Q2xhc3MpLGZkd09wdGlvbnMsc2FtRGVzaXJlZCxscFNlY0F0dHJpYnMsCiAgICAgICAgICByZXRrZXksbHBEaXNwb3MpOwoKICAgIGxwc3pTdWJLZXlXID0gbHBzelN1YktleT9zdHJkdXBBMlcobHBzelN1YktleSk6TlVMTDsKICAgIGxwc3pDbGFzc1cgPSBscHN6Q2xhc3M/c3RyZHVwQTJXKGxwc3pDbGFzcyk6TlVMTDsKCiAgICByZXQgPSBSZWdDcmVhdGVLZXlFeDMyVyggaGtleSwgbHBzelN1YktleVcsIGR3UmVzZXJ2ZWQsIGxwc3pDbGFzc1csIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkd09wdGlvbnMsIHNhbURlc2lyZWQsIGxwU2VjQXR0cmlicywgcmV0a2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscERpc3BvcyApOwoKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIGlmKGxwc3pDbGFzc1cpIGZyZWUobHBzekNsYXNzVyk7CgogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ3JlYXRlS2V5MzJXIFtBRFZBUEkzMi4xMzJdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIERXT1JEIGp1bms7CiAgICBMUEtFWVNUUlVDVAlscE5leHRLZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLCBoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkscmV0a2V5KTsKCiAgICAvKiBUaGlzIGNoZWNrIGlzIGhlcmUgYmVjYXVzZSB0aGUgcmV0dXJuIHZhbHVlIGlzIGRpZmZlcmVudCB0aGFuIHRoZQogICAgICAgb25lIGZyb20gdGhlIEV4IGZ1bmN0aW9ucyAqLwogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfQkFES0VZOwoKICAgIHJldHVybiBSZWdDcmVhdGVLZXlFeDMyVyggaGtleSwgbHBzelN1YktleSwgMCwgTlVMTCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfQUxMX0FDQ0VTUywgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0a2V5LCAmanVuayk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleTMyQSBbQURWQVBJMzIuMTI5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIERXT1JEIHJldDsKICAgIExQV1NUUiBscHN6U3ViS2V5VzsKCiAgICBUUkFDRShyZWcsIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICBscHN6U3ViS2V5VyA9IGxwc3pTdWJLZXk/c3RyZHVwQTJXKGxwc3pTdWJLZXkpOk5VTEw7CiAgICByZXQgPSBSZWdDcmVhdGVLZXkzMlcoIGhrZXksIGxwc3pTdWJLZXlXLCByZXRrZXkgKTsKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleTE2IFtTSEVMTC4yXSBbS0VSTkVMLjIxOF0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdDcmVhdGVLZXkzMkEoIGhrZXksIGxwc3pTdWJLZXksIHJldGtleSApOwp9CgoKLyogCiAqIFF1ZXJ5IFZhbHVlIEZ1bmN0aW9ucwogKiBXaW4zMiBkaWZmZXJzIGJldHdlZW4ga2V5bmFtZXMgYW5kIHZhbHVlbmFtZXMuIAogKiBtdWx0aXBsZSB2YWx1ZXMgbWF5IGJlbG9uZyB0byBvbmUga2V5LCB0aGUgc3BlY2lhbCB2YWx1ZQogKiB3aXRoIG5hbWUgTlVMTCBpcyB0aGUgZGVmYXVsdCB2YWx1ZSB1c2VkIGJ5IHRoZSB3aW4zMQogKiBjb21wYXQgZnVuY3Rpb25zLgogKgogKiBDYWxscGF0aDoKICogUmVnUXVlcnlWYWx1ZTE2IC0+IFJlZ1F1ZXJ5VmFsdWUzMkEgLT4gUmVnUXVlcnlWYWx1ZUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnUXVlcnlWYWx1ZTMyVyAtPiBSZWdRdWVyeVZhbHVlRXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlRXgzMlcgW0FEVkFQSTMyLjE1OF0KICogUmV0cmlldmVzIHR5cGUgYW5kIGRhdGEgZm9yIGEgc3BlY2lmaWVkIG5hbWUgYXNzb2NpYXRlZCB3aXRoIGFuIG9wZW4ga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgIFtJXSAgIEhhbmRsZSBvZiBrZXkgdG8gcXVlcnkKICogICAgbHBWYWx1ZU5hbWUgICBbSV0gICBOYW1lIG9mIHZhbHVlIHRvIHF1ZXJ5CiAqICAgIGxwZHdSZXNlcnZlZCAgW0ldICAgUmVzZXJ2ZWQgLSBtdXN0IGJlIE5VTEwKICogICAgbHBkd1R5cGUgICAgICBbT10gICBBZGRyZXNzIG9mIGJ1ZmZlciBmb3IgdmFsdWUgdHlwZS4gIElmIE5VTEwsIHRoZSB0eXBlCiAqICAgICAgICAgICAgICAgICAgICAgICAgaXMgbm90IHJlcXVpcmVkLgogKiAgICBscGJEYXRhICAgICAgIFtPXSAgIEFkZHJlc3Mgb2YgZGF0YSBidWZmZXIuICBJZiBOVUxMLCB0aGUgYWN0dWFsIGRhdGEgaXMKICogICAgICAgICAgICAgICAgICAgICAgICBub3QgcmVxdWlyZWQuCiAqICAgIGxwY2JEYXRhICAgICAgW0kvT10gQWRkcmVzcyBvZiBkYXRhIGJ1ZmZlciBzaXplCiAqCiAqIFJFVFVSTlMgCiAqICAgIEVSUk9SX1NVQ0NFU1M6ICAgU3VjY2VzcwogKiAgICBFUlJPUl9NT1JFX0RBVEE6IFRoZSBzcGVjaWZpZWQgYnVmZmVyIGlzIG5vdCBiaWcgZW5vdWdoIHRvIGhvbGQgdGhlIGRhdGEKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXgzMlcoIEhLRVkgaGtleSwgTFBXU1RSIGxwVmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGxwYkRhdGEsIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUEtFWVNUUlVDVAlscGtleTsKCWludAkJaTsKCiAgICBUUkFDRShyZWcsIigleCwlcywlcCwlcCwlcCwlbGQpXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwVmFsdWVOYW1lKSwKICAgICAgICAgIGxwZHdSZXNlcnZlZCwgbHBkd1R5cGUsIGxwYkRhdGEsIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgLyogUmVzZXJ2ZWQgbXVzdCBiZSBOVUxMIChhdCBsZWFzdCBmb3Igbm93KSAqLwogICAgaWYgKGxwZHdSZXNlcnZlZCkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgLyogQW4gZW1wdHkgbmFtZSBzdHJpbmcgaXMgZXF1aXZhbGVudCB0byBOVUxMICovCiAgICBpZiAobHBWYWx1ZU5hbWUgJiYgISpscFZhbHVlTmFtZSkKICAgICAgICBscFZhbHVlTmFtZSA9IE5VTEw7CgoJaWYgKGxwVmFsdWVOYW1lPT1OVUxMKSB7CiAgICAgICAgICAgICAgICAvKiBVc2Uga2V5J3MgdW5uYW1lZCBvciBkZWZhdWx0IHZhbHVlLCBpZiBhbnkgKi8KCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIFNlYXJjaCBmb3IgdGhlIGtleSBuYW1lICovCgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmICgJbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmCgkJCQkhbHN0cmNtcGkzMlcobHBWYWx1ZU5hbWUsbHBrZXktPnZhbHVlc1tpXS5uYW1lKQoJCQkpCgkJCQlicmVhazsKCX0KCglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKICAgICAgICAgICAgICAgIFRSQUNFKHJlZywiS2V5IG5vdCBmb3VuZFxuIik7CgkJaWYgKGxwVmFsdWVOYW1lPT1OVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEVtcHR5IGtleW5hbWUgbm90IGZvdW5kICovCgkJCWlmIChscGJEYXRhKSB7CgkJCQkqKFdDSEFSKilscGJEYXRhID0gMDsKCQkJCSpscGNiRGF0YQk9IDI7CgkJCX0KCQkJaWYgKGxwZHdUeXBlKQoJCQkJKmxwZHdUeXBlCT0gUkVHX1NaOwogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRShyZWcsICJSZXR1cm5pbmcgYW4gZW1wdHkgc3RyaW5nXG4iKTsKCQkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CgkJfQoJCXJldHVybiBFUlJPUl9CQURfUEFUSE5BTUU7Cgl9CgogICAgaWYgKGxwZHdUeXBlKQogICAgICAgICpscGR3VHlwZSA9IGxwa2V5LT52YWx1ZXNbaV0udHlwZTsKCiAgICBpZiAobHBiRGF0YT09TlVMTCkgewogICAgICAgIC8qIERhdGEgaXMgbm90IHJlcXVpcmVkICovCiAgICAgICAgaWYgKGxwY2JEYXRhPT1OVUxMKSB7CiAgICAgICAgICAgIC8qIEFuZCBkYXRhIHNpemUgaXMgbm90IHJlcXVpcmVkICovCiAgICAgICAgICAgIC8qIFNvIGFsbCB0aGF0IGlzIHJldHVybmVkIGlzIHRoZSB0eXBlIChzZXQgYWJvdmUpICovCiAgICAgICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwogICAgICAgIH0KICAgICAgICAvKiBTZXQgdGhlIHNpemUgcmVxdWlyZWQgYW5kIHJldHVybiBzdWNjZXNzICovCiAgICAgICAgKmxwY2JEYXRhID0gbHBrZXktPnZhbHVlc1tpXS5sZW47CiAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CiAgICB9CgogICAgaWYgKCpscGNiRGF0YTxscGtleS0+dmFsdWVzW2ldLmxlbikgewogICAgICAgIC8qIFRoZSBzaXplIHdhcyBzcGVjaWZpZWQsIGJ1dCB0aGUgZGF0YSBpcyB0b28gYmlnIGZvciBpdCAqLwogICAgICAgIC8qIEluc3RlYWQgb2Ygc2V0dGluZyBpdCB0byBOVUxMLCBmaWxsIGluIHdpdGggYXMgbXVjaCBhcyBwb3NzaWJsZSAqLwogICAgICAgIC8qIEJ1dCB0aGUgZG9jcyBkbyBub3Qgc3BlY2lmeSBob3cgdG8gaGFuZGxlIHRoZSBscGJEYXRhIGhlcmUgKi8KICAgICAgICAvKiAqKFdDSEFSKilscGJEYXRhPSAwOyAqLwogICAgICAgIG1lbWNweShscGJEYXRhLGxwa2V5LT52YWx1ZXNbaV0uZGF0YSwqbHBjYkRhdGEpOwogICAgICAgICpscGNiRGF0YSA9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwogICAgICAgIHJldHVybiBFUlJPUl9NT1JFX0RBVEE7CiAgICB9CgogICAgbWVtY3B5KGxwYkRhdGEsbHBrZXktPnZhbHVlc1tpXS5kYXRhLGxwa2V5LT52YWx1ZXNbaV0ubGVuKTsKCiAgICAvKiBFeHRyYSBkZWJ1Z2dpbmcgb3V0cHV0ICovCiAgICBpZiAobHBkd1R5cGUpIHsKICAgICAgICBzd2l0Y2goKmxwZHdUeXBlKXsKICAgICAgICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsIiBEYXRhKHN6KT0lc1xuIixkZWJ1Z3N0cl93KChMUENXU1RSKWxwYkRhdGEpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFR19EV09SRDoKICAgICAgICAgICAgICAgIFRSQUNFKHJlZywiIERhdGEoZHdvcmQpPSVseFxuIiwgKERXT1JEKSpscGJEYXRhKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFR19CSU5BUlk6CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsIiBEYXRhKGJpbmFyeSlcbiIpOwogICAgICAgICAgICAgICAgLyogSXMgdGhlcmUgYSB3YXkgb2YgcHJpbnRpbmcgdGhpcyBpbiByZWFkYWJsZSBmb3JtPyAqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsICJVbmtub3duIGRhdGEgdHlwZSAlbGRcbiIsICpscGR3VHlwZSk7CiAgICAgICAgfSAvKiBzd2l0Y2ggKi8KICAgIH0gLyogaWYgKi8KCiAgICAvKiBTZXQgdGhlIGFjdHVhbCBzaXplICovCiAgICAqbHBjYkRhdGEgPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlMzJXIFtBRFZBUEkzMi4xNTldCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZTMyVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzelN1YktleSwgTFBXU1RSIGxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQsbHBkd1R5cGU7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksbHBzekRhdGEsCiAgICAgICAgICBscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgogICAgLyogT25seSBvcGVuIHN1YmtleSwgaWYgd2UgcmVhbGx5IGRvIGRlc2NlbmQgKi8KICAgIGlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CiAgICAgICAgcmV0ID0gUmVnT3BlbktleTMyVyggaGtleSwgbHBzelN1YktleSwgJnhoa2V5ICk7CiAgICAgICAgaWYgKHJldCAhPSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIFdBUk4ocmVnLCAiQ291bGQgbm90IG9wZW4gJXNcbiIsIGRlYnVnc3RyX3cobHBzelN1YktleSkpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgIH0gZWxzZQogICAgICAgIHhoa2V5ID0gaGtleTsKCiAgICBscGR3VHlwZSA9IFJFR19TWjsKICAgIHJldCA9IFJlZ1F1ZXJ5VmFsdWVFeDMyVyggeGhrZXksIE5VTEwsIE5VTEwsICZscGR3VHlwZSwgKExQQllURSlscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBjYkRhdGEgKTsKICAgIGlmICh4aGtleSAhPSBoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KHhoa2V5KTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWVFeDMyQSBbQURWQVBJMzIuMTU3XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDMyQSggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGxwYkRhdGEsIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUFdTVFIJbHBzelZhbHVlTmFtZVc7CglMUEJZVEUJYnVmOwoJRFdPUkQJcmV0LG15eGxlbjsKCURXT1JECSpteWxlbjsKCURXT1JECXR5cGU7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIiwgaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIGxwc3pWYWx1ZU5hbWVXID0gbHBzelZhbHVlTmFtZT9zdHJkdXBBMlcobHBzelZhbHVlTmFtZSk6TlVMTDsKCiAgICAvKiBXaHkgd291bGQgdGhpcyBiZSBzZXQ/IEl0IGlzIGp1c3QgYW4gb3V0cHV0ICovCiAgICBpZiAobHBkd1R5cGUpCiAgICAgICAgdHlwZSA9ICpscGR3VHlwZTsKCglpZiAobHBiRGF0YSkgewoJCW15eGxlbiAgPSAwOwoJCW15bGVuCT0gJm15eGxlbjsKCQlidWYJPSB4bWFsbG9jKDQpOwogICAgICAgICAgICAgICAgLyogT25seSBnZXQgdGhlIHNpemUgZm9yIG5vdyAqLwoJCXJldCA9IFJlZ1F1ZXJ5VmFsdWVFeDMyVyggaGtleSwgbHBzelZhbHVlTmFtZVcsIGxwZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnR5cGUsIGJ1ZiwgbXlsZW4gKTsKCQlmcmVlKGJ1Zik7CgkJaWYgKHJldD09RVJST1JfTU9SRV9EQVRBKSB7CgkJCWJ1Zgk9IChMUEJZVEUpeG1hbGxvYygqbXlsZW4pOwoJCX0gZWxzZSB7CgkJCWJ1Zgk9IChMUEJZVEUpeG1hbGxvYygyKigqbHBjYkRhdGEpKTsKCQkJbXl4bGVuICA9IDIqKCpscGNiRGF0YSk7CgkJfQoJfSBlbHNlIHsKCQkvKiBEYXRhIGlzIG5vdCByZXF1aXJlZCAqLwoJCWJ1Zj1OVUxMOwoJCWlmIChscGNiRGF0YSkgewoJCQlteXhsZW4JPSAqbHBjYkRhdGEqMjsKCQkJbXlsZW4JPSAmbXl4bGVuOwoJCX0gZWxzZQoJCQlteWxlbgk9IE5VTEw7Cgl9CgogICAgICAgIC8qIE5vdyBnZXQgdGhlIGRhdGEgKi8KCXJldCA9IFJlZ1F1ZXJ5VmFsdWVFeDMyVyggaGtleSwgbHBzelZhbHVlTmFtZVcsIGxwZHdSZXNlcnZlZCwgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYsIG15bGVuICk7CglpZiAobHBkd1R5cGUpIAoJCSpscGR3VHlwZT10eXBlOwoKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MpIHsKCQlpZiAoYnVmKSB7CgkJCWlmIChVTklDT05WTUFTSyAmICgxPDwodHlwZSkpKSB7CgkJCQkvKiBjb252ZXJ0IFVOSUNPREUgdG8gQVNDSUkgKi8KCQkJCWxzdHJjcHlXdG9BKGxwYkRhdGEsKExQV1NUUilidWYpOwoJCQkJKmxwY2JEYXRhCT0gbXl4bGVuLzI7CgkJCX0gZWxzZSB7CgkJCQlpZiAobXl4bGVuPipscGNiRGF0YSkKCQkJCQlyZXQJPSBFUlJPUl9NT1JFX0RBVEE7CgkJCQllbHNlCgkJCQkJbWVtY3B5KGxwYkRhdGEsYnVmLG15eGxlbik7CgoJCQkJKmxwY2JEYXRhCT0gbXl4bGVuOwoJCQl9CgkJfSBlbHNlIHsKCQkJaWYgKChVTklDT05WTUFTSyAmICgxPDwodHlwZSkpKSAmJiBscGNiRGF0YSkKCQkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJCX0KCX0gZWxzZSB7CgkJaWYgKChVTklDT05WTUFTSyAmICgxPDwodHlwZSkpKSAmJiBscGNiRGF0YSkKCQkJKmxwY2JEYXRhCT0gbXl4bGVuLzI7Cgl9CgogICAgaWYoYnVmKSBmcmVlKGJ1Zik7CiAgICBpZihscHN6VmFsdWVOYW1lVykgZnJlZShscHN6VmFsdWVOYW1lVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlRXgxNiBbS0VSTkVMLjIyNV0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXgxNiggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1Jlc2VydmVkLCBMUERXT1JEIGxwZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBscGJEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlTmFtZSksCiAgICAgICAgICBscGR3UmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YT8qbHBjYkRhdGE6MCk7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUV4MzJBKCBoa2V5LCBscHN6VmFsdWVOYW1lLCBscGR3UmVzZXJ2ZWQsIGxwZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBiRGF0YSwgbHBjYkRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZTMyQSBbQURWQVBJMzIuMTU2XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUzMkEoIEhLRVkgaGtleSwgTFBTVFIgbHBzelN1YktleSwgTFBTVFIgbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewogICAgSEtFWSB4aGtleTsKICAgIERXT1JEIHJldCwgZHdUeXBlOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGxwc3pEYXRhLAogICAgICAgICAgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIGlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CiAgICAgICAgcmV0ID0gUmVnT3BlbktleTE2KCBoa2V5LCBscHN6U3ViS2V5LCAmeGhrZXkgKTsKICAgICAgICBpZiggcmV0ICE9IEVSUk9SX1NVQ0NFU1MgKQogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgfSBlbHNlCiAgICAgICAgeGhrZXkgPSBoa2V5OwoKICAgIGR3VHlwZSA9IFJFR19TWjsKICAgIHJldCA9IFJlZ1F1ZXJ5VmFsdWVFeDMyQSggeGhrZXksIE5VTEwsTlVMTCwgJmR3VHlwZSwgKExQQllURSlscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBjYkRhdGEgKTsKICAgIGlmKCB4aGtleSAhPSBoa2V5ICkKICAgICAgICBSZWdDbG9zZUtleSggeGhrZXkgKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWUxNiBbU0hFTEwuNl0gW0tFUk5FTC4yMjRdCiAqCiAqIE5PVEVTCiAqICAgIElzIHRoaXMgSEFDSyBzdGlsbCBhcHBsaWNhYmxlPwogKgogKiBIQUNLCiAqICAgIFRoZSAxNmJpdCBSZWdRdWVyeVZhbHVlIGRvZXNuJ3QgaGFuZGxlIHNlbGVjdG9yYmxvY2tzIGFueXdheSwgc28gd2UganVzdAogKiAgICBtYXNrIG91dCB0aGUgaGlnaCAxNiBiaXQuICBUaGlzIChub3Qgc28gbXVjaCBpbmNpZGVudGx5KSBob3BlZnVsbHkgZml4ZXMKICogICAgQWxkdXMgRkg0KQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUxNiggSEtFWSBoa2V5LCBMUFNUUiBscHN6U3ViS2V5LCBMUFNUUiBscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGxwc3pEYXRhLAogICAgICAgICAgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIGlmIChscGNiRGF0YSkKICAgICAgICAqbHBjYkRhdGEgJj0gMHhGRkZGOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWUzMkEoaGtleSxscHN6U3ViS2V5LGxwc3pEYXRhLGxwY2JEYXRhKTsKfQoKCi8qCiAqIFNldHRpbmcgdmFsdWVzIG9mIFJlZ2lzdHJ5IGtleXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ1NldFZhbHVlMTYgLT4gUmVnU2V0VmFsdWUzMkEgLT4gUmVnU2V0VmFsdWVFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnU2V0VmFsdWUzMlcgICAtPiBSZWdTZXRWYWx1ZUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWVFeDMyVyBbQURWQVBJMzIuMTcwXQogKiBTZXRzIHRoZSBkYXRhIGFuZCB0eXBlIG9mIGEgdmFsdWUgdW5kZXIgYSByZWdpc3RlciBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldIEhhbmRsZSBvZiBrZXkgdG8gc2V0IHZhbHVlIGZvcgogKiAgICBscHN6VmFsdWVOYW1lIFtJXSBOYW1lIG9mIHZhbHVlIHRvIHNldAogKiAgICBkd1Jlc2VydmVkICAgIFtJXSBSZXNlcnZlZCAtIG11c3QgYmUgemVybwogKiAgICBkd1R5cGUgICAgICAgIFtJXSBGbGFnIGZvciB2YWx1ZSB0eXBlCiAqICAgIGxwYkRhdGEgICAgICAgW0ldIEFkZHJlc3Mgb2YgdmFsdWUgZGF0YQogKiAgICBjYkRhdGEgICAgICAgIFtJXSBTaXplIG9mIHZhbHVlIGRhdGEKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MzJXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6VmFsdWVOYW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3UmVzZXJ2ZWQsIERXT1JEIGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBjYkRhdGEpCnsKICAgIExQS0VZU1RSVUNUIGxwa2V5OwogICAgaW50IGk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgZHdSZXNlcnZlZCwgZHdUeXBlLCBscGJEYXRhLCBjYkRhdGEpOwoKICAgIHN3aXRjaCAoZHdUeXBlKSB7CiAgICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgICAgIFRSQUNFKHJlZywiIERhdGEoc3opPSVzXG4iLCBkZWJ1Z3N0cl93KChMUENXU1RSKWxwYkRhdGEpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfQklOQVJZOgogICAgICAgICAgICBUUkFDRShyZWcsIiBEYXRhKGJpbmFyeSlcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19EV09SRDoKICAgICAgICAgICAgVFJBQ0UocmVnLCIgRGF0YShkd29yZCk9JWx4XG4iLCAoRFdPUkQpbHBiRGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFRSQUNFKHJlZywiVW5rbm93biB0eXBlOiAlbGRcbiIsIGR3VHlwZSk7CiAgICB9CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCglpZiAobHBzelZhbHVlTmFtZT09TlVMTCkgewogICAgICAgICAgICAgLyogU2V0cyB0eXBlIGFuZCBuYW1lIGZvciBrZXkncyB1bm5hbWVkIG9yIGRlZmF1bHQgdmFsdWUgKi8KCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJfSBlbHNlIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKAlscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYKCQkJCSFsc3RyY21waTMyVyhscHN6VmFsdWVOYW1lLGxwa2V5LT52YWx1ZXNbaV0ubmFtZSkKCQkJKQoJCQkJYnJlYWs7Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0gKExQS0VZVkFMVUUpeHJlYWxsb2MoCgkJCQkJbHBrZXktPnZhbHVlcywKCQkJCQkobHBrZXktPm5yb2Z2YWx1ZXMrMSkqc2l6ZW9mKEtFWVZBTFVFKQoJCQkJKTsKCQlscGtleS0+bnJvZnZhbHVlcysrOwoJCW1lbXNldChscGtleS0+dmFsdWVzK2ksJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCX0KCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJaWYgKGxwc3pWYWx1ZU5hbWUpCgkJCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSA9IHN0cmR1cFcobHBzelZhbHVlTmFtZSk7CgkJZWxzZQoJCQlscGtleS0+dmFsdWVzW2ldLm5hbWUgPSBOVUxMOwoJbHBrZXktPnZhbHVlc1tpXS5sZW4JPSBjYkRhdGE7CglscGtleS0+dmFsdWVzW2ldLnR5cGUJPSBkd1R5cGU7CglpZiAobHBrZXktPnZhbHVlc1tpXS5kYXRhICE9TlVMTCkKCQlmcmVlKGxwa2V5LT52YWx1ZXNbaV0uZGF0YSk7CglscGtleS0+dmFsdWVzW2ldLmRhdGEJPSAoTFBCWVRFKXhtYWxsb2MoY2JEYXRhKTsKCWxwa2V5LT52YWx1ZXNbaV0ubGFzdG1vZGlmaWVkID0gdGltZShOVUxMKTsKCW1lbWNweShscGtleS0+dmFsdWVzW2ldLmRhdGEsbHBiRGF0YSxjYkRhdGEpOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgzMkEgW0FEVkFQSTMyLjE2OV0KICoKICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MzJBKCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1Jlc2VydmVkLCBEV09SRCBkd1R5cGUsIExQQllURSBscGJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgY2JEYXRhICkKewoJTFBCWVRFCWJ1ZjsKCUxQV1NUUglscHN6VmFsdWVOYW1lVzsKCURXT1JECXJldDsKCiAgICBUUkFDRShyZWcsIigleCwlcywlbGQsJWxkLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEpOwoKCWlmICgoMTw8ZHdUeXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJYnVmPShMUEJZVEUpc3RyZHVwQTJXKGxwYkRhdGEpOwoJCWNiRGF0YT0yKnN0cmxlbihscGJEYXRhKSsyOwoJfSBlbHNlCgkJYnVmPWxwYkRhdGE7CglpZiAobHBzelZhbHVlTmFtZSkKCQlscHN6VmFsdWVOYW1lVyA9IHN0cmR1cEEyVyhscHN6VmFsdWVOYW1lKTsKCWVsc2UKCQlscHN6VmFsdWVOYW1lVyA9IE5VTEw7CglyZXQ9UmVnU2V0VmFsdWVFeDMyVyhoa2V5LGxwc3pWYWx1ZU5hbWVXLGR3UmVzZXJ2ZWQsZHdUeXBlLGJ1ZixjYkRhdGEpOwoJaWYgKGxwc3pWYWx1ZU5hbWVXKQoJCWZyZWUobHBzelZhbHVlTmFtZVcpOwoJaWYgKGJ1ZiE9bHBiRGF0YSkKCQlmcmVlKGJ1Zik7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZUV4MTYgW0tFUk5FTC4yMjZdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZU5hbWUsIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsIERXT1JEIGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlTmFtZSksCiAgICAgICAgICBkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YSk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVFeDMyQSggaGtleSwgbHBzelZhbHVlTmFtZSwgZHdSZXNlcnZlZCwgZHdUeXBlLCBscGJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNiRGF0YSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZTMyVwlbQURWQVBJMzIuMTcxXQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgRFdPUkQgZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbHBzekRhdGEsIERXT1JEIGNiRGF0YSApCnsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQ7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsCgkJaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGR3VHlwZSxkZWJ1Z3N0cl93KGxwc3pEYXRhKSxjYkRhdGEKCSk7CglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldD1SZWdDcmVhdGVLZXkzMlcoaGtleSxscHN6U3ViS2V5LCZ4aGtleSk7CgkJaWYgKHJldCE9RVJST1JfU1VDQ0VTUykKCQkJcmV0dXJuIHJldDsKCX0gZWxzZQoJCXhoa2V5PWhrZXk7CglpZiAoZHdUeXBlIT1SRUdfU1opIHsKCQlUUkFDRShyZWcsImR3VHlwZT0lbGQgLSBDaGFuZ2luZyB0byBSRUdfU1pcbiIsZHdUeXBlKTsKCQlkd1R5cGU9UkVHX1NaOwoJfQoJaWYgKGNiRGF0YSE9Mipsc3RybGVuMzJXKGxwc3pEYXRhKSsyKSB7CgkJVFJBQ0UocmVnLCJMZW49JWxkICE9IHN0cmxlbiglcykrMT0lZCFcbiIsCgkJCWNiRGF0YSxkZWJ1Z3N0cl93KGxwc3pEYXRhKSwyKmxzdHJsZW4zMlcobHBzekRhdGEpKzIKCQkpOwoJCWNiRGF0YT0yKmxzdHJsZW4zMlcobHBzekRhdGEpKzI7Cgl9CglyZXQ9UmVnU2V0VmFsdWVFeDMyVyh4aGtleSxOVUxMLDAsZHdUeXBlLChMUEJZVEUpbHBzekRhdGEsY2JEYXRhKTsKCWlmIChoa2V5IT14aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZTMyQSBbQURWQVBJMzIuMTY4XQogKgogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwc3pEYXRhLCBEV09SRCBjYkRhdGEgKQp7CglEV09SRAlyZXQ7CglIS0VZCXhoa2V5OwoKCVRSQUNFKHJlZywiKCV4LCVzLCVsZCwlcywlbGQpXG4iLGhrZXksbHBzelN1YktleSxkd1R5cGUsbHBzekRhdGEsY2JEYXRhKTsKCWlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CgkJcmV0PVJlZ0NyZWF0ZUtleTE2KGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleT1oa2V5OwoKCWlmIChkd1R5cGUhPVJFR19TWikgewoJCVRSQUNFKHJlZywiZHdUeXBlPSVsZCFcbiIsZHdUeXBlKTsKCQlkd1R5cGU9UkVHX1NaOwoJfQoJaWYgKGNiRGF0YSE9c3RybGVuKGxwc3pEYXRhKSsxKQoJCWNiRGF0YT1zdHJsZW4obHBzekRhdGEpKzE7CglyZXQ9UmVnU2V0VmFsdWVFeDMyQSh4aGtleSxOVUxMLDAsZHdUeXBlLChMUEJZVEUpbHBzekRhdGEsY2JEYXRhKTsKCWlmICh4aGtleSE9aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZTE2IFtLRVJORUwuMjIxXSBbU0hFTEwuNV0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRAlkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBzekRhdGEsIERXT1JEIGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlcywlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxkd1R5cGUsCiAgICAgICAgICBkZWJ1Z3N0cl9hKGxwc3pEYXRhKSxjYkRhdGEpOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlMzJBKGhrZXksbHBzelN1YktleSxkd1R5cGUsbHBzekRhdGEsY2JEYXRhKTsKfQoKCi8qIAogKiBLZXkgRW51bWVyYXRpb24KICoKICogQ2FsbHBhdGg6CiAqIFJlZ0VudW1LZXkxNiAtPiBSZWdFbnVtS2V5MzJBIC0+IFJlZ0VudW1LZXlFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ0VudW1LZXkzMlcgICAtPiBSZWdFbnVtS2V5RXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5RXgzMlcgW0FEVkFQSTMyLjEzOV0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICBbSV0gSGFuZGxlIHRvIGtleSB0byBlbnVtZXJhdGUKICogICAgaVN1YktleSAgICAgIFtJXSBJbmRleCBvZiBzdWJrZXkgdG8gZW51bWVyYXRlCiAqICAgIGxwc3pOYW1lICAgICBbT10gQnVmZmVyIGZvciBzdWJrZXkgbmFtZQogKiAgICBscGNjaE5hbWUgICAgW09dIFNpemUgb2Ygc3Via2V5IGJ1ZmZlcgogKiAgICBscGR3UmVzZXJ2ZWQgW0ldIFJlc2VydmVkCiAqICAgIGxwc3pDbGFzcyAgICBbT10gQnVmZmVyIGZvciBjbGFzcyBzdHJpbmcKICogICAgbHBjY2hDbGFzcyAgIFtPXSBTaXplIG9mIGNsYXNzIGJ1ZmZlcgogKiAgICBmdCAgICAgICAgICAgW09dIFRpbWUga2V5IGxhc3Qgd3JpdHRlbiB0bwogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlFeDMyVyggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFdTVFIgbHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hOYW1lLCBMUERXT1JEIGxwZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGxwc3pDbGFzcywgTFBEV09SRCBscGNjaENsYXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRVRJTUUgKmZ0ICkKewoJTFBLRVlTVFJVQ1QJbHBrZXksbHB4a2V5OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQsJXAsJXAsJXAsJXApXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSwKICAgICAgICAgICpscGNjaE5hbWUsbHBkd1Jlc2VydmVkLGxwc3pDbGFzcyxscGNjaENsYXNzLGZ0KTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglpZiAoIWxwa2V5LT5uZXh0c3ViKQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoJbHB4a2V5PWxwa2V5LT5uZXh0c3ViOwoKICAgIC8qIFRyYXZlcnNlIHRoZSBzdWJrZXlzICovCgl3aGlsZSAoaVN1YmtleSAmJiBscHhrZXkpIHsKCQlpU3Via2V5LS07CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCglpZiAoaVN1YmtleSB8fCAhbHB4a2V5KQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoJaWYgKDIqbHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpKzI+KmxwY2NoTmFtZSkKCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJbWVtY3B5KGxwc3pOYW1lLGxweGtleS0+a2V5bmFtZSxsc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSkqMisyKTsKCiAgICAgICAgaWYgKCpscGNjaE5hbWUpCiAgICAgICAgICAgICpscGNjaE5hbWUgPSBsc3RybGVuMzJXKGxwc3pOYW1lKTsKCglpZiAobHBzekNsYXNzKSB7CgkJLyogRklYTUU6IHdoYXQgc2hvdWxkIHdlIHdyaXRlIGludG8gaXQ/ICovCgkJKmxwc3pDbGFzcwk9IDA7CgkJKmxwY2NoQ2xhc3MJPSAyOwoJfQoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXkzMlcgW0FEVkFQSTMyLjE0MF0KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MzJXKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQV1NUUiBscHN6TmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBGSUxFVElNRQlmdDsKCiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKICAgIHJldHVybiBSZWdFbnVtS2V5RXgzMlcoaGtleSxpU3Via2V5LGxwc3pOYW1lLCZscGNjaE5hbWUsTlVMTCxOVUxMLE5VTEwsJmZ0KTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleUV4MzJBIFtBRFZBUEkzMi4xMzhdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleUV4MzJBKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTmFtZSwgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiBscHN6Q2xhc3MsIExQRFdPUkQgbHBjY2hDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVUSU1FICpmdCApCnsKCURXT1JECXJldCxscGNjaE5hbWVXLGxwY2NoQ2xhc3NXOwoJTFBXU1RSCWxwc3pOYW1lVyxscHN6Q2xhc3NXOwoKCglUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlTdWJrZXksbHBzek5hbWUsKmxwY2NoTmFtZSxscGR3UmVzZXJ2ZWQsbHBzekNsYXNzLGxwY2NoQ2xhc3MsZnQKCSk7CglpZiAobHBzek5hbWUpIHsKCQlscHN6TmFtZVcJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoTmFtZSoyKTsKCQlscGNjaE5hbWVXCT0gKmxwY2NoTmFtZSoyOwoJfSBlbHNlIHsKCQlscHN6TmFtZVcJPSBOVUxMOwoJCWxwY2NoTmFtZVcgCT0gMDsKCX0KCWlmIChscHN6Q2xhc3MpIHsKCQlscHN6Q2xhc3NXCQk9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hDbGFzcyoyKTsKCQlscGNjaENsYXNzVwk9ICpscGNjaENsYXNzKjI7Cgl9IGVsc2UgewoJCWxwc3pDbGFzc1cJPTA7CgkJbHBjY2hDbGFzc1c9MDsKCX0KCXJldD1SZWdFbnVtS2V5RXgzMlcoCgkJaGtleSwKCQlpU3Via2V5LAoJCWxwc3pOYW1lVywKCQkmbHBjY2hOYW1lVywKCQlscGR3UmVzZXJ2ZWQsCgkJbHBzekNsYXNzVywKCQkmbHBjY2hDbGFzc1csCgkJZnQKCSk7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJbHN0cmNweVd0b0EobHBzek5hbWUsbHBzek5hbWVXKTsKCQkqbHBjY2hOYW1lPXN0cmxlbihscHN6TmFtZSk7CgkJaWYgKGxwc3pDbGFzc1cpIHsKCQkJbHN0cmNweVd0b0EobHBzekNsYXNzLGxwc3pDbGFzc1cpOwoJCQkqbHBjY2hDbGFzcz1zdHJsZW4obHBzekNsYXNzKTsKCQl9Cgl9CglpZiAobHBzek5hbWVXKQoJCWZyZWUobHBzek5hbWVXKTsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5MzJBIFtBRFZBUEkzMi4xMzddCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTMyQSggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGxwY2NoTmFtZSApCnsKICAgIEZJTEVUSU1FCWZ0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwogICAgcmV0dXJuIFJlZ0VudW1LZXlFeDMyQSggaGtleSwgaVN1YmtleSwgbHBzek5hbWUsICZscGNjaE5hbWUsIE5VTEwsIE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgJmZ0ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXkxNiBbU0hFTEwuN10gW0tFUk5FTC4yMTZdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTE2KCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKICAgIHJldHVybiBSZWdFbnVtS2V5MzJBKCBoa2V5LCBpU3Via2V5LCBscHN6TmFtZSwgbHBjY2hOYW1lKTsKfQoKCi8qIAogKiBFbnVtZXJhdGUgUmVnaXN0cnkgVmFsdWVzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdFbnVtVmFsdWUxNiAtPiBSZWdFbnVtVmFsdWUzMkEgLT4gUmVnRW51bVZhbHVlMzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bVZhbHVlMzJXIFtBRFZBUEkzMi4xNDJdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICBbSV0gSGFuZGxlIHRvIGtleSB0byBxdWVyeQogKiAgICBpVmFsdWUgICAgICBbSV0gSW5kZXggb2YgdmFsdWUgdG8gcXVlcnkKICogICAgbHBzelZhbHVlICAgW09dIFZhbHVlIHN0cmluZwogKiAgICBscGNjaFZhbHVlICBbT10gU2l6ZSBvZiB2YWx1ZSBidWZmZXIKICogICAgbHBkUmVzZXJ2ZWQgW0ldIFJlc2VydmVkCiAqICAgIGxwZHdUeXBlICAgIFtPXSBUeXBlIGNvZGUKICogICAgbHBiRGF0YSAgICAgW09dIFZhbHVlIGRhdGEKICogICAgbHBjYkRhdGEgICAgW09dIFNpemUgb2YgZGF0YSBidWZmZXIKICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUzMlcoIEhLRVkgaGtleSwgRFdPUkQgaVZhbHVlLCBMUFdTVFIgbHBzelZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoVmFsdWUsIExQRFdPUkQgbHBkUmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1R5cGUsIExQQllURSBscGJEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJTFBLRVlWQUxVRQl2YWw7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlWYWx1ZSxkZWJ1Z3N0cl93KGxwc3pWYWx1ZSksCiAgICAgICAgICBscGNjaFZhbHVlLGxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIGlmIChscGtleS0+bnJvZnZhbHVlcyA8PSBpVmFsdWUpCiAgICAgICAgcmV0dXJuIEVSUk9SX05PX01PUkVfSVRFTVM7CgogICAgLyogRklYTUU6IFNob3VsZCB0aGlzIGJlIGxwa2V5LT52YWx1ZXMgKyBpVmFsdWUgKiBzaXplb2YoS0VZVkFMVUUpPyAqLwogICAgdmFsID0gbHBrZXktPnZhbHVlcyArIGlWYWx1ZTsKCglpZiAodmFsLT5uYW1lKSB7CgkJaWYgKGxzdHJsZW4zMlcodmFsLT5uYW1lKSoyKzI+KmxwY2NoVmFsdWUpIHsKCQkJKmxwY2NoVmFsdWUgPSBsc3RybGVuMzJXKHZhbC0+bmFtZSkqMisyOwoJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCX0KCQltZW1jcHkobHBzelZhbHVlLHZhbC0+bmFtZSwyKmxzdHJsZW4zMlcodmFsLT5uYW1lKSsyKTsKCQkqbHBjY2hWYWx1ZT1sc3RybGVuMzJXKHZhbC0+bmFtZSkqMisyOwoJfSBlbHNlIHsKCQkqbHBzelZhbHVlCT0gMDsKCQkqbHBjY2hWYWx1ZQk9IDA7Cgl9CgogICAgLyogQ2FuIGJlIE5VTEwgaWYgdGhlIHR5cGUgY29kZSBpcyBub3QgcmVxdWlyZWQgKi8KICAgIGlmIChscGR3VHlwZSkKICAgICAgICAqbHBkd1R5cGUgPSB2YWwtPnR5cGU7CgoJaWYgKGxwYkRhdGEpIHsKCQlpZiAodmFsLT5sZW4+KmxwY2JEYXRhKQoJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCW1lbWNweShscGJEYXRhLHZhbC0+ZGF0YSx2YWwtPmxlbik7CgkJKmxwY2JEYXRhID0gdmFsLT5sZW47Cgl9CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bVZhbHVlMzJBIFtBRFZBUEkzMi4xNDFdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMzJBKCBIS0VZIGhrZXksIERXT1JEIGlWYWx1ZSwgTFBTVFIgbHBzelZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoVmFsdWUsIExQRFdPUkQgbHBkUmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1R5cGUsIExQQllURSBscGJEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKCUxQV1NUUglscHN6VmFsdWVXOwoJTFBCWVRFCWxwYkRhdGFXOwoJRFdPUkQJcmV0LGxwY2JEYXRhVzsKCURXT1JEIGR3VHlwZTsKCglUUkFDRShyZWcsIigleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLGhrZXksaVZhbHVlLGxwc3pWYWx1ZSxscGNjaFZhbHVlLAoJCWxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEpOwoKCWxwc3pWYWx1ZVcgPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoVmFsdWUqMik7CglpZiAobHBiRGF0YSkgewoJCWxwYkRhdGFXID0gKExQQllURSl4bWFsbG9jKCpscGNiRGF0YSoyKTsKCQlscGNiRGF0YVcgPSAqbHBjYkRhdGEqMjsKCX0gZWxzZQoJCWxwYkRhdGFXID0gTlVMTDsKCglyZXQgPSBSZWdFbnVtVmFsdWUzMlcoIGhrZXksIGlWYWx1ZSwgbHBzelZhbHVlVywgbHBjY2hWYWx1ZSwgCgkJCQlscGRSZXNlcnZlZCwgJmR3VHlwZSwgbHBiRGF0YVcsICZscGNiRGF0YVcgKTsKCglpZiAobHBkd1R5cGUpCgkJKmxwZHdUeXBlID0gZHdUeXBlOwoKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MpIHsKCQlsc3RyY3B5V3RvQShscHN6VmFsdWUsbHBzelZhbHVlVyk7CgkJaWYgKGxwYkRhdGEpIHsKCQkJaWYgKCgxPDxkd1R5cGUpICYgVU5JQ09OVk1BU0spIHsKCQkJCWxzdHJjcHlXdG9BKGxwYkRhdGEsKExQV1NUUilscGJEYXRhVyk7CgkJCX0gZWxzZSB7CgkJCQlpZiAobHBjYkRhdGFXID4gKmxwY2JEYXRhKQoJCQkJCXJldAk9IEVSUk9SX01PUkVfREFUQTsKCQkJCWVsc2UKCQkJCQltZW1jcHkobHBiRGF0YSxscGJEYXRhVyxscGNiRGF0YVcpOwoJCQl9CgkJCSpscGNiRGF0YSA9IGxwY2JEYXRhVzsKCQl9Cgl9CiAgICBpZiAobHBiRGF0YVcpIGZyZWUobHBiRGF0YVcpOwogICAgaWYgKGxwc3pWYWx1ZVcpIGZyZWUobHBzelZhbHVlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUxNiBbS0VSTkVMLjIyM10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUxNiggSEtFWSBoa2V5LCBEV09SRCBpVmFsdWUsIExQU1RSIGxwc3pWYWx1ZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaFZhbHVlLCBMUERXT1JEIGxwZFJlc2VydmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsCiAgICAgICAgICBscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhKTsKICAgIHJldHVybiBSZWdFbnVtVmFsdWUzMkEoIGhrZXksIGlWYWx1ZSwgbHBzelZhbHVlLCBscGNjaFZhbHVlLCBscGRSZXNlcnZlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBscGR3VHlwZSwgbHBiRGF0YSwgbHBjYkRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ2xvc2VLZXkgW1NIRUxMLjNdIFtLRVJORUwuMjIwXSBbQURWQVBJMzIuMTI2XQogKiBSZWxlYXNlcyB0aGUgaGFuZGxlIG9mIHRoZSBzcGVjaWZpZWQga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIGNsb3NlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnQ2xvc2VLZXkoIEhLRVkgaGtleSApCnsKICAgIFRSQUNFKHJlZywiKCV4KVxuIixoa2V5KTsKCiAgICAvKiBUaGUgc3RhbmRhcmQgaGFuZGxlcyBhcmUgYWxsb3dlZCB0byBzdWNjZWVkLCBldmVuIHRob3VnaCB0aGV5IGFyZSBub3QKICAgICAgIGNsb3NlZCAqLwogICAgaWYgKGlzX3N0YW5kYXJkX2hrZXkoaGtleSkpCiAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CgogICAgcmV0dXJuIHJlbW92ZV9oYW5kbGUoaGtleSk7Cn0KCgovKiAKICogRGVsZXRlIHJlZ2lzdHJ5IGtleQogKgogKiBDYWxscGF0aDoKICogUmVnRGVsZXRlS2V5MTYgLT4gUmVnRGVsZXRlS2V5MzJBIC0+IFJlZ0RlbGV0ZUtleTMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZUtleTMyVyBbQURWQVBJMzIuMTM0XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIHRvIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIE5hbWUgb2Ygc3Via2V5IHRvIGRlbGV0ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTMyVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzelN1YktleSApCnsKCUxQS0VZU1RSVUNUCSpscGxwUHJldktleSxscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCiAgICBUUkFDRShyZWcsIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpKTsKCiAgICBscE5leHRLZXkgPSBsb29rdXBfaGtleShoa2V5KTsKICAgIGlmICghbHBOZXh0S2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICAvKiBTdWJrZXkgcGFyYW0gY2Fubm90IGJlIE5VTEwgKi8KICAgIGlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0JBREtFWTsKCiAgICAvKiBXZSBuZWVkIHRvIGtub3cgdGhlIHByZXZpb3VzIGtleSBpbiB0aGUgaGllci4gKi8KCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKGk8d3BjLTEpIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJVFJBQ0UocmVnLCAiICBTY2FubmluZyBbJXNdXG4iLAoJCQkJICAgICBkZWJ1Z3N0cl93KGxweGtleS0+a2V5bmFtZSkpOwoJCQlpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KSB7CgkJCUZSRUVfS0VZX1BBVEg7CgkJCVRSQUNFKHJlZywgIiAgTm90IGZvdW5kLlxuIik7CgkJCS8qIG5vdCBmb3VuZCBpcyBzdWNjZXNzICovCgkJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJCX0KCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJbHB4a2V5CT0gbHBOZXh0S2V5LT5uZXh0c3ViOwoJbHBscFByZXZLZXkgPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7Cgl3aGlsZSAobHB4a2V5KSB7CgkJVFJBQ0UocmVnLCAiICBTY2FubmluZyBbJXNdXG4iLAoJCQkgICAgIGRlYnVnc3RyX3cobHB4a2V5LT5rZXluYW1lKSk7CgkJaWYgKCFsc3RyY21waTMyVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJYnJlYWs7CgkJbHBscFByZXZLZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJbHB4a2V5CQk9IGxweGtleS0+bmV4dDsKCX0KCglpZiAoIWxweGtleSkgewoJCUZSRUVfS0VZX1BBVEg7CgkJV0FSTihyZWcgLCAiICBOb3QgZm91bmQuXG4iKTsKCQlyZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7Cgl9CgoJaWYgKGxweGtleS0+bmV4dHN1YikgewoJCUZSRUVfS0VZX1BBVEg7CgkJV0FSTihyZWcgLCAiICBOb3QgZW1wdHkuXG4iKTsKCQlyZXR1cm4gRVJST1JfQ0FOVFdSSVRFOwoJfQoJKmxwbHBQcmV2S2V5CT0gbHB4a2V5LT5uZXh0OwoJZnJlZShscHhrZXktPmtleW5hbWUpOwoJaWYgKGxweGtleS0+Y2xhc3MpCgkJZnJlZShscHhrZXktPmNsYXNzKTsKCWlmIChscHhrZXktPnZhbHVlcykKCQlmcmVlKGxweGtleS0+dmFsdWVzKTsKCWZyZWUobHB4a2V5KTsKCUZSRUVfS0VZX1BBVEg7CglUUkFDRShyZWcsICIgIERvbmUuXG4iKTsKCXJldHVybglFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVLZXkzMkEgW0FEVkFQSTMyLjEzM10KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXkgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVc7CiAgICBEV09SRCAgcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkpOwogICAgbHBzelN1YktleVcgPSBscHN6U3ViS2V5P3N0cmR1cEEyVyhscHN6U3ViS2V5KTpOVUxMOwogICAgcmV0ID0gUmVnRGVsZXRlS2V5MzJXKCBoa2V5LCBscHN6U3ViS2V5VyApOwogICAgaWYobHBzelN1YktleVcpIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlS2V5MTYgW1NIRUxMLjRdIFtLRVJORUwuMjE5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSk7CiAgICByZXR1cm4gUmVnRGVsZXRlS2V5MzJBKCBoa2V5LCBscHN6U3ViS2V5ICk7Cn0KCgovKiAKICogRGVsZXRlIHJlZ2lzdHJ5IHZhbHVlCiAqCiAqIENhbGxwYXRoOgogKiBSZWdEZWxldGVWYWx1ZTE2IC0+IFJlZ0RlbGV0ZVZhbHVlMzJBIC0+IFJlZ0RlbGV0ZVZhbHVlMzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlVmFsdWUzMlcgW0FEVkFQSTMyLjEzNl0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICBbSV0KICogICAgbHBzelZhbHVlIFtJXQogKgogKiBSRVRVUk5TCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUzMlcoIEhLRVkgaGtleSwgTFBXU1RSIGxwc3pWYWx1ZSApCnsKCURXT1JECQlpOwoJTFBLRVlTVFJVQ1QJbHBrZXk7CglMUEtFWVZBTFVFCXZhbDsKCiAgICBUUkFDRShyZWcsIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pWYWx1ZSkpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKCWlmIChscHN6VmFsdWUpIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKAlscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYKCQkJCSFsc3RyY21waTMyVyhscGtleS0+dmFsdWVzW2ldLm5hbWUsbHBzelZhbHVlKQoJCQkpCgkJCQlicmVhazsKCX0gZWxzZSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCX0KCiAgICBpZiAoaSA9PSBscGtleS0+bnJvZnZhbHVlcykKICAgICAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7CgoJdmFsCT0gbHBrZXktPnZhbHVlcytpOwoJaWYgKHZhbC0+bmFtZSkgZnJlZSh2YWwtPm5hbWUpOwoJaWYgKHZhbC0+ZGF0YSkgZnJlZSh2YWwtPmRhdGEpOwoJbWVtY3B5KAkKCQlscGtleS0+dmFsdWVzK2ksCgkJbHBrZXktPnZhbHVlcytpKzEsCgkJc2l6ZW9mKEtFWVZBTFVFKSoobHBrZXktPm5yb2Z2YWx1ZXMtaS0xKQoJKTsKCWxwa2V5LT52YWx1ZXMJPSAoTFBLRVlWQUxVRSl4cmVhbGxvYygKCQkJCWxwa2V5LT52YWx1ZXMsCgkJCQkobHBrZXktPm5yb2Z2YWx1ZXMtMSkqc2l6ZW9mKEtFWVZBTFVFKQoJCQkpOwoJbHBrZXktPm5yb2Z2YWx1ZXMtLTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVWYWx1ZTMyQSBbQURWQVBJMzIuMTM1XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMzJBKCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZSApCnsKICAgIExQV1NUUiBscHN6VmFsdWVXOwogICAgRFdPUkQgIHJldDsKCiAgICBUUkFDRShyZWcsICIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWUpKTsKICAgIGxwc3pWYWx1ZVcgPSBscHN6VmFsdWU/c3RyZHVwQTJXKGxwc3pWYWx1ZSk6TlVMTDsKICAgIHJldCA9IFJlZ0RlbGV0ZVZhbHVlMzJXKCBoa2V5LCBscHN6VmFsdWVXICk7CiAgICBpZihscHN6VmFsdWVXKSBmcmVlKGxwc3pWYWx1ZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlVmFsdWUxNiBbS0VSTkVMLjIyMl0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTE2KCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIiwgaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZSkpOwogICAgcmV0dXJuIFJlZ0RlbGV0ZVZhbHVlMzJBKCBoa2V5LCBscHN6VmFsdWUgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRmx1c2hLZXkgW0tFUk5FTC4yMjddIFtBRFZBUEkzMi4xNDNdCiAqIFdyaXRlcyBrZXkgdG8gcmVnaXN0cnkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgW0ldIEhhbmRsZSBvZiBrZXkgdG8gd3JpdGUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdGbHVzaEtleSggSEtFWSBoa2V5ICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CiAgICBCT09MMzIgcmV0OwoKICAgIFRSQUNFKHJlZywgIigleClcbiIsIGhrZXkpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEVSUihyZWcsICJXaGF0IGlzIHRoZSBjb3JyZWN0IGZpbGVuYW1lP1xuIik7CgogICAgcmV0ID0gX3NhdmVyZWcoIGxwa2V5LCAiZm9vLmJhciIsIFRSVUUpOwoKICAgIGlmKCByZXQgKSB7CiAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CiAgICB9IGVsc2UKICAgICAgICByZXR1cm4gRVJST1JfVU5LTk9XTjsgIC8qIEZJWE1FICovCn0KCgovKiBGSVhNRTogbHBjY2hYWFhYIC4uLiBpcyB0aGlzIGNvdW50aW5nIGluIFdDSEFSUyBvciBpbiBCWVRFcyA/PyAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlJbmZvS2V5MzJXIFtBRFZBUEkzMi4xNTNdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgICAgICAgIFtJXSBIYW5kbGUgdG8ga2V5IHRvIHF1ZXJ5CiAqICAgIGxwc3pDbGFzcyAgICAgICAgICAgICAgW09dIEJ1ZmZlciBmb3IgY2xhc3Mgc3RyaW5nCiAqICAgIGxwY2NoQ2xhc3MgICAgICAgICAgICAgW09dIFNpemUgb2YgY2xhc3Mgc3RyaW5nIGJ1ZmZlcgogKiAgICBscGR3UmVzZXJ2ZWQgICAgICAgICAgIFtJXSBSZXNlcnZlZAogKiAgICBscGNTdWJLZXlzICAgICAgICAgICAgIFtJXSBCdWZmZXIgZm9yIG51bWJlciBvZiBzdWJrZXlzCiAqICAgIGxwY2NoTWF4U3ViS2V5ICAgICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCBzdWJrZXkgbmFtZSBsZW5ndGgKICogICAgbHBjY2hNYXhDbGFzcyAgICAgICAgICBbT10gQnVmZmVyIGZvciBsb25nZXN0IGNsYXNzIHN0cmluZyBsZW5ndGgKICogICAgbHBjVmFsdWVzICAgICAgICAgICAgICBbT10gQnVmZmVyIGZvciBudW1iZXIgb2YgdmFsdWUgZW50cmllcwogKiAgICBscGNjaE1heFZhbHVlTmFtZSAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3QgdmFsdWUgbmFtZSBsZW5ndGgKICogICAgbHBjY2JNYXhWYWx1ZURhdGEgICAgICBbT10gQnVmZmVyIGZvciBsb25nZXN0IHZhbHVlIGRhdGEgbGVuZ3RoCiAqICAgIGxwY2JTZWN1cml0eURlc2NyaXB0b3IgW09dIEJ1ZmZlciBmb3Igc2VjdXJpdHkgZGVzY3JpcHRvciBsZW5ndGgKICogICAgZnQKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeUluZm9LZXkzMlcoIEhLRVkgaGtleSwgTFBXU1RSIGxwc3pDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hDbGFzcywgTFBEV09SRCBscGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjU3ViS2V5cywgTFBEV09SRCBscGNjaE1heFN1YmtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE1heENsYXNzLCBMUERXT1JEIGxwY1ZhbHVlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE1heFZhbHVlTmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2JNYXhWYWx1ZURhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JTZWN1cml0eURlc2NyaXB0b3IsIEZJTEVUSU1FICpmdCApCnsKCUxQS0VZU1RSVUNUCWxwa2V5LGxweGtleTsKCWludAkJbnJvZmtleXMsbWF4c3Via2V5LG1heGNsYXNzLG1heHZuYW1lLG1heHZkYXRhOwoJaW50CQlpOwoKCVRSQUNFKHJlZywiKCV4LCVwLC4uLilcbiIsaGtleSxscHN6Q2xhc3MpOwoJbHBrZXkgPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoJaWYgKGxwc3pDbGFzcykgewoJCWlmIChscGtleS0+Y2xhc3MpIHsKCQkJaWYgKGxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyKzI+KmxwY2NoQ2xhc3MpIHsKCQkJCSpscGNjaENsYXNzPWxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyOwoJCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQkJfQoJCQkqbHBjY2hDbGFzcz1sc3RybGVuMzJXKGxwa2V5LT5jbGFzcykqMjsKCQkJbWVtY3B5KGxwc3pDbGFzcyxscGtleS0+Y2xhc3MsbHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKTsKCQl9IGVsc2UgewoJCQkqbHBzekNsYXNzCT0gMDsKCQkJKmxwY2NoQ2xhc3MJPSAwOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGxwY2NoQ2xhc3MpCgkJCSpscGNjaENsYXNzCT0gbHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjI7Cgl9CglscHhrZXk9bHBrZXktPm5leHRzdWI7Cglucm9ma2V5cz1tYXhzdWJrZXk9bWF4Y2xhc3M9bWF4dm5hbWU9bWF4dmRhdGE9MDsKCXdoaWxlIChscHhrZXkpIHsKCQlucm9ma2V5cysrOwoJCWlmIChsc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSk+bWF4c3Via2V5KQoJCQltYXhzdWJrZXk9bHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpOwoJCWlmIChscHhrZXktPmNsYXNzICYmIGxzdHJsZW4zMlcobHB4a2V5LT5jbGFzcyk+bWF4Y2xhc3MpCgkJCW1heGNsYXNzPWxzdHJsZW4zMlcobHB4a2V5LT5jbGFzcyk7CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJTFBLRVlWQUxVRQl2YWw9bHBrZXktPnZhbHVlcytpOwoKCQlpZiAodmFsLT5uYW1lICYmIGxzdHJsZW4zMlcodmFsLT5uYW1lKT5tYXh2bmFtZSkKCQkJbWF4dm5hbWU9bHN0cmxlbjMyVyh2YWwtPm5hbWUpOwoJCWlmICh2YWwtPmxlbj5tYXh2ZGF0YSkKCQkJbWF4dmRhdGE9dmFsLT5sZW47Cgl9CglpZiAoIW1heGNsYXNzKSBtYXhjbGFzcwk9IDE7CglpZiAoIW1heHZuYW1lKSBtYXh2bmFtZQk9IDE7CglpZiAobHBjVmFsdWVzKQoJCSpscGNWYWx1ZXMJPSBscGtleS0+bnJvZnZhbHVlczsKCWlmIChscGNTdWJLZXlzKQoJCSpscGNTdWJLZXlzCT0gbnJvZmtleXM7CglpZiAobHBjY2hNYXhTdWJrZXkpCgkJKmxwY2NoTWF4U3Via2V5CT0gbWF4c3Via2V5KjI7CglpZiAobHBjY2hNYXhDbGFzcykKCQkqbHBjY2hNYXhDbGFzcwk9IG1heGNsYXNzKjI7CglpZiAobHBjY2hNYXhWYWx1ZU5hbWUpCgkJKmxwY2NoTWF4VmFsdWVOYW1lPSBtYXh2bmFtZTsKCWlmIChscGNjYk1heFZhbHVlRGF0YSkKCQkqbHBjY2JNYXhWYWx1ZURhdGE9IG1heHZkYXRhOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5SW5mb0tleTMyQSBbQURWQVBJMzIuMTUyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5SW5mb0tleTMyQSggSEtFWSBoa2V5LCBMUFNUUiBscHN6Q2xhc3MsIExQRFdPUkQgbHBjY2hDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBjU3ViS2V5cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE1heFN1YmtleSwgTFBEV09SRCBscGNjaE1heENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY1ZhbHVlcywgTFBEV09SRCBscGNjaE1heFZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjYk1heFZhbHVlRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwgRklMRVRJTUUgKmZ0ICkKewoJTFBXU1RSCQlscHN6Q2xhc3NXOwoJRFdPUkQJCXJldDsKCglUUkFDRShyZWcsIigleCwuLi4uLi4pXG4iLGhrZXkpOwoJaWYgKGxwc3pDbGFzcykgewoJCSpscGNjaENsYXNzKj0gMjsKCQlscHN6Q2xhc3NXICA9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hDbGFzcyk7CgoJfSBlbHNlCgkJbHBzekNsYXNzVyAgPSBOVUxMOwoJcmV0PVJlZ1F1ZXJ5SW5mb0tleTMyVygKCQloa2V5LAoJCWxwc3pDbGFzc1csCgkJbHBjY2hDbGFzcywKCQlscGR3UmVzZXJ2ZWQsCgkJbHBjU3ViS2V5cywKCQlscGNjaE1heFN1YmtleSwKCQlscGNjaE1heENsYXNzLAoJCWxwY1ZhbHVlcywKCQlscGNjaE1heFZhbHVlTmFtZSwKCQlscGNjYk1heFZhbHVlRGF0YSwKCQlscGNiU2VjdXJpdHlEZXNjcmlwdG9yLAoJCWZ0CgkpOwoJaWYgKHJldD09RVJST1JfU1VDQ0VTUyAmJiBscHN6Q2xhc3MpCgkJbHN0cmNweVd0b0EobHBzekNsYXNzLGxwc3pDbGFzc1cpOwoJaWYgKGxwY2NoQ2xhc3MpCgkJKmxwY2NoQ2xhc3MvPTI7CglpZiAobHBjY2hNYXhTdWJrZXkpCgkJKmxwY2NoTWF4U3Via2V5Lz0yOwoJaWYgKGxwY2NoTWF4Q2xhc3MpCgkJKmxwY2NoTWF4Q2xhc3MvPTI7CglpZiAobHBjY2hNYXhWYWx1ZU5hbWUpCgkJKmxwY2NoTWF4VmFsdWVOYW1lLz0yOwoJaWYgKGxwc3pDbGFzc1cpCgkJZnJlZShscHN6Q2xhc3NXKTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyVyBbQURWQVBJMzIuMTI4XQogKgogKiBQQVJBTVMKICogICAgbHBNYWNoaW5lTmFtZSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHJlbW90ZSBjb21wdXRlcgogKiAgICBoSGV5ICAgICAgICAgIFtJXSBQcmVkZWZpbmVkIHJlZ2lzdHJ5IGhhbmRsZQogKiAgICBwaGtSZXN1bHQgICAgIFtJXSBBZGRyZXNzIG9mIGJ1ZmZlciBmb3IgcmVtb3RlIHJlZ2lzdHJ5IGhhbmRsZQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5MzJXKCBMUENXU1RSIGxwTWFjaGluZU5hbWUsIEhLRVkgaEtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBIS0VZIHBoa1Jlc3VsdCApCnsKICAgIFRSQUNFKHJlZywiKCVzLCV4LCVwKTogc3R1YlxuIixkZWJ1Z3N0cl93KGxwTWFjaGluZU5hbWUpLGhLZXkscGhrUmVzdWx0KTsKCiAgICBpZiAoIWxwTWFjaGluZU5hbWUgfHwgISpscE1hY2hpbmVOYW1lKSB7CiAgICAgICAgLyogVXNlIHRoZSBsb2NhbCBtYWNoaW5lIG5hbWUgKi8KICAgICAgICByZXR1cm4gUmVnT3BlbktleTE2KCBoS2V5LCAiIiwgcGhrUmVzdWx0ICk7CiAgICB9CgogICAgRklYTUUocmVnLCJDYW5ub3QgY29ubmVjdCB0byAlc1xuIixkZWJ1Z3N0cl93KGxwTWFjaGluZU5hbWUpKTsKICAgIHJldHVybiBFUlJPUl9CQURfTkVUUEFUSDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ29ubmVjdFJlZ2lzdHJ5MzJBIFtBRFZBUEkzMi4xMjddCiAqLwpMT05HIFdJTkFQSSBSZWdDb25uZWN0UmVnaXN0cnkzMkEoIExQQ1NUUiBtYWNoaW5lLCBIS0VZIGhrZXksIExQSEtFWSByZXNrZXkgKQp7CiAgICBEV09SRCByZXQ7CiAgICBMUFdTVFIgbWFjaGluZVcgPSBzdHJkdXBBMlcobWFjaGluZSk7CiAgICByZXQgPSBSZWdDb25uZWN0UmVnaXN0cnkzMlcoIG1hY2hpbmVXLCBoa2V5LCByZXNrZXkgKTsKICAgIGZyZWUobWFjaGluZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnR2V0S2V5U2VjdXJpdHkgW0FEVkFQSTMyLjE0NF0KICogUmV0cmlldmVzIGEgY29weSBvZiBzZWN1cml0eSBkZXNjcmlwdG9yIHByb3RlY3RpbmcgdGhlIHJlZ2lzdHJ5IGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgICAgICAgICBbSV0gICBPcGVuIGhhbmRsZSBvZiBrZXkgdG8gc2V0CiAqICAgIFNlY3VyaXR5SW5mb3JtYXRpb24gICAgW0ldICAgRGVzY3JpcHRvciBjb250ZW50cwogKiAgICBwU2VjdXJpdHlEZXNjcmlwdG9yICAgIFtPXSAgIEFkZHJlc3Mgb2YgZGVzY3JpcHRvciBmb3Iga2V5CiAqICAgIGxwY2JTZWN1cml0eURlc2NyaXB0b3IgW0kvT10gQWRkcmVzcyBvZiBzaXplIG9mIGJ1ZmZlciBhbmQgZGVzY3JpcHRpb24KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkxPTkcgV0lOQVBJIFJlZ0dldEtleVNlY3VyaXR5KCBIS0VZIGhrZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0VDVVJJVFlfSU5GT1JNQVRJT04gU2VjdXJpdHlJbmZvcm1hdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfREVTQ1JJUFRPUiBwU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxTZWN1cml0eUluZm9ybWF0aW9uLHBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yPypscGNiU2VjdXJpdHlEZXNjcmlwdG9yOjApOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIEZJWE1FOiBDaGVjayBmb3IgdmFsaWQgU2VjdXJpdHlJbmZvcm1hdGlvbiB2YWx1ZXMgKi8KCiAgICBpZiAoKmxwY2JTZWN1cml0eURlc2NyaXB0b3IgPCBzaXplb2YoKnBTZWN1cml0eURlc2NyaXB0b3IpKQogICAgICAgIHJldHVybiBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSOwoKICAgIEZJWE1FKHJlZywgIigleCwlbGQsJXAsJWxkKTogc3R1YlxuIixoa2V5LFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICBwU2VjdXJpdHlEZXNjcmlwdG9yLGxwY2JTZWN1cml0eURlc2NyaXB0b3I/KmxwY2JTZWN1cml0eURlc2NyaXB0b3I6MCk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0xvYWRLZXkzMlcgW0FEVkFQSTMyLj8/P10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5IFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5CiAqICAgIGxwc3pGaWxlICAgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIHJlZ2lzdHJ5IGluZm9ybWF0aW9uCiAqLwpMT05HIFdJTkFQSSBSZWdMb2FkS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBDV1NUUiBscHN6RmlsZSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxkZWJ1Z3N0cl93KGxwc3pGaWxlKSk7CgogICAgLyogRG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkgfHwgIWxwc3pGaWxlIHx8ICEqbHBzekZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywiKCV4LCVzLCVzKTogc3R1YlxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwc3pGaWxlKSk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0xvYWRLZXkzMkEgW0FEVkFQSTMyLj8/P10KICovCkxPTkcgV0lOQVBJIFJlZ0xvYWRLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQQ1NUUiBscHN6RmlsZSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwc3pTdWJLZXlXID0gc3RyZHVwQTJXKGxwc3pTdWJLZXkpOwogICAgTFBXU1RSIGxwc3pGaWxlVyA9IHN0cmR1cEEyVyhscHN6RmlsZSk7CiAgICByZXQgPSBSZWdMb2FkS2V5MzJXKCBoa2V5LCBscHN6U3ViS2V5VywgbHBzekZpbGVXICk7CiAgICBpZihscHN6RmlsZVcpIGZyZWUobHBzekZpbGVXKTsKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlIFtBRFZBUEkzMi4/Pz9dCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgW0ldIEhhbmRsZSBvZiBrZXkgdG8gd2F0Y2gKICogICAgZldhdGNoU3ViVHJlZSAgIFtJXSBGbGFnIGZvciBzdWJrZXkgbm90aWZpY2F0aW9uCiAqICAgIGZkd05vdGlmeUZpbHRlciBbSV0gQ2hhbmdlcyB0byBiZSByZXBvcnRlZAogKiAgICBoRXZlbnQgICAgICAgICAgW0ldIEhhbmRsZSBvZiBzaWduYWxlZCBldmVudAogKiAgICBmQXN5bmMgICAgICAgICAgW0ldIEZsYWcgZm9yIGFzeW5jaHJvbm91cyByZXBvcnRpbmcKICovCkxPTkcgV0lOQVBJIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlKCBIS0VZIGhrZXksIEJPT0wzMiBmV2F0Y2hTdWJUcmVlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGZkd05vdGlmeUZpbHRlciwgSEFORExFMzIgaEV2ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTDMyIGZBc3luYyApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwogICAgVFJBQ0UocmVnLCIoJXgsJWksJWxkLCV4LCVpKVxuIixoa2V5LGZXYXRjaFN1YlRyZWUsZmR3Tm90aWZ5RmlsdGVyLAogICAgICAgICAgaEV2ZW50LGZBc3luYyk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUUocmVnLCIoJXgsJWksJWxkLCV4LCVpKTogc3R1YlxuIixoa2V5LGZXYXRjaFN1YlRyZWUsZmR3Tm90aWZ5RmlsdGVyLAogICAgICAgICAgaEV2ZW50LGZBc3luYyk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1VuTG9hZEtleTMyVyBbQURWQVBJMzIuMTczXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscFN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleSB0byB1bmxvYWQKICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwU3ViS2V5ICkKewogICAgRklYTUUocmVnLCIoJXgsJXMpOiBzdHViXG4iLGhrZXksIGRlYnVnc3RyX3cobHBTdWJLZXkpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXkzMkEgW0FEVkFQSTMyLjE3Ml0KICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXkgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscFN1YktleVcgPSBzdHJkdXBBMlcobHBTdWJLZXkpOwogICAgcmV0ID0gUmVnVW5Mb2FkS2V5MzJXKCBoa2V5LCBscFN1YktleVcgKTsKICAgIGlmKGxwU3ViS2V5VykgZnJlZShscFN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0S2V5U2VjdXJpdHkgW0FEVkFQSTMyLjE2N10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldIE9wZW4gaGFuZGxlIG9mIGtleSB0byBzZXQKICogICAgU2VjdXJpdHlJbmZvICBbSV0gRGVzY3JpcHRvciBjb250ZW50cwogKiAgICBwU2VjdXJpdHlEZXNjIFtJXSBBZGRyZXNzIG9mIGRlc2NyaXB0b3IgZm9yIGtleQogKi8KTE9ORyBXSU5BUEkgUmVnU2V0S2V5U2VjdXJpdHkoIEhLRVkgaGtleSwgU0VDVVJJVFlfSU5GT1JNQVRJT04gU2VjdXJpdHlJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9ERVNDUklQVE9SIHBTZWN1cml0eURlc2MgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRShyZWcsIigleCwlbGQsJXApXG4iLGhrZXksU2VjdXJpdHlJbmZvLHBTZWN1cml0eURlc2MpOwoKICAgIC8qIEl0IHNlZW1zIHRvIHBlcmZvcm0gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICgoU2VjdXJpdHlJbmZvICYgT1dORVJfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIEdST1VQX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBEQUNMX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBTQUNMX1NFQ1VSSVRZX0lORk9STUFUSU9OKSkgewogICAgICAgIC8qIFBhcmFtIE9LICovCiAgICB9IGVsc2UKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgaWYgKCFwU2VjdXJpdHlEZXNjKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsIjooJXgsJWxkLCVwKTogc3R1YlxuIixoa2V5LFNlY3VyaXR5SW5mbyxwU2VjdXJpdHlEZXNjKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2F2ZUtleTMyVyBbQURWQVBJMzIuMTY2XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgIFtJXSBIYW5kbGUgb2Yga2V5IHdoZXJlIHNhdmUgYmVnaW5zCiAqICAgIGxwRmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSB0byBzYXZlIHRvCiAqICAgIHNhICAgICBbSV0gQWRkcmVzcyBvZiBzZWN1cml0eSBzdHJ1Y3R1cmUKICovCkxPTkcgV0lOQVBJIFJlZ1NhdmVLZXkzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscEZpbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgc2EgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRShyZWcsICIoJXgsJXMsJXApXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwRmlsZSksIHNhKTsKCiAgICAvKiBJdCBhcHBlYXJzIHRvIGRvIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoIWxwRmlsZSB8fCAhKmxwRmlsZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUUocmVnLCAiKCV4LCVzLCVwKTogc3R1YlxuIiwgaGtleSwgZGVidWdzdHJfdyhscEZpbGUpLCBzYSk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NhdmVLZXkzMkEgW0FEVkFQSTMyLjE2NV0KICovCkxPTkcgV0lOQVBJIFJlZ1NhdmVLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwRmlsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBzYSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwRmlsZVcgPSBzdHJkdXBBMlcobHBGaWxlKTsKICAgIHJldCA9IFJlZ1NhdmVLZXkzMlcoIGhrZXksIGxwRmlsZVcsIHNhICk7CiAgICBmcmVlKGxwRmlsZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleTMyVyBbQURWQVBJMzIuMTY0XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICBbSV0gSGFuZGxlIG9mIGtleSB3aGVyZSByZXN0b3JlIGJlZ2lucwogKiAgICBscEZpbGUgIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGNvbnRhaW5pbmcgc2F2ZWQgdHJlZQogKiAgICBkd0ZsYWdzIFtJXSBPcHRpb25hbCBmbGFncwogKi8KTE9ORyBXSU5BUEkgUmVnUmVzdG9yZUtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFKHJlZywgIigleCwlcywlbGQpXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIEl0IHNlZW1zIHRvIGRvIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoIWxwRmlsZSB8fCAhKmxwRmlsZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUUocmVnLCIoJXgsJXMsJWxkKTogc3R1YlxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBDaGVjayBmb3IgZmlsZSBleGlzdGVuY2UgKi8KCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleTMyQSBbQURWQVBJMzIuMTYzXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVzdG9yZUtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBGaWxlVyA9IHN0cmR1cEEyVyhscEZpbGUpOwogICAgcmV0ID0gUmVnUmVzdG9yZUtleTMyVyggaGtleSwgbHBGaWxlVywgZHdGbGFncyApOwogICAgaWYobHBGaWxlVykgZnJlZShscEZpbGVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1JlcGxhY2VLZXkzMlcgW0FEVkFQSTMyLjE2Ml0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwU3ViS2V5ICBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleQogKiAgICBscE5ld0ZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIGZpbGUgd2l0aCBuZXcgZGF0YQogKiAgICBscE9sZEZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIGJhY2t1cCBmaWxlCiAqLwpMT05HIFdJTkFQSSBSZWdSZXBsYWNlS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBTdWJLZXksIExQQ1dTVFIgbHBOZXdGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIGxwT2xkRmlsZSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVzLCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBTdWJLZXkpLAogICAgICAgICAgZGVidWdzdHJfdyhscE5ld0ZpbGUpLGRlYnVnc3RyX3cobHBPbGRGaWxlKSk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUUocmVnLCAiKCV4LCVzLCVzLCVzKTogc3R1YlxuIiwgaGtleSwgZGVidWdzdHJfdyhscFN1YktleSksIAogICAgICAgICAgZGVidWdzdHJfdyhscE5ld0ZpbGUpLGRlYnVnc3RyX3cobHBPbGRGaWxlKSk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1JlcGxhY2VLZXkzMkEgW0FEVkFQSTMyLjE2MV0KICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5LCBMUENTVFIgbHBOZXdGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBPbGRGaWxlICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBTdWJLZXlXID0gc3RyZHVwQTJXKGxwU3ViS2V5KTsKICAgIExQV1NUUiBscE5ld0ZpbGVXID0gc3RyZHVwQTJXKGxwTmV3RmlsZSk7CiAgICBMUFdTVFIgbHBPbGRGaWxlVyA9IHN0cmR1cEEyVyhscE9sZEZpbGUpOwogICAgcmV0ID0gUmVnUmVwbGFjZUtleTMyVyggaGtleSwgbHBTdWJLZXlXLCBscE5ld0ZpbGVXLCBscE9sZEZpbGVXICk7CiAgICBmcmVlKGxwT2xkRmlsZVcpOwogICAgZnJlZShscE5ld0ZpbGVXKTsKICAgIGZyZWUobHBTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCg==