LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICoKICogRGVjZW1iZXIgMjEsIDE5OTcgLSBLZXZpbiBDb3plbnMKICogRml4ZWQgYnVncyBpbiB0aGUgX3c5NV9sb2FkcmVnKCkgZnVuY3Rpb24uIEFkZGVkIGV4dHJhIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyB0aGUgZm9ybWF0IG9mIHRoZSBXaW5kb3dzICc5NSByZWdpc3RyeSBmaWxlcy4KICoKICogTk9URVMKICogICAgV2hlbiBjaGFuZ2luZyB0aGlzIGZpbGUsIHBsZWFzZSByZS1ydW4gdGhlIHJlZ3Rlc3QgcHJvZ3JhbSB0byBlbnN1cmUKICogICAgdGhlIGNvbmRpdGlvbnMgYXJlIGhhbmRsZWQgcHJvcGVybHkuCiAqCiAqIFRPRE8KICogICAgU2VjdXJpdHkgYWNjZXNzCiAqICAgIE9wdGlvbiBoYW5kbGluZwogKiAgICBUaW1lIGZvciBSZWdFbnVtS2V5KiwgUmVnUXVlcnlJbmZvS2V5KgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL2ZjbnRsLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8cHdkLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJ4bWFsbG9jLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCnN0YXRpYyB2b2lkIFJFR0lTVFJZX0luaXQoKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCi8qIE5PVEU6IGRvIG5vdCBhcHBlbmQgYSAvLiBsaW51eCcgbWtkaXIoKSBXSUxMIEZBSUwgaWYgeW91IGRvIHRoYXQgKi8KI2RlZmluZSBXSU5FX1BSRUZJWAkJCSIvLndpbmUiCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUCQkiL3Vzci9sb2NhbC9ldGMvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUCSIvdXNyL2xvY2FsL2V0Yy93aW5lLnN5c3RlbXJlZyIKCi8qIHJlbGF0aXZlIGluIH51c2VyLy53aW5lLyA6ICovCiNkZWZpbmUgU0FWRV9DVVJSRU5UX1VTRVIJCSJ1c2VyLnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX01BQ0hJTkUJCSJzeXN0ZW0ucmVnIgoKI2RlZmluZSBLRVlfUkVHSVNUUlkJIlNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeSIKI2RlZmluZSBWQUxfU0FWRVVQREFURUQJIlNhdmVPbmx5VXBkYXRlZEtleXMiCgovKiBvbmUgdmFsdWUgb2YgYSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZVkFMVUUKewogICAgTFBXU1RSICAgbmFtZTsgICAgICAgICAgLyogbmFtZSBvZiB2YWx1ZSAoVU5JQ09ERSkgb3IgTlVMTCBmb3Igd2luMzEgKi8KICAgIERXT1JEICAgIHR5cGU7ICAgICAgICAgIC8qIHR5cGUgb2YgdmFsdWUgKi8KICAgIERXT1JEICAgIGxlbjsgICAgICAgICAgIC8qIGxlbmd0aCBvZiBkYXRhIGluIEJZVEVzICovCiAgICBEV09SRCAgICBsYXN0bW9kaWZpZWQ7ICAvKiB0aW1lIG9mIHNlY29uZHMgc2luY2UgMS4xLjE5NzAgKi8KICAgIExQQllURSAgIGRhdGE7ICAgICAgICAgIC8qIGNvbnRlbnQsIG1heSBiZSBzdHJpbmdzLCBiaW5hcmllcywgZXRjLiAqLwp9IEtFWVZBTFVFLCpMUEtFWVZBTFVFOwoKLyogYSByZWdpc3RyeSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZU1RSVUNUCnsKICAgIExQV1NUUiAgICAgICAgICAgICAgIGtleW5hbWU7ICAgICAgIC8qIG5hbWUgb2YgVEhJUyBrZXkgKFVOSUNPREUpICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBmbGFnczsgICAgICAgICAvKiBmbGFncy4gKi8KICAgIExQV1NUUiAgICAgICAgICAgICAgIGNsYXNzOwogICAgLyogdmFsdWVzICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBucm9mdmFsdWVzOyAgICAvKiBuciBvZiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIExQS0VZVkFMVUUgICAgICAgICAgIHZhbHVlczsgICAgICAgIC8qIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgLyoga2V5IG1hbmFnZW1lbnQgcG9pbnRlcnMgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHQ7ICAgICAgICAgIC8qIG5leHQga2V5IG9uIHNhbWUgaGllcmFyY2h5ICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0c3ViOyAgICAgICAvKiBrZXlzIHRoYXQgaGFuZyBiZWxvdyBUSElTIGtleSAqLwp9IEtFWVNUUlVDVCwgKkxQS0VZU1RSVUNUOwoKCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jbGFzc2VzX3Jvb3Q9TlVMTDsJLyogd2luZG93cyAzLjEgZ2xvYmFsIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF91c2VyPU5VTEw7CS8qIHVzZXIgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9sb2NhbF9tYWNoaW5lPU5VTEw7LyogbWFjaGluZSBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3VzZXJzPU5VTEw7CS8qIGFsbCB1c2Vycz8gKi8KCi8qIGR5bmFtaWMsIG5vdCBzYXZlZCAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfcGVyZm9ybWFuY2VfZGF0YT1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF9jb25maWc9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2R5bl9kYXRhPU5VTEw7CgovKiB3aGF0IHZhbHVldHlwZXMgZG8gd2UgbmVlZCB0byBjb252ZXJ0PyAqLwojZGVmaW5lIFVOSUNPTlZNQVNLCSgoMTw8UkVHX1NaKXwoMTw8UkVHX01VTFRJX1NaKXwoMTw8UkVHX0VYUEFORF9TWikpCgoKc3RhdGljIHN0cnVjdCBvcGVuaGFuZGxlIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCVJFR1NBTQkJYWNjZXNzbWFzazsKfSAgKm9wZW5oYW5kbGVzPU5VTEw7CnN0YXRpYyBpbnQJbnJvZm9wZW5oYW5kbGVzPTA7Ci8qIFN0YXJ0cyBhZnRlciAxIGJlY2F1c2UgMCwxIGFyZSByZXNlcnZlZCBmb3IgV2luMTYgKi8KLyogTm90ZTogU2hvdWxkIGFsd2F5cyBiZSBldmVuLCBhcyBXaW45NSBBRFZBUEkzMi5ETEwgcmVzZXJ2ZXMgb2RkCiAgICAgICAgIEhLRVlzIGZvciByZW1vdGUgcmVnaXN0cnkgYWNjZXNzICovCnN0YXRpYyBpbnQJY3VycmVudGhhbmRsZT0yOwoKCi8qCiAqIFFVRVNUSU9OCiAqICAgQXJlIHRoZXNlIGRvaW5nIHRoZSBzYW1lIGFzIEhFQVBfc3RyZHVwQXRvVyBhbmQgSEVBUF9zdHJkdXBXdG9BPwogKiAgIElmIHNvLCBjYW4gd2UgcmVtb3ZlIHRoZW0/CiAqIEFOU1dFUgogKiAgIE5vLCB0aGUgbWVtb3J5IGhhbmRsaW5nIGZ1bmN0aW9ucyBhcmUgY2FsbGVkIHZlcnkgb2Z0ZW4gaW4gaGVyZSwgCiAqICAganVzdCByZXBsYWNpbmcgdGhlbSBieSBIZWFwQWxsb2MoU3lzdGVtSGVhcCwuLi4pIG1ha2VzIHJlZ2lzdHJ5CiAqICAgbG9hZGluZyAxMDAgdGltZXMgc2xvd2VyLiAtTU0KICovCnN0YXRpYyBMUFdTVFIgc3RyZHVwQTJXKExQQ1NUUiBzcmMpCnsKICAgIGlmKHNyYykgewoJTFBXU1RSIGRlc3Q9eG1hbGxvYygyKnN0cmxlbihzcmMpKzIpOwoJbHN0cmNweUF0b1coZGVzdCxzcmMpOwoJcmV0dXJuIGRlc3Q7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIExQV1NUUiBzdHJkdXBXKExQQ1dTVFIgYSkgewoJTFBXU1RSCWI7CglpbnQJbGVuOwoKICAgIGlmKGEpIHsKCWxlbj1zaXplb2YoV0NIQVIpKihsc3RybGVuMzJXKGEpKzEpOwoJYj0oTFBXU1RSKXhtYWxsb2MobGVuKTsKCW1lbWNweShiLGEsbGVuKTsKCXJldHVybiBiOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCkxQV1NUUiBzdHJjdnRBMlcoTFBDU1RSIHNyYywgaW50IG5jaGFycykKCnsKICAgTFBXU1RSIGRlc3QgPSB4bWFsbG9jICgyICogbmNoYXJzICsgMik7CgogICBsc3RyY3B5bkF0b1coZGVzdCxzcmMsbmNoYXJzKzEpOwogICBkZXN0W25jaGFyc10gPSAwOwogICByZXR1cm4gZGVzdDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogaXNfc3RhbmRhcmRfaGtleSBbSW50ZXJuYWxdCiAqIERldGVybWluZXMgaWYgYSBoa2V5IGlzIGEgc3RhbmRhcmQga2V5CiAqLwpzdGF0aWMgQk9PTDMyIGlzX3N0YW5kYXJkX2hrZXkoIEhLRVkgaGtleSApCnsKICAgIHN3aXRjaChoa2V5KSB7CiAgICAgICAgY2FzZSAweDAwMDAwMDAwOgogICAgICAgIGNhc2UgMHgwMDAwMDAwMToKICAgICAgICBjYXNlIEhLRVlfQ0xBU1NFU19ST09UOgogICAgICAgIGNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKICAgICAgICBjYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgogICAgICAgIGNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgogICAgICAgIGNhc2UgSEtFWV9VU0VSUzoKICAgICAgICBjYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKICAgICAgICBjYXNlIEhLRVlfRFlOX0RBVEE6CiAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBhZGRfaGFuZGxlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIGFkZF9oYW5kbGUoIEhLRVkgaGtleSwgTFBLRVlTVFJVQ1QgbHBrZXksIFJFR1NBTSBhY2Nlc3NtYXNrICkKewogICAgaW50IGk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXAsJWx4KVxuIixoa2V5LGxwa2V5LGFjY2Vzc21hc2spOwogICAgLyogQ2hlY2sgZm9yIGR1cGxpY2F0ZXMgKi8KICAgIGZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykgewogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5scGtleT09bHBrZXkpIHsKICAgICAgICAgICAgLyogVGhpcyBpcyBub3QgcmVhbGx5IGFuIGVycm9yIC0gdGhlIHVzZXIgaXMgYWxsb3dlZCB0byBjcmVhdGUKICAgICAgICAgICAgICAgdHdvIChvciBtb3JlKSBoYW5kbGVzIHRvIHRoZSBzYW1lIGtleSAqLwogICAgICAgICAgICAvKldBUk4ocmVnLCAiQWRkaW5nIGtleSAlcCB0d2ljZVxuIixscGtleSk7Ki8KICAgICAgICB9CiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpIHsKICAgICAgICAgICAgV0FSTihyZWcsICJBZGRpbmcgaGFuZGxlICV4IHR3aWNlXG4iLGhrZXkpOwogICAgICAgIH0KICAgIH0KICAgIG9wZW5oYW5kbGVzPXhyZWFsbG9jKCBvcGVuaGFuZGxlcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzKzEpKTsKCiAgICBvcGVuaGFuZGxlc1tpXS5scGtleSA9IGxwa2V5OwogICAgb3BlbmhhbmRsZXNbaV0uaGtleSA9IGhrZXk7CiAgICBvcGVuaGFuZGxlc1tpXS5hY2Nlc3NtYXNrID0gYWNjZXNzbWFzazsKICAgIG5yb2ZvcGVuaGFuZGxlcysrOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBnZXRfaGFuZGxlIFtJbnRlcm5hbF0KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBQb2ludGVyIHRvIGtleQogKiAgICBGYWlsdXJlOiBOVUxMCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgZ2V0X2hhbmRsZSggSEtFWSBoa2V5ICkKewogICAgaW50IGk7CgogICAgZm9yIChpPTA7IGk8bnJvZm9wZW5oYW5kbGVzOyBpKyspCiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXkgPT0gaGtleSkKICAgICAgICAgICAgcmV0dXJuIG9wZW5oYW5kbGVzW2ldLmxwa2V5OwogICAgV0FSTihyZWcsICJDb3VsZCBub3QgZmluZCBoYW5kbGUgJXhcbiIsaGtleSk7CiAgICByZXR1cm4gTlVMTDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogcmVtb3ZlX2hhbmRsZSBbSW50ZXJuYWxdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHJlbW92ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRVJST1JfSU5WQUxJRF9IQU5ETEUKICovCnN0YXRpYyBEV09SRCByZW1vdmVfaGFuZGxlKCBIS0VZIGhrZXkgKQp7CiAgICBpbnQgaTsKCiAgICBmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspCiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpCiAgICAgICAgICAgIGJyZWFrOwoKICAgIGlmIChpID09IG5yb2ZvcGVuaGFuZGxlcykgewogICAgICAgIFdBUk4ocmVnLCAiQ291bGQgbm90IGZpbmQgaGFuZGxlICV4XG4iLGhrZXkpOwogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKICAgIH0KCiAgICBtZW1jcHkoIG9wZW5oYW5kbGVzK2ksCiAgICAgICAgICAgIG9wZW5oYW5kbGVzK2krMSwKICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLWktMSkKICAgICk7CiAgICBvcGVuaGFuZGxlcz14cmVhbGxvYyhvcGVuaGFuZGxlcyxzaXplb2Yoc3RydWN0IG9wZW5oYW5kbGUpKihucm9mb3BlbmhhbmRsZXMtMSkpOwogICAgbnJvZm9wZW5oYW5kbGVzLS07CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBsb29rdXBfaGtleSBbSW50ZXJuYWxdCiAqIAogKiBKdXN0IGFzIHRoZSBuYW1lIHNheXMuIENyZWF0ZXMgdGhlIHJvb3Qga2V5cyBvbiBkZW1hbmQsIHNvIHdlIGNhbiBjYWxsIHRoZQogKiBSZWcqIGZ1bmN0aW9ucyBhdCBhbnkgdGltZS4KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBQb2ludGVyIHRvIGtleSBzdHJ1Y3R1cmUKICogICAgRmFpbHVyZTogTlVMTAogKi8KI2RlZmluZSBBRERfUk9PVF9LRVkoeHgpIFwKCXh4ID0gKExQS0VZU1RSVUNUKXhtYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpO1wKCW1lbXNldCh4eCwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTtcCgl4eC0+a2V5bmFtZT0gc3RyZHVwQTJXKCI8c2hvdWxkX25vdF9hcHBlYXJfYW55d2hlcmU+Iik7CgpzdGF0aWMgTFBLRVlTVFJVQ1QgbG9va3VwX2hrZXkoIEhLRVkgaGtleSApCnsKCXN3aXRjaCAoaGtleSkgewoJLyogMCBhbmQgMSBhcmUgdmFsaWQgcm9vdGtleXMgaW4gd2luMTYgc2hlbGwuZGxsIGFuZCBhcmUgdXNlZCBieQoJICogc29tZSBwcm9ncmFtcy4gRG8gbm90IHJlbW92ZSB0aG9zZSBjYXNlcy4gLU1NCgkgKi8KICAgIAljYXNlIDB4MDAwMDAwMDA6CgljYXNlIDB4MDAwMDAwMDE6CgljYXNlIEhLRVlfQ0xBU1NFU19ST09UOiB7CgkJaWYgKCFrZXlfY2xhc3Nlc19yb290KSB7CgkJCUhLRVkJY2xfcl9oa2V5OwoKCQkJLyogY2FsbHMgbG9va3VwX2hrZXkgcmVjdXJzaXZlbHksIFRXSUNFICovCgkJCWlmIChSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlNPRlRXQVJFXFxDbGFzc2VzIiwmY2xfcl9oa2V5KSE9RVJST1JfU1VDQ0VTUykgewoJCQkJRVJSKHJlZywiQ291bGQgbm90IGNyZWF0ZSBIS0xNXFxTT0ZUV0FSRVxcQ2xhc3Nlcy4gVGhpcyBpcyBpbXBvc3NpYmxlLlxuIik7CgkJCQlleGl0KDEpOwoJCQl9CgkJCWtleV9jbGFzc2VzX3Jvb3QgPSBsb29rdXBfaGtleShjbF9yX2hrZXkpOwoJCX0KCQlyZXR1cm4ga2V5X2NsYXNzZXNfcm9vdDsKCX0KCWNhc2UgSEtFWV9DVVJSRU5UX1VTRVI6CgkJaWYgKCFrZXlfY3VycmVudF91c2VyKSB7CgkJCUhLRVkJY191X2hrZXk7CgkJCXN0cnVjdAlwYXNzd2QJKnB3ZDsKCgkJCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CgkJCS8qIGNhbGxzIGxvb2t1cF9oa2V5IHJlY3Vyc2l2ZWx5LCBUV0lDRSAqLwoJCQlpZiAocHdkICYmIHB3ZC0+cHdfbmFtZSkgewoJCQkJaWYgKFJlZ0NyZWF0ZUtleTE2KEhLRVlfVVNFUlMscHdkLT5wd19uYW1lLCZjX3VfaGtleSkhPUVSUk9SX1NVQ0NFU1MpIHsKCQkJCQlFUlIocmVnLCJDb3VsZCBub3QgY3JlYXRlIEhVXFwlcy4gVGhpcyBpcyBpbXBvc3NpYmxlLlxuIixwd2QtPnB3X25hbWUpOwoJCQkJCWV4aXQoMSk7CgkJCQl9CgkJCQlrZXlfY3VycmVudF91c2VyID0gbG9va3VwX2hrZXkoY191X2hrZXkpOwoJCQl9IGVsc2UgewoJCQkJLyogbm90aGluZyBmb3VuZCwgdXNlIHN0YW5kYWxvbmUgKi8KCQkJCUFERF9ST09UX0tFWShrZXlfY3VycmVudF91c2VyKTsKCQkJfQoJCX0KCQlyZXR1cm4ga2V5X2N1cnJlbnRfdXNlcjsKCWNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgoJCWlmICgha2V5X2xvY2FsX21hY2hpbmUpIHsKCQkJQUREX1JPT1RfS0VZKGtleV9sb2NhbF9tYWNoaW5lKTsKCQkJUkVHSVNUUllfSW5pdCgpOwoJCX0KCQlyZXR1cm4ga2V5X2xvY2FsX21hY2hpbmU7CgljYXNlIEhLRVlfVVNFUlM6CgkJaWYgKCFrZXlfdXNlcnMpIHsKCQkJQUREX1JPT1RfS0VZKGtleV91c2Vycyk7CgkJfQoJCXJldHVybiBrZXlfdXNlcnM7CgljYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKCQlpZiAoIWtleV9wZXJmb3JtYW5jZV9kYXRhKSB7CgkJCUFERF9ST09UX0tFWShrZXlfcGVyZm9ybWFuY2VfZGF0YSk7CgkJfQoJCXJldHVybiBrZXlfcGVyZm9ybWFuY2VfZGF0YTsKCWNhc2UgSEtFWV9EWU5fREFUQToKCQlpZiAoIWtleV9keW5fZGF0YSkgewoJCQlBRERfUk9PVF9LRVkoa2V5X2R5bl9kYXRhKTsKCQl9CgkJcmV0dXJuIGtleV9keW5fZGF0YTsKCWNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKCQlpZiAoIWtleV9jdXJyZW50X2NvbmZpZykgewoJCQlBRERfUk9PVF9LRVkoa2V5X2N1cnJlbnRfY29uZmlnKTsKCQl9CgkJcmV0dXJuIGtleV9jdXJyZW50X2NvbmZpZzsKCWRlZmF1bHQ6CgkJcmV0dXJuIGdldF9oYW5kbGUoaGtleSk7Cgl9CgkvKk5PVFJFQUNIRUQqLwp9CiN1bmRlZiBBRERfUk9PVF9LRVkKLyogc28gd2UgZG9uJ3QgYWNjaWRlbnRseSBhY2Nlc3MgdGhlbSAuLi4gKi8KI2RlZmluZSBrZXlfY3VycmVudF9jb25maWcgTlVMTCBOVUxMCiNkZWZpbmUga2V5X2N1cnJlbnRfdXNlciBOVUxMIE5VTEwKI2RlZmluZSBrZXlfdXNlcnMgTlVMTCBOVUxMCiNkZWZpbmUga2V5X2xvY2FsX21hY2hpbmUgTlVMTCBOVUxMCiNkZWZpbmUga2V5X2NsYXNzZXNfcm9vdCBOVUxMIE5VTEwKI2RlZmluZSBrZXlfZHluX2RhdGEgTlVMTCBOVUxMCiNkZWZpbmUga2V5X3BlcmZvcm1hbmNlX2RhdGEgTlVMTCBOVUxMCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIHNwbGl0X2tleXBhdGggW0ludGVybmFsXQogKiBzcGxpdHMgdGhlIHVuaWNvZGUgc3RyaW5nICd3cCcgaW50byBhbiBhcnJheSBvZiBzdHJpbmdzLgogKiB0aGUgYXJyYXkgaXMgYWxsb2NhdGVkIGJ5IHRoaXMgZnVuY3Rpb24uIAogKiBGcmVlIHRoZSBhcnJheSB1c2luZyBGUkVFX0tFWV9QQVRICiAqCiAqIFBBUkFNUwogKiAgICB3cCAgW0ldIFN0cmluZyB0byBzcGxpdCB1cAogKiAgICB3cHYgW09dIEFycmF5IG9mIHBvaW50ZXJzIHRvIHN0cmluZ3MKICogICAgd3BjIFtPXSBOdW1iZXIgb2YgY29tcG9uZW50cwogKi8Kc3RhdGljIHZvaWQgc3BsaXRfa2V5cGF0aCggTFBDV1NUUiB3cCwgTFBXU1RSICoqd3B2LCBpbnQgKndwYykKewogICAgaW50CWksaixsZW47CiAgICBMUFdTVFIgd3M7CgogICAgVFJBQ0UocmVnLCIoJXMsJXAsJXApXG4iLGRlYnVnc3RyX3cod3ApLHdwdix3cGMpOwoKICAgIHdzCT0gSEVBUF9zdHJkdXBXKCBTeXN0ZW1IZWFwLCAwLCB3cCApOwoKICAgIC8qIFdlIGtub3cgd2UgaGF2ZSBhdCBsZWFzdCBvbmUgc3Vic3RyaW5nICovCiAgICAqd3BjID0gMTsKCiAgICAvKiBSZXBsYWNlIGVhY2ggYmFja3NsYXNoIHdpdGggTlVMTCwgYW5kIGluY3JlbWVudCB0aGUgY291bnQgKi8KICAgIGZvciAoaT0wO3dzW2ldO2krKykgewogICAgICAgIGlmICh3c1tpXT09J1xcJykgewogICAgICAgICAgICB3c1tpXT0wOwogICAgICAgICAgICAoKndwYykrKzsKICAgICAgICB9CiAgICB9CgogICAgbGVuID0gaTsKCiAgICAvKiBBbGxvY2F0ZSB0aGUgc3BhY2UgZm9yIHRoZSBhcnJheSBvZiBwb2ludGVycywgbGVhdmluZyByb29tIGZvciB0aGUKICAgICAgIE5VTEwgYXQgdGhlIGVuZCAqLwogICAgKndwdiA9IChMUFdTVFIqKUhlYXBBbGxvYyggU3lzdGVtSGVhcCwgMCwgc2l6ZW9mKExQV1NUUikqKCp3cGMrMikpOwogICAgKCp3cHYpWzBdPSB3czsKCiAgICAvKiBBc3NpZ24gZWFjaCBwb2ludGVyIHRvIHRoZSBhcHByb3ByaWF0ZSBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZyAqLwogICAgaiA9IDE7CiAgICBmb3IgKGk9MTtpPGxlbjtpKyspCiAgICAgICAgaWYgKHdzW2ktMV09PTApIHsKICAgICAgICAgICAgKCp3cHYpW2orK109d3MraTsKICAgICAgICAgICAgLyogVFJBQ0UocmVnLCAiIFN1Yml0ZW0gJWQgPSAlc1xuIixqLTEsZGVidWdzdHJfdygoKndwdilbai0xXSkpOyAqLwogICAgICAgIH0KCiAgICAoKndwdilbal09TlVMTDsKfQojZGVmaW5lIEZSRUVfS0VZX1BBVEggSGVhcEZyZWUoU3lzdGVtSGVhcCwwLHdwc1swXSk7SGVhcEZyZWUoU3lzdGVtSGVhcCwwLHdwcyk7CgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJFR0lTVFJZX0luaXQgW0ludGVybmFsXQogKiBSZWdpc3RyeSBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIHNvbWUgZGVmYXVsdCBrZXlzLiAKICovCnN0YXRpYyB2b2lkIFJFR0lTVFJZX0luaXQoKSB7CglIS0VZCWhrZXk7CgljaGFyCWJ1ZlsyMDBdOwoKCVRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCglSZWdDcmVhdGVLZXkxNihIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIkhBUkRXQVJFXFxERVNDUklQVElPTlxcU3lzdGVtIiwmaGtleSk7CglSZWdTZXRWYWx1ZUV4MzJBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3cgTlRcXEN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRCdWlsZE51bWJlcgoJICoJCQkJCQlDdXJyZW50VHlwZQoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3duZXIKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE9yZ2FuaXphdGlvbgoJICoKCSAqLwoJLyogU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXFNOTVBcXFBhcmFtZXRlcnNcXFJGQzExNTZBZ2VudAoJICogCQkJCQlzdHJpbmcJU3lzQ29udGFjdAoJICogCQkJCQlzdHJpbmcJU3lzTG9jYXRpb24KCSAqIAkJCQkJCVN5c1NlcnZpY2VzCgkgKi8JCQkJCQkKCWlmICgtMSE9Z2V0aG9zdG5hbWUoYnVmLDIwMCkpIHsKCQlSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXENvbnRyb2xcXENvbXB1dGVyTmFtZVxcQ29tcHV0ZXJOYW1lIiwmaGtleSk7CgkJUmVnU2V0VmFsdWVFeDE2KGhrZXksIkNvbXB1dGVyTmFtZSIsMCxSRUdfU1osYnVmLHN0cmxlbihidWYpKzEpOwoJCVJlZ0Nsb3NlS2V5KGhrZXkpOwoJfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKiBTQVZFIFJlZ2lzdHJ5IEZ1bmN0aW9uICoqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIFJFR0lTVFJZX1NBVkVfVkVSU0lPTgkweDAwMDAwMDAxCgovKiBSZWdpc3RyeSBzYXZlZm9ybWF0OgogKiBJZiB5b3UgY2hhbmdlIGl0LCBpbmNyZWFzZSBhYm92ZSBudW1iZXIgYnkgMSwgd2hpY2ggd2lsbCBmbHVzaAogKiBvbGQgcmVnaXN0cnkgZGF0YWJhc2UgZmlsZXMuCiAqIAogKiBHbG9iYWw6CiAqIAkiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIgogKiAJc3Via2V5cy4uLi4KICogU3Via2V5czoKICogCWtleW5hbWUKICoJCXZhbHVlbmFtZT1sYXN0bW9kaWZpZWQsdHlwZSxkYXRhCiAqCQkuLi4KICoJCXN1YmtleXMKICoJLi4uCiAqIGtleW5hbWUsdmFsdWVuYW1lLHN0cmluZ2RhdGE6CiAqCXRoZSB1c3VhbCBhc2NpaSBjaGFyYWN0ZXJzIGZyb20gMHgwMC0weGZmICh3ZWxsLCBub3QgMHgwMCkKICoJYW5kIFx1WFhYWCBhcyBVTklDT0RFIHZhbHVlIFhYWFggd2l0aCBYWFhYPjB4ZmYKICoJKCAiPVxcXHQiIGVzY2FwZWQgaW4gXHVYWFhYIGZvcm0uKQogKiB0eXBlLGxhc3Rtb2RpZmllZDogCiAqCWludAogKiAKICogRklYTUU6IGRvZXNuJ3Qgc2F2ZSAnY2xhc3MnICh3aGF0IGRvZXMgaXQgbWVhbiBhbnl3YXk/KSwgbm9yIGZsYWdzLgogKgogKiBbSEtFWV9DVVJSRU5UX1VTRVJcXFNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeV0KICogU2F2ZU9ubHlVcGRhdGVkS2V5cz15ZXMKICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlX2NoZWNrX3RhaW50ZWQgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfc2F2ZV9jaGVja190YWludGVkKCBMUEtFWVNUUlVDVCBscGtleSApCnsKCWludAkJdGFpbnRlZDsKCglpZiAoIWxwa2V5KQoJCXJldHVybiAwOwoJaWYgKGxwa2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkKCQl0YWludGVkID0gMTsKCWVsc2UKCQl0YWludGVkID0gMDsKCXdoaWxlIChscGtleSkgewoJCWlmIChfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKSkgewoJCQlscGtleS0+ZmxhZ3MgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoJCQl0YWludGVkID0gMTsKCQl9CgkJbHBrZXkJPSBscGtleS0+bmV4dDsKCX0KCXJldHVybiB0YWludGVkOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlX1VTVFJJTkcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3NhdmVfVVNUUklORyggRklMRSAqRiwgTFBXU1RSIHdzdHIsIGludCBlc2NhcGVlcSApCnsKCUxQV1NUUglzOwoJaW50CWRvZXNjYXBlOwoKCWlmICh3c3RyPT1OVUxMKQoJCXJldHVybjsKCXM9d3N0cjsKCXdoaWxlICgqcykgewoJCWRvZXNjYXBlPTA7CgkJaWYgKCpzPjB4ZmYpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoKnM9PSdcbicpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoZXNjYXBlZXEgJiYgKnM9PSc9JykKCQkJZG9lc2NhcGUgPSAxOwoJCWlmICgqcz09J1xcJykKICAgICAgICAgICAgICAgICAgICAgICAgZnB1dGMoKnMsRik7IC8qIGlmIFxcIHRoZW4gcHV0IGl0IHR3aWNlLiAqLwoJCWlmIChkb2VzY2FwZSkKCQkJZnByaW50ZihGLCJcXHUlMDR4IiwqKCh1bnNpZ25lZCBzaG9ydCopcykpOwoJCWVsc2UKCQkJZnB1dGMoKnMsRik7CgkJcysrOwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlc3Via2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3NhdmVzdWJrZXkoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgbGV2ZWwsIGludCBhbGwgKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWksdGFicyxqOwoKCWxweGtleQk9IGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJIShscHhrZXktPmZsYWdzICYgUkVHX09QVElPTl9WT0xBVElMRSkgJiYKCQkJKGFsbCB8fCAobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkpCgkJKSB7CgkJCWZvciAodGFicz1sZXZlbDt0YWJzLS07KQoJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJX3NhdmVfVVNUUklORyhGLGxweGtleS0+a2V5bmFtZSwxKTsKCQkJZnB1dHMoIlxuIixGKTsKCQkJZm9yIChpPTA7aTxscHhrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJCQlMUEtFWVZBTFVFCXZhbD1scHhrZXktPnZhbHVlcytpOwoKCQkJCWZvciAodGFicz1sZXZlbCsxO3RhYnMtLTspCgkJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJCV9zYXZlX1VTVFJJTkcoRix2YWwtPm5hbWUsMCk7CgkJCQlmcHV0YygnPScsRik7CgkJCQlmcHJpbnRmKEYsIiVsZCwlbGQsIix2YWwtPnR5cGUsdmFsLT5sYXN0bW9kaWZpZWQpOwoJCQkJaWYgKCgxPDx2YWwtPnR5cGUpICYgVU5JQ09OVk1BU0spCgkJCQkJX3NhdmVfVVNUUklORyhGLChMUFdTVFIpdmFsLT5kYXRhLDApOwoJCQkJZWxzZQoJCQkJCWZvciAoaj0wO2o8dmFsLT5sZW47aisrKQoJCQkJCQlmcHJpbnRmKEYsIiUwMngiLCooKHVuc2lnbmVkIGNoYXIqKXZhbC0+ZGF0YStqKSk7CgkJCQlmcHV0cygiXG4iLEYpOwoJCQl9CgkJCS8qIGRlc2NlbmQgcmVjdXJzaXZlbHkgKi8KCQkJaWYgKCFfc2F2ZXN1YmtleShGLGxweGtleS0+bmV4dHN1YixsZXZlbCsxLGFsbCkpCgkJCQlyZXR1cm4gMDsKCQl9CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXN1YnJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF9zYXZlc3VicmVnKCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGFsbCApCnsKCWZwcmludGYoRiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkXG4iLFJFR0lTVFJZX1NBVkVfVkVSU0lPTik7Cglfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKTsKCXJldHVybiBfc2F2ZXN1YmtleShGLGxwa2V5LT5uZXh0c3ViLDAsYWxsKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIEJPT0wzMiBfc2F2ZXJlZyggTFBLRVlTVFJVQ1QgbHBrZXksIGNoYXIgKmZuLCBpbnQgYWxsICkKewoJRklMRQkqRjsKCglGPWZvcGVuKGZuLCJ3Iik7CglpZiAoRj09TlVMTCkgewoJCVdBUk4ocmVnLCJDb3VsZG4ndCBvcGVuICVzIGZvciB3cml0aW5nOiAlc1xuIiwKCQkJZm4sc3RyZXJyb3IoZXJybm8pCgkJKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglpZiAoIV9zYXZlc3VicmVnKEYsbHBrZXksYWxsKSkgewoJCWZjbG9zZShGKTsKCQl1bmxpbmsoZm4pOwoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gc2F2ZSBrZXlzLCBwZXJoYXBzIG5vIG1vcmUgZGlza3NwYWNlIGZvciAlcz9cbiIsZm4pOwoJCXJldHVybiBGQUxTRTsKCX0KCWZjbG9zZShGKTsKICAgICAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfU2F2ZVJlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnZvaWQgU0hFTExfU2F2ZVJlZ2lzdHJ5KCB2b2lkICkKewoJY2hhcgkqZm47CglzdHJ1Y3QJcGFzc3dkCSpwd2Q7CgljaGFyCWJ1Zls0XTsKCUhLRVkJaGtleTsKCWludAlhbGw7CgogICAgVFJBQ0UocmVnLCIodm9pZClcbiIpOwoKCWFsbD0wOwoJaWYgKFJlZ09wZW5LZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJc3RyY3B5KGJ1ZiwieWVzIik7Cgl9IGVsc2UgewoJCURXT1JEIGxlbixqdW5rLHR5cGU7CgoJCWxlbj00OwoJCWlmICgJKEVSUk9SX1NVQ0NFU1MhPVJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQkJCWhrZXksCgkJCQlWQUxfU0FWRVVQREFURUQsCgkJCQkmanVuaywKCQkJCSZ0eXBlLAoJCQkJYnVmLAoJCQkJJmxlbgoJCQkpKXx8ICh0eXBlIT1SRUdfU1opCgkJKQoJCQlzdHJjcHkoYnVmLCJ5ZXMiKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KCWlmIChsc3RyY21waTMyQShidWYsInllcyIpKQoJCWFsbD0xOwoJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCWlmIChwd2QhPU5VTEwgJiYgcHdkLT5wd19kaXIhPU5VTEwpCiAgICAgICAgewogICAgICAgICAgICAgICAgY2hhciAqdG1wOwoKCQlmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKHB3ZC0+cHdfZGlyKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikgKyAyICk7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgpOwoJCS8qIGNyZWF0ZSB0aGUgZGlyZWN0b3J5LiBkb24ndCBjYXJlIGFib3V0IGVycm9yY29kZXMuICovCgkJbWtkaXIoZm4sMDc1NSk7IC8qIGRyd3hyLXhyLXggKi8KCQlzdHJjYXQoZm4sIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwoJCXRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CgkJc3RyY3B5KHRtcCxmbik7c3RyY2F0KHRtcCwiLnRtcCIpOwoJCWlmIChfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUiksdG1wLGFsbCkpIHsKCQkJaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewoJCQkJcGVycm9yKCJyZW5hbWUgdG1wIHJlZ2lzdHJ5Iik7CgkJCQl1bmxpbmsodG1wKTsKCQkJfQoJCX0KCQlmcmVlKHRtcCk7CgkJZnJlZShmbik7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9NQUNISU5FKTsKCQl0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwoJCXN0cmNweSh0bXAsZm4pO3N0cmNhdCh0bXAsIi50bXAiKTsKCQlpZiAoX3NhdmVyZWcobG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSx0bXAsYWxsKSkgewoJCQlpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CgkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKCQkJCXVubGluayh0bXApOwoJCQl9CgkJfQoJCWZyZWUodG1wKTsKCQlmcmVlKGZuKTsKCX0gZWxzZQoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVkLlxuIixnZXR1aWQoKSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqIExPQUQgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmluZF9vcl9hZGRfa2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBMUEtFWVNUUlVDVCBfZmluZF9vcl9hZGRfa2V5KCBMUEtFWVNUUlVDVCBscGtleSwgTFBXU1RSIGtleW5hbWUgKQp7CglMUEtFWVNUUlVDVAlscHhrZXksKmxwbHBrZXk7CgoJaWYgKCgha2V5bmFtZSkgfHwgKGtleW5hbWVbMF09PTApKSB7CgkJZnJlZShrZXluYW1lKTsKCQlyZXR1cm4gbHBrZXk7Cgl9CglscGxwa2V5PSAmKGxwa2V5LT5uZXh0c3ViKTsKCWxweGtleQk9ICpscGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICghbHN0cmNtcGkzMlcobHB4a2V5LT5rZXluYW1lLGtleW5hbWUpKQoJCQlicmVhazsKCQlscGxwa2V5CT0gJihscHhrZXktPm5leHQpOwoJCWxweGtleQk9ICpscGxwa2V5OwoJfQoJaWYgKGxweGtleT09TlVMTCkgewoJCSpscGxwa2V5ID0gKExQS0VZU1RSVUNUKXhtYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpOwoJCWxweGtleQk9ICpscGxwa2V5OwoJCW1lbXNldChscHhrZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5LT5rZXluYW1lCT0ga2V5bmFtZTsKCX0gZWxzZQoJCWZyZWUoa2V5bmFtZSk7CglyZXR1cm4gbHB4a2V5Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF92YWx1ZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfZmluZF9vcl9hZGRfdmFsdWUoIExQS0VZU1RSVUNUIGxwa2V5LCBMUFdTVFIgbmFtZSwgRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgZGF0YSwgRFdPUkQgbGVuLCBEV09SRCBsYXN0bW9kaWZpZWQgKQp7CglMUEtFWVZBTFVFCXZhbD1OVUxMOwoJaW50CQlpOwoKCWlmIChuYW1lICYmICEqbmFtZSkgey8qIGVtcHR5IHN0cmluZyBlcXVhbHMgZGVmYXVsdCAoTlVMTCkgdmFsdWUgKi8KCQlmcmVlKG5hbWUpOwoJCW5hbWUgPSBOVUxMOwoJfQoKCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJdmFsPWxwa2V5LT52YWx1ZXMraTsKCQlpZiAobmFtZT09TlVMTCkgewoJCQlpZiAodmFsLT5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7CgkJfSBlbHNlIHsKCQkJaWYgKAl2YWwtPm5hbWUhPU5VTEwgJiYgCgkJCQkhbHN0cmNtcGkzMlcodmFsLT5uYW1lLG5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJCX0KCX0KCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewoJCWxwa2V5LT52YWx1ZXMgPSB4cmVhbGxvYygKCQkJbHBrZXktPnZhbHVlcywKCQkJKCsrbHBrZXktPm5yb2Z2YWx1ZXMpKnNpemVvZihLRVlWQUxVRSkKCQkpOwoJCXZhbD1scGtleS0+dmFsdWVzK2k7CgkJbWVtc2V0KHZhbCwnXDAnLHNpemVvZihLRVlWQUxVRSkpOwoJCXZhbC0+bmFtZSA9IG5hbWU7Cgl9IGVsc2UgewoJCWlmIChuYW1lKQoJCQlmcmVlKG5hbWUpOwoJfQoJaWYgKHZhbC0+bGFzdG1vZGlmaWVkPGxhc3Rtb2RpZmllZCkgewoJCXZhbC0+bGFzdG1vZGlmaWVkPWxhc3Rtb2RpZmllZDsKCQl2YWwtPnR5cGUgPSB0eXBlOwoJCXZhbC0+bGVuICA9IGxlbjsKCQlpZiAodmFsLT5kYXRhKSAKCQkJZnJlZSh2YWwtPmRhdGEpOwoJCXZhbC0+ZGF0YSA9IGRhdGE7Cgl9IGVsc2UKCQlmcmVlKGRhdGEpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9yZWFkX2xpbmUgW0ludGVybmFsXQogKgogKiByZWFkcyBhIGxpbmUgaW5jbHVkaW5nIGR5bmFtaWNhbGx5IGVubGFyZ2luZyB0aGUgcmVhZGJ1ZmZlciBhbmQgdGhyb3dpbmcKICogYXdheSBjb21tZW50cwogKi8Kc3RhdGljIGludCBfd2luZV9yZWFkX2xpbmUoIEZJTEUgKkYsIGNoYXIgKipidWYsIGludCAqbGVuICkKewoJY2hhcgkqcywqY3VycmVhZDsKCWludAlteWxlbixjdXJvZmY7CgoJY3VycmVhZAk9ICpidWY7CglteWxlbgk9ICpsZW47CgkqKmJ1Zgk9ICdcMCc7Cgl3aGlsZSAoMSkgewoJCXdoaWxlICgxKSB7CgkJCXM9ZmdldHMoY3VycmVhZCxteWxlbixGKTsKCQkJaWYgKHM9PU5VTEwpCgkJCQlyZXR1cm4gMDsgLyogRU9GICovCgkJCWlmIChOVUxMPT0ocz1zdHJjaHIoY3VycmVhZCwnXG4nKSkpIHsKCQkJCS8qIGJ1ZmZlciB3YXNuJ3QgbGFyZ2UgZW5vdWdoICovCgkJCQljdXJvZmYJPSBzdHJsZW4oKmJ1Zik7CgkJCQkqYnVmCT0geHJlYWxsb2MoKmJ1ZiwqbGVuKjIpOwoJCQkJY3VycmVhZAk9ICpidWYgKyBjdXJvZmY7CgkJCQlteWxlbgk9ICpsZW47CS8qIHdlIGZpbGxlZCB1cCB0aGUgYnVmZmVyIGFuZCAKCQkJCQkJICogZ290IG5ldyAnKmxlbicgYnl0ZXMgdG8gZmlsbAoJCQkJCQkgKi8KCQkJCSpsZW4JPSAqbGVuICogMjsKCQkJfSBlbHNlIHsKCQkJCSpzPSdcMCc7CgkJCQlicmVhazsKCQkJfQoJCX0KCQkvKiB0aHJvdyBhd2F5IGNvbW1lbnRzICovCgkJaWYgKCoqYnVmPT0nIycgfHwgKipidWY9PSc7JykgewoJCQljdXJyZWFkCT0gKmJ1ZjsKCQkJbXlsZW4JPSAqbGVuOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKHMpIAkvKiBnb3QgZW5kIG9mIGxpbmUgKi8KCQkJYnJlYWs7Cgl9CglyZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9VU1RSSU5HIFtJbnRlcm5hbF0KICoKICogY29udmVydHMgYSBjaGFyKiBpbnRvIGEgVU5JQ09ERSBzdHJpbmcgKHVwIHRvIGEgc3BlY2lhbCBjaGFyKQogKiBhbmQgcmV0dXJucyB0aGUgcG9zaXRpb24gZXhhY3RseSBhZnRlciB0aGF0IHN0cmluZwogKi8Kc3RhdGljIGNoYXIqIF93aW5lX3JlYWRfVVNUUklORyggY2hhciAqYnVmLCBMUFdTVFIgKnN0ciApCnsKCWNoYXIJKnM7CglMUFdTVFIJd3M7CgoJLyogcmVhZCB1cCB0byAiPSIgb3IgIlwwIiBvciAiXG4iICovCglzCT0gYnVmOwoJaWYgKCpzID09ICc9JykgewoJCS8qIGVtcHR5IHN0cmluZyBpcyB0aGUgd2luMy4xIGRlZmF1bHQgdmFsdWUoTlVMTCkqLwoJCSpzdHIJPSBOVUxMOwoJCXJldHVybiBzOwoJfQoJKnN0cgk9IChMUFdTVFIpeG1hbGxvYygyKnN0cmxlbihidWYpKzIpOwoJd3MJPSAqc3RyOwoJd2hpbGUgKCpzICYmICgqcyE9J1xuJykgJiYgKCpzIT0nPScpKSB7CgkJaWYgKCpzIT0nXFwnKQoJCQkqd3MrKz0qKCh1bnNpZ25lZCBjaGFyKilzKyspOwoJCWVsc2UgewoJCQlzKys7CgkJCWlmICgqcz09J1xcJykgewoJCQkJKndzKys9J1xcJzsKCQkJCXMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWlmICgqcyE9J3UnKSB7CgkJCQlXQVJOKHJlZywiTm9uIHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlIFxcJWMgZm91bmQgaW4gfCVzfFxuIiwqcyxidWYpOwoJCQkJKndzKys9J1xcJzsKCQkJCSp3cysrPSpzKys7CgkJCX0gZWxzZSB7CgkJCQljaGFyCXhidWZbNV07CgkJCQlpbnQJd2M7CgoJCQkJcysrOwoJCQkJbWVtY3B5KHhidWYscyw0KTt4YnVmWzRdPSdcMCc7CgkJCQlpZiAoIXNzY2FuZih4YnVmLCIleCIsJndjKSkKCQkJCQlXQVJOKHJlZywiU3RyYW5nZSBlc2NhcGUgc2VxdWVuY2UgJXMgZm91bmQgaW4gfCVzfFxuIix4YnVmLGJ1Zik7CgkJCQlzKz00OwoJCQkJKndzKysJPSh1bnNpZ25lZCBzaG9ydCl3YzsKCQkJfQoJCX0KCX0KCSp3cwk9IDA7Cgl3cwk9ICpzdHI7CglpZiAoKndzKQoJCSpzdHIJPSBzdHJkdXBXKCpzdHIpOwoJZWxzZQoJCSpzdHIJPSBOVUxMOwoJZnJlZSh3cyk7CglyZXR1cm4gczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHN1YmtleSBbSW50ZXJuYWxdCiAqCiAqIE5PVEVTCiAqICAgIEl0IHNlZW1zIGxpa2UgdGhpcyBpcyByZXR1cm5pbmcgYSBib29sZWFuLiAgU2hvdWxkIGl0PwogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IDEKICogICAgRmFpbHVyZTogMAogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3Via2V5KCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGxldmVsLCBjaGFyICoqYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqYnVmbGVuLCBEV09SRCBvcHRmbGFnICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlpOwoJY2hhcgkJKnM7CglMUFdTVFIJCW5hbWU7CgogICAgVFJBQ0UocmVnLCIoJXAsJXAsJWQsJXMsJWQsJWx4KVxuIiwgRiwgbHBrZXksIGxldmVsLCBkZWJ1Z3N0cl9hKCpidWYpLAogICAgICAgICAgKmJ1Zmxlbiwgb3B0ZmxhZyk7CgogICAgbHBrZXktPmZsYWdzIHw9IG9wdGZsYWc7CgogICAgLyogR29vZC4gIFdlIGFscmVhZHkgZ290IGEgbGluZSBoZXJlIC4uLiBzbyBwYXJzZSBpdCAqLwogICAgbHB4a2V5ID0gTlVMTDsKICAgIHdoaWxlICgxKSB7CiAgICAgICAgaT0wO3M9KmJ1ZjsKICAgICAgICB3aGlsZSAoKnM9PSdcdCcpIHsKICAgICAgICAgICAgcysrOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQogICAgICAgIGlmIChpPmxldmVsKSB7CiAgICAgICAgICAgIGlmIChscHhrZXk9PU5VTEwpIHsKICAgICAgICAgICAgICAgIFdBUk4ocmVnLCJHb3QgYSBzdWJoaWVyYXJjaHkgd2l0aG91dCByZXNwLiBrZXk/XG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF93aW5lX2xvYWRzdWJrZXkoRixscHhrZXksbGV2ZWwrMSxidWYsYnVmbGVuLG9wdGZsYWcpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoJCS8qIGxldCB0aGUgY2FsbGVyIGhhbmRsZSB0aGlzIGxpbmUgKi8KCQlpZiAoaTxsZXZlbCB8fCAqKmJ1Zj09J1wwJykKCQkJcmV0dXJuIDE7CgoJCS8qIGl0IGNhbiBiZTogYSB2YWx1ZSBvciBhIGtleW5hbWUuIFBhcnNlIHRoZSBuYW1lIGZpcnN0ICovCgkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywmbmFtZSk7CgoJCS8qIHN3aXRjaCgpIGRlZmF1bHQ6IGhhY2sgdG8gYXZvaWQgZ290b3MgKi8KCQlzd2l0Y2ggKDApIHsKCQlkZWZhdWx0OgoJCQlpZiAoKnM9PSdcMCcpIHsKCQkJCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoJCQl9IGVsc2UgewoJCQkJTFBCWVRFCQlkYXRhOwoJCQkJaW50CQlsZW4sbGFzdG1vZGlmaWVkLHR5cGU7CgoJCQkJaWYgKCpzIT0nPScpIHsKCQkJCQlXQVJOKHJlZywiVW5leHBlY3RlZCBjaGFyYWN0ZXI6ICVjXG4iLCpzKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCXMrKzsKCQkJCWlmICgyIT1zc2NhbmYocywiJWQsJWQsIiwmdHlwZSwmbGFzdG1vZGlmaWVkKSkgewoJCQkJCVdBUk4ocmVnLCJIYXZlbid0IHVuZGVyc3Rvb2QgcG9zc2libGUgdmFsdWUgaW4gfCVzfCwgc2tpcHBpbmcuXG4iLCpidWYpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJLyogc2tpcCB0aGUgMiAsICovCgkJCQlzPXN0cmNocihzLCcsJyk7cysrOwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCWlmICgoMTw8dHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsKExQV1NUUiopJmRhdGEpOwoJCQkJCWlmIChkYXRhKQoJCQkJCQlsZW4gPSBsc3RybGVuMzJXKChMUFdTVFIpZGF0YSkqMisyOwoJCQkJCWVsc2UJCgkJCQkJCWxlbiA9IDA7CgkJCQl9IGVsc2UgewoJCQkJCWxlbj1zdHJsZW4ocykvMjsKCQkJCQlkYXRhID0gKExQQllURSl4bWFsbG9jKGxlbisxKTsKCQkJCQlmb3IgKGk9MDtpPGxlbjtpKyspIHsKCQkJCQkJZGF0YVtpXT0wOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXT0oKnMtJzAnKTw8NDsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV09KCpzLSdhJysnXHhhJyk8PDQ7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nQScrJ1x4YScpPDw0OwoJCQkJCQlzKys7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldfD0qcy0nMCc7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nYScrJ1x4YSc7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nQScrJ1x4YSc7CgkJCQkJCXMrKzsKCQkJCQl9CgkJCQl9CgkJCQlfZmluZF9vcl9hZGRfdmFsdWUobHBrZXksbmFtZSx0eXBlLGRhdGEsbGVuLGxhc3Rtb2RpZmllZCk7CgkJCX0KCQl9CgkJLyogcmVhZCB0aGUgbmV4dCBsaW5lICovCgkJaWYgKCFfd2luZV9yZWFkX2xpbmUoRixidWYsYnVmbGVuKSkKCQkJcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHN1YnJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93aW5lX2xvYWRzdWJyZWcoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBEV09SRCBvcHRmbGFnICkKewoJaW50CXZlcjsKCWNoYXIJKmJ1ZjsKCWludAlidWZsZW47CgoJYnVmPXhtYWxsb2MoMTApO2J1Zmxlbj0xMDsKCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghc3NjYW5mKGJ1ZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIiwmdmVyKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICh2ZXIhPVJFR0lTVFJZX1NBVkVfVkVSU0lPTikgewoJCVRSQUNFKHJlZywiT2xkIGZvcm1hdCAoJWQpIHJlZ2lzdHJ5IGZvdW5kLCBpZ25vcmluZyBpdC4gKGJ1ZiB3YXMgJXMpLlxuIix2ZXIsYnVmKTsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIV93aW5lX2xvYWRzdWJrZXkoRixscGtleSwwLCZidWYsJmJ1ZmxlbixvcHRmbGFnKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWZyZWUoYnVmKTsKCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93aW5lX2xvYWRyZWcoIExQS0VZU1RSVUNUIGxwa2V5LCBjaGFyICpmbiwgRFdPUkQgb3B0ZmxhZyApCnsKICAgIEZJTEUgKkY7CgogICAgVFJBQ0UocmVnLCIoJXAsJXMsJWx4KVxuIixscGtleSxkZWJ1Z3N0cl9hKGZuKSxvcHRmbGFnKTsKCiAgICBGID0gZm9wZW4oZm4sInJiIik7CiAgICBpZiAoRj09TlVMTCkgewogICAgICAgIFdBUk4ocmVnLCJDb3VsZG4ndCBvcGVuICVzIGZvciByZWFkaW5nOiAlc1xuIixmbixzdHJlcnJvcihlcnJubykgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoIV93aW5lX2xvYWRzdWJyZWcoRixscGtleSxvcHRmbGFnKSkgewogICAgICAgIGZjbG9zZShGKTsKICAgICAgICB1bmxpbmsoZm4pOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGZjbG9zZShGKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2NvcHlfcmVnaXN0cnkgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX2NvcHlfcmVnaXN0cnkoIExQS0VZU1RSVUNUIGZyb20sIExQS0VZU1RSVUNUIHRvICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlqOwoJTFBLRVlWQUxVRQl2YWxmcm9tOwoKCWZyb209ZnJvbS0+bmV4dHN1YjsKCXdoaWxlIChmcm9tKSB7CgkJbHB4a2V5ID0gX2ZpbmRfb3JfYWRkX2tleSh0byxzdHJkdXBXKGZyb20tPmtleW5hbWUpKTsKCgkJZm9yIChqPTA7ajxmcm9tLT5ucm9mdmFsdWVzO2orKykgewoJCQlMUFdTVFIJbmFtZTsKCQkJTFBCWVRFCWRhdGE7CgoJCQl2YWxmcm9tID0gZnJvbS0+dmFsdWVzK2o7CgkJCW5hbWU9dmFsZnJvbS0+bmFtZTsKCQkJaWYgKG5hbWUpIG5hbWU9c3RyZHVwVyhuYW1lKTsKCQkJZGF0YT0oTFBCWVRFKXhtYWxsb2ModmFsZnJvbS0+bGVuKTsKCQkJbWVtY3B5KGRhdGEsdmFsZnJvbS0+ZGF0YSx2YWxmcm9tLT5sZW4pOwoKCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJCQkJbHB4a2V5LAoJCQkJbmFtZSwKCQkJCXZhbGZyb20tPnR5cGUsCgkJCQlkYXRhLAoJCQkJdmFsZnJvbS0+bGVuLAoJCQkJdmFsZnJvbS0+bGFzdG1vZGlmaWVkCgkJCSk7CgkJfQoJCV9jb3B5X3JlZ2lzdHJ5KGZyb20sbHB4a2V5KTsKCQlmcm9tID0gZnJvbS0+bmV4dDsKCX0KfQoKCi8qIFdJTkRPV1MgOTUgUkVHSVNUUlkgTE9BREVSICovCi8qIAogKiBTdHJ1Y3R1cmUgb2YgYSB3aW45NSByZWdpc3RyeSBkYXRhYmFzZS4KICogbWFpbiBoZWFkZXI6CiAqIDAgOgkiQ1JFRyIJLSBtYWdpYwogKiA0IDoJRFdPUkQgdmVyc2lvbgogKiA4IDoJRFdPUkQgb2Zmc2V0X29mX1JHREJfcGFydAogKiAwQy4uMEY6CT8gKHNvbWVvbmUgZmlsbCBpbiBwbGVhc2UpCiAqIDEwOiAgV09SRAludW1iZXIgb2YgUkdEQiBibG9ja3MKICogMTI6ICBXT1JECT8KICogMTQ6ICBXT1JECWFsd2F5cyAwMDAwPwogKiAxNjogIFdPUkQJYWx3YXlzIDAwMDE/CiAqIDE4Li4xRjoJPyAoc29tZW9uZSBmaWxsIGluIHBsZWFzZSkKICoKICogMjA6IFJHS05fc2VjdGlvbjoKICogICBoZWFkZXI6CiAqIAkwIDoJCSJSR0tOIgktIG1hZ2ljCiAqICAgICAgNCA6IERXT1JECW9mZnNldCB0byBmaXJzdCBSR0RCIHNlY3Rpb24KICogICAgICA4IDogRFdPUkQJb2Zmc2V0IHRvID8KICogCUMuLjB4MUI6IAk/IChmaWxsIGluKQogKiAgICAgIDB4MjAgLi4uIG9mZnNldF9vZl9SR0RCX3BhcnQ6IERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZXMKICoKICogICBEaXNrIEtleSBFbnRyeSBTdHJ1Y3R1cmU6CiAqCTAwOiBEV09SRAktIEZyZWUgZW50cnkgaW5kaWNhdG9yKD8pCiAqCTA0OiBEV09SRAktIEhhc2ggPSBzdW0gb2YgYnl0ZXMgb2Yga2V5bmFtZQogKgkwODogRFdPUkQJLSBSb290IGtleSBpbmRpY2F0b3I/IHVua25vd24sIGJ1dCB1c3VhbGx5IDB4RkZGRkZGRkYgb24gd2luOTUgc3lzdGVtcwogKgkwQzogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgUHJldmlvdXNMZXZlbCBLZXkuCiAqCTEwOiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBOZXh0IFN1YmxldmVsIEtleS4KICoJMTQ6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIE5leHQgS2V5IChvbiBzYW1lIGxldmVsKS4KICogREtFUD4xODogV09SRAktIE5yLCBMb3cgU2lnbmlmaWNhbnQgcGFydC4KICoJMUE6IFdPUkQJLSBOciwgSGlnaCBTaWduaWZpY2FudCBwYXJ0LgogKgogKiBUaGUgZGlzayBhZGRyZXNzIGFsd2F5cyBwb2ludHMgdG8gdGhlIG5yIHBhcnQgb2YgdGhlIHByZXZpb3VzIGtleSBlbnRyeSAKICogb2YgdGhlIHJlZmVyZW5jZWQga2V5LiBEb24ndCBhc2sgbWUgd2h5LCBvciBldmVuIGlmIEkgZ290IHRoaXMgY29ycmVjdAogKiBmcm9tIHN0YXJpbmcgYXQgMWtnIG9mIGhleGR1bXBzLiAoREtFUCkKICoKICogVGhlIEhpZ2ggc2lnbmlmaWNhbnQgcGFydCBvZiB0aGUgc3RydWN0dXJlIHNlZW1zIHRvIGVxdWFsIHRoZSBudW1iZXIKICogb2YgdGhlIFJHREIgc2VjdGlvbi4gVGhlIGxvdyBzaWduaWZpY2FudCBwYXJ0IGlzIGEgdW5pcXVlIElEIHdpdGhpbgogKiB0aGF0IFJHREIgc2VjdGlvbgogKgogKiBUaGVyZSBhcmUgdHdvIG1pbm9yIGNvcnJlY3Rpb25zIHRvIHRoZSBwb3NpdGlvbiBvZiB0aGF0IHN0cnVjdHVyZS4KICogMS4gSWYgdGhlIGFkZHJlc3MgaXMgeHh4MDE0IG9yIHh4eDAxOCBpdCB3aWxsIGJlIGFsaWduZWQgdG8geHh4MDFjIEFORCAKICogICAgdGhlIERLRSByZXJlYWQgZnJvbSB0aGVyZS4KICogMi4gSWYgdGhlIGFkZHJlc3MgaXMgeHh4RkZ4IGl0IHdpbGwgYmUgYWxpZ25lZCB0byAoeHh4KzEpMDAwLgogKiBDUFMgLSBJIGhhdmUgbm90IGV4cGVyaWVuY2VkIHRoZSBhYm92ZSBwaGVub21lbm9uIGluIG15IHJlZ2lzdHJ5IGZpbGVzCiAqCiAqIFJHREJfc2VjdGlvbjoKICogCTAwOgkJIlJHREIiCS0gbWFnaWMKICoJMDQ6IERXT1JECW9mZnNldCB0byBuZXh0IFJHREIgc2VjdGlvbgogKgkwODogRFdPUkQJPwogKgkwQzogV09SRAlhbHdheXMgMDAwZD8KICoJMEU6IFdPUkQJUkdEQiBibG9jayBudW1iZXIKICoJMTA6CURXT1JECT8gKGVxdWFscyB2YWx1ZSBhdCBvZmZzZXQgNCAtIHZhbHVlIGF0IG9mZnNldCA4KQogKgkxNC4uMUY6CQk/CiAqCTIwLi4uLi46CWRpc2sga2V5cwogKgogKiBkaXNrIGtleToKICogCTAwOiAJRFdPUkQJbmV4dGtleW9mZnNldAktIG9mZnNldCB0byB0aGUgbmV4dCBkaXNrIGtleSBzdHJ1Y3R1cmUKICoJMDg6IAlXT1JECW5yTFMJCS0gbG93IHNpZ25pZmljYW50IHBhcnQgb2YgTlIKICoJMEE6IAlXT1JECW5ySFMJCS0gaGlnaCBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBDOiAJRFdPUkQJYnl0ZXN1c2VkCS0gYnl0ZXMgdXNlZCBpbiB0aGlzIHN0cnVjdHVyZS4KICoJMTA6IAlXT1JECW5hbWVfbGVuCS0gbGVuZ3RoIG9mIG5hbWUgaW4gYnl0ZXMuIHdpdGhvdXQgXDAKICoJMTI6IAlXT1JECW5yX29mX3ZhbHVlcwktIG51bWJlciBvZiB2YWx1ZXMuCiAqCTE0OiAJY2hhcgluYW1lW25hbWVfbGVuXQktIG5hbWUgc3RyaW5nLiBObyBcMC4KICoJMTQrbmFtZV9sZW46IGRpc2sgdmFsdWVzCiAqCW5leHRrZXlvZmZzZXQ6IC4uLiBuZXh0IGRpc2sga2V5CiAqCiAqIGRpc2sgdmFsdWU6CiAqCTAwOglEV09SRAl0eXBlCQktIHZhbHVlIHR5cGUgKGhtbSwgY291bGQgYmUgV09SRCB0b28pCiAqCTA0OglEV09SRAkJCS0gdW5rbm93biwgdXN1YWxseSAwCiAqCTA4OglXT1JECW5hbWVsZW4JCS0gbGVuZ3RoIG9mIE5hbWUuIDAgbWVhbnMgbmFtZT1OVUxMCiAqCTBDOglXT1JECWRhdGFsZW4JCS0gbGVuZ3RoIG9mIERhdGEuCiAqCTEwOgljaGFyCW5hbWVbbmFtZWxlbl0JLSBuYW1lLCBubyBcMAogKgkxMCtuYW1lbGVuOiBCWVRFCWRhdGFbZGF0YWxlbl0gLSBkYXRhLCB3aXRob3V0IFwwIGlmIHN0cmluZwogKgkxMCtuYW1lbGVuK2RhdGFsZW46IG5leHQgdmFsdWVzIG9yIGRpc2sga2V5CiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuckhTIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKiByZXBlYXQgdW50aWwgZW5kIG9mIGZpbGUuCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgdmFsdWUgYXQgb2Zmc2V0CiAqIDEwIGVxdWFscyB0aGUgdmFsdWUgYXQgb2Zmc2V0IDQgbWludXMgdGhlIHZhbHVlIGF0IG9mZnNldCA4LiBJIGhhdmUgbm8KICogaWRlYSBhdCB0aGUgbW9tZW50IHdoYXQgdGhpcyBtZWFucy4gIChLZXZpbiBDb3plbnMpCiAqCiAqIEZJWE1FOiB0aGlzIGRlc2NyaXB0aW9uIG5lZWRzIHNvbWUgc2VyaW91cyBoZWxwLCB5ZXMuCiAqLwoKc3RydWN0CV93OTVrZXl2YWx1ZSB7Cgl1bnNpZ25lZCBsb25nCQl0eXBlOwoJdW5zaWduZWQgc2hvcnQJCWRhdGFsZW47CgljaGFyCQkJKm5hbWU7Cgl1bnNpZ25lZCBjaGFyCQkqZGF0YTsKCXVuc2lnbmVkIGxvbmcJCXgxOwoJaW50CQkJbGFzdG1vZGlmaWVkOwp9OwoKc3RydWN0IAlfdzk1a2V5IHsKCWNoYXIJCQkqbmFtZTsKCWludAkJCW5yb2Z2YWxzOwoJc3RydWN0CV93OTVrZXl2YWx1ZQkqdmFsdWVzOwoJc3RydWN0IF93OTVrZXkJCSpwcmV2bHZsOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0c3ViOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0Owp9OwoKCnN0cnVjdCBfdzk1X2luZm8gewogIGNoYXIgKnJna25idWZmZXI7CiAgaW50ICByZ2tuc2l6ZTsKICBjaGFyICpyZ2RiYnVmZmVyOwogIGludCAgcmdkYnNpemU7CiAgaW50ICBkZXB0aDsKICBpbnQgIGxhc3Rtb2RpZmllZDsKfTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfcHJvY2Vzc0tleSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgX3c5NV9wcm9jZXNzS2V5ICggTFBLRVlTVFJVQ1QgbHBrZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuckxTLCBpbnQgbnJNUywgc3RydWN0IF93OTVfaW5mbyAqaW5mbyApCgp7CiAgLyogRGlzayBLZXkgSGVhZGVyIHN0cnVjdHVyZSAoUkdEQiBwYXJ0KSAqLwoJc3RydWN0CWRraCB7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nCQluZXh0a2V5b2ZmOyAKCQl1bnNpZ25lZCBzaG9ydAkJbnJMUzsKCQl1bnNpZ25lZCBzaG9ydAkJbnJNUzsKCQl1bnNpZ25lZCBsb25nCQlieXRlc3VzZWQ7CgkJdW5zaWduZWQgc2hvcnQJCWtleW5hbWVsZW47CgkJdW5zaWduZWQgc2hvcnQJCXZhbHVlczsKCQl1bnNpZ25lZCBsb25nCQl4eDE7CgkJLyoga2V5bmFtZSAqLwoJCS8qIGRpc2sga2V5IHZhbHVlcyBvciBub3RoaW5nICovCgl9OwoJLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlICovCglzdHJ1Y3QJZGt2IHsKCQl1bnNpZ25lZCBsb25nCQl0eXBlOwoJCXVuc2lnbmVkIGxvbmcJCXgxOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxuYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxkYXRhbGVuOwoJCS8qIHZhbG5hbWUsIHZhbGRhdGEgKi8KCX07CgoJCglzdHJ1Y3QJZGtoIGRraDsKCWludAlieXRlc3JlYWQgPSAwOwoJY2hhciAgICAqcmdkYmRhdGEgPSBpbmZvLT5yZ2RiYnVmZmVyOwoJaW50ICAgICBuYnl0ZXMgPSBpbmZvLT5yZ2Ric2l6ZTsKCWNoYXIgICAgKmN1cmRhdGEgPSByZ2RiZGF0YTsKCWNoYXIgICAgKmVuZCA9IHJnZGJkYXRhICsgbmJ5dGVzOwoJaW50ICAgICBvZmZfbmV4dF9yZ2RiOwoJY2hhciAgICAqbmV4dCA9IHJnZGJkYXRhOwoJaW50ICAgICBucmdkYiwgaTsKCUxQS0VZU1RSVUNUCWxweGtleTsKCQoJZG8gewoJICBjdXJkYXRhID0gbmV4dDsKCSAgaWYgKHN0cm5jbXAoY3VyZGF0YSwgIlJHREIiLCA0KSkgcmV0dXJuIChOVUxMKTsKCSAgICAKCSAgbWVtY3B5KCZvZmZfbmV4dF9yZ2RiLGN1cmRhdGErNCw0KTsKCSAgbmV4dCA9IGN1cmRhdGEgKyBvZmZfbmV4dF9yZ2RiOwoJICBucmdkYiA9IChpbnQpICooKHNob3J0ICopY3VyZGF0YSArIDcpOwoKCX0gd2hpbGUgKG5yZ2RiICE9IG5yTVMgJiYgKG5leHQgPCBlbmQpKTsKCgkvKiBjdXJkYXRhIG5vdyBwb2ludHMgdG8gdGhlIHN0YXJ0IG9mIHRoZSByaWdodCBSR0RCIHNlY3Rpb24gKi8KCWN1cmRhdGEgKz0gMHgyMDsKCiNkZWZpbmUgWFJFQUQod2hlcmV0byxsZW4pIFwKCWlmICgoY3VyZGF0YSArIGxlbikgPGVuZCkge1wKCQltZW1jcHkod2hlcmV0byxjdXJkYXRhLGxlbik7XAoJCWN1cmRhdGErPWxlbjtcCgkJYnl0ZXNyZWFkKz1sZW47XAoJfQoKCWRvIHsKCSAgWFJFQUQoJmRraCwgc2l6ZW9mIChka2gpKTsKCSAgaWYgKGRraC5uckxTID09IG5yTFMpIGJyZWFrOwoKCSAgY3VyZGF0YSArPSBka2gubmV4dGtleW9mZiAtIHNpemVvZihka2gpOwoJfSB3aGlsZSAoY3VyZGF0YSA8IG5leHQpOwoKCWlmIChka2gubnJMUyAhPSBuckxTKSByZXR1cm4gKE5VTEwpOwoKCWlmIChucmdkYiAhPSBka2gubnJNUykgewoJICByZXR1cm4gKE5VTEwpOwoJfQoKICAgICAgICBhc3NlcnQoKGRraC5rZXluYW1lbGVuPDIpIHx8IGN1cmRhdGFbMF0pOwoJbHB4a2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksc3RyY3Z0QTJXKGN1cmRhdGEsIGRraC5rZXluYW1lbGVuKSk7CgljdXJkYXRhICs9IGRraC5rZXluYW1lbGVuOwoKCWZvciAoaT0wO2k8IGRraC52YWx1ZXM7IGkrKykgewoJICBzdHJ1Y3QgZGt2IGRrdjsKCSAgTFBCWVRFIGRhdGE7CgkgIGludCBsZW47CgkgIExQV1NUUiBuYW1lOwoKCSAgWFJFQUQoJmRrdixzaXplb2YoZGt2KSk7CgoJICBuYW1lID0gc3RyY3Z0QTJXKGN1cmRhdGEsIGRrdi52YWxuYW1lbGVuKTsKCSAgY3VyZGF0YSArPSBka3YudmFsbmFtZWxlbjsKCgkgIGlmICgoMSA8PCBka3YudHlwZSkgJiBVTklDT05WTUFTSykgewoJICAgIGRhdGEgPSAoTFBCWVRFKSBzdHJjdnRBMlcoY3VyZGF0YSwgZGt2LnZhbGRhdGFsZW4pOwoJICAgIGxlbiA9IDIqKGRrdi52YWxkYXRhbGVuICsgMSk7CgkgIH0gZWxzZSB7CgkgICAgLyogSSBkb24ndCB0aGluayB3ZSB3YW50IHRvIE5VTEwgdGVybWluYXRlIGFsbCBkYXRhICovCgkgICAgZGF0YSA9IHhtYWxsb2MoZGt2LnZhbGRhdGFsZW4pOwoJICAgIG1lbWNweSAoZGF0YSwgY3VyZGF0YSwgZGt2LnZhbGRhdGFsZW4pOwoJICAgIGxlbiA9IGRrdi52YWxkYXRhbGVuOwoJICB9CgoJICBjdXJkYXRhICs9IGRrdi52YWxkYXRhbGVuOwoJICAKCSAgX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJCQkgICAgIGxweGtleSwKCQkJICAgICBuYW1lLAoJCQkgICAgIGRrdi50eXBlLAoJCQkgICAgIGRhdGEsCgkJCSAgICAgbGVuLAoJCQkgICAgIGluZm8tPmxhc3Rtb2RpZmllZAoJCQkgICAgICk7CgoJfQoKCXJldHVybiAobHB4a2V5KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X3dhbGtyZ2tuIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93OTVfd2Fsa3Jna24oIExQS0VZU1RSVUNUIHByZXZrZXksIGNoYXIgKm9mZiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBfdzk1X2luZm8gKmluZm8gKQoKewogIC8qIERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZSAoUkdLTiBwYXJ0KSAqLwogIHN0cnVjdAlka2UgewogICAgdW5zaWduZWQgbG9uZwkJeDE7CiAgICB1bnNpZ25lZCBsb25nCQl4MjsKICAgIHVuc2lnbmVkIGxvbmcJCXgzOy8qdXN1YWxseSAweEZGRkZGRkZGICovCiAgICB1bnNpZ25lZCBsb25nCQlwcmV2bHZsOwogICAgdW5zaWduZWQgbG9uZwkJbmV4dHN1YjsKICAgIHVuc2lnbmVkIGxvbmcJCW5leHQ7CiAgICB1bnNpZ25lZCBzaG9ydAkJbnJMUzsKICAgIHVuc2lnbmVkIHNob3J0CQluck1TOwogIH0gKmRrZSA9IChzdHJ1Y3QgZGtlICopb2ZmOwogIExQS0VZU1RSVUNUICBscHhrZXk7CgogIGlmIChka2UgPT0gTlVMTCkgewogICAgZGtlID0gKHN0cnVjdCBka2UgKikgKChjaGFyICopaW5mby0+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/ICovCgkJKmxwc3pDbGFzcwk9IDA7CgkJKmxwY2NoQ2xhc3MJPSAyOwoJfQoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXkzMlcgW0FEVkFQSTMyLjE0MF0KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MzJXKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQV1NUUiBscHN6TmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBGSUxFVElNRQlmdDsKCiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKICAgIHJldHVybiBSZWdFbnVtS2V5RXgzMlcoaGtleSxpU3Via2V5LGxwc3pOYW1lLCZscGNjaE5hbWUsTlVMTCxOVUxMLE5VTEwsJmZ0KTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleUV4MzJBIFtBRFZBUEkzMi4xMzhdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleUV4MzJBKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTmFtZSwgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiBscHN6Q2xhc3MsIExQRFdPUkQgbHBjY2hDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVUSU1FICpmdCApCnsKCURXT1JECXJldCxscGNjaE5hbWVXLGxwY2NoQ2xhc3NXOwoJTFBXU1RSCWxwc3pOYW1lVyxscHN6Q2xhc3NXOwoKCglUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlTdWJrZXksbHBzek5hbWUsKmxwY2NoTmFtZSxscGR3UmVzZXJ2ZWQsbHBzekNsYXNzLGxwY2NoQ2xhc3MsZnQKCSk7CglpZiAobHBzek5hbWUpIHsKCQlscHN6TmFtZVcJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoTmFtZSoyKTsKCQlscGNjaE5hbWVXCT0gKmxwY2NoTmFtZSoyOwoJfSBlbHNlIHsKCQlscHN6TmFtZVcJPSBOVUxMOwoJCWxwY2NoTmFtZVcgCT0gMDsKCX0KCWlmIChscHN6Q2xhc3MpIHsKCQlscHN6Q2xhc3NXCQk9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hDbGFzcyoyKTsKCQlscGNjaENsYXNzVwk9ICpscGNjaENsYXNzKjI7Cgl9IGVsc2UgewoJCWxwc3pDbGFzc1cJPTA7CgkJbHBjY2hDbGFzc1c9MDsKCX0KCXJldD1SZWdFbnVtS2V5RXgzMlcoCgkJaGtleSwKCQlpU3Via2V5LAoJCWxwc3pOYW1lVywKCQkmbHBjY2hOYW1lVywKCQlscGR3UmVzZXJ2ZWQsCgkJbHBzekNsYXNzVywKCQkmbHBjY2hDbGFzc1csCgkJZnQKCSk7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJbHN0cmNweVd0b0EobHBzek5hbWUsbHBzek5hbWVXKTsKCQkqbHBjY2hOYW1lPXN0cmxlbihscHN6TmFtZSk7CgkJaWYgKGxwc3pDbGFzc1cpIHsKCQkJbHN0cmNweVd0b0EobHBzekNsYXNzLGxwc3pDbGFzc1cpOwoJCQkqbHBjY2hDbGFzcz1zdHJsZW4obHBzekNsYXNzKTsKCQl9Cgl9CglpZiAobHBzek5hbWVXKQoJCWZyZWUobHBzek5hbWVXKTsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5MzJBIFtBRFZBUEkzMi4xMzddCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTMyQSggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGxwY2NoTmFtZSApCnsKICAgIEZJTEVUSU1FCWZ0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwogICAgcmV0dXJuIFJlZ0VudW1LZXlFeDMyQSggaGtleSwgaVN1YmtleSwgbHBzek5hbWUsICZscGNjaE5hbWUsIE5VTEwsIE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgJmZ0ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXkxNiBbU0hFTEwuN10gW0tFUk5FTC4yMTZdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTE2KCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKICAgIHJldHVybiBSZWdFbnVtS2V5MzJBKCBoa2V5LCBpU3Via2V5LCBscHN6TmFtZSwgbHBjY2hOYW1lKTsKfQoKCi8qIAogKiBFbnVtZXJhdGUgUmVnaXN0cnkgVmFsdWVzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdFbnVtVmFsdWUxNiAtPiBSZWdFbnVtVmFsdWUzMkEgLT4gUmVnRW51bVZhbHVlMzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bVZhbHVlMzJXIFtBRFZBUEkzMi4xNDJdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICBbSV0gSGFuZGxlIHRvIGtleSB0byBxdWVyeQogKiAgICBpVmFsdWUgICAgICBbSV0gSW5kZXggb2YgdmFsdWUgdG8gcXVlcnkKICogICAgbHBzelZhbHVlICAgW09dIFZhbHVlIHN0cmluZwogKiAgICBscGNjaFZhbHVlICBbT10gU2l6ZSBvZiB2YWx1ZSBidWZmZXIKICogICAgbHBkUmVzZXJ2ZWQgW0ldIFJlc2VydmVkCiAqICAgIGxwZHdUeXBlICAgIFtPXSBUeXBlIGNvZGUKICogICAgbHBiRGF0YSAgICAgW09dIFZhbHVlIGRhdGEKICogICAgbHBjYkRhdGEgICAgW09dIFNpemUgb2YgZGF0YSBidWZmZXIKICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUzMlcoIEhLRVkgaGtleSwgRFdPUkQgaVZhbHVlLCBMUFdTVFIgbHBzelZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoVmFsdWUsIExQRFdPUkQgbHBkUmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1R5cGUsIExQQllURSBscGJEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJTFBLRVlWQUxVRQl2YWw7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlWYWx1ZSxkZWJ1Z3N0cl93KGxwc3pWYWx1ZSksCiAgICAgICAgICBscGNjaFZhbHVlLGxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIE5vbmUgYXNrZWQgZm9yICovCiAgICBpZiAoIWlWYWx1ZSkKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKCiAgICBpZiAobHBrZXktPm5yb2Z2YWx1ZXMgPD0gaVZhbHVlKQogICAgICAgIHJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoKICAgIC8qIEZJWE1FOiBTaG91bGQgdGhpcyBiZSBscGtleS0+dmFsdWVzICsgaVZhbHVlICogc2l6ZW9mKEtFWVZBTFVFKT8gKi8KICAgIHZhbCA9IGxwa2V5LT52YWx1ZXMgKyBpVmFsdWU7CgoJaWYgKHZhbC0+bmFtZSkgewoJCWlmIChsc3RybGVuMzJXKHZhbC0+bmFtZSkqMisyPipscGNjaFZhbHVlKSB7CgkJCSpscGNjaFZhbHVlID0gbHN0cmxlbjMyVyh2YWwtPm5hbWUpKjIrMjsKCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQl9CgkJbWVtY3B5KGxwc3pWYWx1ZSx2YWwtPm5hbWUsMipsc3RybGVuMzJXKHZhbC0+bmFtZSkrMik7CgkJKmxwY2NoVmFsdWU9bHN0cmxlbjMyVyh2YWwtPm5hbWUpKjIrMjsKCX0gZWxzZSB7CgkJKmxwc3pWYWx1ZQk9IDA7CgkJKmxwY2NoVmFsdWUJPSAwOwoJfQoKICAgIC8qIENhbiBiZSBOVUxMIGlmIHRoZSB0eXBlIGNvZGUgaXMgbm90IHJlcXVpcmVkICovCiAgICBpZiAobHBkd1R5cGUpCiAgICAgICAgKmxwZHdUeXBlID0gdmFsLT50eXBlOwoKCWlmIChscGJEYXRhKSB7CgkJaWYgKHZhbC0+bGVuPipscGNiRGF0YSkKCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQltZW1jcHkobHBiRGF0YSx2YWwtPmRhdGEsdmFsLT5sZW4pOwoJCSpscGNiRGF0YSA9IHZhbC0+bGVuOwoJfQoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1WYWx1ZTMyQSBbQURWQVBJMzIuMTQxXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1WYWx1ZTMyQSggSEtFWSBoa2V5LCBEV09SRCBpVmFsdWUsIExQU1RSIGxwc3pWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaFZhbHVlLCBMUERXT1JEIGxwZFJlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUFdTVFIJbHBzelZhbHVlVzsKCUxQQllURQlscGJEYXRhVzsKCURXT1JECXJldCxscGNiRGF0YVc7CglEV09SRCBkd1R5cGU7CgoJVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSwKCQlscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhKTsKCglscHN6VmFsdWVXID0gKExQV1NUUil4bWFsbG9jKCpscGNjaFZhbHVlKjIpOwoJaWYgKGxwYkRhdGEpIHsKCQlscGJEYXRhVyA9IChMUEJZVEUpeG1hbGxvYygqbHBjYkRhdGEqMik7CgkJbHBjYkRhdGFXID0gKmxwY2JEYXRhKjI7Cgl9IGVsc2UKCQlscGJEYXRhVyA9IE5VTEw7CgoJcmV0ID0gUmVnRW51bVZhbHVlMzJXKCBoa2V5LCBpVmFsdWUsIGxwc3pWYWx1ZVcsIGxwY2NoVmFsdWUsIAoJCQkJbHBkUmVzZXJ2ZWQsICZkd1R5cGUsIGxwYkRhdGFXLCAmbHBjYkRhdGFXICk7CgoJaWYgKGxwZHdUeXBlKQoJCSpscGR3VHlwZSA9IGR3VHlwZTsKCglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJbHN0cmNweVd0b0EobHBzelZhbHVlLGxwc3pWYWx1ZVcpOwoJCWlmIChscGJEYXRhKSB7CgkJCWlmICgoMTw8ZHdUeXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJCQlsc3RyY3B5V3RvQShscGJEYXRhLChMUFdTVFIpbHBiRGF0YVcpOwoJCQl9IGVsc2UgewoJCQkJaWYgKGxwY2JEYXRhVyA+ICpscGNiRGF0YSkKCQkJCQlyZXQJPSBFUlJPUl9NT1JFX0RBVEE7CgkJCQllbHNlCgkJCQkJbWVtY3B5KGxwYkRhdGEsbHBiRGF0YVcsbHBjYkRhdGFXKTsKCQkJfQoJCQkqbHBjYkRhdGEgPSBscGNiRGF0YVc7CgkJfQoJfQogICAgaWYgKGxwYkRhdGFXKSBmcmVlKGxwYkRhdGFXKTsKICAgIGlmIChscHN6VmFsdWVXKSBmcmVlKGxwc3pWYWx1ZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bVZhbHVlMTYgW0tFUk5FTC4yMjNdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMTYoIEhLRVkgaGtleSwgRFdPUkQgaVZhbHVlLCBMUFNUUiBscHN6VmFsdWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hWYWx1ZSwgTFBEV09SRCBscGRSZXNlcnZlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLGhrZXksaVZhbHVlLGxwc3pWYWx1ZSxscGNjaFZhbHVlLAogICAgICAgICAgbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YSk7CiAgICByZXR1cm4gUmVnRW51bVZhbHVlMzJBKCBoa2V5LCBpVmFsdWUsIGxwc3pWYWx1ZSwgbHBjY2hWYWx1ZSwgbHBkUmVzZXJ2ZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBkd1R5cGUsIGxwYkRhdGEsIGxwY2JEYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nsb3NlS2V5IFtTSEVMTC4zXSBbS0VSTkVMLjIyMF0gW0FEVkFQSTMyLjEyNl0KICogUmVsZWFzZXMgdGhlIGhhbmRsZSBvZiB0aGUgc3BlY2lmaWVkIGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byBjbG9zZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0Nsb3NlS2V5KCBIS0VZIGhrZXkgKQp7CiAgICBUUkFDRShyZWcsIigleClcbiIsaGtleSk7CgogICAgLyogVGhlIHN0YW5kYXJkIGhhbmRsZXMgYXJlIGFsbG93ZWQgdG8gc3VjY2VlZCwgZXZlbiB0aG91Z2ggdGhleSBhcmUgbm90CiAgICAgICBjbG9zZWQgKi8KICAgIGlmIChpc19zdGFuZGFyZF9oa2V5KGhrZXkpKQogICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwoKICAgIHJldHVybiByZW1vdmVfaGFuZGxlKGhrZXkpOwp9CgoKLyogCiAqIERlbGV0ZSByZWdpc3RyeSBrZXkKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZUtleTE2IC0+IFJlZ0RlbGV0ZUtleTMyQSAtPiBSZWdEZWxldGVLZXkzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVLZXkzMlcgW0FEVkFQSTMyLjEzNF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldIEhhbmRsZSB0byBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5IFtJXSBOYW1lIG9mIHN1YmtleSB0byBkZWxldGUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkzMlcoIEhLRVkgaGtleSwgTFBXU1RSIGxwc3pTdWJLZXkgKQp7CglMUEtFWVNUUlVDVAkqbHBscFByZXZLZXksbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CgogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgLyogU3Via2V5IHBhcmFtIGNhbm5vdCBiZSBOVUxMICovCiAgICBpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KQogICAgICAgIHJldHVybiBFUlJPUl9CQURLRVk7CgogICAgLyogV2UgbmVlZCB0byBrbm93IHRoZSBwcmV2aW91cyBrZXkgaW4gdGhlIGhpZXIuICovCglzcGxpdF9rZXlwYXRoKGxwc3pTdWJLZXksJndwcywmd3BjKTsKCWkgCT0gMDsKCWxweGtleQk9IGxwTmV4dEtleTsKCXdoaWxlIChpPHdwYy0xKSB7CgkJbHB4a2V5PWxwTmV4dEtleS0+bmV4dHN1YjsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCVRSQUNFKHJlZywgIiAgU2Nhbm5pbmcgWyVzXVxuIiwKCQkJCSAgICAgZGVidWdzdHJfdyhscHhrZXktPmtleW5hbWUpKTsKCQkJaWYgKCFsc3RyY21waTMyVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJCWJyZWFrOwoJCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJCX0KCQlpZiAoIWxweGtleSkgewoJCQlGUkVFX0tFWV9QQVRIOwoJCQlUUkFDRShyZWcsICIgIE5vdCBmb3VuZC5cbiIpOwoJCQkvKiBub3QgZm91bmQgaXMgc3VjY2VzcyAqLwoJCQlyZXR1cm4gRVJST1JfU1VDQ0VTUzsKCQl9CgkJaSsrOwoJCWxwTmV4dEtleQk9IGxweGtleTsKCX0KCWxweGtleQk9IGxwTmV4dEtleS0+bmV4dHN1YjsKCWxwbHBQcmV2S2V5ID0gJihscE5leHRLZXktPm5leHRzdWIpOwoJd2hpbGUgKGxweGtleSkgewoJCVRSQUNFKHJlZywgIiAgU2Nhbm5pbmcgWyVzXVxuIiwKCQkJICAgICBkZWJ1Z3N0cl93KGxweGtleS0+a2V5bmFtZSkpOwoJCWlmICghbHN0cmNtcGkzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCWJyZWFrOwoJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCWxweGtleQkJPSBscHhrZXktPm5leHQ7Cgl9CgoJaWYgKCFscHhrZXkpIHsKCQlGUkVFX0tFWV9QQVRIOwoJCVdBUk4ocmVnICwgIiAgTm90IGZvdW5kLlxuIik7CgkJcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoJfQoKCWlmIChscHhrZXktPm5leHRzdWIpIHsKCQlGUkVFX0tFWV9QQVRIOwoJCVdBUk4ocmVnICwgIiAgTm90IGVtcHR5LlxuIik7CgkJcmV0dXJuIEVSUk9SX0NBTlRXUklURTsKCX0KCSpscGxwUHJldktleQk9IGxweGtleS0+bmV4dDsKCWZyZWUobHB4a2V5LT5rZXluYW1lKTsKCWlmIChscHhrZXktPmNsYXNzKQoJCWZyZWUobHB4a2V5LT5jbGFzcyk7CglpZiAobHB4a2V5LT52YWx1ZXMpCgkJZnJlZShscHhrZXktPnZhbHVlcyk7CglmcmVlKGxweGtleSk7CglGUkVFX0tFWV9QQVRIOwoJVFJBQ0UocmVnLCAiICBEb25lLlxuIik7CglyZXR1cm4JRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlS2V5MzJBIFtBRFZBUEkzMi4xMzNdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5ICkKewogICAgTFBXU1RSIGxwc3pTdWJLZXlXOwogICAgRFdPUkQgIHJldDsKCiAgICBUUkFDRShyZWcsIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpKTsKICAgIGxwc3pTdWJLZXlXID0gbHBzelN1YktleT9zdHJkdXBBMlcobHBzelN1YktleSk6TlVMTDsKICAgIHJldCA9IFJlZ0RlbGV0ZUtleTMyVyggaGtleSwgbHBzelN1YktleVcgKTsKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZUtleTE2IFtTSEVMTC40XSBbS0VSTkVMLjIxOV0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkpOwogICAgcmV0dXJuIFJlZ0RlbGV0ZUtleTMyQSggaGtleSwgbHBzelN1YktleSApOwp9CgoKLyogCiAqIERlbGV0ZSByZWdpc3RyeSB2YWx1ZQogKgogKiBDYWxscGF0aDoKICogUmVnRGVsZXRlVmFsdWUxNiAtPiBSZWdEZWxldGVWYWx1ZTMyQSAtPiBSZWdEZWxldGVWYWx1ZTMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZVZhbHVlMzJXIFtBRFZBUEkzMi4xMzZdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgW0ldCiAqICAgIGxwc3pWYWx1ZSBbSV0KICoKICogUkVUVVJOUwogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMzJXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6VmFsdWUgKQp7CglEV09SRAkJaTsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJTFBLRVlWQUxVRQl2YWw7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscHN6VmFsdWUpKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglpZiAobHBzelZhbHVlKSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmICgJbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmCgkJCQkhbHN0cmNtcGkzMlcobHBrZXktPnZhbHVlc1tpXS5uYW1lLGxwc3pWYWx1ZSkKCQkJKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9CgogICAgaWYgKGkgPT0gbHBrZXktPm5yb2Z2YWx1ZXMpCiAgICAgICAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoKCXZhbAk9IGxwa2V5LT52YWx1ZXMraTsKCWlmICh2YWwtPm5hbWUpIGZyZWUodmFsLT5uYW1lKTsKCWlmICh2YWwtPmRhdGEpIGZyZWUodmFsLT5kYXRhKTsKCW1lbWNweSgJCgkJbHBrZXktPnZhbHVlcytpLAoJCWxwa2V5LT52YWx1ZXMraSsxLAoJCXNpemVvZihLRVlWQUxVRSkqKGxwa2V5LT5ucm9mdmFsdWVzLWktMSkKCSk7CglscGtleS0+dmFsdWVzCT0gKExQS0VZVkFMVUUpeHJlYWxsb2MoCgkJCQlscGtleS0+dmFsdWVzLAoJCQkJKGxwa2V5LT5ucm9mdmFsdWVzLTEpKnNpemVvZihLRVlWQUxVRSkKCQkJKTsKCWxwa2V5LT5ucm9mdmFsdWVzLS07CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlVmFsdWUzMkEgW0FEVkFQSTMyLjEzNV0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTMyQSggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWUgKQp7CiAgICBMUFdTVFIgbHBzelZhbHVlVzsKICAgIERXT1JEICByZXQ7CgogICAgVFJBQ0UocmVnLCAiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlKSk7CiAgICBscHN6VmFsdWVXID0gbHBzelZhbHVlP3N0cmR1cEEyVyhscHN6VmFsdWUpOk5VTEw7CiAgICByZXQgPSBSZWdEZWxldGVWYWx1ZTMyVyggaGtleSwgbHBzelZhbHVlVyApOwogICAgaWYobHBzelZhbHVlVykgZnJlZShscHN6VmFsdWVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZVZhbHVlMTYgW0tFUk5FTC4yMjJdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUxNiggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWUgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcylcbiIsIGhrZXksZGVidWdzdHJfYShscHN6VmFsdWUpKTsKICAgIHJldHVybiBSZWdEZWxldGVWYWx1ZTMyQSggaGtleSwgbHBzelZhbHVlICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0ZsdXNoS2V5IFtLRVJORUwuMjI3XSBbQURWQVBJMzIuMTQzXQogKiBXcml0ZXMga2V5IHRvIHJlZ2lzdHJ5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdyaXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkoIEhLRVkgaGtleSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwogICAgQk9PTDMyIHJldDsKCiAgICBUUkFDRShyZWcsICIoJXgpXG4iLCBoa2V5KTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBFUlIocmVnLCAiV2hhdCBpcyB0aGUgY29ycmVjdCBmaWxlbmFtZT9cbiIpOwoKICAgIHJldCA9IF9zYXZlcmVnKCBscGtleSwgImZvby5iYXIiLCBUUlVFKTsKCiAgICBpZiggcmV0ICkgewogICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwogICAgfSBlbHNlCiAgICAgICAgcmV0dXJuIEVSUk9SX1VOS05PV047ICAvKiBGSVhNRSAqLwp9CgoKLyogRklYTUU6IGxwY2NoWFhYWCAuLi4gaXMgdGhpcyBjb3VudGluZyBpbiBXQ0hBUlMgb3IgaW4gQllURXMgPz8gKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5SW5mb0tleTMyVyBbQURWQVBJMzIuMTUzXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgICAgICAgICBbSV0gSGFuZGxlIHRvIGtleSB0byBxdWVyeQogKiAgICBscHN6Q2xhc3MgICAgICAgICAgICAgIFtPXSBCdWZmZXIgZm9yIGNsYXNzIHN0cmluZwogKiAgICBscGNjaENsYXNzICAgICAgICAgICAgIFtPXSBTaXplIG9mIGNsYXNzIHN0cmluZyBidWZmZXIKICogICAgbHBkd1Jlc2VydmVkICAgICAgICAgICBbSV0gUmVzZXJ2ZWQKICogICAgbHBjU3ViS2V5cyAgICAgICAgICAgICBbSV0gQnVmZmVyIGZvciBudW1iZXIgb2Ygc3Via2V5cwogKiAgICBscGNjaE1heFN1YktleSAgICAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3Qgc3Via2V5IG5hbWUgbGVuZ3RoCiAqICAgIGxwY2NoTWF4Q2xhc3MgICAgICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCBjbGFzcyBzdHJpbmcgbGVuZ3RoCiAqICAgIGxwY1ZhbHVlcyAgICAgICAgICAgICAgW09dIEJ1ZmZlciBmb3IgbnVtYmVyIG9mIHZhbHVlIGVudHJpZXMKICogICAgbHBjY2hNYXhWYWx1ZU5hbWUgICAgICBbT10gQnVmZmVyIGZvciBsb25nZXN0IHZhbHVlIG5hbWUgbGVuZ3RoCiAqICAgIGxwY2NiTWF4VmFsdWVEYXRhICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCB2YWx1ZSBkYXRhIGxlbmd0aAogKiAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yIFtPXSBCdWZmZXIgZm9yIHNlY3VyaXR5IGRlc2NyaXB0b3IgbGVuZ3RoCiAqICAgIGZ0CiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlJbmZvS2V5MzJXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6Q2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoQ2xhc3MsIExQRFdPUkQgbHBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY1N1YktleXMsIExQRFdPUkQgbHBjY2hNYXhTdWJrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hNYXhDbGFzcywgTFBEV09SRCBscGNWYWx1ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hNYXhWYWx1ZU5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NiTWF4VmFsdWVEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yLCBGSUxFVElNRSAqZnQgKQp7CglMUEtFWVNUUlVDVAlscGtleSxscHhrZXk7CglpbnQJCW5yb2ZrZXlzLG1heHN1YmtleSxtYXhjbGFzcyxtYXh2bmFtZSxtYXh2ZGF0YTsKCWludAkJaTsKCglUUkFDRShyZWcsIigleCwlcCwuLi4pXG4iLGhrZXksbHBzekNsYXNzKTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCWlmIChscHN6Q2xhc3MpIHsKCQlpZiAobHBrZXktPmNsYXNzKSB7CgkJCWlmIChsc3RybGVuMzJXKGxwa2V5LT5jbGFzcykqMisyPipscGNjaENsYXNzKSB7CgkJCQkqbHBjY2hDbGFzcz1sc3RybGVuMzJXKGxwa2V5LT5jbGFzcykqMjsKCQkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJCX0KCQkJKmxwY2NoQ2xhc3M9bHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjI7CgkJCW1lbWNweShscHN6Q2xhc3MsbHBrZXktPmNsYXNzLGxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSk7CgkJfSBlbHNlIHsKCQkJKmxwc3pDbGFzcwk9IDA7CgkJCSpscGNjaENsYXNzCT0gMDsKCQl9Cgl9IGVsc2UgewoJCWlmIChscGNjaENsYXNzKQoJCQkqbHBjY2hDbGFzcwk9IGxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyOwoJfQoJbHB4a2V5PWxwa2V5LT5uZXh0c3ViOwoJbnJvZmtleXM9bWF4c3Via2V5PW1heGNsYXNzPW1heHZuYW1lPW1heHZkYXRhPTA7Cgl3aGlsZSAobHB4a2V5KSB7CgkJbnJvZmtleXMrKzsKCQlpZiAobHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpPm1heHN1YmtleSkKCQkJbWF4c3Via2V5PWxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKTsKCQlpZiAobHB4a2V5LT5jbGFzcyAmJiBsc3RybGVuMzJXKGxweGtleS0+Y2xhc3MpPm1heGNsYXNzKQoJCQltYXhjbGFzcz1sc3RybGVuMzJXKGxweGtleS0+Y2xhc3MpOwoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9Cglmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykgewoJCUxQS0VZVkFMVUUJdmFsPWxwa2V5LT52YWx1ZXMraTsKCgkJaWYgKHZhbC0+bmFtZSAmJiBsc3RybGVuMzJXKHZhbC0+bmFtZSk+bWF4dm5hbWUpCgkJCW1heHZuYW1lPWxzdHJsZW4zMlcodmFsLT5uYW1lKTsKCQlpZiAodmFsLT5sZW4+bWF4dmRhdGEpCgkJCW1heHZkYXRhPXZhbC0+bGVuOwoJfQoJaWYgKCFtYXhjbGFzcykgbWF4Y2xhc3MJPSAxOwoJaWYgKCFtYXh2bmFtZSkgbWF4dm5hbWUJPSAxOwoJaWYgKGxwY1ZhbHVlcykKCQkqbHBjVmFsdWVzCT0gbHBrZXktPm5yb2Z2YWx1ZXM7CglpZiAobHBjU3ViS2V5cykKCQkqbHBjU3ViS2V5cwk9IG5yb2ZrZXlzOwoJaWYgKGxwY2NoTWF4U3Via2V5KQoJCSpscGNjaE1heFN1YmtleQk9IG1heHN1YmtleSoyOwoJaWYgKGxwY2NoTWF4Q2xhc3MpCgkJKmxwY2NoTWF4Q2xhc3MJPSBtYXhjbGFzcyoyOwoJaWYgKGxwY2NoTWF4VmFsdWVOYW1lKQoJCSpscGNjaE1heFZhbHVlTmFtZT0gbWF4dm5hbWU7CglpZiAobHBjY2JNYXhWYWx1ZURhdGEpCgkJKmxwY2NiTWF4VmFsdWVEYXRhPSBtYXh2ZGF0YTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeUluZm9LZXkzMkEgW0FEVkFQSTMyLjE1Ml0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeUluZm9LZXkzMkEoIEhLRVkgaGtleSwgTFBTVFIgbHBzekNsYXNzLCBMUERXT1JEIGxwY2NoQ2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1Jlc2VydmVkLCBMUERXT1JEIGxwY1N1YktleXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hNYXhTdWJrZXksIExQRFdPUkQgbHBjY2hNYXhDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNWYWx1ZXMsIExQRFdPUkQgbHBjY2hNYXhWYWx1ZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2JNYXhWYWx1ZURhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JTZWN1cml0eURlc2NyaXB0b3IsIEZJTEVUSU1FICpmdCApCnsKCUxQV1NUUgkJbHBzekNsYXNzVzsKCURXT1JECQlyZXQ7CgoJVFJBQ0UocmVnLCIoJXgsLi4uLi4uKVxuIixoa2V5KTsKCWlmIChscHN6Q2xhc3MpIHsKCQkqbHBjY2hDbGFzcyo9IDI7CgkJbHBzekNsYXNzVyAgPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoQ2xhc3MpOwoKCX0gZWxzZQoJCWxwc3pDbGFzc1cgID0gTlVMTDsKCXJldD1SZWdRdWVyeUluZm9LZXkzMlcoCgkJaGtleSwKCQlscHN6Q2xhc3NXLAoJCWxwY2NoQ2xhc3MsCgkJbHBkd1Jlc2VydmVkLAoJCWxwY1N1YktleXMsCgkJbHBjY2hNYXhTdWJrZXksCgkJbHBjY2hNYXhDbGFzcywKCQlscGNWYWx1ZXMsCgkJbHBjY2hNYXhWYWx1ZU5hbWUsCgkJbHBjY2JNYXhWYWx1ZURhdGEsCgkJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCQlmdAoJKTsKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MgJiYgbHBzekNsYXNzKQoJCWxzdHJjcHlXdG9BKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCWlmIChscGNjaENsYXNzKQoJCSpscGNjaENsYXNzLz0yOwoJaWYgKGxwY2NoTWF4U3Via2V5KQoJCSpscGNjaE1heFN1YmtleS89MjsKCWlmIChscGNjaE1heENsYXNzKQoJCSpscGNjaE1heENsYXNzLz0yOwoJaWYgKGxwY2NoTWF4VmFsdWVOYW1lKQoJCSpscGNjaE1heFZhbHVlTmFtZS89MjsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnkzMlcgW0FEVkFQSTMyLjEyOF0KICoKICogUEFSQU1TCiAqICAgIGxwTWFjaGluZU5hbWUgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiByZW1vdGUgY29tcHV0ZXIKICogICAgaEhleSAgICAgICAgICBbSV0gUHJlZGVmaW5lZCByZWdpc3RyeSBoYW5kbGUKICogICAgcGhrUmVzdWx0ICAgICBbSV0gQWRkcmVzcyBvZiBidWZmZXIgZm9yIHJlbW90ZSByZWdpc3RyeSBoYW5kbGUKICovCkxPTkcgV0lOQVBJIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyVyggTFBDV1NUUiBscE1hY2hpbmVOYW1lLCBIS0VZIGhLZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSBwaGtSZXN1bHQgKQp7CiAgICBUUkFDRShyZWcsIiglcywleCwlcCk6IHN0dWJcbiIsZGVidWdzdHJfdyhscE1hY2hpbmVOYW1lKSxoS2V5LHBoa1Jlc3VsdCk7CgogICAgaWYgKCFscE1hY2hpbmVOYW1lIHx8ICEqbHBNYWNoaW5lTmFtZSkgewogICAgICAgIC8qIFVzZSB0aGUgbG9jYWwgbWFjaGluZSBuYW1lICovCiAgICAgICAgcmV0dXJuIFJlZ09wZW5LZXkxNiggaEtleSwgIiIsIHBoa1Jlc3VsdCApOwogICAgfQoKICAgIEZJWE1FKHJlZywiQ2Fubm90IGNvbm5lY3QgdG8gJXNcbiIsZGVidWdzdHJfdyhscE1hY2hpbmVOYW1lKSk7CiAgICByZXR1cm4gRVJST1JfQkFEX05FVFBBVEg7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyQSBbQURWQVBJMzIuMTI3XQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5MzJBKCBMUENTVFIgbWFjaGluZSwgSEtFWSBoa2V5LCBMUEhLRVkgcmVza2V5ICkKewogICAgRFdPUkQgcmV0OwogICAgTFBXU1RSIG1hY2hpbmVXID0gc3RyZHVwQTJXKG1hY2hpbmUpOwogICAgcmV0ID0gUmVnQ29ubmVjdFJlZ2lzdHJ5MzJXKCBtYWNoaW5lVywgaGtleSwgcmVza2V5ICk7CiAgICBmcmVlKG1hY2hpbmVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0dldEtleVNlY3VyaXR5IFtBRFZBUEkzMi4xNDRdCiAqIFJldHJpZXZlcyBhIGNvcHkgb2Ygc2VjdXJpdHkgZGVzY3JpcHRvciBwcm90ZWN0aW5nIHRoZSByZWdpc3RyeSBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICAgICAgICAgW0ldICAgT3BlbiBoYW5kbGUgb2Yga2V5IHRvIHNldAogKiAgICBTZWN1cml0eUluZm9ybWF0aW9uICAgIFtJXSAgIERlc2NyaXB0b3IgY29udGVudHMKICogICAgcFNlY3VyaXR5RGVzY3JpcHRvciAgICBbT10gICBBZGRyZXNzIG9mIGRlc2NyaXB0b3IgZm9yIGtleQogKiAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yIFtJL09dIEFkZHJlc3Mgb2Ygc2l6ZSBvZiBidWZmZXIgYW5kIGRlc2NyaXB0aW9uCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpMT05HIFdJTkFQSSBSZWdHZXRLZXlTZWN1cml0eSggSEtFWSBoa2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFQ1VSSVRZX0lORk9STUFUSU9OIFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksU2VjdXJpdHlJbmZvcm1hdGlvbixwU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvcj8qbHBjYlNlY3VyaXR5RGVzY3JpcHRvcjowKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICAvKiBGSVhNRTogQ2hlY2sgZm9yIHZhbGlkIFNlY3VyaXR5SW5mb3JtYXRpb24gdmFsdWVzICovCgogICAgaWYgKCpscGNiU2VjdXJpdHlEZXNjcmlwdG9yIDwgc2l6ZW9mKCpwU2VjdXJpdHlEZXNjcmlwdG9yKSkKICAgICAgICByZXR1cm4gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUjsKCiAgICBGSVhNRShyZWcsICIoJXgsJWxkLCVwLCVsZCk6IHN0dWJcbiIsaGtleSxTZWN1cml0eUluZm9ybWF0aW9uLAogICAgICAgICAgcFNlY3VyaXR5RGVzY3JpcHRvcixscGNiU2VjdXJpdHlEZXNjcmlwdG9yPypscGNiU2VjdXJpdHlEZXNjcmlwdG9yOjApOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdMb2FkS2V5MzJXIFtBRFZBUEkzMi4/Pz9dCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBzelN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleQogKiAgICBscHN6RmlsZSAgIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGZvciByZWdpc3RyeSBpbmZvcm1hdGlvbgogKi8KTE9ORyBXSU5BUEkgUmVnTG9hZEtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQQ1dTVFIgbHBzekZpbGUgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksZGVidWdzdHJfdyhscHN6RmlsZSkpOwoKICAgIC8qIERvIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5IHx8ICFscHN6RmlsZSB8fCAhKmxwc3pGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsIigleCwlcywlcyk6IHN0dWJcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLAogICAgICAgICAgZGVidWdzdHJfdyhscHN6RmlsZSkpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdMb2FkS2V5MzJBIFtBRFZBUEkzMi4/Pz9dCiAqLwpMT05HIFdJTkFQSSBSZWdMb2FkS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUENTVFIgbHBzekZpbGUgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscHN6U3ViS2V5VyA9IHN0cmR1cEEyVyhscHN6U3ViS2V5KTsKICAgIExQV1NUUiBscHN6RmlsZVcgPSBzdHJkdXBBMlcobHBzekZpbGUpOwogICAgcmV0ID0gUmVnTG9hZEtleTMyVyggaGtleSwgbHBzelN1YktleVcsIGxwc3pGaWxlVyApOwogICAgaWYobHBzekZpbGVXKSBmcmVlKGxwc3pGaWxlVyk7CiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdOb3RpZnlDaGFuZ2VLZXlWYWx1ZSBbQURWQVBJMzIuPz8/XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgIFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdhdGNoCiAqICAgIGZXYXRjaFN1YlRyZWUgICBbSV0gRmxhZyBmb3Igc3Via2V5IG5vdGlmaWNhdGlvbgogKiAgICBmZHdOb3RpZnlGaWx0ZXIgW0ldIENoYW5nZXMgdG8gYmUgcmVwb3J0ZWQKICogICAgaEV2ZW50ICAgICAgICAgIFtJXSBIYW5kbGUgb2Ygc2lnbmFsZWQgZXZlbnQKICogICAgZkFzeW5jICAgICAgICAgIFtJXSBGbGFnIGZvciBhc3luY2hyb25vdXMgcmVwb3J0aW5nCiAqLwpMT05HIFdJTkFQSSBSZWdOb3RpZnlDaGFuZ2VLZXlWYWx1ZSggSEtFWSBoa2V5LCBCT09MMzIgZldhdGNoU3ViVHJlZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBmZHdOb3RpZnlGaWx0ZXIsIEhBTkRMRTMyIGhFdmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wzMiBmQXN5bmMgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKICAgIFRSQUNFKHJlZywiKCV4LCVpLCVsZCwleCwlaSlcbiIsaGtleSxmV2F0Y2hTdWJUcmVlLGZkd05vdGlmeUZpbHRlciwKICAgICAgICAgIGhFdmVudCxmQXN5bmMpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywiKCV4LCVpLCVsZCwleCwlaSk6IHN0dWJcbiIsaGtleSxmV2F0Y2hTdWJUcmVlLGZkd05vdGlmeUZpbHRlciwKICAgICAgICAgIGhFdmVudCxmQXN5bmMpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXkzMlcgW0FEVkFQSTMyLjE3M10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBTdWJLZXkgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkgdG8gdW5sb2FkCiAqLwpMT05HIFdJTkFQSSBSZWdVbkxvYWRLZXkzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSApCnsKICAgIEZJWE1FKHJlZywiKCV4LCVzKTogc3R1YlxuIixoa2V5LCBkZWJ1Z3N0cl93KGxwU3ViS2V5KSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnVW5Mb2FkS2V5MzJBIFtBRFZBUEkzMi4xNzJdCiAqLwpMT05HIFdJTkFQSSBSZWdVbkxvYWRLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5ICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBTdWJLZXlXID0gc3RyZHVwQTJXKGxwU3ViS2V5KTsKICAgIHJldCA9IFJlZ1VuTG9hZEtleTMyVyggaGtleSwgbHBTdWJLZXlXICk7CiAgICBpZihscFN1YktleVcpIGZyZWUobHBTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldEtleVNlY3VyaXR5IFtBRFZBUEkzMi4xNjddCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgIFtJXSBPcGVuIGhhbmRsZSBvZiBrZXkgdG8gc2V0CiAqICAgIFNlY3VyaXR5SW5mbyAgW0ldIERlc2NyaXB0b3IgY29udGVudHMKICogICAgcFNlY3VyaXR5RGVzYyBbSV0gQWRkcmVzcyBvZiBkZXNjcmlwdG9yIGZvciBrZXkKICovCkxPTkcgV0lOQVBJIFJlZ1NldEtleVNlY3VyaXR5KCBIS0VZIGhrZXksIFNFQ1VSSVRZX0lORk9STUFUSU9OIFNlY3VyaXR5SW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfREVTQ1JJUFRPUiBwU2VjdXJpdHlEZXNjICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwKVxuIixoa2V5LFNlY3VyaXR5SW5mbyxwU2VjdXJpdHlEZXNjKTsKCiAgICAvKiBJdCBzZWVtcyB0byBwZXJmb3JtIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoKFNlY3VyaXR5SW5mbyAmIE9XTkVSX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBHUk9VUF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgREFDTF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgU0FDTF9TRUNVUklUWV9JTkZPUk1BVElPTikpIHsKICAgICAgICAvKiBQYXJhbSBPSyAqLwogICAgfSBlbHNlCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGlmICghcFNlY3VyaXR5RGVzYykKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUUocmVnLCI6KCV4LCVsZCwlcCk6IHN0dWJcbiIsaGtleSxTZWN1cml0eUluZm8scFNlY3VyaXR5RGVzYyk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NhdmVLZXkzMlcgW0FEVkFQSTMyLjE2Nl0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICBbSV0gSGFuZGxlIG9mIGtleSB3aGVyZSBzYXZlIGJlZ2lucwogKiAgICBscEZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgdG8gc2F2ZSB0bwogKiAgICBzYSAgICAgW0ldIEFkZHJlc3Mgb2Ygc2VjdXJpdHkgc3RydWN0dXJlCiAqLwpMT05HIFdJTkFQSSBSZWdTYXZlS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIHNhICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCAiKCV4LCVzLCVwKVxuIiwgaGtleSwgZGVidWdzdHJfdyhscEZpbGUpLCBzYSk7CgogICAgLyogSXQgYXBwZWFycyB0byBkbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscEZpbGUgfHwgISpscEZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywgIigleCwlcywlcCk6IHN0dWJcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBGaWxlKSwgc2EpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTYXZlS2V5MzJBIFtBRFZBUEkzMi4xNjVdCiAqLwpMT05HIFdJTkFQSSBSZWdTYXZlS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscEZpbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgc2EgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscEZpbGVXID0gc3RyZHVwQTJXKGxwRmlsZSk7CiAgICByZXQgPSBSZWdTYXZlS2V5MzJXKCBoa2V5LCBscEZpbGVXLCBzYSApOwogICAgZnJlZShscEZpbGVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1Jlc3RvcmVLZXkzMlcgW0FEVkFQSTMyLjE2NF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgcmVzdG9yZSBiZWdpbnMKICogICAgbHBGaWxlICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBjb250YWluaW5nIHNhdmVkIHRyZWUKICogICAgZHdGbGFncyBbSV0gT3B0aW9uYWwgZmxhZ3MKICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXkzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscEZpbGUsIERXT1JEIGR3RmxhZ3MgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRShyZWcsICIoJXgsJXMsJWxkKVxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBJdCBzZWVtcyB0byBkbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscEZpbGUgfHwgISpscEZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywiKCV4LCVzLCVsZCk6IHN0dWJcbiIsaGtleSxkZWJ1Z3N0cl93KGxwRmlsZSksZHdGbGFncyk7CgogICAgLyogQ2hlY2sgZm9yIGZpbGUgZXhpc3RlbmNlICovCgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1Jlc3RvcmVLZXkzMkEgW0FEVkFQSTMyLjE2M10KICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwRmlsZVcgPSBzdHJkdXBBMlcobHBGaWxlKTsKICAgIHJldCA9IFJlZ1Jlc3RvcmVLZXkzMlcoIGhrZXksIGxwRmlsZVcsIGR3RmxhZ3MgKTsKICAgIGlmKGxwRmlsZVcpIGZyZWUobHBGaWxlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5MzJXIFtBRFZBUEkzMi4xNjJdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscFN1YktleSAgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkKICogICAgbHBOZXdGaWxlIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGZvciBmaWxlIHdpdGggbmV3IGRhdGEKICogICAgbHBPbGRGaWxlIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGZvciBiYWNrdXAgZmlsZQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwU3ViS2V5LCBMUENXU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBscE9sZEZpbGUgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRShyZWcsIigleCwlcywlcywlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwU3ViS2V5KSwKICAgICAgICAgIGRlYnVnc3RyX3cobHBOZXdGaWxlKSxkZWJ1Z3N0cl93KGxwT2xkRmlsZSkpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywgIigleCwlcywlcywlcyk6IHN0dWJcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBTdWJLZXkpLCAKICAgICAgICAgIGRlYnVnc3RyX3cobHBOZXdGaWxlKSxkZWJ1Z3N0cl93KGxwT2xkRmlsZSkpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5MzJBIFtBRFZBUEkzMi4xNjFdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXBsYWNlS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSwgTFBDU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwT2xkRmlsZSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwU3ViS2V5VyA9IHN0cmR1cEEyVyhscFN1YktleSk7CiAgICBMUFdTVFIgbHBOZXdGaWxlVyA9IHN0cmR1cEEyVyhscE5ld0ZpbGUpOwogICAgTFBXU1RSIGxwT2xkRmlsZVcgPSBzdHJkdXBBMlcobHBPbGRGaWxlKTsKICAgIHJldCA9IFJlZ1JlcGxhY2VLZXkzMlcoIGhrZXksIGxwU3ViS2V5VywgbHBOZXdGaWxlVywgbHBPbGRGaWxlVyApOwogICAgZnJlZShscE9sZEZpbGVXKTsKICAgIGZyZWUobHBOZXdGaWxlVyk7CiAgICBmcmVlKGxwU3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9Cgo=