LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpZmRlZiBIQVZFX1NZU19FUlJOT19ICiNpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9mY250bC5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS93aW5lc3RyaW5nLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAiaGVhcC5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW52ZXJzaW9uLmgiCgpERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVnKQpERUNMQVJFX0RFQlVHX0NIQU5ORUwoc3RyaW5nKQoKc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCh2b2lkKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCi8qIE5PVEU6IGRvIG5vdCBhcHBlbmQgYSAvLiBsaW51eCcgbWtkaXIoKSBXSUxMIEZBSUwgaWYgeW91IGRvIHRoYXQgKi8KI2RlZmluZSBXSU5FX1BSRUZJWCAgICAgICAgICAgICAgICAgIi8ud2luZSIKI2RlZmluZSBTQVZFX1VTRVJTX0RFRkFVTFQgICAgICAgICAgRVRDRElSIi93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQgIEVUQ0RJUiIvd2luZS5zeXN0ZW1yZWciCgovKiByZWxhdGl2ZSBpbiB+dXNlci8ud2luZS8gOiAqLwojZGVmaW5lIFNBVkVfQ1VSUkVOVF9VU0VSICAgICAgICAgICAidXNlci5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUICAgICJ3aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FICAgICAgICAgICJzeXN0ZW0ucmVnIgoKI2RlZmluZSBLRVlfUkVHSVNUUlkgICAgICAgICAgICAgICAgIlNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeSIKI2RlZmluZSBWQUxfU0FWRVVQREFURUQgICAgICAgICAgICAgIlNhdmVPbmx5VXBkYXRlZEtleXMiCgovKiBvbmUgdmFsdWUgb2YgYSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZVkFMVUUKewogICAgTFBXU1RSICAgbmFtZTsgICAgICAgICAgLyogbmFtZSBvZiB2YWx1ZSAoVU5JQ09ERSkgb3IgTlVMTCBmb3Igd2luMzEgKi8KICAgIERXT1JEICAgIHR5cGU7ICAgICAgICAgIC8qIHR5cGUgb2YgdmFsdWUgKi8KICAgIERXT1JEICAgIGxlbjsgICAgICAgICAgIC8qIGxlbmd0aCBvZiBkYXRhIGluIEJZVEVzICovCiAgICBEV09SRCAgICBsYXN0bW9kaWZpZWQ7ICAvKiB0aW1lIG9mIHNlY29uZHMgc2luY2UgMS4xLjE5NzAgKi8KICAgIExQQllURSAgIGRhdGE7ICAgICAgICAgIC8qIGNvbnRlbnQsIG1heSBiZSBzdHJpbmdzLCBiaW5hcmllcywgZXRjLiAqLwp9IEtFWVZBTFVFLCpMUEtFWVZBTFVFOwoKLyogYSByZWdpc3RyeSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZU1RSVUNUCnsKICAgIExQV1NUUiAgICAgICAgICAgICAgIGtleW5hbWU7ICAgICAgIC8qIG5hbWUgb2YgVEhJUyBrZXkgKFVOSUNPREUpICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBmbGFnczsgICAgICAgICAvKiBmbGFncy4gKi8KICAgIExQV1NUUiAgICAgICAgICAgICAgIGNsYXNzOwogICAgLyogdmFsdWVzICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBucm9mdmFsdWVzOyAgICAvKiBuciBvZiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIExQS0VZVkFMVUUgICAgICAgICAgIHZhbHVlczsgICAgICAgIC8qIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgLyoga2V5IG1hbmFnZW1lbnQgcG9pbnRlcnMgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHQ7ICAgICAgICAgIC8qIG5leHQga2V5IG9uIHNhbWUgaGllcmFyY2h5ICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0c3ViOyAgICAgICAvKiBrZXlzIHRoYXQgaGFuZyBiZWxvdyBUSElTIGtleSAqLwp9IEtFWVNUUlVDVCwgKkxQS0VZU1RSVUNUOwoKCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jbGFzc2VzX3Jvb3Q9TlVMTDsJLyogd2luZG93cyAzLjEgZ2xvYmFsIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF91c2VyPU5VTEw7CS8qIHVzZXIgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9sb2NhbF9tYWNoaW5lPU5VTEw7LyogbWFjaGluZSBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3VzZXJzPU5VTEw7CS8qIGFsbCB1c2Vycz8gKi8KCi8qIGR5bmFtaWMsIG5vdCBzYXZlZCAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfcGVyZm9ybWFuY2VfZGF0YT1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF9jb25maWc9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2R5bl9kYXRhPU5VTEw7CgovKiB3aGF0IHZhbHVldHlwZXMgZG8gd2UgbmVlZCB0byBjb252ZXJ0PyAqLwojZGVmaW5lIFVOSUNPTlZNQVNLCSgoMTw8UkVHX1NaKXwoMTw8UkVHX01VTFRJX1NaKXwoMTw8UkVHX0VYUEFORF9TWikpCgoKc3RhdGljIHN0cnVjdCBvcGVuaGFuZGxlIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCVJFR1NBTQkJYWNjZXNzbWFzazsKfSAgKm9wZW5oYW5kbGVzPU5VTEw7CnN0YXRpYyBpbnQJbnJvZm9wZW5oYW5kbGVzPTA7Ci8qIFN0YXJ0cyBhZnRlciAxIGJlY2F1c2UgMCwxIGFyZSByZXNlcnZlZCBmb3IgV2luMTYgKi8KLyogTm90ZTogU2hvdWxkIGFsd2F5cyBiZSBldmVuLCBhcyBXaW45NSBBRFZBUEkzMi5ETEwgcmVzZXJ2ZXMgb2RkCiAgICAgICAgIEhLRVlzIGZvciByZW1vdGUgcmVnaXN0cnkgYWNjZXNzICovCnN0YXRpYyBpbnQJY3VycmVudGhhbmRsZT0yOwoKCi8qCiAqIFFVRVNUSU9OCiAqICAgQXJlIHRoZXNlIGRvaW5nIHRoZSBzYW1lIGFzIEhFQVBfc3RyZHVwQXRvVyBhbmQgSEVBUF9zdHJkdXBXdG9BPwogKiAgIElmIHNvLCBjYW4gd2UgcmVtb3ZlIHRoZW0/CiAqIEFOU1dFUgogKiAgIE5vLCB0aGUgbWVtb3J5IGhhbmRsaW5nIGZ1bmN0aW9ucyBhcmUgY2FsbGVkIHZlcnkgb2Z0ZW4gaW4gaGVyZSwgCiAqICAganVzdCByZXBsYWNpbmcgdGhlbSBieSBIZWFwQWxsb2MoU3lzdGVtSGVhcCwuLi4pIG1ha2VzIHJlZ2lzdHJ5CiAqICAgbG9hZGluZyAxMDAgdGltZXMgc2xvd2VyLiAtTU0KICovCnN0YXRpYyBMUFdTVFIgc3RyZHVwQTJXKExQQ1NUUiBzcmMpCnsKICAgIGlmKHNyYykgewoJTFBXU1RSIGRlc3Q9eG1hbGxvYygyKnN0cmxlbihzcmMpKzIpOwoJbHN0cmNweUF0b1coZGVzdCxzcmMpOwoJcmV0dXJuIGRlc3Q7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIExQV1NUUiBzdHJkdXBXKExQQ1dTVFIgYSkgewoJTFBXU1RSCWI7CglpbnQJbGVuOwoKICAgIGlmKGEpIHsKCWxlbj1zaXplb2YoV0NIQVIpKihsc3RybGVuVyhhKSsxKTsKCWI9KExQV1NUUil4bWFsbG9jKGxlbik7CgltZW1jcHkoYixhLGxlbik7CglyZXR1cm4gYjsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgpMUFdTVFIgc3RyY3Z0QTJXKExQQ1NUUiBzcmMsIGludCBuY2hhcnMpCgp7CiAgIExQV1NUUiBkZXN0ID0geG1hbGxvYyAoMiAqIG5jaGFycyArIDIpOwoKICAgbHN0cmNweW5BdG9XKGRlc3Qsc3JjLG5jaGFycysxKTsKICAgZGVzdFtuY2hhcnNdID0gMDsKICAgcmV0dXJuIGRlc3Q7Cn0KLyoKICogd2UgbmVlZCB0byBjb252ZXJ0IEEgdG8gVyB3aXRoICdcMCcgaW4gc3RyaW5ncyAoTVVMVElfU1opIAogKi8KCnN0YXRpYyBMUFdTVFIgIGxtZW1jcHluQXRvVyggTFBXU1RSIGRzdCwgTFBDU1RSIHNyYywgSU5UIG4gKQp7CUxQV1NUUiBwID0gZHN0OwoKCVRSQUNFXyhyZWcpKCJcIiVzXCIgJWlcbiIsc3JjLCBuKTsKCgl3aGlsZSAobi0tID4gMCkgKnArKyA9IChXQ0hBUikodW5zaWduZWQgY2hhcikqc3JjKys7CgoJcmV0dXJuIGRzdDsKfQpzdGF0aWMgTFBTVFIgbG1lbWNweW5XdG9BKCBMUFNUUiBkc3QsIExQQ1dTVFIgc3JjLCBJTlQgbiApCnsJTFBTVFIgcCA9IGRzdDsKCglUUkFDRV8oc3RyaW5nKSgiTFwiJXNcIiAlaVxuIixkZWJ1Z3N0cl93KHNyYyksIG4pOwoKCXdoaWxlIChuLS0gPiAwKSAqcCsrID0gKENIQVIpKnNyYysrOwoKCXJldHVybiBkc3Q7Cn0KCnN0YXRpYyB2b2lkIGRlYnVnX3ByaW50X3ZhbHVlIChMUEJZVEUgbHBiRGF0YSwgTFBLRVlWQUxVRSBrZXkpCnsKICBpZiAoVFJBQ0VfT04ocmVnKSAmJiBscGJEYXRhKSAKICB7IAogICAgc3dpdGNoKGtleS0+dHlwZSkKICAgIHsgCiAgICAgIGNhc2UgUkVHX0VYUEFORF9TWjoKICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgVFJBQ0VfKHJlZykoIiBWYWx1ZSAlcywgRGF0YShzeik9JXNcbiIsIAogICAgICAgICAgZGVidWdzdHJfdyhrZXktPm5hbWUpLCAKICAgICAgICAgIGRlYnVnc3RyX3coKExQQ1dTVFIpbHBiRGF0YSkpOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgVFJBQ0VfKHJlZykoIiBWYWx1ZSAlcywgRGF0YShkd29yZCk9MHglMDhseFxuIiwKICAgICAgICAgIGRlYnVnc3RyX3coa2V5LT5uYW1lKSwgCiAgICAgICAgICAoRFdPUkQpKmxwYkRhdGEpOwogICAgICAgIGJyZWFrOwogICAgCiAgICAgIGNhc2UgUkVHX01VTFRJX1NaOgogICAgICB7IAogICAgICAgIGludCBpOwogICAgICAgIExQQ1dTVFIgcHRyID0gKExQQ1dTVFIpbHBiRGF0YTsKICAgICAgICBmb3IgKGk9MDtwdHJbMF07aSsrKQogICAgICAgIHsgCiAgICAgICAgICBUUkFDRV8ocmVnKSgiIFZhbHVlICVzLCBNVUxUSV9TWiglaT0lcylcbiIsIAogICAgICAgICAgICBkZWJ1Z3N0cl93KGtleS0+bmFtZSksIAogICAgICAgICAgICBpLCAKICAgICAgICAgICAgZGVidWdzdHJfdyhwdHIpKTsKCiAgICAgICAgICBwdHIgKz0gbHN0cmxlblcocHRyKSsxOwogICAgICAgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgICAgIGRlZmF1bHQ6CiAgICAgIHsgCiAgICAgICAgY2hhciBzelRlbXBbMTAwXTsgICAgICAvKiAzKjMyICsgMyArIDEgKi8KICAgICAgICBpbnQgaTsKICAgICAgICBmb3IgKCBpID0gMDsgaSA8IGtleS0+bGVuIDsgaSsrKSAgICAgIAogICAgICAgIHsgCiAgICAgICAgICBzcHJpbnRmICgmKHN6VGVtcFtpKjNdKSwiJTAyeCAiLCBscGJEYXRhW2ldKTsKICAgICAgICAgIGlmIChpPj0zMSkKICAgICAgICAgIHsgCiAgICAgICAgICAgIHNwcmludGYgKCYoc3pUZW1wW2kqMyszXSksIi4uLiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgVFJBQ0VfKHJlZykoIiBWYWx1ZSAlcywgRGF0YShyYXcpPSglcylcbiIsIAogICAgICAgICAgZGVidWdzdHJfdyhrZXktPm5hbWUpLCAKICAgICAgICAgIHN6VGVtcCk7ICAgICAgICAgICAgICAgICAgCiAgICAgIH0KICAgIH0gLyogc3dpdGNoICovCiAgfSAvKiBpZiAqLwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBpc19zdGFuZGFyZF9oa2V5IFtJbnRlcm5hbF0KICogRGV0ZXJtaW5lcyBpZiBhIGhrZXkgaXMgYSBzdGFuZGFyZCBrZXkKICovCnN0YXRpYyBCT09MIGlzX3N0YW5kYXJkX2hrZXkoIEhLRVkgaGtleSApCnsKICAgIHN3aXRjaChoa2V5KSB7CiAgICAgICAgY2FzZSAweDAwMDAwMDAwOgogICAgICAgIGNhc2UgMHgwMDAwMDAwMToKICAgICAgICBjYXNlIEhLRVlfQ0xBU1NFU19ST09UOgogICAgICAgIGNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKICAgICAgICBjYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgogICAgICAgIGNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgogICAgICAgIGNhc2UgSEtFWV9VU0VSUzoKICAgICAgICBjYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKICAgICAgICBjYXNlIEhLRVlfRFlOX0RBVEE6CiAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBhZGRfaGFuZGxlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIGFkZF9oYW5kbGUoIEhLRVkgaGtleSwgTFBLRVlTVFJVQ1QgbHBrZXksIFJFR1NBTSBhY2Nlc3NtYXNrICkKewogICAgaW50IGk7CgogICAgVFJBQ0VfKHJlZykoIigweCV4LCVwLDB4JWx4KVxuIixoa2V5LGxwa2V5LGFjY2Vzc21hc2spOwogICAgLyogQ2hlY2sgZm9yIGR1cGxpY2F0ZXMgKi8KICAgIGZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykgewogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5scGtleT09bHBrZXkpIHsKICAgICAgICAgICAgLyogVGhpcyBpcyBub3QgcmVhbGx5IGFuIGVycm9yIC0gdGhlIHVzZXIgaXMgYWxsb3dlZCB0byBjcmVhdGUKICAgICAgICAgICAgICAgdHdvIChvciBtb3JlKSBoYW5kbGVzIHRvIHRoZSBzYW1lIGtleSAqLwogICAgICAgICAgICAvKldBUk4ocmVnLCAiQWRkaW5nIGtleSAlcCB0d2ljZVxuIixscGtleSk7Ki8KICAgICAgICB9CiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpIHsKICAgICAgICAgICAgV0FSTl8ocmVnKSgiQWRkaW5nIGhhbmRsZSAleCB0d2ljZVxuIixoa2V5KTsKICAgICAgICB9CiAgICB9CiAgICBvcGVuaGFuZGxlcz14cmVhbGxvYyggb3BlbmhhbmRsZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcysxKSk7CgogICAgb3BlbmhhbmRsZXNbaV0ubHBrZXkgPSBscGtleTsKICAgIG9wZW5oYW5kbGVzW2ldLmhrZXkgPSBoa2V5OwogICAgb3BlbmhhbmRsZXNbaV0uYWNjZXNzbWFzayA9IGFjY2Vzc21hc2s7CiAgICBucm9mb3BlbmhhbmRsZXMrKzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZ2V0X2hhbmRsZSBbSW50ZXJuYWxdCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogUG9pbnRlciB0byBrZXkKICogICAgRmFpbHVyZTogTlVMTAogKi8Kc3RhdGljIExQS0VZU1RSVUNUIGdldF9oYW5kbGUoIEhLRVkgaGtleSApCnsKICAgIGludCBpOwoKICAgIGZvciAoaT0wOyBpPG5yb2ZvcGVuaGFuZGxlczsgaSsrKQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5ID09IGhrZXkpCiAgICAgICAgICAgIHJldHVybiBvcGVuaGFuZGxlc1tpXS5scGtleTsKICAgIFdBUk5fKHJlZykoIkNvdWxkIG5vdCBmaW5kIGhhbmRsZSAweCV4XG4iLGhrZXkpOwogICAgcmV0dXJuIE5VTEw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIHJlbW92ZV9oYW5kbGUgW0ludGVybmFsXQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byByZW1vdmUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVSUk9SX0lOVkFMSURfSEFORExFCiAqLwpzdGF0aWMgRFdPUkQgcmVtb3ZlX2hhbmRsZSggSEtFWSBoa2V5ICkKewogICAgaW50IGk7CgogICAgZm9yIChpPTA7aTxucm9mb3BlbmhhbmRsZXM7aSsrKQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KQogICAgICAgICAgICBicmVhazsKCiAgICBpZiAoaSA9PSBucm9mb3BlbmhhbmRsZXMpIHsKICAgICAgICBXQVJOXyhyZWcpKCJDb3VsZCBub3QgZmluZCBoYW5kbGUgMHgleFxuIixoa2V5KTsKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CiAgICB9CgogICAgbWVtY3B5KCBvcGVuaGFuZGxlcytpLAogICAgICAgICAgICBvcGVuaGFuZGxlcytpKzEsCiAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy1pLTEpCiAgICApOwogICAgb3BlbmhhbmRsZXM9eHJlYWxsb2Mob3BlbmhhbmRsZXMsc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLTEpKTsKICAgIG5yb2ZvcGVuaGFuZGxlcy0tOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogbG9va3VwX2hrZXkgW0ludGVybmFsXQogKiAKICogSnVzdCBhcyB0aGUgbmFtZSBzYXlzLiBDcmVhdGVzIHRoZSByb290IGtleXMgb24gZGVtYW5kLCBzbyB3ZSBjYW4gY2FsbCB0aGUKICogUmVnKiBmdW5jdGlvbnMgYXQgYW55IHRpbWUuCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogUG9pbnRlciB0byBrZXkgc3RydWN0dXJlCiAqICAgIEZhaWx1cmU6IE5VTEwKICovCiNkZWZpbmUgQUREX1JPT1RfS0VZKHh4KSBcCgl4eCA9IChMUEtFWVNUUlVDVCl4bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTtcCgltZW1zZXQoeHgsJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7XAoJeHgtPmtleW5hbWU9IHN0cmR1cEEyVygiPHNob3VsZF9ub3RfYXBwZWFyX2FueXdoZXJlPiIpOwoKc3RhdGljIExQS0VZU1RSVUNUIGxvb2t1cF9oa2V5KCBIS0VZIGhrZXkgKQp7CiAgc3dpdGNoIChoa2V5KSB7CiAgLyogMCBhbmQgMSBhcmUgdmFsaWQgcm9vdGtleXMgaW4gd2luMTYgc2hlbGwuZGxsIGFuZCBhcmUgdXNlZCBieQogICAqIHNvbWUgcHJvZ3JhbXMuIERvIG5vdCByZW1vdmUgdGhvc2UgY2FzZXMuIC1NTQogICAqLwogCWNhc2UgMHgwMDAwMDAwMDoKICBjYXNlIDB4MDAwMDAwMDE6CiAgY2FzZSBIS0VZX0NMQVNTRVNfUk9PVDogCiAgewogICAgaWYgKCFrZXlfY2xhc3Nlc19yb290KSAKICAgIHsKICAgICAgSEtFWQljbF9yX2hrZXk7CgogICAgICAvKiBjYWxscyBsb29rdXBfaGtleSByZWN1cnNpdmVseSwgVFdJQ0UgKi8KICAgICAgaWYgKCBSZWdDcmVhdGVLZXkxNigKICAgICAgICAgICAgSEtFWV9MT0NBTF9NQUNISU5FLAogICAgICAgICAgICAiU09GVFdBUkVcXENsYXNzZXMiLAogICAgICAgICAgICAmY2xfcl9oa2V5KSAhPSBFUlJPUl9TVUNDRVNTKSAKICAgICAgewogICAgICAgIEVSUl8ocmVnKSgiQ291bGQgbm90IGNyZWF0ZSBIS0xNXFxTT0ZUV0FSRVxcQ2xhc3Nlcy4gVGhpcyBpcyBpbXBvc3NpYmxlLlxuIik7CiAgICAgICAgZXhpdCgxKTsKICAgICAgfQoKICAgICAga2V5X2NsYXNzZXNfcm9vdCA9IGxvb2t1cF9oa2V5KGNsX3JfaGtleSk7CiAgICB9CiAgICByZXR1cm4ga2V5X2NsYXNzZXNfcm9vdDsKICB9CgogIGNhc2UgSEtFWV9DVVJSRU5UX1VTRVI6CiAgICBpZiAoIWtleV9jdXJyZW50X3VzZXIpIHsKICAgICAgQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X3VzZXIpOwogICAgfQogICAgcmV0dXJuIGtleV9jdXJyZW50X3VzZXI7CgogIGNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgogICAgaWYgKCFrZXlfbG9jYWxfbWFjaGluZSkgewogICAgICBBRERfUk9PVF9LRVkoa2V5X2xvY2FsX21hY2hpbmUpOwogICAgICBSRUdJU1RSWV9Jbml0KCk7CiAgICB9CiAgICByZXR1cm4ga2V5X2xvY2FsX21hY2hpbmU7CgogIGNhc2UgSEtFWV9VU0VSUzoKICAgIGlmICgha2V5X3VzZXJzKSB7CiAgICAgIEFERF9ST09UX0tFWShrZXlfdXNlcnMpOwogICAgfQogICAgcmV0dXJuIGtleV91c2VyczsKCiAgY2FzZSBIS0VZX1BFUkZPUk1BTkNFX0RBVEE6CiAgICBpZiAoIWtleV9wZXJmb3JtYW5jZV9kYXRhKSB7CiAgICAgIEFERF9ST09UX0tFWShrZXlfcGVyZm9ybWFuY2VfZGF0YSk7CiAgICB9CiAgICByZXR1cm4ga2V5X3BlcmZvcm1hbmNlX2RhdGE7CgogIGNhc2UgSEtFWV9EWU5fREFUQToKICAgIGlmICgha2V5X2R5bl9kYXRhKSB7CiAgICAgIEFERF9ST09UX0tFWShrZXlfZHluX2RhdGEpOwogICAgfQogICAgcmV0dXJuIGtleV9keW5fZGF0YTsKCiAgY2FzZSBIS0VZX0NVUlJFTlRfQ09ORklHOgogICAgaWYgKCFrZXlfY3VycmVudF9jb25maWcpIHsKICAgICAgQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X2NvbmZpZyk7CiAgICB9CiAgICByZXR1cm4ga2V5X2N1cnJlbnRfY29uZmlnOwoKICBkZWZhdWx0OgogICAgcmV0dXJuIGdldF9oYW5kbGUoaGtleSk7CgogIH0KICAvKk5PVFJFQUNIRUQqLwp9CgoKLyoKICogcmVjdXJzaXZlbHkgc2VhcmNoZXMgZm9yIGxwa2V5X3RvX2ZpbmQgaW4gdGhlIHJvb3Qga2V5IGJyYW5jaAogKiBnaXZlbiBpbiBscGN1cnJrZXkuCiAqLwpzdGF0aWMgaW50IHN1YmtleV9mb3VuZChMUEtFWVNUUlVDVCBscGN1cnJrZXksIExQS0VZU1RSVUNUIGxwa2V5X3RvX2ZpbmQpCnsKCXdoaWxlIChscGN1cnJrZXkpCgl7CgkJaWYgKGxwY3VycmtleSA9PSBscGtleV90b19maW5kKQoJCQlyZXR1cm4gMTsKCQlpZiAoc3Via2V5X2ZvdW5kKGxwY3VycmtleS0+bmV4dHN1YiwgbHBrZXlfdG9fZmluZCkpCgkJCXJldHVybiAxOwoKCQlscGN1cnJrZXkgPSBscGN1cnJrZXktPm5leHQ7Cgl9CgoJVFJBQ0VfKHJlZykoIk5vIGtleSBmb3VuZCBpbiB0aGlzIHJvb3Qga2V5IGJyYW5jaFxuIik7CglyZXR1cm4gMDsKfQoKCi8qCiAqIGZpbmRzIHRoZSBjb3JyZXNwb25kaW5nIHJvb3Qga2V5IGZvciBhIHN1YiBrZXksIGkuZS4gZS5nLiBIS0VZX0NMQVNTRVNfUk9PVC4KICovIApzdGF0aWMgSEtFWSBmaW5kX3Jvb3Rfa2V5KExQS0VZU1RSVUNUIGxwa2V5KQp7Cgl0eXBlZGVmIHN0cnVjdCB0YWdST09UX0tFWVMgewogICAgCQlLRVlTVFJVQ1QgKmxwa2V5OwogICAgCQlIS0VZIGhrZXk7Cgl9IFJPT1RfS0VZUzsKCVJPT1RfS0VZUyByb290X2tleXNbNF07CglpbnQgaTsKCglyb290X2tleXNbMF0ubHBrZXkgPSBrZXlfY2xhc3Nlc19yb290OwoJcm9vdF9rZXlzWzBdLmhrZXkgPSBIS0VZX0NMQVNTRVNfUk9PVDsKCXJvb3Rfa2V5c1sxXS5scGtleSA9IGtleV9jdXJyZW50X3VzZXI7Cglyb290X2tleXNbMV0uaGtleSA9IEhLRVlfQ1VSUkVOVF9VU0VSOwoJcm9vdF9rZXlzWzJdLmxwa2V5ID0ga2V5X2xvY2FsX21hY2hpbmU7Cglyb290X2tleXNbMl0uaGtleSA9IEhLRVlfTE9DQUxfTUFDSElORTsKCXJvb3Rfa2V5c1szXS5scGtleSA9IGtleV91c2VyczsKCXJvb3Rfa2V5c1szXS5oa2V5ID0gSEtFWV9VU0VSUzsKCglmb3IgKGk9MDsgaTw0O2krKykKCXsKCQlpZiAoc3Via2V5X2ZvdW5kKHJvb3Rfa2V5c1tpXS5scGtleSwgbHBrZXkpKQoJCQkJcmV0dXJuIHJvb3Rfa2V5c1tpXS5oa2V5OwkJCQkKCX0KCUVSUl8ocmVnKSgiRGlkbid0IGZpbmQgY29ycmVzcG9uZGluZyByb290IGtleSBlbnRyeSAhIFNlYXJjaCBzdHJhdGVneSBicm9rZW4gPz9cbiIpOwoJcmV0dXJuIDA7CiN1bmRlZiBST09UX0tFWVMKfQojdW5kZWYgQUREX1JPT1RfS0VZCi8qIHNvIHdlIGRvbid0IGFjY2lkZW50bHkgYWNjZXNzIHRoZW0gLi4uICovCiNkZWZpbmUga2V5X2N1cnJlbnRfY29uZmlnIE5VTEwgTlVMTAojZGVmaW5lIGtleV9jdXJyZW50X3VzZXIgTlVMTCBOVUxMCiNkZWZpbmUga2V5X3VzZXJzIE5VTEwgTlVMTAojZGVmaW5lIGtleV9sb2NhbF9tYWNoaW5lIE5VTEwgTlVMTAojZGVmaW5lIGtleV9jbGFzc2VzX3Jvb3QgTlVMTCBOVUxMCiNkZWZpbmUga2V5X2R5bl9kYXRhIE5VTEwgTlVMTAojZGVmaW5lIGtleV9wZXJmb3JtYW5jZV9kYXRhIE5VTEwgTlVMTAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBzcGxpdF9rZXlwYXRoIFtJbnRlcm5hbF0KICogc3BsaXRzIHRoZSB1bmljb2RlIHN0cmluZyAnd3AnIGludG8gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KICogdGhlIGFycmF5IGlzIGFsbG9jYXRlZCBieSB0aGlzIGZ1bmN0aW9uLiAKICogRnJlZSB0aGUgYXJyYXkgdXNpbmcgRlJFRV9LRVlfUEFUSAogKgogKiBQQVJBTVMKICogICAgd3AgIFtJXSBTdHJpbmcgdG8gc3BsaXQgdXAKICogICAgd3B2IFtPXSBBcnJheSBvZiBwb2ludGVycyB0byBzdHJpbmdzCiAqICAgIHdwYyBbT10gTnVtYmVyIG9mIGNvbXBvbmVudHMKICovCnN0YXRpYyB2b2lkIHNwbGl0X2tleXBhdGgoIExQQ1dTVFIgd3AsIExQV1NUUiAqKndwdiwgaW50ICp3cGMpCnsKICAgIGludAlpLGosbGVuOwogICAgTFBXU1RSIHdzOwoKICAgIFRSQUNFXyhyZWcpKCIoJXMsJXAsJXApXG4iLGRlYnVnc3RyX3cod3ApLHdwdix3cGMpOwoKICAgIHdzCT0gSEVBUF9zdHJkdXBXKCBTeXN0ZW1IZWFwLCAwLCB3cCApOwoKICAgIC8qIFdlIGtub3cgd2UgaGF2ZSBhdCBsZWFzdCBvbmUgc3Vic3RyaW5nICovCiAgICAqd3BjID0gMTsKCiAgICAvKiBSZXBsYWNlIGVhY2ggYmFja3NsYXNoIHdpdGggTlVMTCwgYW5kIGluY3JlbWVudCB0aGUgY291bnQgKi8KICAgIGZvciAoaT0wO3dzW2ldO2krKykgewogICAgICAgIGlmICh3c1tpXT09J1xcJykgewogICAgICAgICAgICB3c1tpXT0wOwogICAgICAgICAgICAoKndwYykrKzsKICAgICAgICB9CiAgICB9CgogICAgbGVuID0gaTsKCiAgICAvKiBBbGxvY2F0ZSB0aGUgc3BhY2UgZm9yIHRoZSBhcnJheSBvZiBwb2ludGVycywgbGVhdmluZyByb29tIGZvciB0aGUKICAgICAgIE5VTEwgYXQgdGhlIGVuZCAqLwogICAgKndwdiA9IChMUFdTVFIqKUhlYXBBbGxvYyggU3lzdGVtSGVhcCwgMCwgc2l6ZW9mKExQV1NUUikqKCp3cGMrMikpOwogICAgKCp3cHYpWzBdPSB3czsKCiAgICAvKiBBc3NpZ24gZWFjaCBwb2ludGVyIHRvIHRoZSBhcHByb3ByaWF0ZSBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZyAqLwogICAgaiA9IDE7CiAgICBmb3IgKGk9MTtpPGxlbjtpKyspCiAgICAgICAgaWYgKHdzW2ktMV09PTApIHsKICAgICAgICAgICAgKCp3cHYpW2orK109d3MraTsKICAgICAgICAgICAgLyogVFJBQ0UocmVnLCAiIFN1Yml0ZW0gJWQgPSAlc1xuIixqLTEsZGVidWdzdHJfdygoKndwdilbai0xXSkpOyAqLwogICAgICAgIH0KCiAgICAoKndwdilbal09TlVMTDsKfQojZGVmaW5lIEZSRUVfS0VZX1BBVEggSGVhcEZyZWUoU3lzdGVtSGVhcCwwLHdwc1swXSk7SGVhcEZyZWUoU3lzdGVtSGVhcCwwLHdwcyk7CgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJFR0lTVFJZX0luaXQgW0ludGVybmFsXQogKiBSZWdpc3RyeSBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIHNvbWUgZGVmYXVsdCBrZXlzLiAKICovCnN0YXRpYyB2b2lkIFJFR0lTVFJZX0luaXQodm9pZCkgewoJSEtFWQloa2V5OwoJY2hhcglidWZbMjAwXTsKCglUUkFDRV8ocmVnKSgiKHZvaWQpXG4iKTsKCglSZWdDcmVhdGVLZXkxNihIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIkhBUkRXQVJFXFxERVNDUklQVElPTlxcU3lzdGVtIiwmaGtleSk7CglSZWdTZXRWYWx1ZUV4QShoa2V5LCJJZGVudGlmaWVyIiwwLFJFR19TWiwiU3lzdGVtVHlwZSBXSU5FIixzdHJsZW4oIlN5c3RlbVR5cGUgV0lORSIpKTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKCS8qIFxcU09GVFdBUkVcXE1pY3Jvc29mdFxcV2luZG93IE5UXFxDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50QnVpbGROdW1iZXIKCSAqCQkJCQkJQ3VycmVudFR5cGUKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE93bmVyCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPcmdhbml6YXRpb24KCSAqCgkgKi8KCS8qIFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTTk1QXFxQYXJhbWV0ZXJzXFxSRkMxMTU2QWdlbnQKCSAqIAkJCQkJc3RyaW5nCVN5c0NvbnRhY3QKCSAqIAkJCQkJc3RyaW5nCVN5c0xvY2F0aW9uCgkgKiAJCQkJCQlTeXNTZXJ2aWNlcwoJICovCQkJCQkJCglpZiAoLTEhPWdldGhvc3RuYW1lKGJ1ZiwyMDApKSB7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxDb250cm9sXFxDb21wdXRlck5hbWVcXENvbXB1dGVyTmFtZSIsJmhrZXkpOwoJCVJlZ1NldFZhbHVlRXgxNihoa2V5LCJDb21wdXRlck5hbWUiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSsxKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKiogU0FWRSBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBSRUdJU1RSWV9TQVZFX1ZFUlNJT04JMHgwMDAwMDAwMQoKLyogUmVnaXN0cnkgc2F2ZWZvcm1hdDoKICogSWYgeW91IGNoYW5nZSBpdCwgaW5jcmVhc2UgYWJvdmUgbnVtYmVyIGJ5IDEsIHdoaWNoIHdpbGwgZmx1c2gKICogb2xkIHJlZ2lzdHJ5IGRhdGFiYXNlIGZpbGVzLgogKiAKICogR2xvYmFsOgogKiAJIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIKICogCXN1YmtleXMuLi4uCiAqIFN1YmtleXM6CiAqIAlrZXluYW1lCiAqCQl2YWx1ZW5hbWU9bGFzdG1vZGlmaWVkLHR5cGUsZGF0YQogKgkJLi4uCiAqCQlzdWJrZXlzCiAqCS4uLgogKiBrZXluYW1lLHZhbHVlbmFtZSxzdHJpbmdkYXRhOgogKgl0aGUgdXN1YWwgYXNjaWkgY2hhcmFjdGVycyBmcm9tIDB4MDAtMHhmZiAod2VsbCwgbm90IDB4MDApCiAqCWFuZCBcdVhYWFggYXMgVU5JQ09ERSB2YWx1ZSBYWFhYIHdpdGggWFhYWD4weGZmCiAqCSggIj1cXFx0IiBlc2NhcGVkIGluIFx1WFhYWCBmb3JtLikKICogdHlwZSxsYXN0bW9kaWZpZWQ6IAogKglpbnQKICogCiAqIEZJWE1FOiBkb2Vzbid0IHNhdmUgJ2NsYXNzJyAod2hhdCBkb2VzIGl0IG1lYW4gYW55d2F5PyksIG5vciBmbGFncy4KICoKICogW0hLRVlfQ1VSUkVOVF9VU0VSXFxTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnldCiAqIFNhdmVPbmx5VXBkYXRlZEtleXM9eWVzCiAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZV9jaGVja190YWludGVkIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3NhdmVfY2hlY2tfdGFpbnRlZCggTFBLRVlTVFJVQ1QgbHBrZXkgKQp7CglpbnQJCXRhaW50ZWQ7CgoJaWYgKCFscGtleSkKCQlyZXR1cm4gMDsKCWlmIChscGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1RBSU5URUQpCgkJdGFpbnRlZCA9IDE7CgllbHNlCgkJdGFpbnRlZCA9IDA7Cgl3aGlsZSAobHBrZXkpIHsKCQlpZiAoX3NhdmVfY2hlY2tfdGFpbnRlZChscGtleS0+bmV4dHN1YikpIHsKCQkJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCQkJdGFpbnRlZCA9IDE7CgkJfQoJCWxwa2V5CT0gbHBrZXktPm5leHQ7Cgl9CglyZXR1cm4gdGFpbnRlZDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZV9VU1RSSU5HIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9zYXZlX1VTVFJJTkcoIEZJTEUgKkYsIExQV1NUUiB3c3RyLCBpbnQgZXNjYXBlZXEgKQp7CglMUFdTVFIJczsKCWludAlkb2VzY2FwZTsKCglpZiAod3N0cj09TlVMTCkKCQlyZXR1cm47CglzPXdzdHI7Cgl3aGlsZSAoKnMpIHsKCQlkb2VzY2FwZT0wOwoJCWlmICgqcz4weDdmKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKCpzPT0nXG4nKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKGVzY2FwZWVxICYmICpzPT0nPScpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoKnM9PSdcXCcpCiAgICAgICAgICAgICAgICAgICAgICAgIGZwdXRjKCpzLEYpOyAvKiBpZiBcXCB0aGVuIHB1dCBpdCB0d2ljZS4gKi8KCQlpZiAoZG9lc2NhcGUpCgkJCWZwcmludGYoRiwiXFx1JTA0eCIsKigodW5zaWduZWQgc2hvcnQqKXMpKTsKCQllbHNlCgkJCWZwdXRjKCpzLEYpOwoJCXMrKzsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXN1YmtleSBbSW50ZXJuYWxdCiAqCiAqIE5PVEVTCiAqICBSRUdfTVVMVElfU1ogaXMgaGFuZGxlZCBhcyBiaW5hcnkgKGxpa2UgaW4gd2luOTUpIChqcykKICovCnN0YXRpYyBpbnQgX3NhdmVzdWJrZXkoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgbGV2ZWwsIGludCBhbGwgKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWksdGFicyxqOwoKCWxweGtleQk9IGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJIShscHhrZXktPmZsYWdzICYgUkVHX09QVElPTl9WT0xBVElMRSkgJiYKCQkJKGFsbCB8fCAobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkpCgkJKSB7CgkJCWZvciAodGFicz1sZXZlbDt0YWJzLS07KQoJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJX3NhdmVfVVNUUklORyhGLGxweGtleS0+a2V5bmFtZSwxKTsKCQkJZnB1dHMoIlxuIixGKTsKCQkJZm9yIChpPTA7aTxscHhrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJCQlMUEtFWVZBTFVFCXZhbD1scHhrZXktPnZhbHVlcytpOwoKCQkJCWZvciAodGFicz1sZXZlbCsxO3RhYnMtLTspCgkJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJCV9zYXZlX1VTVFJJTkcoRix2YWwtPm5hbWUsMCk7CgkJCQlmcHV0YygnPScsRik7CgkJCQlmcHJpbnRmKEYsIiVsZCwlbGQsIix2YWwtPnR5cGUsdmFsLT5sYXN0bW9kaWZpZWQpOwoJCQkJaWYgKCB2YWwtPnR5cGUgPT0gUkVHX1NaIHx8IHZhbC0+dHlwZSA9PSBSRUdfRVhQQU5EX1NaICkKCQkJCQlfc2F2ZV9VU1RSSU5HKEYsKExQV1NUUil2YWwtPmRhdGEsMCk7CgkJCQllbHNlCgkJCQkJZm9yIChqPTA7ajx2YWwtPmxlbjtqKyspCgkJCQkJCWZwcmludGYoRiwiJTAyeCIsKigodW5zaWduZWQgY2hhciopdmFsLT5kYXRhK2opKTsKCQkJCWZwdXRzKCJcbiIsRik7CgkJCX0KCQkJLyogZGVzY2VuZCByZWN1cnNpdmVseSAqLwoJCQlpZiAoIV9zYXZlc3Via2V5KEYsbHB4a2V5LT5uZXh0c3ViLGxldmVsKzEsYWxsKSkKCQkJCXJldHVybiAwOwoJCX0KCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlc3VicmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3NhdmVzdWJyZWcoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgYWxsICkKewoJZnByaW50ZihGLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWRcbiIsUkVHSVNUUllfU0FWRV9WRVJTSU9OKTsKCV9zYXZlX2NoZWNrX3RhaW50ZWQobHBrZXktPm5leHRzdWIpOwoJcmV0dXJuIF9zYXZlc3Via2V5KEYsbHBrZXktPm5leHRzdWIsMCxhbGwpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgQk9PTCBfc2F2ZXJlZyggTFBLRVlTVFJVQ1QgbHBrZXksIGNoYXIgKmZuLCBpbnQgYWxsICkKewoJRklMRQkqRjsKCglGPWZvcGVuKGZuLCJ3Iik7CglpZiAoRj09TlVMTCkgewoJCVdBUk5fKHJlZykoIkNvdWxkbid0IG9wZW4gJXMgZm9yIHdyaXRpbmc6ICVzXG4iLAoJCQlmbixzdHJlcnJvcihlcnJubykKCQkpOwoJCXJldHVybiBGQUxTRTsKCX0KCWlmICghX3NhdmVzdWJyZWcoRixscGtleSxhbGwpKSB7CgkJZmNsb3NlKEYpOwoJCXVubGluayhmbik7CgkJV0FSTl8ocmVnKSgiRmFpbGVkIHRvIHNhdmUga2V5cywgcGVyaGFwcyBubyBtb3JlIGRpc2tzcGFjZSBmb3IgJXM/XG4iLGZuKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglmY2xvc2UoRik7CiAgICAgICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX1NhdmVSZWdpc3RyeUJyYW5jaCBbSW50ZXJuYWxdCiAqCiAqIFNhdmVzIG1haW4gcmVnaXN0cnkgYnJhbmNoIHNwZWNpZmllZCBieSBoa2V5LgogKi8Kc3RhdGljIHZvaWQgU0hFTExfU2F2ZVJlZ2lzdHJ5QnJhbmNoKEhLRVkgaGtleSwgaW50IGFsbCkKewogICAgY2hhciAgICpmbiwgKmhvbWUsICp0bXA7CgogICAgLyogRmluZCBvdXQgd2hhdCB0byBzYXZlIHRvLCBnZXQgZnJvbSBjb25maWcgZmlsZSAqLwogICAgQk9PTCB3cml0ZVRvSG9tZSA9IFBST0ZJTEVfR2V0V2luZUluaUJvb2woInJlZ2lzdHJ5IiwiV3JpdGV0b0hvbWVSZWdpc3RyaWVzIiwxKTsKICAgIEJPT0wgd3JpdGVUb0FsdCA9IFBST0ZJTEVfR2V0V2luZUluaUJvb2woInJlZ2lzdHJ5IiwiV3JpdGV0b0FsdFJlZ2lzdHJpZXMiLDEpOwoKICAgIC8qIEZJWE1FOiBkb2VzIHRoaXMgY2hlY2sgYXBwbHkgdG8gYWxsIGtleXMgd3JpdHRlbiBiZWxvdyA/ICovCiAgICBpZiAoIShob21lID0gZ2V0ZW52KCAiSE9NRSIgKSkpCiAgICAgICAgRVJSXyhyZWcpKCJGYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVsZC5cbiIsKGxvbmcpIGdldHVpZCgpKTsKCiAgICAvKiBIS0VZX0xPQ0FMX01BQ0hJTkUgY29udGFpbnMgdGhlIEhLRVlfQ0xBU1NFU19ST09UIGJyYW5jaCAqLwogICAgaWYgKGhrZXkgPT0gSEtFWV9DTEFTU0VTX1JPT1QpIGhrZXkgPSBIS0VZX0xPQ0FMX01BQ0hJTkU7CgogICAgc3dpdGNoIChoa2V5KQogICAgewogICAgY2FzZSBIS0VZX0NVUlJFTlRfVVNFUjoKICAgICAgICBmbiA9IHhtYWxsb2MoIE1BWF9QQVRITkFNRV9MRU4gKTsgCiAgICAgICAgaWYgKHdyaXRlVG9BbHQgJiYgUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAicmVnaXN0cnkiLCAiQWx0Q3VycmVudFVzZXJGaWxlIiwgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiwgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKQogICAgICAgICAgICBfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUiksZm4sYWxsKTsKICAgICAgICBmcmVlIChmbik7CgogICAgICAgIGlmIChob21lICYmIHdyaXRlVG9Ib21lKQogICAgICAgIHsKICAgICAgICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfQ1VSUkVOVF9VU0VSKSArIDIgKTsKICAgICAgICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICAgICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgpOwogIAogICAgICAgICAgICAvKiBjcmVhdGUgdGhlIGRpcmVjdG9yeS4gZG9uJ3QgY2FyZSBhYm91dCBlcnJvcmNvZGVzLiAqLwogICAgICAgICAgICBta2RpcihmbiwwNzU1KTsgLyogZHJ3eHIteHIteCAqLwogICAgICAgICAgICBzdHJjYXQoZm4sIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwoKICAgICAgICAgICAgdG1wID0gKGNoYXIqKXhtYWxsb2Moc3RybGVuKGZuKStzdHJsZW4oIi50bXAiKSsxKTsKICAgICAgICAgICAgc3RyY3B5KHRtcCxmbik7CiAgICAgICAgICAgIHN0cmNhdCh0bXAsIi50bXAiKTsKICAKICAgICAgICAgICAgaWYgKF9zYXZlcmVnKGxvb2t1cF9oa2V5KEhLRVlfQ1VSUkVOVF9VU0VSKSx0bXAsYWxsKSkgewogICAgICAgICAgICAgICAgaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewogICAgICAgICAgICAgICAgICAgIHBlcnJvcigicmVuYW1lIHRtcCByZWdpc3RyeSIpOwogICAgICAgICAgICAgICAgICAgIHVubGluayh0bXApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZyZWUodG1wKTsKICAgICAgICAgICAgZnJlZShmbik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBIS0VZX0xPQ0FMX01BQ0hJTkU6CiAgICAgICAgLyogVHJ5IGZpcnN0IHNhdmluZyBhY2NvcmRpbmcgdG8gdGhlIGRlZmluZWQgbG9jYXRpb24gaW4gLndpbmVyYyAqLwogICAgICAgIGZuID0geG1hbGxvYyAoIE1BWF9QQVRITkFNRV9MRU4pOwogICAgICAgIGlmICh3cml0ZVRvQWx0ICYmIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggIlJlZ2lzdHJ5IiwgIkFsdExvY2FsTWFjaGluZUZpbGUiLCAiIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiwgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKQogICAgICAgICAgICBfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpLCBmbiwgYWxsKTsKICAgICAgICBmcmVlIChmbik7CgogICAgICAgIGlmIChob21lICYmIHdyaXRlVG9Ib21lKQogICAgICAgIHsKICAgICAgICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfTE9DQUxfTUFDSElORSkgKyAyKTsKICAgICAgICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICAgICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwoKICAgICAgICAgICAgdG1wID0gKGNoYXIqKXhtYWxsb2Moc3RybGVuKGZuKStzdHJsZW4oIi50bXAiKSsxKTsKICAgICAgICAgICAgc3RyY3B5KHRtcCxmbik7CiAgICAgICAgICAgIHN0cmNhdCh0bXAsIi50bXAiKTsKCiAgICAgICAgICAgIGlmIChfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpLHRtcCxhbGwpKSB7CiAgICAgICAgICAgICAgICBpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CiAgICAgICAgICAgICAgICAgICAgcGVycm9yKCJyZW5hbWUgdG1wIHJlZ2lzdHJ5Iik7CiAgICAgICAgICAgICAgICAgICAgdW5saW5rKHRtcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZnJlZSh0bXApOwogICAgICAgICAgICBmcmVlKGZuKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEhLRVlfVVNFUlM6CiAgICAgICAgZm4gPSB4bWFsbG9jKCBNQVhfUEFUSE5BTUVfTEVOICk7CiAgICAgICAgaWYgKHdyaXRlVG9BbHQgJiYgUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiUmVnaXN0cnkiLCAiQWx0VXNlckZpbGUiLCAiIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiwgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKQogICAgICAgICAgICBfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpLCBmbiwgYWxsKTsKICAgICAgICBmcmVlIChmbik7CgogICAgICAgIGlmIChob21lICYmIHdyaXRlVG9Ib21lKQogICAgICAgIHsKICAgICAgICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCkgKyAyKTsKICAgICAgICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICAgICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpOwoKICAgICAgICAgICAgdG1wID0gKGNoYXIqKXhtYWxsb2Moc3RybGVuKGZuKStzdHJsZW4oIi50bXAiKSsxKTsKICAgICAgICAgICAgc3RyY3B5KHRtcCxmbik7CiAgICAgICAgICAgIHN0cmNhdCh0bXAsIi50bXAiKTsKICAgICAgICAgICAgaWYgKCBfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX1VTRVJTKSx0bXAsRkFMU0UpKSB7CiAgICAgICAgICAgICAgICBpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CiAgICAgICAgICAgICAgICAgICAgcGVycm9yKCJyZW5hbWUgdG1wIHJlZ2lzdHJ5Iik7CiAgICAgICAgICAgICAgICAgICAgdW5saW5rKHRtcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZnJlZSh0bXApOwogICAgICAgICAgICBmcmVlKGZuKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIEVSUl8ocmVnKSgidW5rbm93bi9pbnZhbGlkIGtleSBoYW5kbGUgIVxuIik7CiAgICAgICAgYnJlYWs7CiAgICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX1NhdmVSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwp2b2lkIFNIRUxMX1NhdmVSZWdpc3RyeSggdm9pZCApCnsKICAgIGNoYXIgICBidWZbNF07CiAgICBIS0VZICAgaGtleTsKICAgIGludCAgICBhbGw7CgogICAgVFJBQ0VfKHJlZykoIih2b2lkKVxuIik7CgogICAgYWxsPTA7CiAgICBpZiAoUmVnT3BlbktleTE2KEhLRVlfQ1VSUkVOVF9VU0VSLEtFWV9SRUdJU1RSWSwmaGtleSkhPUVSUk9SX1NVQ0NFU1MpIAogICAgewogICAgICAgIHN0cmNweShidWYsInllcyIpOwogICAgfSAKICAgIGVsc2UgCiAgICB7CiAgICAgICAgRFdPUkQgbGVuLGp1bmssdHlwZTsKCiAgICAgICAgbGVuPTQ7CiAgICAgICAgaWYgKChFUlJPUl9TVUNDRVNTIT1SZWdRdWVyeVZhbHVlRXhBKCBoa2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFMX1NBVkVVUERBVEVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmp1bmssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZsZW4pKSB8fCAodHlwZSE9UkVHX1NaKSkKICAgICAgICB7CiAgICAgICAgICAgIHN0cmNweShidWYsInllcyIpOwogICAgICAgIH0KICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKfQoKICAgIGlmIChsc3RyY21waUEoYnVmLCJ5ZXMiKSkKCQlhbGwgPSAxOwoKCVNIRUxMX1NhdmVSZWdpc3RyeUJyYW5jaChIS0VZX0NVUlJFTlRfVVNFUiwgYWxsKTsKCVNIRUxMX1NhdmVSZWdpc3RyeUJyYW5jaChIS0VZX0xPQ0FMX01BQ0hJTkUsIGFsbCk7CglTSEVMTF9TYXZlUmVnaXN0cnlCcmFuY2goSEtFWV9VU0VSUywgYWxsKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKiogTE9BRCBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF9rZXkgW0ludGVybmFsXQogKi8Kc3RhdGljIExQS0VZU1RSVUNUIF9maW5kX29yX2FkZF9rZXkoIExQS0VZU1RSVUNUIGxwa2V5LCBMUFdTVFIga2V5bmFtZSApCnsKCUxQS0VZU1RSVUNUCWxweGtleSwqbHBscGtleTsKCglpZiAoKCFrZXluYW1lKSB8fCAoa2V5bmFtZVswXT09MCkpIHsKCQlmcmVlKGtleW5hbWUpOwoJCXJldHVybiBscGtleTsKCX0KCWxwbHBrZXk9ICYobHBrZXktPm5leHRzdWIpOwoJbHB4a2V5CT0gKmxwbHBrZXk7Cgl3aGlsZSAobHB4a2V5KSB7CgkJaWYgKAl0b2xvd2VyKGxweGtleS0+a2V5bmFtZVswXSk9PXRvbG93ZXIoa2V5bmFtZVswXSkgJiYgCgkJCSFsc3RyY21waVcobHB4a2V5LT5rZXluYW1lLGtleW5hbWUpCgkJKQoJCQlicmVhazsKCQlscGxwa2V5CT0gJihscHhrZXktPm5leHQpOwoJCWxweGtleQk9ICpscGxwa2V5OwoJfQoJaWYgKGxweGtleT09TlVMTCkgewoJCSpscGxwa2V5ID0gKExQS0VZU1RSVUNUKXhtYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpOwoJCWxweGtleQk9ICpscGxwa2V5OwoJCW1lbXNldChscHhrZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5LT5rZXluYW1lCT0ga2V5bmFtZTsKCX0gZWxzZQoJCWZyZWUoa2V5bmFtZSk7CglyZXR1cm4gbHB4a2V5Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF92YWx1ZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfZmluZF9vcl9hZGRfdmFsdWUoIExQS0VZU1RSVUNUIGxwa2V5LCBMUFdTVFIgbmFtZSwgRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgZGF0YSwgRFdPUkQgbGVuLCBEV09SRCBsYXN0bW9kaWZpZWQgKQp7CglMUEtFWVZBTFVFCXZhbD1OVUxMOwoJaW50CQlpOwoKCWlmIChuYW1lICYmICEqbmFtZSkgey8qIGVtcHR5IHN0cmluZyBlcXVhbHMgZGVmYXVsdCAoTlVMTCkgdmFsdWUgKi8KCQlmcmVlKG5hbWUpOwoJCW5hbWUgPSBOVUxMOwoJfQoKCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJdmFsPWxwa2V5LT52YWx1ZXMraTsKCQlpZiAobmFtZT09TlVMTCkgewoJCQlpZiAodmFsLT5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7CgkJfSBlbHNlIHsKCQkJaWYgKAl2YWwtPm5hbWUhPU5VTEwgJiYKCQkJCXRvbG93ZXIodmFsLT5uYW1lWzBdKT09dG9sb3dlcihuYW1lWzBdKSAmJgoJCQkJIWxzdHJjbXBpVyh2YWwtPm5hbWUsbmFtZSkKCQkJKQoJCQkJYnJlYWs7CgkJfQoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CgkJbHBrZXktPnZhbHVlcyA9IHhyZWFsbG9jKAoJCQlscGtleS0+dmFsdWVzLAoJCQkoKytscGtleS0+bnJvZnZhbHVlcykqc2l6ZW9mKEtFWVZBTFVFKQoJCSk7CgkJdmFsPWxwa2V5LT52YWx1ZXMraTsKCQltZW1zZXQodmFsLCdcMCcsc2l6ZW9mKEtFWVZBTFVFKSk7CgkJdmFsLT5uYW1lID0gbmFtZTsKCX0gZWxzZSB7CgkJaWYgKG5hbWUpCgkJCWZyZWUobmFtZSk7Cgl9CglpZiAodmFsLT5sYXN0bW9kaWZpZWQ8bGFzdG1vZGlmaWVkKSB7CgkJdmFsLT5sYXN0bW9kaWZpZWQ9bGFzdG1vZGlmaWVkOwoJCXZhbC0+dHlwZSA9IHR5cGU7CgogICAgICAgICAgICAgICAgaWYgKCh0eXBlID09IFJFR19TWiB8fCB0eXBlID09IFJFR19FWFBBTkRfU1opICYmICFkYXRhKXsKCiAgICAgICAgICAgICAgICAgICAgZGF0YT14bWFsbG9jKHNpemVvZihXQ0hBUikpOwogICAgICAgICAgICAgICAgICAgIG1lbXNldChkYXRhLDAsc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgICAgICAgICAgICAgbGVuID1zaXplb2YoV0NIQVIpOwogICAgICAgICAgICAgICAgfQoKCQl2YWwtPmxlbiAgPSBsZW47CgkJaWYgKHZhbC0+ZGF0YSkgCgkJCWZyZWUodmFsLT5kYXRhKTsKCQl2YWwtPmRhdGEgPSBkYXRhOwoJfSBlbHNlCgkJZnJlZShkYXRhKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9saW5lIFtJbnRlcm5hbF0KICoKICogcmVhZHMgYSBsaW5lIGluY2x1ZGluZyBkeW5hbWljYWxseSBlbmxhcmdpbmcgdGhlIHJlYWRidWZmZXIgYW5kIHRocm93aW5nCiAqIGF3YXkgY29tbWVudHMKICovCnN0YXRpYyBpbnQgX3dpbmVfcmVhZF9saW5lKCBGSUxFICpGLCBjaGFyICoqYnVmLCBpbnQgKmxlbiApCnsKCWNoYXIJKnMsKmN1cnJlYWQ7CglpbnQJbXlsZW4sY3Vyb2ZmOwoKCWN1cnJlYWQJPSAqYnVmOwoJbXlsZW4JPSAqbGVuOwoJKipidWYJPSAnXDAnOwoJd2hpbGUgKDEpIHsKCQl3aGlsZSAoMSkgewoJCQlzPWZnZXRzKGN1cnJlYWQsbXlsZW4sRik7CgkJCWlmIChzPT1OVUxMKQoJCQkJcmV0dXJuIDA7IC8qIEVPRiAqLwoJCQlpZiAoTlVMTD09KHM9c3RyY2hyKGN1cnJlYWQsJ1xuJykpKSB7CgkJCQkvKiBidWZmZXIgd2Fzbid0IGxhcmdlIGVub3VnaCAqLwoJCQkJY3Vyb2ZmCT0gc3RybGVuKCpidWYpOwoJCQkJKmJ1Zgk9IHhyZWFsbG9jKCpidWYsKmxlbioyKTsKCQkJCWN1cnJlYWQJPSAqYnVmICsgY3Vyb2ZmOwoJCQkJbXlsZW4JPSAqbGVuOwkvKiB3ZSBmaWxsZWQgdXAgdGhlIGJ1ZmZlciBhbmQgCgkJCQkJCSAqIGdvdCBuZXcgJypsZW4nIGJ5dGVzIHRvIGZpbGwKCQkJCQkJICovCgkJCQkqbGVuCT0gKmxlbiAqIDI7CgkJCX0gZWxzZSB7CgkJCQkqcz0nXDAnOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLyogdGhyb3cgYXdheSBjb21tZW50cyAqLwoJCWlmICgqKmJ1Zj09JyMnIHx8ICoqYnVmPT0nOycpIHsKCQkJY3VycmVhZAk9ICpidWY7CgkJCW15bGVuCT0gKmxlbjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzKSAJLyogZ290IGVuZCBvZiBsaW5lICovCgkJCWJyZWFrOwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfVVNUUklORyBbSW50ZXJuYWxdCiAqCiAqIGNvbnZlcnRzIGEgY2hhciogaW50byBhIFVOSUNPREUgc3RyaW5nICh1cCB0byBhIHNwZWNpYWwgY2hhcikKICogYW5kIHJldHVybnMgdGhlIHBvc2l0aW9uIGV4YWN0bHkgYWZ0ZXIgdGhhdCBzdHJpbmcKICovCnN0YXRpYyBjaGFyKiBfd2luZV9yZWFkX1VTVFJJTkcoIGNoYXIgKmJ1ZiwgTFBXU1RSICpzdHIgKQp7CgljaGFyCSpzOwoJTFBXU1RSCXdzOwoKCS8qIHJlYWQgdXAgdG8gIj0iIG9yICJcMCIgb3IgIlxuIiAqLwoJcwk9IGJ1ZjsKCWlmICgqcyA9PSAnPScpIHsKCQkvKiBlbXB0eSBzdHJpbmcgaXMgdGhlIHdpbjMuMSBkZWZhdWx0IHZhbHVlKE5VTEwpKi8KCQkqc3RyCT0gTlVMTDsKCQlyZXR1cm4gczsKCX0KCSpzdHIJPSAoTFBXU1RSKXhtYWxsb2MoMipzdHJsZW4oYnVmKSsyKTsKCXdzCT0gKnN0cjsKCXdoaWxlICgqcyAmJiAoKnMhPSdcbicpICYmICgqcyE9Jz0nKSkgewoJCWlmICgqcyE9J1xcJykKCQkJKndzKys9KigodW5zaWduZWQgY2hhciopcysrKTsKCQllbHNlIHsKCQkJcysrOwoJCQlpZiAoISpzKSB7CgkJCQkvKiBEYW5nbGluZyBcIC4uLiBtYXkgb25seSBoYXBwZW4gaWYgYSByZWdpc3RyeQoJCQkJICogd3JpdGUgd2FzIHNob3J0LiBGSVhNRTogV2hhdCBkbyB0bz8KCQkJCSAqLwoJCQkJIGJyZWFrOwoJCQl9CgkJCWlmICgqcz09J1xcJykgewoJCQkJKndzKys9J1xcJzsKCQkJCXMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWlmICgqcyE9J3UnKSB7CgkJCQlXQVJOXyhyZWcpKCJOb24gdW5pY29kZSBlc2NhcGUgc2VxdWVuY2UgXFwlYyBmb3VuZCBpbiB8JXN8XG4iLCpzLGJ1Zik7CgkJCQkqd3MrKz0nXFwnOwoJCQkJKndzKys9KnMrKzsKCQkJfSBlbHNlIHsKCQkJCWNoYXIJeGJ1Zls1XTsKCQkJCWludAl3YzsKCgkJCQlzKys7CgkJCQltZW1jcHkoeGJ1ZixzLDQpO3hidWZbNF09J1wwJzsKCQkJCWlmICghc3NjYW5mKHhidWYsIiV4Iiwmd2MpKQoJCQkJCVdBUk5fKHJlZykoIlN0cmFuZ2UgZXNjYXBlIHNlcXVlbmNlICVzIGZvdW5kIGluIHwlc3xcbiIseGJ1ZixidWYpOwoJCQkJcys9NDsKCQkJCSp3cysrCT0odW5zaWduZWQgc2hvcnQpd2M7CgkJCX0KCQl9Cgl9Cgkqd3MJPSAwOwoJd3MJPSAqc3RyOwoJaWYgKCp3cykKCQkqc3RyCT0gc3RyZHVwVygqc3RyKTsKCWVsc2UKCQkqc3RyCT0gTlVMTDsKCWZyZWUod3MpOwoJcmV0dXJuIHM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJrZXkgW0ludGVybmFsXQogKgogKiBOT1RFUwogKiAgICBJdCBzZWVtcyBsaWtlIHRoaXMgaXMgcmV0dXJuaW5nIGEgYm9vbGVhbi4gIFNob3VsZCBpdD8KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiAxCiAqICAgIEZhaWx1cmU6IDAKICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YmtleSggRklMRSAqRiwgTFBLRVlTVFJVQ1QgbHBrZXksIGludCBsZXZlbCwgY2hhciAqKmJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKmJ1ZmxlbiwgRFdPUkQgb3B0ZmxhZyApCnsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJaTsKCWNoYXIJCSpzOwoJTFBXU1RSCQluYW1lOwoKICAgIFRSQUNFXyhyZWcpKCIoJXAsJXAsJWQsJXMsJWQsJWx4KVxuIiwgRiwgbHBrZXksIGxldmVsLCBkZWJ1Z3N0cl9hKCpidWYpLAogICAgICAgICAgKmJ1Zmxlbiwgb3B0ZmxhZyk7CgogICAgbHBrZXktPmZsYWdzIHw9IG9wdGZsYWc7CgogICAgLyogR29vZC4gIFdlIGFscmVhZHkgZ290IGEgbGluZSBoZXJlIC4uLiBzbyBwYXJzZSBpdCAqLwogICAgbHB4a2V5ID0gTlVMTDsKICAgIHdoaWxlICgxKSB7CiAgICAgICAgaT0wO3M9KmJ1ZjsKICAgICAgICB3aGlsZSAoKnM9PSdcdCcpIHsKICAgICAgICAgICAgcysrOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQogICAgICAgIGlmIChpPmxldmVsKSB7CiAgICAgICAgICAgIGlmIChscHhrZXk9PU5VTEwpIHsKICAgICAgICAgICAgICAgIFdBUk5fKHJlZykoIkdvdCBhIHN1YmhpZXJhcmNoeSB3aXRob3V0IHJlc3AuIGtleT9cbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3dpbmVfbG9hZHN1YmtleShGLGxweGtleSxsZXZlbCsxLGJ1ZixidWZsZW4sb3B0ZmxhZyk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCgkJLyogbGV0IHRoZSBjYWxsZXIgaGFuZGxlIHRoaXMgbGluZSAqLwoJCWlmIChpPGxldmVsIHx8ICoqYnVmPT0nXDAnKQoJCQlyZXR1cm4gMTsKCgkJLyogaXQgY2FuIGJlOiBhIHZhbHVlIG9yIGEga2V5bmFtZS4gUGFyc2UgdGhlIG5hbWUgZmlyc3QgKi8KCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLCZuYW1lKTsKCgkJLyogc3dpdGNoKCkgZGVmYXVsdDogaGFjayB0byBhdm9pZCBnb3RvcyAqLwoJCXN3aXRjaCAoMCkgewoJCWRlZmF1bHQ6CgkJCWlmICgqcz09J1wwJykgewoJCQkJbHB4a2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksbmFtZSk7CgkJCX0gZWxzZSB7CgkJCQlMUEJZVEUJCWRhdGE7CgkJCQlpbnQJCWxlbixsYXN0bW9kaWZpZWQsdHlwZTsKCgkJCQlpZiAoKnMhPSc9JykgewoJCQkJCVdBUk5fKHJlZykoIlVuZXhwZWN0ZWQgY2hhcmFjdGVyOiAlY1xuIiwqcyk7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlzKys7CgkJCQlpZiAoMiE9c3NjYW5mKHMsIiVkLCVkLCIsJnR5cGUsJmxhc3Rtb2RpZmllZCkpIHsKCQkJCQlXQVJOXyhyZWcpKCJIYXZlbid0IHVuZGVyc3Rvb2QgcG9zc2libGUgdmFsdWUgaW4gfCVzfCwgc2tpcHBpbmcuXG4iLCpidWYpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJLyogc2tpcCB0aGUgMiAsICovCgkJCQlzPXN0cmNocihzLCcsJyk7cysrOwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCWlmICh0eXBlID09IFJFR19TWiB8fCB0eXBlID09IFJFR19FWFBBTkRfU1opIHsKCQkJCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLChMUFdTVFIqKSZkYXRhKTsKCQkJCQlpZiAoZGF0YSkKCQkJCQkJbGVuID0gbHN0cmxlblcoKExQV1NUUilkYXRhKSoyKzI7CgkJCQkJZWxzZQkKCQkJCQkJbGVuID0gMDsKCQkJCX0gZWxzZSB7CgkJCQkJbGVuPXN0cmxlbihzKS8yOwoJCQkJCWRhdGEgPSAoTFBCWVRFKXhtYWxsb2MobGVuKzEpOwoJCQkJCWZvciAoaT0wO2k8bGVuO2krKykgewoJCQkJCQlkYXRhW2ldPTA7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldPSgqcy0nMCcpPDw0OwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ2EnKydceGEnKTw8NDsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV09KCpzLSdBJysnXHhhJyk8PDQ7CgkJCQkJCXMrKzsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV18PSpzLScwJzsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV18PSpzLSdhJysnXHhhJzsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV18PSpzLSdBJysnXHhhJzsKCQkJCQkJcysrOwoJCQkJCX0KCQkJCX0KCQkJCV9maW5kX29yX2FkZF92YWx1ZShscGtleSxuYW1lLHR5cGUsZGF0YSxsZW4sbGFzdG1vZGlmaWVkKTsKCQkJfQoJCX0KCQkvKiByZWFkIHRoZSBuZXh0IGxpbmUgKi8KCQlpZiAoIV93aW5lX3JlYWRfbGluZShGLGJ1ZixidWZsZW4pKQoJCQlyZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2Fkc3VicmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YnJlZyggRklMRSAqRiwgTFBLRVlTVFJVQ1QgbHBrZXksIERXT1JEIG9wdGZsYWcgKQp7CglpbnQJdmVyOwoJY2hhcgkqYnVmOwoJaW50CWJ1ZmxlbjsKCglidWY9eG1hbGxvYygxMCk7YnVmbGVuPTEwOwoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFzc2NhbmYoYnVmLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWQiLCZ2ZXIpKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKHZlciE9UkVHSVNUUllfU0FWRV9WRVJTSU9OKSB7CgkJVFJBQ0VfKHJlZykoIk9sZCBmb3JtYXQgKCVkKSByZWdpc3RyeSBmb3VuZCwgaWdub3JpbmcgaXQuIChidWYgd2FzICVzKS5cbiIsdmVyLGJ1Zik7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFfd2luZV9sb2Fkc3Via2V5KEYsbHBrZXksMCwmYnVmLCZidWZsZW4sb3B0ZmxhZykpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglmcmVlKGJ1Zik7CglyZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfd2luZV9sb2FkcmVnKCBMUEtFWVNUUlVDVCBscGtleSwgY2hhciAqZm4sIERXT1JEIG9wdGZsYWcgKQp7CiAgICBGSUxFICpGOwoKICAgIFRSQUNFXyhyZWcpKCIoJXAsJXMsJWx4KVxuIixscGtleSxkZWJ1Z3N0cl9hKGZuKSxvcHRmbGFnKTsKCiAgICBGID0gZm9wZW4oZm4sInJiIik7CiAgICBpZiAoRj09TlVMTCkgewogICAgICAgIFdBUk5fKHJlZykoIkNvdWxkbid0IG9wZW4gJXMgZm9yIHJlYWRpbmc6ICVzXG4iLGZuLHN0cmVycm9yKGVycm5vKSApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmICghX3dpbmVfbG9hZHN1YnJlZyhGLGxwa2V5LG9wdGZsYWcpKSB7CiAgICAgICAgZmNsb3NlKEYpOwogICAgICAgIHVubGluayhmbik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgZmNsb3NlKEYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9mbHVzaF9yZWdpc3RyeSBbSW50ZXJuYWxdCiAqIAogKiBUaGlzIGZ1bmN0aW9uIGFsbG93IHRvIGZsdXNoIHNlY3Rpb24gb2YgdGhlIGludGVybmFsIHJlZ2lzdHJ5LiAgSXQgaXMgbWFpbmx5CiAqIGltcGxlbWVudHMgdG8gZml4IGEgcHJvYmxlbSB3aXRoIHRoZSBnbG9iYWwgSEtVIGFuZCB0aGUgbG9jYWwgSEtVLgogKiBUaG9zZSB0d28gZmlsZXMgYXJlIHJlYWQgdG8gYnVpbGQgdGhlIEhLVVwuRGVmYXVsdCBicmFuY2ggdG8gZmluYWx5IGNvcHkKICogdGhpcyBicmFuY2ggb250byBIS0NVIGhpdmUsIG9uY2UgdGhpcyBpcyBkb25lLCBpZiB3ZSBrZWVwIHRoZSBIS1UgaGl2ZSBhcyBpcywgCiAqIGFsbCB0aGUgZ2xvYmFsIEhLVSBhcmUgc2F2ZWQgb250byB0aGUgdXNlcidzIHBlcnNvbmFsIHZlcnNpb24gb2YgSEtVIGhpdmUuCiAqIHdoaWNoIGlzIGJhZC4uLgogKi8KCiAvKiBGb3J3YXJkIGRlY2xhcmF0aW9uIG9mIHJlY3VzaXZlIGFnZW50ICovCnN0YXRpYyB2b2lkIF9mbHVzaF9yZWcoTFBLRVlTVFJVQ1QgZnJvbSk7CgpzdGF0aWMgdm9pZCBfZmx1c2hfcmVnaXN0cnkoIExQS0VZU1RSVUNUIGZyb20gKQp7CiAgLyogbWFrZSBzdXJlIHdlIGhhdmUgc29tZXRoaW5nLi4uICovCiAgaWYgKGZyb20gPT0gTlVMTCkKICAgIHJldHVybjsKCiAgLyogTGF1bmNoIHRoZSByZWN1c2l2ZSBhZ2VudCBvbiBzdWIgYnJhbmNoZXMgKi8KICBfZmx1c2hfcmVnKCBmcm9tLT5uZXh0c3ViICk7CiAgX2ZsdXNoX3JlZyggZnJvbS0+bmV4dCApOwoKICAvKiBJbml0aWFsaXplIHBvaW50ZXJzICovCiAgZnJvbS0+bmV4dHN1YiA9IE5VTEw7CiAgZnJvbS0+bmV4dCAgICA9IE5VTEw7Cn0Kc3RhdGljIHZvaWQgX2ZsdXNoX3JlZyggTFBLRVlTVFJVQ1QgZnJvbSApCnsKCWludAlqOwoKICAvKiBtYWtlIHN1cmUgd2UgaGF2ZSBzb21ldGhpbmcuLi4gKi8KICBpZiAoZnJvbSA9PSBOVUxMKQogICAgcmV0dXJuOwoKICAvKiAKICAgKiBkbyB0aGUgc2FtZSBmb3IgdGhlIGNoaWxkIGtleXMgCiAgICovCiAgaWYgKGZyb20tPm5leHRzdWIgIT0gTlVMTCkKICAgIF9mbHVzaF9yZWcoZnJvbS0+bmV4dHN1Yik7CgogIC8qIAogICAqIGRvIHRoZSBzYW1lIGZvciB0aGUgc2libGluZyBrZXlzIAogICAqLwogIGlmIChmcm9tLT5uZXh0ICE9IE5VTEwpCiAgICBfZmx1c2hfcmVnKGZyb20tPm5leHQpOwoKICAvKgogICAqIGl0ZXJhdGUgdGhyb3VnaCB0aGlzIGtleSdzIHZhbHVlcyBhbmQgZGVsZXRlIHRoZW0KICAgKi8KICBmb3IgKGo9MDtqPGZyb20tPm5yb2Z2YWx1ZXM7aisrKSAKICB7CiAgICBmcmVlKCAoZnJvbS0+dmFsdWVzK2opLT5uYW1lKTsKICAgIGZyZWUoIChmcm9tLT52YWx1ZXMraiktPmRhdGEpOwogIH0KCiAgLyoKICAgKiBmcmVlIHRoZSBzdHJ1Y3R1cmUKICAgKi8KICBpZiAoIGZyb20gIT0gTlVMTCApCiAgICBmcmVlKGZyb20pOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfY29weV9yZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfY29weV9yZWdpc3RyeSggTFBLRVlTVFJVQ1QgZnJvbSwgTFBLRVlTVFJVQ1QgdG8gKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWo7CglMUEtFWVZBTFVFCXZhbGZyb207CgoJZnJvbT1mcm9tLT5uZXh0c3ViOwoJd2hpbGUgKGZyb20pIHsKCQlscHhrZXkgPSBfZmluZF9vcl9hZGRfa2V5KHRvLHN0cmR1cFcoZnJvbS0+a2V5bmFtZSkpOwoKCQlmb3IgKGo9MDtqPGZyb20tPm5yb2Z2YWx1ZXM7aisrKSB7CgkJCUxQV1NUUgluYW1lOwoJCQlMUEJZVEUJZGF0YTsKCgkJCXZhbGZyb20gPSBmcm9tLT52YWx1ZXMrajsKCQkJbmFtZT12YWxmcm9tLT5uYW1lOwoJCQlpZiAobmFtZSkgbmFtZT1zdHJkdXBXKG5hbWUpOwoJCQlkYXRhPShMUEJZVEUpeG1hbGxvYyh2YWxmcm9tLT5sZW4pOwoJCQltZW1jcHkoZGF0YSx2YWxmcm9tLT5kYXRhLHZhbGZyb20tPmxlbik7CgoJCQlfZmluZF9vcl9hZGRfdmFsdWUoCgkJCQlscHhrZXksCgkJCQluYW1lLAoJCQkJdmFsZnJvbS0+dHlwZSwKCQkJCWRhdGEsCgkJCQl2YWxmcm9tLT5sZW4sCgkJCQl2YWxmcm9tLT5sYXN0bW9kaWZpZWQKCQkJKTsKCQl9CgkJX2NvcHlfcmVnaXN0cnkoZnJvbSxscHhrZXkpOwoJCWZyb20gPSBmcm9tLT5uZXh0OwoJfQp9CgoKLyogV0lORE9XUyA5NSBSRUdJU1RSWSBMT0FERVIgKi8KLyogCiAqIFN0cnVjdHVyZSBvZiBhIHdpbjk1IHJlZ2lzdHJ5IGRhdGFiYXNlLgogKiBtYWluIGhlYWRlcjoKICogMCA6CSJDUkVHIgktIG1hZ2ljCiAqIDQgOglEV09SRCB2ZXJzaW9uCiAqIDggOglEV09SRCBvZmZzZXRfb2ZfUkdEQl9wYXJ0CiAqIDBDLi4wRjoJPyAoc29tZW9uZSBmaWxsIGluIHBsZWFzZSkKICogMTA6ICBXT1JECW51bWJlciBvZiBSR0RCIGJsb2NrcwogKiAxMjogIFdPUkQJPwogKiAxNDogIFdPUkQJYWx3YXlzIDAwMDA/CiAqIDE2OiAgV09SRAlhbHdheXMgMDAwMT8KICogMTguLjFGOgk/IChzb21lb25lIGZpbGwgaW4gcGxlYXNlKQogKgogKiAyMDogUkdLTl9zZWN0aW9uOgogKiAgIGhlYWRlcjoKICogCTAgOgkJIlJHS04iCS0gbWFnaWMKICogICAgICA0IDogRFdPUkQJb2Zmc2V0IHRvIGZpcnN0IFJHREIgc2VjdGlvbgogKiAgICAgIDggOiBEV09SRAlvZmZzZXQgdG8gdGhlIHJvb3QgcmVjb3JkCiAqIAlDLi4weDFCOiAJPyAoZmlsbCBpbikKICogICAgICAweDIwIC4uLiBvZmZzZXRfb2ZfUkdEQl9wYXJ0OiBEaXNrIEtleSBFbnRyeSBzdHJ1Y3R1cmVzCiAqCiAqICAgRGlzayBLZXkgRW50cnkgU3RydWN0dXJlOgogKgkwMDogRFdPUkQJLSBGcmVlIGVudHJ5IGluZGljYXRvcig/KQogKgkwNDogRFdPUkQJLSBIYXNoID0gc3VtIG9mIGJ5dGVzIG9mIGtleW5hbWUKICoJMDg6IERXT1JECS0gUm9vdCBrZXkgaW5kaWNhdG9yPyB1bmtub3duLCBidXQgdXN1YWxseSAweEZGRkZGRkZGIG9uIHdpbjk1IHN5c3RlbXMKICoJMEM6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIFByZXZpb3VzTGV2ZWwgS2V5LgogKgkxMDogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgTmV4dCBTdWJsZXZlbCBLZXkuCiAqCTE0OiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBOZXh0IEtleSAob24gc2FtZSBsZXZlbCkuCiAqIERLRVA+MTg6IFdPUkQJLSBOciwgTG93IFNpZ25pZmljYW50IHBhcnQuCiAqCTFBOiBXT1JECS0gTnIsIEhpZ2ggU2lnbmlmaWNhbnQgcGFydC4KICoKICogVGhlIGRpc2sgYWRkcmVzcyBhbHdheXMgcG9pbnRzIHRvIHRoZSBuciBwYXJ0IG9mIHRoZSBwcmV2aW91cyBrZXkgZW50cnkgCiAqIG9mIHRoZSByZWZlcmVuY2VkIGtleS4gRG9uJ3QgYXNrIG1lIHdoeSwgb3IgZXZlbiBpZiBJIGdvdCB0aGlzIGNvcnJlY3QKICogZnJvbSBzdGFyaW5nIGF0IDFrZyBvZiBoZXhkdW1wcy4gKERLRVApCiAqCiAqIFRoZSBIaWdoIHNpZ25pZmljYW50IHBhcnQgb2YgdGhlIHN0cnVjdHVyZSBzZWVtcyB0byBlcXVhbCB0aGUgbnVtYmVyCiAqIG9mIHRoZSBSR0RCIHNlY3Rpb24uIFRoZSBsb3cgc2lnbmlmaWNhbnQgcGFydCBpcyBhIHVuaXF1ZSBJRCB3aXRoaW4KICogdGhhdCBSR0RCIHNlY3Rpb24KICoKICogVGhlcmUgYXJlIHR3byBtaW5vciBjb3JyZWN0aW9ucyB0byB0aGUgcG9zaXRpb24gb2YgdGhhdCBzdHJ1Y3R1cmUuCiAqIDEuIElmIHRoZSBhZGRyZXNzIGlzIHh4eDAxNCBvciB4eHgwMTggaXQgd2lsbCBiZSBhbGlnbmVkIHRvIHh4eDAxYyBBTkQgCiAqICAgIHRoZSBES0UgcmVyZWFkIGZyb20gdGhlcmUuCiAqIDIuIElmIHRoZSBhZGRyZXNzIGlzIHh4eEZGeCBpdCB3aWxsIGJlIGFsaWduZWQgdG8gKHh4eCsxKTAwMC4KICogQ1BTIC0gSSBoYXZlIG5vdCBleHBlcmllbmNlZCB0aGUgYWJvdmUgcGhlbm9tZW5vbiBpbiBteSByZWdpc3RyeSBmaWxlcwogKgogKiBSR0RCX3NlY3Rpb246CiAqIAkwMDoJCSJSR0RCIgktIG1hZ2ljCiAqCTA0OiBEV09SRAlvZmZzZXQgdG8gbmV4dCBSR0RCIHNlY3Rpb24KICoJMDg6IERXT1JECT8KICoJMEM6IFdPUkQJYWx3YXlzIDAwMGQ/CiAqCTBFOiBXT1JECVJHREIgYmxvY2sgbnVtYmVyCiAqCTEwOglEV09SRAk/IChlcXVhbHMgdmFsdWUgYXQgb2Zmc2V0IDQgLSB2YWx1ZSBhdCBvZmZzZXQgOCkKICoJMTQuLjFGOgkJPwogKgkyMC4uLi4uOglkaXNrIGtleXMKICoKICogZGlzayBrZXk6CiAqIAkwMDogCURXT1JECW5leHRrZXlvZmZzZXQJLSBvZmZzZXQgdG8gdGhlIG5leHQgZGlzayBrZXkgc3RydWN0dXJlCiAqCTA4OiAJV09SRAluckxTCQktIGxvdyBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBBOiAJV09SRAluckhTCQktIGhpZ2ggc2lnbmlmaWNhbnQgcGFydCBvZiBOUgogKgkwQzogCURXT1JECWJ5dGVzdXNlZAktIGJ5dGVzIHVzZWQgaW4gdGhpcyBzdHJ1Y3R1cmUuCiAqCTEwOiAJV09SRAluYW1lX2xlbgktIGxlbmd0aCBvZiBuYW1lIGluIGJ5dGVzLiB3aXRob3V0IFwwCiAqCTEyOiAJV09SRAlucl9vZl92YWx1ZXMJLSBudW1iZXIgb2YgdmFsdWVzLgogKgkxNDogCWNoYXIJbmFtZVtuYW1lX2xlbl0JLSBuYW1lIHN0cmluZy4gTm8gXDAuCiAqCTE0K25hbWVfbGVuOiBkaXNrIHZhbHVlcwogKgluZXh0a2V5b2Zmc2V0OiAuLi4gbmV4dCBkaXNrIGtleQogKgogKiBkaXNrIHZhbHVlOgogKgkwMDoJRFdPUkQJdHlwZQkJLSB2YWx1ZSB0eXBlIChobW0sIGNvdWxkIGJlIFdPUkQgdG9vKQogKgkwNDoJRFdPUkQJCQktIHVua25vd24sIHVzdWFsbHkgMAogKgkwODoJV09SRAluYW1lbGVuCQktIGxlbmd0aCBvZiBOYW1lLiAwIG1lYW5zIG5hbWU9TlVMTAogKgkwQzoJV09SRAlkYXRhbGVuCQktIGxlbmd0aCBvZiBEYXRhLgogKgkxMDoJY2hhcgluYW1lW25hbWVsZW5dCS0gbmFtZSwgbm8gXDAKICoJMTArbmFtZWxlbjogQllURQlkYXRhW2RhdGFsZW5dIC0gZGF0YSwgd2l0aG91dCBcMCBpZiBzdHJpbmcKICoJMTArbmFtZWxlbitkYXRhbGVuOiBuZXh0IHZhbHVlcyBvciBkaXNrIGtleQogKgogKiBEaXNrIGtleXMgYXJlIGxheWVkIG91dCBmbGF0IC4uLiBCdXQsIHNvbWV0aW1lcywgbnJMUyBhbmQgbnJIUyBhcmUgYm90aAogKiAweEZGRkYsIHdoaWNoIG1lYW5zIHNraXBwaW5nIG92ZXIgbmV4dGtleW9mZnNldCBieXRlcyAoaW5jbHVkaW5nIHRoaXMKICogc3RydWN0dXJlKSBhbmQgcmVhZGluZyBhbm90aGVyIFJHREJfc2VjdGlvbi4KICogcmVwZWF0IHVudGlsIGVuZCBvZiBmaWxlLgogKgogKiBBbiBpbnRlcmVzdGluZyByZWxhdGlvbnNoaXAgZXhpc3RzIGluIFJHREJfc2VjdGlvbi4gVGhlIHZhbHVlIGF0IG9mZnNldAogKiAxMCBlcXVhbHMgdGhlIHZhbHVlIGF0IG9mZnNldCA0IG1pbnVzIHRoZSB2YWx1ZSBhdCBvZmZzZXQgOC4gSSBoYXZlIG5vCiAqIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKgogKiBGSVhNRTogdGhpcyBkZXNjcmlwdGlvbiBuZWVkcyBzb21lIHNlcmlvdXMgaGVscCwgeWVzLgogKi8KCnN0cnVjdAlfdzk1a2V5dmFsdWUgewoJdW5zaWduZWQgbG9uZwkJdHlwZTsKCXVuc2lnbmVkIHNob3J0CQlkYXRhbGVuOwoJY2hhcgkJCSpuYW1lOwoJdW5zaWduZWQgY2hhcgkJKmRhdGE7Cgl1bnNpZ25lZCBsb25nCQl4MTsKCWludAkJCWxhc3Rtb2RpZmllZDsKfTsKCnN0cnVjdCAJX3c5NWtleSB7CgljaGFyCQkJKm5hbWU7CglpbnQJCQlucm9mdmFsczsKCXN0cnVjdAlfdzk1a2V5dmFsdWUJKnZhbHVlczsKCXN0cnVjdCBfdzk1a2V5CQkqcHJldmx2bDsKCXN0cnVjdCBfdzk1a2V5CQkqbmV4dHN1YjsKCXN0cnVjdCBfdzk1a2V5CQkqbmV4dDsKfTsKCgpzdHJ1Y3QgX3c5NV9pbmZvIHsKICBjaGFyICpyZ2tuYnVmZmVyOwogIGludCAgcmdrbnNpemU7CiAgY2hhciAqcmdkYmJ1ZmZlcjsKICBpbnQgIHJnZGJzaXplOwogIGludCAgZGVwdGg7CiAgaW50ICBsYXN0bW9kaWZpZWQ7Cn07CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X3Byb2Nlc3NLZXkgW0ludGVybmFsXQogKi8Kc3RhdGljIExQS0VZU1RSVUNUIF93OTVfcHJvY2Vzc0tleSAoIExQS0VZU1RSVUNUIGxwa2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnJMUywgaW50IG5yTVMsIHN0cnVjdCBfdzk1X2luZm8gKmluZm8gKQoKewogIC8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCkgKi8KCXN0cnVjdAlka2ggewogICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZwkJbmV4dGtleW9mZjsgCgkJdW5zaWduZWQgc2hvcnQJCW5yTFM7CgkJdW5zaWduZWQgc2hvcnQJCW5yTVM7CgkJdW5zaWduZWQgbG9uZwkJYnl0ZXN1c2VkOwoJCXVuc2lnbmVkIHNob3J0CQlrZXluYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWx1ZXM7CgkJdW5zaWduZWQgbG9uZwkJeHgxOwoJCS8qIGtleW5hbWUgKi8KCQkvKiBkaXNrIGtleSB2YWx1ZXMgb3Igbm90aGluZyAqLwoJfTsKCS8qIERpc2sgS2V5IFZhbHVlIHN0cnVjdHVyZSAqLwoJc3RydWN0CWRrdiB7CgkJdW5zaWduZWQgbG9uZwkJdHlwZTsKCQl1bnNpZ25lZCBsb25nCQl4MTsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsbmFtZWxlbjsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsZGF0YWxlbjsKCQkvKiB2YWxuYW1lLCB2YWxkYXRhICovCgl9OwoKCQoJc3RydWN0CWRraCBka2g7CglpbnQJYnl0ZXNyZWFkID0gMDsKCWNoYXIgICAgKnJnZGJkYXRhID0gaW5mby0+cmdkYmJ1ZmZlcjsKCWludCAgICAgbmJ5dGVzID0gaW5mby0+cmdkYnNpemU7CgljaGFyICAgICpjdXJkYXRhID0gcmdkYmRhdGE7CgljaGFyICAgICplbmQgPSByZ2RiZGF0YSArIG5ieXRlczsKCWludCAgICAgb2ZmX25leHRfcmdkYjsKCWNoYXIgICAgKm5leHQgPSByZ2RiZGF0YTsKCWludCAgICAgbnJnZGIsIGk7CglMUEtFWVNUUlVDVAlscHhrZXk7CgkKCWRvIHsKCSAgY3VyZGF0YSA9IG5leHQ7CgkgIGlmIChzdHJuY21wKGN1cmRhdGEsICJSR0RCIiwgNCkpIHJldHVybiAoTlVMTCk7CgkgICAgCgkgIG1lbWNweSgmb2ZmX25leHRfcmdkYixjdXJkYXRhKzQsNCk7CgkgIG5leHQgPSBjdXJkYXRhICsgb2ZmX25leHRfcmdkYjsKCSAgbnJnZGIgPSAoaW50KSAqKChzaG9ydCAqKWN1cmRhdGEgKyA3KTsKCgl9IHdoaWxlIChucmdkYiAhPSBuck1TICYmIChuZXh0IDwgZW5kKSk7CgoJLyogY3VyZGF0YSBub3cgcG9pbnRzIHRvIHRoZSBzdGFydCBvZiB0aGUgcmlnaHQgUkdEQiBzZWN0aW9uICovCgljdXJkYXRhICs9IDB4MjA7CgojZGVmaW5lIFhSRUFEKHdoZXJldG8sbGVuKSBcCglpZiAoKGN1cmRhdGEgKyBsZW4pIDw9IGVuZCkge1wKCQltZW1jcHkod2hlcmV0byxjdXJkYXRhLGxlbik7XAoJCWN1cmRhdGErPWxlbjtcCgkJYnl0ZXNyZWFkKz1sZW47XAoJfQoKCXdoaWxlIChjdXJkYXRhIDwgbmV4dCkgewoJICBzdHJ1Y3QJZGtoICp4ZGtoID0gKHN0cnVjdCBka2gqKWN1cmRhdGE7CgoJICBieXRlc3JlYWQgKz0gc2l6ZW9mKGRraCk7IC8qIEZJWE1FLi4uIG5leHRrZXlvZmY/ICovCgkgIGlmICh4ZGtoLT5uckxTID09IG5yTFMpIHsKCSAgCW1lbWNweSgmZGtoLHhka2gsc2l6ZW9mKGRraCkpOwoJICAJY3VyZGF0YSArPSBzaXplb2YoZGtoKTsKCSAgCWJyZWFrOwoJICB9CgkgIGN1cmRhdGEgKz0geGRraC0+bmV4dGtleW9mZjsKCX07CgoJaWYgKGRraC5uckxTICE9IG5yTFMpIHJldHVybiAoTlVMTCk7CgoJaWYgKG5yZ2RiICE9IGRraC5uck1TKQoJICByZXR1cm4gKE5VTEwpOwoKICAgICAgICBhc3NlcnQoKGRraC5rZXluYW1lbGVuPDIpIHx8IGN1cmRhdGFbMF0pOwoJbHB4a2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksc3RyY3Z0QTJXKGN1cmRhdGEsIGRraC5rZXluYW1lbGVuKSk7CgljdXJkYXRhICs9IGRraC5rZXluYW1lbGVuOwoKCWZvciAoaT0wO2k8IGRraC52YWx1ZXM7IGkrKykgewoJICBzdHJ1Y3QgZGt2IGRrdjsKCSAgTFBCWVRFIGRhdGE7CgkgIGludCBsZW47CgkgIExQV1NUUiBuYW1lOwoKCSAgWFJFQUQoJmRrdixzaXplb2YoZGt2KSk7CgoJICBuYW1lID0gc3RyY3Z0QTJXKGN1cmRhdGEsIGRrdi52YWxuYW1lbGVuKTsKCSAgY3VyZGF0YSArPSBka3YudmFsbmFtZWxlbjsKCgkgIGlmICgoMSA8PCBka3YudHlwZSkgJiBVTklDT05WTUFTSykgewoJICAgIGRhdGEgPSAoTFBCWVRFKSBzdHJjdnRBMlcoY3VyZGF0YSwgZGt2LnZhbGRhdGFsZW4pOwoJICAgIGxlbiA9IDIqKGRrdi52YWxkYXRhbGVuICsgMSk7CgkgIH0gZWxzZSB7CgkgICAgLyogSSBkb24ndCB0aGluayB3ZSB3YW50IHRvIE5VTEwgdGVybWluYXRlIGFsbCBkYXRhICovCgkgICAgZGF0YSA9IHhtYWxsb2MoZGt2LnZhbGRhdGFsZW4pOwoJICAgIG1lbWNweSAoZGF0YSwgY3VyZGF0YSwgZGt2LnZhbGRhdGFsZW4pOwoJICAgIGxlbiA9IGRrdi52YWxkYXRhbGVuOwoJICB9CgoJICBjdXJkYXRhICs9IGRrdi52YWxkYXRhbGVuOwoJICAKCSAgX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJCQkgICAgIGxweGtleSwKCQkJICAgICBuYW1lLAoJCQkgICAgIGRrdi50eXBlLAoJCQkgICAgIGRhdGEsCgkJCSAgICAgbGVuLAoJCQkgICAgIGluZm8tPmxhc3Rtb2RpZmllZAoJCQkgICAgICk7Cgl9CglyZXR1cm4gKGxweGtleSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV93YWxrcmdrbiBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfdzk1X3dhbGtyZ2tuKCBMUEtFWVNUUlVDVCBwcmV2a2V5LCBjaGFyICpvZmYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgX3c5NV9pbmZvICppbmZvICkKCnsKICAvKiBEaXNrIEtleSBFbnRyeSBzdHJ1Y3R1cmUgKFJHS04gcGFydCkgKi8KICBzdHJ1Y3QJZGtlIHsKICAgIHVuc2lnbmVkIGxvbmcJCXgxOwogICAgdW5zaWduZWQgbG9uZwkJeDI7CiAgICB1bnNpZ25lZCBsb25nCQl4MzsvKnVzdWFsbHkgMHhGRkZGRkZGRiAqLwogICAgdW5zaWduZWQgbG9uZwkJcHJldmx2bDsKICAgIHVuc2lnbmVkIGxvbmcJCW5leHRzdWI7CiAgICB1bnNpZ25lZCBsb25nCQluZXh0OwogICAgdW5zaWduZWQgc2hvcnQJCW5yTFM7CiAgICB1bnNpZ25lZCBzaG9ydAkJbnJNUzsKICB9ICpka2UgPSAoc3RydWN0IGRrZSAqKW9mZjsKICBMUEtFWVNUUlVDVCAgbHB4a2V5OwoKICBpZiAoZGtlID09IE5VTEwpIHsKICAgIGRrZSA9IChzdHJ1Y3QgZGtlICopICgoY2hhciAqKWluZm8tPnJna25idWZmZXIpOwogIH0KCiAgbHB4a2V5ID0gX3c5NV9wcm9jZXNzS2V5KHByZXZrZXksIGRrZS0+bnJMUywgZGtlLT5uck1TLCBpbmZvKTsKICAvKiBYWFggPC0tIFRoaXMgaXMgYSBoYWNrKi8KICBpZiAoIWxweGtleSkgewogICAgbHB4a2V5ID0gcHJldmtleTsKICB9CgogIGlmIChka2UtPm5leHRzdWIgIT0gLTEgJiYgCiAgICAgICgoZGtlLT5uZXh0c3ViIC0gMHgyMCkgPCBpbmZvLT5yZ2tuc2l6ZSkgCiAgICAgICYmIChka2UtPm5leHRzdWIgPiAweDIwKSkgewogICAgCiAgICBfdzk1X3dhbGtyZ2tuKGxweGtleSwgCgkJICBpbmZvLT5yZ2tuYnVmZmVyICsgZGtlLT5uZXh0c3ViIC0gMHgyMCwgCgkJICBpbmZvKTsKICB9CiAgCiAgaWYgKGRrZS0+bmV4dCAhPSAtMSAmJiAKICAgICAgKChka2UtPm5leHQgLSAweDIwKSA8IGluZm8tPnJna25zaXplKSAmJiAKICAgICAgKGRrZS0+bmV4dCA+IDB4MjApKSB7CiAgICBfdzk1X3dhbGtyZ2tuKHByZXZrZXksICAKCQkgIGluZm8tPnJna25idWZmZXIgKyBka2UtPm5leHQgLSAweDIwLAoJCSAgaW5mbyk7CiAgfQoKICByZXR1cm47Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfdzk1X2xvYWRyZWcoIGNoYXIqIGZuLCBMUEtFWVNUUlVDVCBscGtleSApCnsKCUhGSUxFCQloZmQ7CgljaGFyCQltYWdpY1s1XTsKCXVuc2lnbmVkIGxvbmcJd2hlcmUsdmVyc2lvbixyZ2Ric2VjdGlvbixlbmQ7CglzdHJ1Y3QgICAgICAgICAgX3c5NV9pbmZvIGluZm87CglPRlNUUlVDVAlvZnM7CglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmRpbmZvOwoKCVRSQUNFXyhyZWcpKCJMb2FkaW5nIFdpbjk1IHJlZ2lzdHJ5IGRhdGFiYXNlICclcydcbiIsZm4pOwoJaGZkPU9wZW5GaWxlKGZuLCZvZnMsT0ZfUkVBRCk7CglpZiAoaGZkPT1IRklMRV9FUlJPUikKCQlyZXR1cm47CgltYWdpY1s0XT0wOwoJaWYgKDQhPV9scmVhZChoZmQsbWFnaWMsNCkpCgkJcmV0dXJuOwoJaWYgKHN0cmNtcChtYWdpYywiQ1JFRyIpKSB7CgkJV0FSTl8ocmVnKSgiJXMgaXMgbm90IGEgdzk1IHJlZ2lzdHJ5LlxuIixmbik7CgkJcmV0dXJuOwoJfQoJaWYgKDQhPV9scmVhZChoZmQsJnZlcnNpb24sNCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZChoZmQsJnJnZGJzZWN0aW9uLDQpKQoJCXJldHVybjsKCWlmICgtMT09X2xsc2VlayhoZmQsMHgyMCxTRUVLX1NFVCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZChoZmQsbWFnaWMsNCkpCgkJcmV0dXJuOwoJaWYgKHN0cmNtcChtYWdpYywiUkdLTiIpKSB7CgkJV0FSTl8ocmVnKSgic2Vjb25kIElGRiBoZWFkZXIgbm90IFJHS04sIGJ1dCAlc1xuIiwgbWFnaWMpOwoJCXJldHVybjsKCX0KCgkvKiBTVEVQIDE6IEtleWxpbmsgc3RydWN0dXJlcyAqLwoJaWYgKC0xPT1fbGxzZWVrKGhmZCwweDQwLFNFRUtfU0VUKSkKCQlyZXR1cm47Cgl3aGVyZQk9IDB4NDA7CgllbmQJPSByZ2Ric2VjdGlvbjsKCglpbmZvLnJna25zaXplID0gZW5kIC0gd2hlcmU7CglpbmZvLnJna25idWZmZXIgPSAoY2hhciopeG1hbGxvYyhpbmZvLnJna25zaXplKTsKCWlmIChpbmZvLnJna25zaXplICE9IF9scmVhZChoZmQsaW5mby5yZ2tuYnVmZmVyLGluZm8ucmdrbnNpemUpKQoJCXJldHVybjsKCglpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmZCwmaGZkaW5mbykpCgkJcmV0dXJuOwoKCWVuZCA9IGhmZGluZm8ubkZpbGVTaXplTG93OwoJaW5mby5sYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmZGluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoKCWlmICgtMT09X2xsc2VlayhoZmQscmdkYnNlY3Rpb24sU0VFS19TRVQpKQoJCXJldHVybjsKCglpbmZvLnJnZGJidWZmZXIgPSAoY2hhciopeG1hbGxvYyhlbmQtcmdkYnNlY3Rpb24pOwoJaW5mby5yZ2Ric2l6ZSA9IGVuZCAtIHJnZGJzZWN0aW9uOwoKCWlmIChpbmZvLnJnZGJzaXplICE9X2xyZWFkKGhmZCxpbmZvLnJnZGJidWZmZXIsaW5mby5yZ2Ric2l6ZSkpCgkJcmV0dXJuOwoJX2xjbG9zZShoZmQpOwoKCV93OTVfd2Fsa3Jna24obHBrZXksIE5VTEwsICZpbmZvKTsKCglmcmVlIChpbmZvLnJnZGJidWZmZXIpOwoJZnJlZSAoaW5mby5yZ2tuYnVmZmVyKTsKfQoKCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCgovKgogICAgcmVnaGFjayAtIHdpbmRvd3MgMy4xMSByZWdpc3RyeSBkYXRhIGZvcm1hdCBkZW1vIHByb2dyYW0uCgogICAgVGhlIHJlZy5kYXQgZmlsZSBoYXMgMyBwYXJ0cywgYSBoZWFkZXIsIGEgdGFibGUgb2YgOC1ieXRlIGVudHJpZXMgdGhhdCBpcwogICAgYSBjb21iaW5lZCBoYXNoIHRhYmxlIGFuZCB0cmVlIGRlc2NyaXB0aW9uLCBhbmQgZmluYWxseSBhIHRleHQgdGFibGUuCgogICAgVGhlIGhlYWRlciBpcyBvYnZpb3VzIGZyb20gdGhlIHN0cnVjdCBoZWFkZXIuIFRoZSB0YWJvZmYxIGFuZCB0YWJvZmYyCiAgICBmaWVsZHMgYXJlIGFsd2F5cyAweDIwLCBhbmQgdGhlaXIgdXNhZ2UgaXMgdW5rbm93bi4KCiAgICBUaGUgOC1ieXRlIGVudHJ5IHRhYmxlIGhhcyB2YXJpb3VzIGVudHJ5IHR5cGVzLgoKICAgIHRhYmVudFswXSBpcyBhIHJvb3QgaW5kZXguIFRoZSBzZWNvbmQgd29yZCBoYXMgdGhlIGluZGV4IG9mIHRoZSByb290IG9mCiAgICAgICAgICAgIHRoZSBkaXJlY3RvcnkuCiAgICB0YWJlbnRbMS4uaGFzaHNpemVdIGlzIGEgaGFzaCB0YWJsZS4gVGhlIGZpcnN0IHdvcmQgaW4gdGhlIGhhc2ggZW50cnkgaXMKICAgICAgICAgICAgdGhlIGluZGV4IG9mIHRoZSBrZXkvdmFsdWUgdGhhdCBoYXMgdGhhdCBoYXNoLiBEYXRhIHdpdGggdGhlIHNhbWUKICAgICAgICAgICAgaGFzaCB2YWx1ZSBhcmUgb24gYSBjaXJjdWxhciBsaXN0LiBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlCiAgICAgICAgICAgIGhhc2ggZW50cnkgYXJlIGFsd2F5cyB6ZXJvLgogICAgdGFiZW50W2hhc2hzaXplLi50YWJjbnRdIGlzIHRoZSB0cmVlIHN0cnVjdHVyZS4gVGhlcmUgYXJlIHR3byBraW5kcyBvZgogICAgICAgICAgICBlbnRyeTogZGlyZW50IGFuZCBrZXllbnQvdmFsZW50LiBUaGV5IGFyZSBpZGVudGlmaWVkIGJ5IGNvbnRleHQuCiAgICB0YWJlbnRbZnJlZWlkeF0gaXMgdGhlIGZpcnN0IGZyZWUgZW50cnkuIFRoZSBmaXJzdCB3b3JkIGluIGEgZnJlZSBlbnRyeQogICAgICAgICAgICBpcyB0aGUgaW5kZXggb2YgdGhlIG5leHQgZnJlZSBlbnRyeS4gVGhlIGxhc3QgaGFzIDAgYXMgYSBsaW5rLgogICAgICAgICAgICBUaGUgb3RoZXIgdGhyZWUgd29yZHMgaW4gdGhlIGZyZWUgbGlzdCBhcmUgcHJvYmFibHkgaXJyZWxldmFudC4KCiAgICBFbnRyaWVzIGluIHRleHQgdGFibGUgYXJlIHByZWNlZWRlZCBieSBhIHdvcmQgYXQgb2Zmc2V0LTIuIFRoaXMgd29yZAogICAgaGFzIHRoZSB2YWx1ZSAoMippbmRleCkrMSwgd2hlcmUgaW5kZXggaXMgdGhlIHJlZmVycmluZyBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBpbiB0aGUgdGFibGUuIEkgaGF2ZSBubyBzdWdnZXN0aW9uIGZvciB0aGUgMiogYW5kIHRoZSArMS4KICAgIEZvbGxvd2luZyB0aGUgd29yZCwgdGhlcmUgYXJlIE4gYnl0ZXMgb2YgZGF0YSwgYXMgcGVyIHRoZSBrZXllbnQvdmFsZW50CiAgICBlbnRyeSBsZW5ndGguIFRoZSBvZmZzZXQgb2YgdGhlIGtleWVudC92YWxlbnQgZW50cnkgaXMgZnJvbSB0aGUgc3RhcnQKICAgIG9mIHRoZSB0ZXh0IHRhYmxlIHRvIHRoZSBmaXJzdCBkYXRhIGJ5dGUuCgogICAgVGhpcyBpbmZvcm1hdGlvbiBpcyBub3QgYXZhaWxhYmxlIGZyb20gTWljcm9zb2Z0LiBUaGUgZGF0YSBmb3JtYXQgaXMKICAgIGRlZHVjZWQgZnJvbSB0aGUgcmVnLmRhdCBmaWxlIGJ5IG1lLiBNaXN0YWtlcyBtYXkKICAgIGhhdmUgYmVlbiBtYWRlLiBJIGNsYWltIG5vIHJpZ2h0cyBhbmQgZ2l2ZSBubyBndWFyYW50ZWVzIGZvciB0aGlzIHByb2dyYW0uCgogICAgVG9yIFNq+HdhbGwsIHRvckBzbi5ubwoqLwoKLyogcmVnLmRhdCBoZWFkZXIgZm9ybWF0ICovCnN0cnVjdCBfdzMxX2hlYWRlciB7CgljaGFyCQljb29raWVbOF07CS8qICdTSENDMy4xMCcgKi8KCXVuc2lnbmVkIGxvbmcJdGFib2ZmMTsJLyogb2Zmc2V0IG9mIGhhc2ggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFib2ZmMjsJLyogb2Zmc2V0IG9mIGluZGV4IHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYmNudDsJCS8qIG51bWJlciBvZiBlbnRyaWVzIGluIGluZGV4IHRhYmxlICovCgl1bnNpZ25lZCBsb25nCXRleHRvZmY7CS8qIG9mZnNldCBvZiB0ZXh0IHBhcnQgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dHNpemU7CS8qIGJ5dGUgc2l6ZSBvZiB0ZXh0IHBhcnQgKi8KCXVuc2lnbmVkIHNob3J0CWhhc2hzaXplOwkvKiBoYXNoIHNpemUgKi8KCXVuc2lnbmVkIHNob3J0CWZyZWVpZHg7CS8qIGZyZWUgaW5kZXggKi8KfTsKCi8qIGdlbmVyaWMgZm9ybWF0IG9mIHRhYmxlIGVudHJpZXMgKi8Kc3RydWN0IF93MzFfdGFiZW50IHsKCXVuc2lnbmVkIHNob3J0IHcwLCB3MSwgdzIsIHczOwp9OwoKLyogZGlyZWN0b3J5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfZGlyZW50IHsKCXVuc2lnbmVkIHNob3J0CXNpYmxpbmdfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBzaWJsaW5nIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJY2hpbGRfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBjaGlsZCBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWtleV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGtleSBrZXllbnQgKi8KCXVuc2lnbmVkIHNob3J0CXZhbHVlX2lkeDsJLyogdGFibGUgaW5kZXggb2YgdmFsdWUgdmFsZW50ICovCn07CgovKiBrZXkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9rZXllbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHZhbHVlIHRhYmVudDogKi8Kc3RydWN0IF93MzFfdmFsZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiByZWN1cnNpdmUgaGVscGVyIGZ1bmN0aW9uIHRvIGRpc3BsYXkgYSBkaXJlY3RvcnkgdHJlZSAqLwp2b2lkCl9fdzMxX2R1bXB0cmVlKAl1bnNpZ25lZCBzaG9ydCBpZHgsCgkJdW5zaWduZWQgY2hhciAqdHh0LAoJCXN0cnVjdCBfdzMxX3RhYmVudCAqdGFiLAoJCXN0cnVjdCBfdzMxX2hlYWRlciAqaGVhZCwKCQlMUEtFWVNUUlVDVAlscGtleSwKCQl0aW1lX3QJCWxhc3Rtb2RpZmllZCwKCQlpbnQJCWxldmVsCikgewoJc3RydWN0IF93MzFfZGlyZW50CSpkaXI7CglzdHJ1Y3QgX3czMV9rZXllbnQJKmtleTsKCXN0cnVjdCBfdzMxX3ZhbGVudAkqdmFsOwoJTFBLRVlTVFJVQ1QJCXhscGtleSA9IE5VTEw7CglMUFdTVFIJCQluYW1lLHZhbHVlOwoJc3RhdGljIGNoYXIJCXRhaWxbNDAwXTsKCgl3aGlsZSAoaWR4IT0wKSB7CgkJZGlyPShzdHJ1Y3QgX3czMV9kaXJlbnQqKSZ0YWJbaWR4XTsKCgkJaWYgKGRpci0+a2V5X2lkeCkgewoJCQlrZXkgPSAoc3RydWN0IF93MzFfa2V5ZW50KikmdGFiW2Rpci0+a2V5X2lkeF07CgoJCQltZW1jcHkodGFpbCwmdHh0W2tleS0+c3RyaW5nX29mZl0sa2V5LT5sZW5ndGgpOwoJCQl0YWlsW2tleS0+bGVuZ3RoXT0nXDAnOwoJCQkvKiBhbGwgdG9wbGV2ZWwgZW50cmllcyBBTkQgdGhlIGVudHJpZXMgaW4gdGhlIAoJCQkgKiB0b3BsZXZlbCBzdWJkaXJlY3RvcnkgYmVsb25nIHRvIFxTT0ZUV0FSRVxDbGFzc2VzCgkJCSAqLwoJCQlpZiAoIWxldmVsICYmICFsc3RyY21wQSh0YWlsLCIuY2xhc3NlcyIpKSB7CgkJCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCQkJaWR4PWRpci0+c2libGluZ19pZHg7CgkJCQljb250aW51ZTsKCQkJfQoJCQluYW1lPXN0cmR1cEEyVyh0YWlsKTsKCgkJCXhscGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoKCQkJLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCgkJCWlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKCQkJCWlmIChkaXItPnZhbHVlX2lkeCkgewoJCQkJCXZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKCQkJCQltZW1jcHkodGFpbCwmdHh0W3ZhbC0+c3RyaW5nX29mZl0sdmFsLT5sZW5ndGgpOwoJCQkJCXRhaWxbdmFsLT5sZW5ndGhdPSdcMCc7CgkJCQkJdmFsdWU9c3RyZHVwQTJXKHRhaWwpOwoJCQkJCV9maW5kX29yX2FkZF92YWx1ZSh4bHBrZXksTlVMTCxSRUdfU1osKExQQllURSl2YWx1ZSxsc3RybGVuVyh2YWx1ZSkqMisyLGxhc3Rtb2RpZmllZCk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQlUUkFDRV8ocmVnKSgic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKCQl9CgkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHhscGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJaWR4PWRpci0+c2libGluZ19pZHg7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93MzFfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwp2b2lkIF93MzFfbG9hZHJlZyh2b2lkKSB7CglIRklMRQkJCWhmOwoJc3RydWN0IF93MzFfaGVhZGVyCWhlYWQ7CglzdHJ1Y3QgX3czMV90YWJlbnQJKnRhYjsKCXVuc2lnbmVkIGNoYXIJCSp0eHQ7CglpbnQJCQlsZW47CglPRlNUUlVDVAkJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZpbmZvOwoJdGltZV90CQkJbGFzdG1vZGlmaWVkOwoJTFBLRVlTVFJVQ1QJCWxwa2V5OwoKCVRSQUNFXyhyZWcpKCIodm9pZClcbiIpOwoKCWhmID0gT3BlbkZpbGUoInJlZy5kYXQiLCZvZnMsT0ZfUkVBRCk7CglpZiAoaGY9PUhGSUxFX0VSUk9SKQoJCXJldHVybjsKCgkvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KCWlmIChzaXplb2YoaGVhZCkhPV9scmVhZChoZiwmaGVhZCxzaXplb2YoaGVhZCkpKSB7CgkJRVJSXyhyZWcpKCJyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpIT0wKSB7CgkJRVJSXyhyZWcpKCJyZWcuZGF0IGhhcyBiYWQgc2lnbmF0dXJlLlxuIik7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCWxlbiA9IGhlYWQudGFiY250ICogc2l6ZW9mKHN0cnVjdCBfdzMxX3RhYmVudCk7CgkvKiByZWFkIGFuZCBkdW1wIGluZGV4IHRhYmxlICovCgl0YWIgPSB4bWFsbG9jKGxlbik7CglpZiAobGVuIT1fbHJlYWQoaGYsdGFiLGxlbikpIHsKCQlFUlJfKHJlZykoImNvdWxkbid0IHJlYWQgJWQgYnl0ZXMuXG4iLGxlbik7IAoJCWZyZWUodGFiKTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJLyogcmVhZCB0ZXh0ICovCgl0eHQgPSB4bWFsbG9jKGhlYWQudGV4dHNpemUpOwoJaWYgKC0xPT1fbGxzZWVrKGhmLGhlYWQudGV4dG9mZixTRUVLX1NFVCkpIHsKCQlFUlJfKHJlZykoImNvdWxkbid0IHNlZWsgdG8gdGV4dGJsb2NrLlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoJaWYgKGhlYWQudGV4dHNpemUhPV9scmVhZChoZix0eHQsaGVhZC50ZXh0c2l6ZSkpIHsKCQlFUlJfKHJlZykoInRleHRibG9jayB0b28gc2hvcnQgKCVkIGluc3RlYWQgb2YgJWxkKS5cbiIsbGVuLGhlYWQudGV4dHNpemUpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCglpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmLCZoZmluZm8pKSB7CgkJRVJSXyhyZWcpKCJHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoJbGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoJbHBrZXkgPSBsb29rdXBfaGtleShIS0VZX0NMQVNTRVNfUk9PVCk7CglfX3czMV9kdW1wdHJlZSh0YWJbMF0udzEsdHh0LHRhYiwmaGVhZCxscGtleSxsYXN0bW9kaWZpZWQsMCk7CglmcmVlKHRhYik7CglmcmVlKHR4dCk7CglfbGNsb3NlKGhmKTsKCXJldHVybjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX0xvYWRSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwp2b2lkIFNIRUxMX0xvYWRSZWdpc3RyeSggdm9pZCApCnsKICBjaGFyCSAgICAgICpmbiwgKmhvbWU7CiAgTFBLRVlTVFJVQ1QJbHBrZXksIEhLQ1UsIEhLVSwgSEtMTTsKICBIS0VZCQkgICAgaGtleTsKCiAgVFJBQ0VfKHJlZykoIih2b2lkKVxuIik7CgogIEhLQ1UgPSBsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUik7CiAgSEtVICA9IGxvb2t1cF9oa2V5KEhLRVlfVVNFUlMpOwogIEhLTE0gPSBsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpOwoKICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCAoInJlZ2lzdHJ5IiwgIkxvYWRXaW5kb3dzUmVnaXN0cnlGaWxlcyIsIDEpKSAKICB7IAogICAgICAvKiBMb2FkIHdpbmRvd3MgMy4xIGVudHJpZXMgKi8KICAgICAgX3czMV9sb2FkcmVnKCk7CiAgICAgIC8qIExvYWQgd2luZG93cyA5NSBlbnRyaWVzICovCiAgICAgIF93OTVfbG9hZHJlZygiQzpcXHN5c3RlbS4xc3QiLAlIS0xNKTsKICAgICAgX3c5NV9sb2FkcmVnKCJzeXN0ZW0uZGF0IiwJSEtMTSk7CiAgICAgIF93OTVfbG9hZHJlZygidXNlci5kYXQiLAlIS1UpOwogIH0KCiAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2wgKCJyZWdpc3RyeSIsIkxvYWRHbG9iYWxSZWdpc3RyeUZpbGVzIiwgMSkpCiAgewogICAgICAvKiAKICAgICAgICogTG9hZCB0aGUgZ2xvYmFsIEhLVSBoaXZlIGRpcmVjdGx5IGZyb20gc3lzY29uZmRpcgogICAgICAgKi8gCiAgICAgIF93aW5lX2xvYWRyZWcoIEhLVSwgU0FWRV9VU0VSU19ERUZBVUxULCAwKTsKCiAgICAgIC8qIAogICAgICAgKiBMb2FkIHRoZSBnbG9iYWwgbWFjaGluZSBkZWZhdWx0cyBkaXJlY3RseSBmb3JtIHN5c2NvbmZkaXIKICAgICAgICovCiAgICAgIF93aW5lX2xvYWRyZWcoIEhLTE0sIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxULCAwKTsKICB9CgogIC8qCiAgICogTG9hZCB0aGUgdXNlciBzYXZlZCByZWdpc3RyaWVzIAogICAqLwogIGlmICghKGhvbWUgPSBnZXRlbnYoICJIT01FIiApKSkKICAgICAgV0FSTl8ocmVnKSgiRmFpbGVkIHRvIGdldCBob21lZGlyZWN0b3J5IG9mIFVJRCAlbGQuXG4iLChsb25nKSBnZXR1aWQoKSk7CiAgZWxzZSBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgicmVnaXN0cnkiLCAiTG9hZEhvbWVSZWdpc3RyeUZpbGVzIiwgMSkpCiAgewogICAgICAvKiAKICAgICAgICogTG9hZCB1c2VyJ3MgcGVyc29uYWwgdmVyc2lvbnMgb2YgZ2xvYmFsIEhLVS8uRGVmYXVsdCBrZXlzCiAgICAgICAqLwogICAgICBmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKGhvbWUpKyBzdHJsZW4oV0lORV9QUkVGSVgpICsKICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpKzIpOwogICAgICBzdHJjcHkoZm4sIGhvbWUpOwogICAgICBzdHJjYXQoZm4sIFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKTsKICAgICAgX3dpbmVfbG9hZHJlZyhIS1UsIGZuLCBSRUdfT1BUSU9OX1RBSU5URUQpOyAKICAgICAgZnJlZShmbik7CgogICAgICBmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKGhvbWUpICsgc3RybGVuKFdJTkVfUFJFRklYKSArIHN0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikrMik7CiAgICAgIHN0cmNweShmbiwgaG9tZSk7CiAgICAgIHN0cmNhdChmbiwgV0lORV9QUkVGSVgiLyJTQVZFX0NVUlJFTlRfVVNFUik7CiAgICAgIF93aW5lX2xvYWRyZWcoSEtDVSwgZm4sIFJFR19PUFRJT05fVEFJTlRFRCk7CiAgICAgIGZyZWUoZm4pOwoKICAgICAgLyogCiAgICAgICAqIExvYWQgSEtMTSwgYXR0ZW1wdCB0byBnZXQgdGhlIHJlZ2lzdHJ5IGxvY2F0aW9uIGZyb20gdGhlIGNvbmZpZyAKICAgICAgICogZmlsZSBmaXJzdCwgaWYgZXhpc3QsIGxvYWQgYW5kIGtlZXAgZ29pbmcuCiAgICAgICAqLwogICAgICBmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKGhvbWUpKyBzdHJsZW4oV0lORV9QUkVGSVgpKyBzdHJsZW4oU0FWRV9MT0NBTF9NQUNISU5FKSsyKTsKICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwogICAgICBfd2luZV9sb2FkcmVnKEhLTE0sIGZuLCBSRUdfT1BUSU9OX1RBSU5URUQpOwogICAgICBmcmVlKGZuKTsKICB9CiAgCiAgLyogCiAgICogTG9hZCBIS0NVLCBnZXQgdGhlIHJlZ2lzdHJ5IGxvY2F0aW9uIGZyb20gdGhlIGNvbmZpZyAKICAgKiBmaWxlLCBpZiBleGlzdCwgbG9hZCBhbmQga2VlcCBnb2luZy4KICAgKi8gICAgICAKICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCAoICJyZWdpc3RyeSIsICJMb2FkQWx0UmVnaXN0cnlGaWxlcyIsIDEpKQogIHsKICAgICAgZm4gPSB4bWFsbG9jKCBNQVhfUEFUSE5BTUVfTEVOICk7IAogICAgICBpZiAoIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggInJlZ2lzdHJ5IiwgIkFsdEN1cnJlbnRVc2VyRmlsZSIsICIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZuLCBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpIAogICAgICAgewogICAgICAgICBfd2luZV9sb2FkcmVnKEhLQ1UsZm4sUkVHX09QVElPTl9UQUlOVEVEKTsKICAgICAgIH0KICAgICAgZnJlZSAoZm4pOwogICAgICAvKgogICAgICAgKiBMb2FkIEhLVSwgZ2V0IHRoZSByZWdpc3RyeSBsb2NhdGlvbiBmcm9tIHRoZSBjb25maWcKICAgICAgICogZmlsZSwgaWYgZXhpc3QsIGxvYWQgYW5kIGtlZXAgZ29pbmcuCiAgICAgICAqLwogICAgICBmbiA9IHhtYWxsb2MgKCBNQVhfUEFUSE5BTUVfTEVOICk7CiAgICAgIGlmICggUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nICggInJlZ2lzdHJ5IiwgIkFsdFVzZXJGaWxlIiwgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm4sIE1BWF9QQVRITkFNRV9MRU4gLSAxKSkKICAgICAgIHsKICAgICAgICAgX3dpbmVfbG9hZHJlZyhIS1UsZm4sUkVHX09QVElPTl9UQUlOVEVEKTsKICAgICAgIH0KICAgICAgZnJlZSAoZm4pOwogICAgICAvKgogICAgICAgKiBMb2FkIEhLTE0sIGdldCB0aGUgcmVnaXN0cnkgbG9jYXRpb24gZnJvbSB0aGUgY29uZmlnCiAgICAgICAqIGZpbGUsIGlmIGV4aXN0LCBsb2FkIGFuZCBrZWVwIGdvaW5nLgogICAgICAgKi8KICAgICAgZm4gPSB4bWFsbG9jICggTUFYX1BBVEhOQU1FX0xFTiApOwogICAgICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nICggInJlZ2lzdHJ5IiwgIkFsdExvY2FsTWFjaGluZUZpbGUiLCAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZuLCBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpCiAgICAgICB7CiAgICAgICAgIF93aW5lX2xvYWRyZWcoSEtMTSxmbixSRUdfT1BUSU9OX1RBSU5URUQpOyAKICAgICAgIH0KICAgICAgZnJlZSAoZm4pOwogICAgfQogIAogIC8qIAogICAqIE9idGFpbiB0aGUgaGFuZGxlIG9mIHRoZSBIS1VcLkRlZmF1bHQga2V5LgogICAqIGluIG9yZGVyIHRvIGNvcHkgSEtVXC5EZWZhdWx0XCogb250byBIS0VZX0NVUlJFTlRfVVNFUiAKICAgKi8KICBSZWdDcmVhdGVLZXkxNihIS0VZX1VTRVJTLCIuRGVmYXVsdCIsJmhrZXkpOwogIGxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgaWYoIWxwa2V5KXsKICAgICBXQVJOXyhyZWcpKCJDb3VsZCBub3QgY3JlYXRlIGdsb2JhbCB1c2VyIGRlZmF1bHQga2V5XG4iKTsKICB9IGVsc2UgewogICAgX2NvcHlfcmVnaXN0cnkobHBrZXksIEhLQ1UgKTsKICB9CgogIFJlZ0Nsb3NlS2V5KGhrZXkpOwoKICAvKiAKICAgKiBTaW5jZSBIS1UgaXMgYnVpbHQgZnJvbSB0aGUgZ2xvYmFsIEhLVSBhbmQgdGhlIGxvY2FsIHVzZXIgSEtVIGZpbGUgd2UgbXVzdAogICAqIGZsdXNoIHRoZSBIS1UgdHJlZSB3ZSBoYXZlIGJ1aWx0IGF0IHRoaXMgcG9pbnQgb3RoZXJ3aXNlIHRoZSBwYXJ0IGJyb3VnaHQKICAgKiBpbiBmcm9tIHRoZSBnbG9iYWwgSEtVIGlzIHNhdmVkIGludG8gdGhlIGxvY2FsIEhLVS4gIFRvIGF2b2lkIHRoaXMgCiAgICogdXNlbGVzcyBkdXBwbGljYXRpb24gb2YgSEtVIGtleXMgd2UgcmVyZWFkIHRoZSBsb2NhbCBIS1Uga2V5LgogICAqLwoKICAvKiBBbGx3YXlzIGZsdXNoIHRoZSBIS1UgaGl2ZSBhbmQgcmVsb2FkIGl0IG9ubHkgd2l0aCB1c2VyJ3MgcGVyc29uYWwgSEtVICovCiAgX2ZsdXNoX3JlZ2lzdHJ5KEhLVSk7IAoKICAvKiBSZWxvYWQgdXNlcidzIGxvY2FsIEhLVSBoaXZlICovCiAgaWYgKGhvbWUgJiYgUFJPRklMRV9HZXRXaW5lSW5pQm9vbCAoInJlZ2lzdHJ5IiwiTG9hZEhvbWVSZWdpc3RyeUZpbGVzIiwxKSkKICB7CiAgICAgIGZuPShjaGFyKil4bWFsbG9jKCBzdHJsZW4oaG9tZSkgKyBzdHJsZW4oV0lORV9QUkVGSVgpCiAgICAgICAgICAgICAgICAgICAgICAgICArIHN0cmxlbihTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpICsgMik7CiAgICAgIAogICAgICBzdHJjcHkoZm4saG9tZSk7CiAgICAgIHN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCk7CgogICAgICBfd2luZV9sb2FkcmVnKCBIS1UsIGZuLCBSRUdfT1BUSU9OX1RBSU5URUQpOwoKICAgICAgZnJlZShmbik7CiAgfQoKICAvKiAKICAgKiBNYWtlIHN1cmUgdGhlIHVwZGF0ZSBtb2RlIGlzIHRoZXJlCiAgICovCiAgaWYgKEVSUk9SX1NVQ0NFU1M9PVJlZ0NyZWF0ZUtleTE2KEhLRVlfQ1VSUkVOVF9VU0VSLEtFWV9SRUdJU1RSWSwmaGtleSkpIAogIHsKICAgIERXT1JECWp1bmssdHlwZSxsZW47CiAgICBjaGFyCWRhdGFbNV07CgogICAgbGVuPTQ7CiAgICBpZiAoKAlSZWdRdWVyeVZhbHVlRXhBKAogICAgICAgICAgICBoa2V5LAogICAgICAgICAgICBWQUxfU0FWRVVQREFURUQsCiAgICAgICAgICAgICZqdW5rLAogICAgICAgICAgICAmdHlwZSwKICAgICAgICAgICAgZGF0YSwKICAgICAgICAgICAgJmxlbikgIT0gRVJST1JfU1VDQ0VTUykgfHwgKHR5cGUgIT0gUkVHX1NaKSkKICAgIHsKICAgICAgUmVnU2V0VmFsdWVFeEEoaGtleSxWQUxfU0FWRVVQREFURUQsMCxSRUdfU1osInllcyIsNCk7CiAgICB9CgogICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKiBBUEkgRlVOQ1RJT05TICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoKICogT3BlbiBLZXlzLgogKgogKiBBbGwgZnVuY3Rpb25zIGFyZSBzdHVicyB0byBSZWdPcGVuS2V5RXgzMlcgd2hlcmUgYWxsIHRoZQogKiBtYWdpYyBoYXBwZW5zLiAKICoKICogQ2FsbHBhdGg6CiAqIFJlZ09wZW5LZXkxNiAtPiBSZWdPcGVuS2V5MzJBIC0+IFJlZ09wZW5LZXlFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ09wZW5LZXkzMlcgICAtPiBSZWdPcGVuS2V5RXgzMlcgCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleUV4MzJXIFtBRFZBUEkzMi4xNTBdCiAqIE9wZW5zIHRoZSBzcGVjaWZpZWQga2V5CiAqCiAqIFVubGlrZSBSZWdDcmVhdGVLZXlFeCwgdGhpcyBkb2VzIG5vdCBjcmVhdGUgdGhlIGtleSBpZiBpdCBkb2VzIG5vdCBleGlzdC4KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5IFtJXSBOYW1lIG9mIHN1YmtleSB0byBvcGVuCiAqICAgIGR3UmVzZXJ2ZWQgW0ldIFJlc2VydmVkIC0gbXVzdCBiZSB6ZXJvCiAqICAgIHNhbURlc2lyZWQgW0ldIFNlY3VyaXR5IGFjY2VzcyBtYXNrCiAqICAgIHJldGtleSAgICAgW09dIEFkZHJlc3Mgb2YgaGFuZGxlIG9mIG9wZW4ga2V5CiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleUV4VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR1NBTSBzYW1EZXNpcmVkLCBMUEhLRVkgcmV0a2V5ICkKewoJTFBLRVlTVFJVQ1QJbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgogICAgVFJBQ0VfKHJlZykoIigweCV4LCVzLCVsZCwlbHgsJXApXG4iLCBoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksZHdSZXNlcnZlZCwKICAgICAgICAgIHNhbURlc2lyZWQscmV0a2V5KTsKCiAgICBscE5leHRLZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIGlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpIHsKICAgICAgICAvKiBFaXRoZXIgTlVMTCBvciBwb2ludGVyIHRvIGVtcHR5IHN0cmluZywgc28gcmV0dXJuIGEgbmV3IGhhbmRsZQogICAgICAgICAgIHRvIHRoZSBvcmlnaW5hbCBoa2V5ICovCiAgICAgICAgY3VycmVudGhhbmRsZSArPSAyOwogICAgICAgIGFkZF9oYW5kbGUoY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CiAgICAgICAgKnJldGtleT1jdXJyZW50aGFuZGxlOwogICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwogICAgfQoKICAgIGlmIChscHN6U3ViS2V5WzBdID09ICdcXCcpIHsKICAgICAgICBXQVJOXyhyZWcpKCJTdWJrZXkgJXMgbXVzdCBub3QgYmVnaW4gd2l0aCBiYWNrc2xhc2guXG4iLGRlYnVnc3RyX3cobHBzelN1YktleSkpOwogICAgICAgIHJldHVybiBFUlJPUl9CQURfUEFUSE5BTUU7CiAgICB9CgoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpID0gMDsKCXdoaWxlICgoaTx3cGMpICYmICh3cHNbaV1bMF09PSdcMCcpKSBpKys7CglscHhrZXkgPSBscE5leHRLZXk7CgogICAgd2hpbGUgKHdwc1tpXSkgewogICAgICAgIGxweGtleT1scE5leHRLZXktPm5leHRzdWI7CiAgICAgICAgd2hpbGUgKGxweGtleSkgewogICAgICAgICAgICBpZiAoIWxzdHJjbXBpVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbHB4a2V5PWxweGtleS0+bmV4dDsKICAgICAgICB9CgogICAgICAgIGlmICghbHB4a2V5KSB7CiAgICAgICAgICAgIFRSQUNFXyhyZWcpKCJDb3VsZCBub3QgZmluZCBzdWJrZXkgJXNcbiIsZGVidWdzdHJfdyh3cHNbaV0pKTsKICAgICAgICAgICAgRlJFRV9LRVlfUEFUSDsKICAgICAgICAgICAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwogICAgICAgIH0KICAgICAgICBpKys7CiAgICAgICAgbHBOZXh0S2V5ID0gbHB4a2V5OwogICAgfQoKICAgIGN1cnJlbnRoYW5kbGUgKz0gMjsKICAgIGFkZF9oYW5kbGUoY3VycmVudGhhbmRsZSxscHhrZXksc2FtRGVzaXJlZCk7CiAgICAqcmV0a2V5ID0gY3VycmVudGhhbmRsZTsKICAgIFRSQUNFXyhyZWcpKCIgIFJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CiAgICBGUkVFX0tFWV9QQVRIOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXlFeDMyQSBbQURWQVBJMzIuMTQ5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXlFeEEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR1NBTSBzYW1EZXNpcmVkLCBMUEhLRVkgcmV0a2V5ICkKewogICAgTFBXU1RSIGxwc3pTdWJLZXlXID0gc3RyZHVwQTJXKGxwc3pTdWJLZXkpOwogICAgRFdPUkQgcmV0OwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJWxkLCVseCwlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGR3UmVzZXJ2ZWQsCiAgICAgICAgICBzYW1EZXNpcmVkLHJldGtleSk7CiAgICByZXQgPSBSZWdPcGVuS2V5RXhXKCBoa2V5LCBscHN6U3ViS2V5VywgZHdSZXNlcnZlZCwgc2FtRGVzaXJlZCwgcmV0a2V5ICk7CiAgICBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXkzMlcgW0FEVkFQSTMyLjE1MV0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5IFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5IHRvIG9wZW4KICogICAgcmV0a2V5ICAgICBbT10gQWRkcmVzcyBvZiBoYW5kbGUgb2Ygb3BlbiBrZXkKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdPcGVuS2V5RXhXKCBoa2V5LCBscHN6U3ViS2V5LCAwLCBLRVlfQUxMX0FDQ0VTUywgcmV0a2V5ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXkzMkEgW0FEVkFQSTMyLjE0OF0KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIERXT1JEIHJldDsKICAgIExQV1NUUiBscHN6U3ViS2V5VyA9IHN0cmR1cEEyVyhscHN6U3ViS2V5KTsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0ID0gIFJlZ09wZW5LZXlXKCBoa2V5LCBscHN6U3ViS2V5VywgcmV0a2V5ICk7CiAgICBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXkxNiBbU0hFTEwuMV0gW0tFUk5FTC4yMTddCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICByZXR1cm4gUmVnT3BlbktleUEoIGhrZXksIGxwc3pTdWJLZXksIHJldGtleSApOwp9CgoKLyogCiAqIENyZWF0ZSBrZXlzCiAqIAogKiBBbGwgdGhvc2UgZnVuY3Rpb25zIGNvbnZlcnQgdGhlaXIgcmVzcGVjdGl2ZSAKICogYXJndW1lbnRzIGFuZCBjYWxsIFJlZ0NyZWF0ZUtleUV4VyBhdCB0aGUgZW5kLgogKgogKiBXZSBzdGF5IGF3YXkgZnJvbSB0aGUgRXggZnVuY3Rpb25zIGFzIGxvbmcgYXMgcG9zc2libGUgYmVjYXVzZSB0aGVyZSBhcmUKICogZGlmZmVyZW5jZXMgaW4gdGhlIHJldHVybiB2YWx1ZXMKICoKICogQ2FsbHBhdGg6CiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdDcmVhdGVLZXlFeDMyQSBcCiAqIFJlZ0NyZWF0ZUtleTE2IC0+IFJlZ0NyZWF0ZUtleTMyQSAtPiBSZWdDcmVhdGVLZXkzMlcgICAtPiBSZWdDcmVhdGVLZXlFeDMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleUV4MzJXIFtBRFZBUEkzMi4xMzFdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgW0ldIEhhbmRsZSBvZiBhbiBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5ICAgW0ldIEFkZHJlc3Mgb2Ygc3Via2V5IG5hbWUKICogICAgZHdSZXNlcnZlZCAgIFtJXSBSZXNlcnZlZCAtIG11c3QgYmUgMAogKiAgICBscHN6Q2xhc3MgICAgW0ldIEFkZHJlc3Mgb2YgY2xhc3Mgc3RyaW5nCiAqICAgIGZkd09wdGlvbnMgICBbSV0gU3BlY2lhbCBvcHRpb25zIGZsYWcKICogICAgc2FtRGVzaXJlZCAgIFtJXSBEZXNpcmVkIHNlY3VyaXR5IGFjY2VzcwogKiAgICBscFNlY0F0dHJpYnMgW0ldIEFkZHJlc3Mgb2Yga2V5IHNlY3VyaXR5IHN0cnVjdHVyZQogKiAgICByZXRrZXkgICAgICAgW09dIEFkZHJlc3Mgb2YgYnVmZmVyIGZvciBvcGVuZWQgaGFuZGxlCiAqICAgIGxwRGlzcG9zICAgICBbT10gUmVjZWl2ZXMgUkVHX0NSRUFURURfTkVXX0tFWSBvciBSRUdfT1BFTkVEX0VYSVNUSU5HX0tFWQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleUV4VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3UmVzZXJ2ZWQsIExQV1NUUiBscHN6Q2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGZkd09wdGlvbnMsIFJFR1NBTSBzYW1EZXNpcmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBscFNlY0F0dHJpYnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSByZXRrZXksIExQRFdPUkQgbHBEaXNwb3MgKQp7CglMUEtFWVNUUlVDVAkqbHBscFByZXZLZXksbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcywlbGQsJXMsJWx4LCVseCwlcCwlcCwlcClcbiIsIGhrZXksCgkJZGVidWdzdHJfdyhscHN6U3ViS2V5KSwgZHdSZXNlcnZlZCwgZGVidWdzdHJfdyhscHN6Q2xhc3MpLAoJCWZkd09wdGlvbnMsIHNhbURlc2lyZWQsIGxwU2VjQXR0cmlicywgcmV0a2V5LCBscERpc3Bvcyk7CgogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgLyogQ2hlY2sgZm9yIHZhbGlkIG9wdGlvbnMgKi8KICAgIHN3aXRjaChmZHdPcHRpb25zKSB7CiAgICAgICAgY2FzZSBSRUdfT1BUSU9OX05PTl9WT0xBVElMRToKICAgICAgICBjYXNlIFJFR19PUFRJT05fVk9MQVRJTEU6CiAgICAgICAgY2FzZSBSRUdfT1BUSU9OX0JBQ0tVUF9SRVNUT1JFOgogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CiAgICB9CgogICAgLyogU2FtIGhhcyB0byBiZSBhIGNvbWJpbmF0aW9uIG9mIHRoZSBmb2xsb3dpbmcgKi8KICAgIGlmICghKHNhbURlc2lyZWQgJiAKICAgICAgICAgIChLRVlfQUxMX0FDQ0VTUyB8IEtFWV9DUkVBVEVfTElOSyB8IEtFWV9DUkVBVEVfU1VCX0tFWSB8IAogICAgICAgICAgIEtFWV9FTlVNRVJBVEVfU1VCX0tFWVMgfCBLRVlfRVhFQ1VURSB8IEtFWV9OT1RJRlkgfAogICAgICAgICAgIEtFWV9RVUVSWV9WQUxVRSB8IEtFWV9SRUFEIHwgS0VZX1NFVF9WQUxVRSB8IEtFWV9XUklURSkpKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCglpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KSB7CiAgICAgICAgICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CgkJYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKCQkqcmV0a2V5PWN1cnJlbnRoYW5kbGU7CiAgICAgICAgICAgICAgICBUUkFDRV8ocmVnKSgiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCQlscE5leHRLZXktPmZsYWdzfD1SRUdfT1BUSU9OX1RBSU5URUQ7CgkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgl9CgogICAgaWYgKGxwc3pTdWJLZXlbMF0gPT0gJ1xcJykgewogICAgICAgIFdBUk5fKHJlZykoIlN1YmtleSAlcyBtdXN0IG5vdCBiZWdpbiB3aXRoIGJhY2tzbGFzaC5cbiIsZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CiAgICAgICAgcmV0dXJuIEVSUk9SX0JBRF9QQVRITkFNRTsKICAgIH0KCglzcGxpdF9rZXlwYXRoKGxwc3pTdWJLZXksJndwcywmd3BjKTsKCWkgCT0gMDsKCXdoaWxlICgoaTx3cGMpICYmICh3cHNbaV1bMF09PSdcMCcpKSBpKys7CglscHhrZXkJPSBscE5leHRLZXk7Cgl3aGlsZSAod3BzW2ldKSB7CgkJbHB4a2V5PWxwTmV4dEtleS0+bmV4dHN1YjsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCWlmICghbHN0cmNtcGlXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KQoJCQlicmVhazsKCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJaWYgKGxweGtleSkgewogICAgICAgICAgICAgICAgY3VycmVudGhhbmRsZSArPSAyOwoJCWFkZF9oYW5kbGUoY3VycmVudGhhbmRsZSxscHhrZXksc2FtRGVzaXJlZCk7CgkJbHB4a2V5LT5mbGFncyAgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoJCSpyZXRrZXkJCT0gY3VycmVudGhhbmRsZTsKICAgICAgICAgICAgICAgIFRSQUNFXyhyZWcpKCJSZXR1cm5pbmcgJXhcbiIsIGN1cnJlbnRoYW5kbGUpOwoJCWlmIChscERpc3BvcykKCQkJKmxwRGlzcG9zCT0gUkVHX09QRU5FRF9FWElTVElOR19LRVk7CgkJRlJFRV9LRVlfUEFUSDsKCQlyZXR1cm4gRVJST1JfU1VDQ0VTUzsKCX0KCgkvKiBHb29kLiAgTm93IHRoZSBoYXJkIHBhcnQgKi8KCXdoaWxlICh3cHNbaV0pIHsKCQlscGxwUHJldktleQk9ICYobHBOZXh0S2V5LT5uZXh0c3ViKTsKCQlscHhrZXkJCT0gKmxwbHBQcmV2S2V5OwoJCXdoaWxlIChscHhrZXkpIHsKCQkJbHBscFByZXZLZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJCWxweGtleQkJPSAqbHBscFByZXZLZXk7CgkJfQoJCSpscGxwUHJldktleT1tYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpOwoJCWlmICghKmxwbHBQcmV2S2V5KSB7CgkJCUZSRUVfS0VZX1BBVEg7CiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFXyhyZWcpKCJSZXR1cm5pbmcgT1VUT0ZNRU1PUllcbiIpOwoJCQlyZXR1cm4gRVJST1JfT1VUT0ZNRU1PUlk7CgkJfQoJCW1lbXNldCgqbHBscFByZXZLZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CiAgICAgICAgICAgICAgICBUUkFDRV8ocmVnKSgiQWRkaW5nICVzXG4iLCBkZWJ1Z3N0cl93KHdwc1tpXSkpOwoJCSgqbHBscFByZXZLZXkpLT5rZXluYW1lCT0gc3RyZHVwVyh3cHNbaV0pOwoJCSgqbHBscFByZXZLZXkpLT5uZXh0CT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+bmV4dHN1Ygk9IE5VTEw7CgkJKCpscGxwUHJldktleSktPnZhbHVlcwk9IE5VTEw7CgkJKCpscGxwUHJldktleSktPm5yb2Z2YWx1ZXMgPSAwOwoJCSgqbHBscFByZXZLZXkpLT5mbGFncyAJPSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJaWYgKGxwc3pDbGFzcykKCQkJKCpscGxwUHJldktleSktPmNsYXNzID0gc3RyZHVwVyhscHN6Q2xhc3MpOwoJCWVsc2UKCQkJKCpscGxwUHJldktleSktPmNsYXNzID0gTlVMTDsKCQlscE5leHRLZXkJPSAqbHBscFByZXZLZXk7CgkJaSsrOwoJfQogICAgICAgIGN1cnJlbnRoYW5kbGUgKz0gMjsKCWFkZF9oYW5kbGUoY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgoJLypGSVhNRTogZmxhZyBoYW5kbGluZyBjb3JyZWN0PyAqLwoJbHBOZXh0S2V5LT5mbGFncz0gZmR3T3B0aW9ucyB8UkVHX09QVElPTl9UQUlOVEVEOwoJaWYgKGxwc3pDbGFzcykKCQlscE5leHRLZXktPmNsYXNzID0gc3RyZHVwVyhscHN6Q2xhc3MpOwoJZWxzZQoJCWxwTmV4dEtleS0+Y2xhc3MgPSBOVUxMOwoJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwogICAgICAgIFRSQUNFXyhyZWcpKCJSZXR1cm5pbmcgJXhcbiIsIGN1cnJlbnRoYW5kbGUpOwoJaWYgKGxwRGlzcG9zKQoJCSpscERpc3Bvcwk9IFJFR19DUkVBVEVEX05FV19LRVk7CglGUkVFX0tFWV9QQVRIOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleUV4MzJBIFtBRFZBUEkzMi4xMzBdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5RXhBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGxwc3pDbGFzcywgRFdPUkQgZmR3T3B0aW9ucywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHU0FNIHNhbURlc2lyZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBscFNlY0F0dHJpYnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSByZXRrZXksIExQRFdPUkQgbHBEaXNwb3MgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVcsIGxwc3pDbGFzc1c7CiAgICBEV09SRCAgcmV0OwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJWxkLCVzLCVseCwlbHgsJXAsJXAsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsZGVidWdzdHJfYShscHN6Q2xhc3MpLGZkd09wdGlvbnMsc2FtRGVzaXJlZCxscFNlY0F0dHJpYnMsCiAgICAgICAgICByZXRrZXksbHBEaXNwb3MpOwoKICAgIGxwc3pTdWJLZXlXID0gbHBzelN1YktleT9zdHJkdXBBMlcobHBzelN1YktleSk6TlVMTDsKICAgIGxwc3pDbGFzc1cgPSBscHN6Q2xhc3M/c3RyZHVwQTJXKGxwc3pDbGFzcyk6TlVMTDsKCiAgICByZXQgPSBSZWdDcmVhdGVLZXlFeFcoIGhrZXksIGxwc3pTdWJLZXlXLCBkd1Jlc2VydmVkLCBscHN6Q2xhc3NXLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZHdPcHRpb25zLCBzYW1EZXNpcmVkLCBscFNlY0F0dHJpYnMsIHJldGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBEaXNwb3MgKTsKCiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICBpZihscHN6Q2xhc3NXKSBmcmVlKGxwc3pDbGFzc1cpOwoKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleTMyVyBbQURWQVBJMzIuMTMyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgRFdPUkQganVuazsKICAgIExQS0VZU1RSVUNUCWxwTmV4dEtleTsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVwKVxuIiwgaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLHJldGtleSk7CgogICAgLyogVGhpcyBjaGVjayBpcyBoZXJlIGJlY2F1c2UgdGhlIHJldHVybiB2YWx1ZSBpcyBkaWZmZXJlbnQgdGhhbiB0aGUKICAgICAgIG9uZSBmcm9tIHRoZSBFeCBmdW5jdGlvbnMgKi8KICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0JBREtFWTsKCiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5RXhXKCBoa2V5LCBscHN6U3ViS2V5LCAwLCBOVUxMLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHX09QVElPTl9OT05fVk9MQVRJTEUsIEtFWV9BTExfQUNDRVNTLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXRrZXksICZqdW5rKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ3JlYXRlS2V5MzJBIFtBRFZBUEkzMi4xMjldCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIERXT1JEIHJldDsKICAgIExQV1NUUiBscHN6U3ViS2V5VzsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIGxwc3pTdWJLZXlXID0gbHBzelN1YktleT9zdHJkdXBBMlcobHBzelN1YktleSk6TlVMTDsKICAgIHJldCA9IFJlZ0NyZWF0ZUtleVcoIGhrZXksIGxwc3pTdWJLZXlXLCByZXRrZXkgKTsKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleTE2IFtTSEVMTC4yXSBbS0VSTkVMLjIxOF0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0dXJuIFJlZ0NyZWF0ZUtleUEoIGhrZXksIGxwc3pTdWJLZXksIHJldGtleSApOwp9CgoKLyogCiAqIFF1ZXJ5IFZhbHVlIEZ1bmN0aW9ucwogKiBXaW4zMiBkaWZmZXJzIGJldHdlZW4ga2V5bmFtZXMgYW5kIHZhbHVlbmFtZXMuIAogKiBtdWx0aXBsZSB2YWx1ZXMgbWF5IGJlbG9uZyB0byBvbmUga2V5LCB0aGUgc3BlY2lhbCB2YWx1ZQogKiB3aXRoIG5hbWUgTlVMTCBpcyB0aGUgZGVmYXVsdCB2YWx1ZSB1c2VkIGJ5IHRoZSB3aW4zMQogKiBjb21wYXQgZnVuY3Rpb25zLgogKgogKiBDYWxscGF0aDoKICogUmVnUXVlcnlWYWx1ZTE2IC0+IFJlZ1F1ZXJ5VmFsdWUzMkEgLT4gUmVnUXVlcnlWYWx1ZUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnUXVlcnlWYWx1ZTMyVyAtPiBSZWdRdWVyeVZhbHVlRXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlRXgzMlcgW0FEVkFQSTMyLjE1OF0KICogUmV0cmlldmVzIHR5cGUgYW5kIGRhdGEgZm9yIGEgc3BlY2lmaWVkIG5hbWUgYXNzb2NpYXRlZCB3aXRoIGFuIG9wZW4ga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgIFtJXSAgIEhhbmRsZSBvZiBrZXkgdG8gcXVlcnkKICogICAgbHBWYWx1ZU5hbWUgICBbSV0gICBOYW1lIG9mIHZhbHVlIHRvIHF1ZXJ5CiAqICAgIGxwZHdSZXNlcnZlZCAgW0ldICAgUmVzZXJ2ZWQgLSBtdXN0IGJlIE5VTEwKICogICAgbHBkd1R5cGUgICAgICBbT10gICBBZGRyZXNzIG9mIGJ1ZmZlciBmb3IgdmFsdWUgdHlwZS4gIElmIE5VTEwsIHRoZSB0eXBlCiAqICAgICAgICAgICAgICAgICAgICAgICAgaXMgbm90IHJlcXVpcmVkLgogKiAgICBscGJEYXRhICAgICAgIFtPXSAgIEFkZHJlc3Mgb2YgZGF0YSBidWZmZXIuICBJZiBOVUxMLCB0aGUgYWN0dWFsIGRhdGEgaXMKICogICAgICAgICAgICAgICAgICAgICAgICBub3QgcmVxdWlyZWQuCiAqICAgIGxwY2JEYXRhICAgICAgW0kvT10gQWRkcmVzcyBvZiBkYXRhIGJ1ZmZlciBzaXplCiAqCiAqIFJFVFVSTlMgCiAqICAgIEVSUk9SX1NVQ0NFU1M6ICAgU3VjY2VzcwogKiAgICBFUlJPUl9NT1JFX0RBVEE6ICEhISBpZiB0aGUgc3BlY2lmaWVkIGJ1ZmZlciBpcyBub3QgYmlnIGVub3VnaCB0byBob2xkIHRoZSBkYXRhCiAqIAkJICAgICAgIGJ1ZmZlciBpcyBsZWZ0IHVudG91Y2hlZC4gVGhlIE1TLWRvY3VtZW50YXRpb24gaXMgd3JvbmcgKGpzKSAhISEKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXhXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBWYWx1ZU5hbWUsCgkJCSAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGR3VHlwZSwKCQkJICAgICAgIExQQllURSBscGJEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglpbnQJCWk7CglEV09SRAkJcmV0OwoKCVRSQUNFXyhyZWcpKCIoMHgleCwlcywlcCwlcCwlcCwlcD0lbGQpXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwVmFsdWVOYW1lKSwKICAgICAgICAgIGxwZHdSZXNlcnZlZCwgbHBkd1R5cGUsIGxwYkRhdGEsIGxwY2JEYXRhLCBscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgoJbHBrZXkgPSBsb29rdXBfaGtleShoa2V5KTsKCglpZiAoIWxwa2V5KQoJICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJaWYgKChscGJEYXRhICYmICEgbHBjYkRhdGEpIHx8IGxwZHdSZXNlcnZlZCkKCSAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKCS8qIEFuIGVtcHR5IG5hbWUgc3RyaW5nIGlzIGVxdWl2YWxlbnQgdG8gTlVMTCAqLwoJaWYgKGxwVmFsdWVOYW1lICYmICEqbHBWYWx1ZU5hbWUpCgkgIGxwVmFsdWVOYW1lID0gTlVMTDsKCglpZiAobHBWYWx1ZU5hbWU9PU5VTEwpIAoJeyAvKiBVc2Uga2V5J3MgdW5uYW1lZCBvciBkZWZhdWx0IHZhbHVlLCBpZiBhbnkgKi8KCSAgZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkgICAgaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCSAgICAgIGJyZWFrOwoJfSAKCWVsc2UgCgl7IC8qIFNlYXJjaCBmb3IgdGhlIGtleSBuYW1lICovCgkgIGZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJICAgIGlmICggbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmICFsc3RyY21waVcobHBWYWx1ZU5hbWUsbHBrZXktPnZhbHVlc1tpXS5uYW1lKSkKCSAgICAgIGJyZWFrOwoJfQoKCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgCgl7IFRSQUNFXyhyZWcpKCIgS2V5IG5vdCBmb3VuZFxuIik7CgkgIGlmIChscFZhbHVlTmFtZT09TlVMTCkgCgkgIHsgLyogRW1wdHkga2V5bmFtZSBub3QgZm91bmQgKi8KCSAgICBpZiAobHBiRGF0YSkgCgkgICAgeyAqKFdDSEFSKilscGJEYXRhID0gMDsKCSAgICAgICpscGNiRGF0YQk9IDI7CgkgICAgfQoJICAgIGlmIChscGR3VHlwZSkKCSAgICAgICpscGR3VHlwZQk9IFJFR19TWjsKCSAgICBUUkFDRV8ocmVnKSgiIFJldHVybmluZyBhbiBlbXB0eSBzdHJpbmdcbiIpOwoJICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwoJICB9CgkgIHJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsKCX0KCglyZXQgPSBFUlJPUl9TVUNDRVNTOwoKCWlmIChscGR3VHlwZSkgCQkJCQkvKiB0eXBlIHJlcXVpcmVkID8qLwoJICAqbHBkd1R5cGUgPSBscGtleS0+dmFsdWVzW2ldLnR5cGU7CgoJaWYgKGxwYkRhdGEpCQkJCQkvKiBkYXRhIHJlcXVpcmVkID8qLwoJeyBpZiAoKmxwY2JEYXRhID49IGxwa2V5LT52YWx1ZXNbaV0ubGVuKQkvKiBidWZmZXIgbGFyZ2UgZW5vdWdodCA/Ki8KCSAgICBtZW1jcHkobHBiRGF0YSxscGtleS0+dmFsdWVzW2ldLmRhdGEsbHBrZXktPnZhbHVlc1tpXS5sZW4pOwoJICBlbHNlIHsKCSAgICAqbHBjYkRhdGEgPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKCSAgICByZXQgPSBFUlJPUl9NT1JFX0RBVEE7CgkgIH0KCX0KCglpZiAobHBjYkRhdGEpIAkJCQkJLyogc2l6ZSByZXF1aXJlZCA/Ki8KCXsgKmxwY2JEYXRhID0gbHBrZXktPnZhbHVlc1tpXS5sZW47Cgl9CgoJZGVidWdfcHJpbnRfdmFsdWUgKCBscGJEYXRhLCAmbHBrZXktPnZhbHVlc1tpXSk7CgoJVFJBQ0VfKHJlZykoIiAocmV0PSVseCwgdHlwZT0lbHgsIGxlbj0lbGQpXG4iLCByZXQsIGxwZHdUeXBlPypscGR3VHlwZTowLGxwY2JEYXRhPypscGNiRGF0YTowKTsKCglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlMzJXIFtBRFZBUEkzMi4xNTldCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBMUFdTVFIgbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUExPTkcgbHBjYkRhdGEgKQp7CglIS0VZCXhoa2V5OwoJRFdPUkQJcmV0LGxwZHdUeXBlOwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksbHBzekRhdGEsCiAgICAgICAgICBscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgogICAgLyogT25seSBvcGVuIHN1YmtleSwgaWYgd2UgcmVhbGx5IGRvIGRlc2NlbmQgKi8KICAgIGlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CiAgICAgICAgcmV0ID0gUmVnT3BlbktleVcoIGhrZXksIGxwc3pTdWJLZXksICZ4aGtleSApOwogICAgICAgIGlmIChyZXQgIT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgICAgICBXQVJOXyhyZWcpKCJDb3VsZCBub3Qgb3BlbiAlc1xuIiwgZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgfSBlbHNlCiAgICAgICAgeGhrZXkgPSBoa2V5OwoKICAgIGxwZHdUeXBlID0gUkVHX1NaOwogICAgcmV0ID0gUmVnUXVlcnlWYWx1ZUV4VyggeGhrZXksIE5VTEwsIE5VTEwsICZscGR3VHlwZSwgKExQQllURSlscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBjYkRhdGEgKTsKICAgIGlmICh4aGtleSAhPSBoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KHhoa2V5KTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWVFeDMyQSBbQURWQVBJMzIuMTU3XQogKgogKiBOT1RFUzoKICogdGhlIGRvY3VtYW50YXRpb24gaXMgd3Jvbmc6IGlmIHRoZSBidWZmZXIgaXMgdG8gc21hbGwgaXQgcmVtYWlucyB1bnRvdWNoZWQgCiAqCiAqIEZJWE1FOiBjaGVjayByZXR1cm52YWx1ZSAobGVuKSBmb3IgYW4gZW1wdHkga2V5CiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4QSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelZhbHVlTmFtZSwKCQkJICAgICAgIExQRFdPUkQgbHBkd1Jlc2VydmVkLCBMUERXT1JEIGxwZHdUeXBlLAoJCQkgICAgICAgTFBCWVRFIGxwYkRhdGEsIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUFdTVFIJbHBzelZhbHVlTmFtZVc7CglMUEJZVEUJbXlidWYgPSBOVUxMOwoJRFdPUkQJcmV0LCBteXR5cGUsIG15bGVuID0gMDsKCglUUkFDRV8ocmVnKSgiKCV4LCVzLCVwLCVwLCVwLCVwPSVsZClcbiIsIGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhLGxwY2JEYXRhPypscGNiRGF0YTowKTsKCglpZiAoIWxwY2JEYXRhICYmIGxwYkRhdGEpCQkJLyogYnVmZmVyIHdpdGhvdXQgc2l6ZSBpcyBpbGxlZ2FsICovCgl7ICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7Cgl9CgoJbHBzelZhbHVlTmFtZVcgPSBscHN6VmFsdWVOYW1lID8gc3RyZHVwQTJXKGxwc3pWYWx1ZU5hbWUpIDogTlVMTDsJCgkKCS8qIGdldCBqdXN0IHRoZSB0eXBlIGZpcnN0ICovCglyZXQgPSBSZWdRdWVyeVZhbHVlRXhXKCBoa2V5LCBscHN6VmFsdWVOYW1lVywgbHBkd1Jlc2VydmVkLCAmbXl0eXBlLCBOVUxMLCBOVUxMICk7CgkKCWlmICggcmV0ICE9IEVSUk9SX1NVQ0NFU1MgKQkJCS8qIGZhaWxlZCA/PyAqLwoJeyBpZihscHN6VmFsdWVOYW1lVykgZnJlZShscHN6VmFsdWVOYW1lVyk7CgkgIHJldHVybiByZXQ7Cgl9CgkKCWlmIChscGNiRGF0YSkJCQkJCS8qIGF0IGxlYXN0IGxlbmd0aCByZXF1ZXN0ZWQ/ICovCgl7IGlmIChVTklDT05WTUFTSyAmICgxPDwobXl0eXBlKSkpCQkvKiBzdHJpbmcgcmVxdWVzdGVkPyAqLwoJICB7IGlmIChscGJEYXRhICkJCQkJLyogdmFsdWUgcmVxdWVzdGVkPyAqLwoJICAgIHsgbXlsZW4gPSAyKiggKmxwY2JEYXRhICk7CgkgICAgICBteWJ1ZiA9IChMUEJZVEUpeG1hbGxvYyggbXlsZW4gKTsKCSAgICB9CgoJICAgIHJldCA9IFJlZ1F1ZXJ5VmFsdWVFeFcoIGhrZXksIGxwc3pWYWx1ZU5hbWVXLCBscGR3UmVzZXJ2ZWQsIGxwZHdUeXBlLCBteWJ1ZiwgJm15bGVuICk7CgoJICAgIGlmIChyZXQgPT0gRVJST1JfU1VDQ0VTUyApCgkgICAgeyBpZiAoIGxwYkRhdGEgKQoJICAgICAgeyBsbWVtY3B5bld0b0EobHBiRGF0YSwgKExQV1NUUilteWJ1ZiwgbXlsZW4vMik7CgkgICAgICB9CgkgICAgfQoKCSAgICAqbHBjYkRhdGEgPSBteWxlbi8yOwkJCS8qIHNpemUgaXMgaW4gYnl0ZSEgKi8KCSAgfQoJICBlbHNlCQkJCQkJLyogbm8gc3RyaW5ncywgY2FsbCBpdCBzdHJhaWdodCAqLwoJICB7IHJldCA9IFJlZ1F1ZXJ5VmFsdWVFeFcoIGhrZXksIGxwc3pWYWx1ZU5hbWVXLCBscGR3UmVzZXJ2ZWQsIGxwZHdUeXBlLCBscGJEYXRhLCBscGNiRGF0YSApOwoJICB9Cgl9CgkKCWlmIChscGR3VHlwZSkJCQkJCS8qIHR5cGUgd2hlbiByZXF1ZXN0ZWQgKi8KCXsgKmxwZHdUeXBlID0gbXl0eXBlOwoJfQoKCVRSQUNFXyhyZWcpKCIgKHJldD0lbHgsdHlwZT0lbHgsIGxlbj0lbGQpXG4iLCByZXQsbXl0eXBlLGxwY2JEYXRhPypscGNiRGF0YTowKTsKCQoJaWYobXlidWYpIGZyZWUobXlidWYpOwoJaWYobHBzelZhbHVlTmFtZVcpIGZyZWUobHBzelZhbHVlTmFtZVcpOwoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZUV4MTYgW0tFUk5FTC4yMjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgbHBiRGF0YSwgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlTmFtZSksCiAgICAgICAgICBscGR3UmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YT8qbHBjYkRhdGE6MCk7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUV4QSggaGtleSwgbHBzelZhbHVlTmFtZSwgbHBkd1Jlc2VydmVkLCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwYkRhdGEsIGxwY2JEYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWUzMkEgW0FEVkFQSTMyLjE1Nl0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBTVFIgbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUExPTkcgbHBjYkRhdGEgKQp7CiAgICBIS0VZIHhoa2V5OwogICAgRFdPUkQgcmV0LCBkd1R5cGU7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxscHN6RGF0YSwKICAgICAgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewogICAgICAgIHJldCA9IFJlZ09wZW5LZXkxNiggaGtleSwgbHBzelN1YktleSwgJnhoa2V5ICk7CiAgICAgICAgaWYoIHJldCAhPSBFUlJPUl9TVUNDRVNTICkKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgIH0gZWxzZQogICAgICAgIHhoa2V5ID0gaGtleTsKCiAgICBkd1R5cGUgPSBSRUdfU1o7CiAgICByZXQgPSBSZWdRdWVyeVZhbHVlRXhBKCB4aGtleSwgTlVMTCxOVUxMLCAmZHdUeXBlLCAoTFBCWVRFKWxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscGNiRGF0YSApOwogICAgaWYoIHhoa2V5ICE9IGhrZXkgKQogICAgICAgIFJlZ0Nsb3NlS2V5KCB4aGtleSApOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZTE2IFtTSEVMTC42XSBbS0VSTkVMLjIyNF0KICoKICogTk9URVMKICogICAgSXMgdGhpcyBIQUNLIHN0aWxsIGFwcGxpY2FibGU/CiAqCiAqIEhBQ0sKICogICAgVGhlIDE2Yml0IFJlZ1F1ZXJ5VmFsdWUgZG9lc24ndCBoYW5kbGUgc2VsZWN0b3JibG9ja3MgYW55d2F5LCBzbyB3ZSBqdXN0CiAqICAgIG1hc2sgb3V0IHRoZSBoaWdoIDE2IGJpdC4gIFRoaXMgKG5vdCBzbyBtdWNoIGluY2lkZW50bHkpIGhvcGVmdWxseSBmaXhlcwogKiAgICBBbGR1cyBGSDQpCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZTE2KCBIS0VZIGhrZXksIExQU1RSIGxwc3pTdWJLZXksIExQU1RSIGxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxscHN6RGF0YSwKICAgICAgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBpZiAobHBjYkRhdGEpCiAgICAgICAgKmxwY2JEYXRhICY9IDB4RkZGRjsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlQShoa2V5LGxwc3pTdWJLZXksbHBzekRhdGEsbHBjYkRhdGEpOwp9CgoKLyoKICogU2V0dGluZyB2YWx1ZXMgb2YgUmVnaXN0cnkga2V5cwogKgogKiBDYWxscGF0aDoKICogUmVnU2V0VmFsdWUxNiAtPiBSZWdTZXRWYWx1ZTMyQSAtPiBSZWdTZXRWYWx1ZUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdTZXRWYWx1ZTMyVyAgIC0+IFJlZ1NldFZhbHVlRXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZUV4MzJXIFtBRFZBUEkzMi4xNzBdCiAqIFNldHMgdGhlIGRhdGEgYW5kIHR5cGUgb2YgYSB2YWx1ZSB1bmRlciBhIHJlZ2lzdGVyIGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICBbSV0gSGFuZGxlIG9mIGtleSB0byBzZXQgdmFsdWUgZm9yCiAqICAgIGxwc3pWYWx1ZU5hbWUgW0ldIE5hbWUgb2YgdmFsdWUgdG8gc2V0CiAqICAgIGR3UmVzZXJ2ZWQgICAgW0ldIFJlc2VydmVkIC0gbXVzdCBiZSB6ZXJvCiAqICAgIGR3VHlwZSAgICAgICAgW0ldIEZsYWcgZm9yIHZhbHVlIHR5cGUKICogICAgbHBiRGF0YSAgICAgICBbSV0gQWRkcmVzcyBvZiB2YWx1ZSBkYXRhCiAqICAgIGNiRGF0YSAgICAgICAgW0ldIFNpemUgb2YgdmFsdWUgZGF0YQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKgogKiBOT1RFUwogKiAgIHdpbjk1IGRvZXMgbm90IGNhcmUgYWJvdXQgY2JEYXRhIGZvciBSRUdfU1ogYW5kIGZpbmRzIG91dCB0aGUgbGVuIGJ5IGl0c2VsZiAoanMpIAogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXhXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelZhbHVlTmFtZSwgCgkJCSAgICAgRFdPUkQgZHdSZXNlcnZlZCwgRFdPUkQgZHdUeXBlLAoJCQkgICAgIENPTlNUIEJZVEUgKmxwYkRhdGEsIERXT1JEIGNiRGF0YSkKewoJTFBLRVlTVFJVQ1QgbHBrZXk7CglpbnQgaTsKCglUUkFDRV8ocmVnKSgiKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuIiwgaGtleSwgZGVidWdzdHJfdyhscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsIGR3VHlwZSwgbHBiRGF0YSwgY2JEYXRhKTsKCglscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CgoJaWYgKCFscGtleSkKICAgICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglscGtleS0+ZmxhZ3MgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoKCWlmIChscHN6VmFsdWVOYW1lPT1OVUxMKSB7CiAgICAgICAgICAgICAvKiBTZXRzIHR5cGUgYW5kIG5hbWUgZm9yIGtleSdzIHVubmFtZWQgb3IgZGVmYXVsdCB2YWx1ZSAqLwoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXBpVyhscHN6VmFsdWVOYW1lLGxwa2V5LT52YWx1ZXNbaV0ubmFtZSkKCQkJKQoJCQkJYnJlYWs7Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0gKExQS0VZVkFMVUUpeHJlYWxsb2MoCgkJCQkJbHBrZXktPnZhbHVlcywKCQkJCQkobHBrZXktPm5yb2Z2YWx1ZXMrMSkqc2l6ZW9mKEtFWVZBTFVFKQoJCQkJKTsKCQlscGtleS0+bnJvZnZhbHVlcysrOwoJCW1lbXNldChscGtleS0+dmFsdWVzK2ksJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCX0KCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpIHsKCQlpZiAobHBzelZhbHVlTmFtZSkKCQkJbHBrZXktPnZhbHVlc1tpXS5uYW1lID0gc3RyZHVwVyhscHN6VmFsdWVOYW1lKTsKCQllbHNlCgkJCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSA9IE5VTEw7Cgl9CgoJaWYgKGR3VHlwZSA9PSBSRUdfU1opCgkgIGNiRGF0YSA9IDIgKiAobHN0cmxlblcgKChMUENXU1RSKWxwYkRhdGEpICsgMSk7CgkgIAoJbHBrZXktPnZhbHVlc1tpXS5sZW4JPSBjYkRhdGE7CglscGtleS0+dmFsdWVzW2ldLnR5cGUJPSBkd1R5cGU7CglpZiAobHBrZXktPnZhbHVlc1tpXS5kYXRhICE9TlVMTCkKCQlmcmVlKGxwa2V5LT52YWx1ZXNbaV0uZGF0YSk7CglscGtleS0+dmFsdWVzW2ldLmRhdGEJPSAoTFBCWVRFKXhtYWxsb2MoY2JEYXRhKTsKCWxwa2V5LT52YWx1ZXNbaV0ubGFzdG1vZGlmaWVkID0gdGltZShOVUxMKTsKCW1lbWNweShscGtleS0+dmFsdWVzW2ldLmRhdGEsbHBiRGF0YSxjYkRhdGEpOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgzMkEgW0FEVkFQSTMyLjE2OV0KICoKICogTk9URVMKICogICB3aW45NSBkb2VzIG5vdCBjYXJlIGFib3V0IGNiRGF0YSBmb3IgUkVHX1NaIGFuZCBmaW5kcyBvdXQgdGhlIGxlbiBieSBpdHNlbGYgKGpzKSAKICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4QSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelZhbHVlTmFtZSwKCQkJICAgICBEV09SRCBkd1Jlc2VydmVkLCBEV09SRCBkd1R5cGUsCgkJCSAgICAgQ09OU1QgQllURSAqbHBiRGF0YSwgRFdPUkQgY2JEYXRhICkKewoJTFBCWVRFCWJ1ZjsKCUxQV1NUUglscHN6VmFsdWVOYW1lVzsKCURXT1JECXJldDsKCglpZiAoIWxwYkRhdGEpCgkJcmV0dXJuIChFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CgkJCglUUkFDRV8ocmVnKSgiKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlTmFtZSksCiAgICAgICAgICBkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YSk7CgoJaWYgKCgxPDxkd1R5cGUpICYgVU5JQ09OVk1BU0spIAoJeyBpZiAoZHdUeXBlID09IFJFR19TWikKCSAgICBjYkRhdGEgPSBzdHJsZW4gKChMUENTVFIpbHBiRGF0YSkrMTsKCgkgIGJ1ZiA9IChMUEJZVEUpeG1hbGxvYyggY2JEYXRhICoyICk7CgkgIGxtZW1jcHluQXRvVyAoKExQVk9JRClidWYsIGxwYkRhdGEsIGNiRGF0YSApOwoJICBjYkRhdGE9MipjYkRhdGE7Cgl9IAoJZWxzZQoJICBidWY9KExQQllURSlscGJEYXRhOwoKCWlmIChscHN6VmFsdWVOYW1lKQoJICBscHN6VmFsdWVOYW1lVyA9IHN0cmR1cEEyVyhscHN6VmFsdWVOYW1lKTsKCWVsc2UKCSAgbHBzelZhbHVlTmFtZVcgPSBOVUxMOwoKCXJldD1SZWdTZXRWYWx1ZUV4Vyhoa2V5LGxwc3pWYWx1ZU5hbWVXLGR3UmVzZXJ2ZWQsZHdUeXBlLGJ1ZixjYkRhdGEpOwoKCWlmIChscHN6VmFsdWVOYW1lVykKCSAgZnJlZShscHN6VmFsdWVOYW1lVyk7CgoJaWYgKGJ1ZiE9bHBiRGF0YSkKCSAgZnJlZShidWYpOwoKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgxNiBbS0VSTkVMLjIyNl0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgRFdPUkQgY2JEYXRhICkKewogICAgVFJBQ0VfKHJlZykoIigleCwlcywlbGQsJWxkLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEpOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlRXhBKCBoa2V5LCBscHN6VmFsdWVOYW1lLCBkd1Jlc2VydmVkLCBkd1R5cGUsIGxwYkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2JEYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMzJXCVtBRFZBUEkzMi4xNzFdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgRFdPUkQgZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbHBzekRhdGEsIERXT1JEIGNiRGF0YSApCnsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQ7CgoJVFJBQ0VfKHJlZykoIigleCwlcywlbGQsJXMsJWxkKVxuIiwKCQloa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksZHdUeXBlLGRlYnVnc3RyX3cobHBzekRhdGEpLGNiRGF0YQoJKTsKCWlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CgkJcmV0PVJlZ0NyZWF0ZUtleVcoaGtleSxscHN6U3ViS2V5LCZ4aGtleSk7CgkJaWYgKHJldCE9RVJST1JfU1VDQ0VTUykKCQkJcmV0dXJuIHJldDsKCX0gZWxzZQoJCXhoa2V5PWhrZXk7CglpZiAoZHdUeXBlIT1SRUdfU1opIHsKCQlUUkFDRV8ocmVnKSgiZHdUeXBlPSVsZCAtIENoYW5naW5nIHRvIFJFR19TWlxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT0yKmxzdHJsZW5XKGxwc3pEYXRhKSsyKSB7CgkJVFJBQ0VfKHJlZykoIkxlbj0lbGQgIT0gc3RybGVuKCVzKSsxPSVkIVxuIiwKCQkJY2JEYXRhLGRlYnVnc3RyX3cobHBzekRhdGEpLDIqbHN0cmxlblcobHBzekRhdGEpKzIKCQkpOwoJCWNiRGF0YT0yKmxzdHJsZW5XKGxwc3pEYXRhKSsyOwoJfQoJcmV0PVJlZ1NldFZhbHVlRXhXKHhoa2V5LE5VTEwsMCxkd1R5cGUsKExQQllURSlscHN6RGF0YSxjYkRhdGEpOwoJaWYgKGhrZXkhPXhoa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMzJBIFtBRFZBUEkzMi4xNjhdCiAqCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwc3pEYXRhLCBEV09SRCBjYkRhdGEgKQp7CglEV09SRAlyZXQ7CglIS0VZCXhoa2V5OwoKCVRSQUNFXyhyZWcpKCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEpOwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQ9UmVnQ3JlYXRlS2V5MTYoaGtleSxscHN6U3ViS2V5LCZ4aGtleSk7CgkJaWYgKHJldCE9RVJST1JfU1VDQ0VTUykKCQkJcmV0dXJuIHJldDsKCX0gZWxzZQoJCXhoa2V5PWhrZXk7CgoJaWYgKGR3VHlwZSE9UkVHX1NaKSB7CgkJVFJBQ0VfKHJlZykoImR3VHlwZT0lbGQhXG4iLGR3VHlwZSk7CgkJZHdUeXBlPVJFR19TWjsKCX0KCWlmIChjYkRhdGEhPXN0cmxlbihscHN6RGF0YSkrMSkKCQljYkRhdGE9c3RybGVuKGxwc3pEYXRhKSsxOwoJcmV0PVJlZ1NldFZhbHVlRXhBKHhoa2V5LE5VTEwsMCxkd1R5cGUsKExQQllURSlscHN6RGF0YSxjYkRhdGEpOwoJaWYgKHhoa2V5IT1oa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMTYgW0tFUk5FTC4yMjFdIFtTSEVMTC41XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JECWR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscHN6RGF0YSwgRFdPUkQgY2JEYXRhICkKewogICAgVFJBQ0VfKHJlZykoIigleCwlcywlbGQsJXMsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSksZHdUeXBlLAogICAgICAgICAgZGVidWdzdHJfYShscHN6RGF0YSksY2JEYXRhKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUEoaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEpOwp9CgoKLyogCiAqIEtleSBFbnVtZXJhdGlvbgogKgogKiBDYWxscGF0aDoKICogUmVnRW51bUtleTE2IC0+IFJlZ0VudW1LZXkzMkEgLT4gUmVnRW51bUtleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnRW51bUtleTMyVyAgIC0+IFJlZ0VudW1LZXlFeDMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXlFeDMyVyBbQURWQVBJMzIuMTM5XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgIFtJXSBIYW5kbGUgdG8ga2V5IHRvIGVudW1lcmF0ZQogKiAgICBpU3ViS2V5ICAgICAgW0ldIEluZGV4IG9mIHN1YmtleSB0byBlbnVtZXJhdGUKICogICAgbHBzek5hbWUgICAgIFtPXSBCdWZmZXIgZm9yIHN1YmtleSBuYW1lCiAqICAgIGxwY2NoTmFtZSAgICBbT10gU2l6ZSBvZiBzdWJrZXkgYnVmZmVyCiAqICAgIGxwZHdSZXNlcnZlZCBbSV0gUmVzZXJ2ZWQKICogICAgbHBzekNsYXNzICAgIFtPXSBCdWZmZXIgZm9yIGNsYXNzIHN0cmluZwogKiAgICBscGNjaENsYXNzICAgW09dIFNpemUgb2YgY2xhc3MgYnVmZmVyCiAqICAgIGZ0ICAgICAgICAgICBbT10gVGltZSBrZXkgbGFzdCB3cml0dGVuIHRvCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleUV4VyggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFdTVFIgbHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hOYW1lLCBMUERXT1JEIGxwZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGxwc3pDbGFzcywgTFBEV09SRCBscGNjaENsYXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRVRJTUUgKmZ0ICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXksbHB4a2V5OwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJWxkLCVwLCVwKCVsZCksJXAsJXAsJXAsJXApXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSwKCQlscGNjaE5hbWUsbHBjY2hOYW1lPyAqbHBjY2hOYW1lIDogLTEsbHBkd1Jlc2VydmVkLGxwc3pDbGFzcywKCQlscGNjaENsYXNzLGZ0KTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBpZiAoIWxwY2NoTmFtZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgaWYgKCFscGtleS0+bmV4dHN1YikKICAgICAgICByZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKICAgIGxweGtleT1scGtleS0+bmV4dHN1YjsKCiAgICAvKiBUcmF2ZXJzZSB0aGUgc3Via2V5cyAqLwogICAgd2hpbGUgKGlTdWJrZXkgJiYgbHB4a2V5KSB7CiAgICAgICAgaVN1YmtleS0tOwoJbHB4a2V5PWxweGtleS0+bmV4dDsKICAgIH0KCiAgICBpZiAoaVN1YmtleSB8fCAhbHB4a2V5KQogICAgICAgIHJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwogICAgaWYgKGxzdHJsZW5XKGxweGtleS0+a2V5bmFtZSkrMT4qbHBjY2hOYW1lKSB7CiAgICAgICAgKmxwY2NoTmFtZSA9IGxzdHJsZW5XKGxweGtleS0+a2V5bmFtZSk7CglyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwogICAgfQogICAgbWVtY3B5KGxwc3pOYW1lLGxweGtleS0+a2V5bmFtZSxsc3RybGVuVyhscHhrZXktPmtleW5hbWUpKjIrMik7CiAgICAqbHBjY2hOYW1lID0gbHN0cmxlblcobHBzek5hbWUpOwoKICAgIGlmIChscHN6Q2xhc3MpIHsKICAgICAgICAvKiBGSVhNRTogd2hhdCBzaG91bGQgd2Ugd3JpdGUgaW50byBpdD8gKi8KICAgICAgKmxwc3pDbGFzcwk9IDA7CiAgICAgICpscGNjaENsYXNzCT0gMjsKICAgIH0KICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5VyBbQURWQVBJMzIuMTQwXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlXKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQV1NUUiBscHN6TmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBEV09SRCByZXQ7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwogICAgcmV0ID0gUmVnRW51bUtleUV4Vyhoa2V5LGlTdWJrZXksbHBzek5hbWUsJmxwY2NoTmFtZSxOVUxMLE5VTEwsTlVMTCxOVUxMKTsKCiAgICAvKiBJZiBscHN6TmFtZSBpcyBOVUxMIHRoZW4gd2UgaGF2ZSBhIHNsaWdodGx5IGRpZmZlcmVudCBiZWhhdmlvdXIgdGhhbgogICAgICAgUmVnRW51bUtleUV4VyAqLwogICAgaWYobHBzek5hbWUgPT0gTlVMTCAmJiByZXQgPT0gRVJST1JfTU9SRV9EQVRBKQogICAgICAgIHJldCA9IEVSUk9SX1NVQ0NFU1M7CgogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleUV4MzJBIFtBRFZBUEkzMi4xMzhdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleUV4QSggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE5hbWUsIExQRFdPUkQgbHBkd1Jlc2VydmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgbHBzekNsYXNzLCBMUERXT1JEIGxwY2NoQ2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFVElNRSAqZnQgKQp7CiAgICBEV09SRAlyZXQ7CiAgICBMUFdTVFIJbHBzek5hbWVXLCBscHN6Q2xhc3NXOwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJWxkLCVwLCVwKCVsZCksJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUsbHBjY2hOYW1lPyAqbHBjY2hOYW1lIDogLTEsCgkJbHBkd1Jlc2VydmVkLGxwc3pDbGFzcyxscGNjaENsYXNzLGZ0KTsKCiAgICBscHN6TmFtZVcgPSBscHN6TmFtZSA/IChMUFdTVFIpeG1hbGxvYygqbHBjY2hOYW1lICogMikgOiBOVUxMOwogICAgbHBzekNsYXNzVyA9IGxwc3pDbGFzcyA/IChMUFdTVFIpeG1hbGxvYygqbHBjY2hDbGFzcyAqIDIpIDogTlVMTDsKCiAgICByZXQgPSBSZWdFbnVtS2V5RXhXKGhrZXksIGlTdWJrZXksIGxwc3pOYW1lVywgbHBjY2hOYW1lLCBscGR3UmVzZXJ2ZWQsCgkJCWxwc3pDbGFzc1csIGxwY2NoQ2xhc3MsIGZ0KTsKCiAgICBpZiAocmV0ID09IEVSUk9SX1NVQ0NFU1MpIHsKICAgICAgICBsc3RyY3B5V3RvQShscHN6TmFtZSxscHN6TmFtZVcpOwoJaWYgKGxwc3pDbGFzc1cpCgkgICAgbHN0cmNweVd0b0EobHBzekNsYXNzLGxwc3pDbGFzc1cpOwogICAgfQogICAgaWYgKGxwc3pOYW1lVykKICAgICAgICBmcmVlKGxwc3pOYW1lVyk7CiAgICBpZiAobHBzekNsYXNzVykKICAgICAgICBmcmVlKGxwc3pDbGFzc1cpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleUEgW0FEVkFQSTMyLjEzN10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5QSggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGxwY2NoTmFtZSApCnsKICAgIERXT1JEIHJldDsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZSk7CiAgICByZXQgPSBSZWdFbnVtS2V5RXhBKCBoa2V5LCBpU3Via2V5LCBscHN6TmFtZSwgJmxwY2NoTmFtZSwgTlVMTCwgTlVMTCwgCgkJCSBOVUxMLCBOVUxMICk7CgogICAgLyogSWYgbHBzek5hbWUgaXMgTlVMTCB0aGVuIHdlIGhhdmUgYSBzbGlnaHRseSBkaWZmZXJlbnQgYmVoYXZpb3VyIHRoYW4KICAgICAgIFJlZ0VudW1LZXlFeEEgKi8KICAgIGlmKGxwc3pOYW1lID09IE5VTEwgJiYgcmV0ID09IEVSUk9SX01PUkVfREFUQSkKICAgICAgICByZXQgPSBFUlJPUl9TVUNDRVNTOwoKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXkxNiBbU0hFTEwuN10gW0tFUk5FTC4yMTZdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleTE2KCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwogICAgcmV0dXJuIFJlZ0VudW1LZXlBKCBoa2V5LCBpU3Via2V5LCBscHN6TmFtZSwgbHBjY2hOYW1lKTsKfQoKCi8qIAogKiBFbnVtZXJhdGUgUmVnaXN0cnkgVmFsdWVzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdFbnVtVmFsdWUxNiAtPiBSZWdFbnVtVmFsdWUzMkEgLT4gUmVnRW51bVZhbHVlMzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bVZhbHVlMzJXIFtBRFZBUEkzMi4xNDJdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICBbSV0gSGFuZGxlIHRvIGtleSB0byBxdWVyeQogKiAgICBpVmFsdWUgICAgICBbSV0gSW5kZXggb2YgdmFsdWUgdG8gcXVlcnkKICogICAgbHBzelZhbHVlICAgW09dIFZhbHVlIHN0cmluZwogKiAgICBscGNjaFZhbHVlICBbSS9PXSBTaXplIG9mIHZhbHVlIGJ1ZmZlciAoaW4gd2NoYXJzKQogKiAgICBscGRSZXNlcnZlZCBbSV0gUmVzZXJ2ZWQKICogICAgbHBkd1R5cGUgICAgW09dIFR5cGUgY29kZQogKiAgICBscGJEYXRhICAgICBbT10gVmFsdWUgZGF0YQogKiAgICBscGNiRGF0YSAgICBbSS9PXSBTaXplIG9mIGRhdGEgYnVmZmVyIChpbiBieXRlcykKICoKICogTm90ZTogIHdpZGUgY2hhcmFjdGVyIGZ1bmN0aW9ucyB0aGF0IHRha2UgYW5kL29yIHJldHVybiAiY2hhcmFjdGVyIGNvdW50cyIKICogIHVzZSBUQ0hBUiAodGhhdCBpcyB1bnNpZ25lZCBzaG9ydCBvciBjaGFyKSBub3QgYnl0ZSBjb3VudHMuCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlVyggSEtFWSBoa2V5LCBEV09SRCBpVmFsdWUsIExQV1NUUiBscHN6VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hWYWx1ZSwgTFBEV09SRCBscGRSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglMUEtFWVZBTFVFCXZhbDsKCglUUkFDRV8ocmVnKSgiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsZGVidWdzdHJfdyhscHN6VmFsdWUpLAogICAgICAgICAgbHBjY2hWYWx1ZSxscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhKTsKCglscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CgkKCWlmICghbHBjYkRhdGEgJiYgbHBiRGF0YSkKCQlyZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgkJCglpZiAoIWxwa2V5KQoJCXJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglpZiAobHBrZXktPm5yb2Z2YWx1ZXMgPD0gaVZhbHVlKQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoKCXZhbCA9ICYobHBrZXktPnZhbHVlc1tpVmFsdWVdKTsKCglpZiAodmFsLT5uYW1lKSB7CgkgICAgICAgIGlmIChsc3RybGVuVyh2YWwtPm5hbWUpKzE+KmxwY2NoVmFsdWUpIHsKCQkJKmxwY2NoVmFsdWUgPSBsc3RybGVuVyh2YWwtPm5hbWUpKzE7CgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJfQoJCW1lbWNweShscHN6VmFsdWUsdmFsLT5uYW1lLDIgKiAobHN0cmxlblcodmFsLT5uYW1lKSsxKSApOwoJCSpscGNjaFZhbHVlPWxzdHJsZW5XKHZhbC0+bmFtZSk7Cgl9IGVsc2UgewoJCSpscHN6VmFsdWUJPSAwOwoJCSpscGNjaFZhbHVlCT0gMDsKCX0KCgkvKiBDYW4gYmUgTlVMTCBpZiB0aGUgdHlwZSBjb2RlIGlzIG5vdCByZXF1aXJlZCAqLwoJaWYgKGxwZHdUeXBlKQoJCSpscGR3VHlwZSA9IHZhbC0+dHlwZTsKCglpZiAobHBiRGF0YSkgewoJCWlmICh2YWwtPmxlbj4qbHBjYkRhdGEpIHsKCQkJKmxwY2JEYXRhID0gdmFsLT5sZW47CgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJfQoJCW1lbWNweShscGJEYXRhLHZhbC0+ZGF0YSx2YWwtPmxlbik7CgkJKmxwY2JEYXRhID0gdmFsLT5sZW47Cgl9CgoJZGVidWdfcHJpbnRfdmFsdWUgKCB2YWwtPmRhdGEsIHZhbCApOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1WYWx1ZTMyQSBbQURWQVBJMzIuMTQxXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1WYWx1ZUEoIEhLRVkgaGtleSwgRFdPUkQgaVZhbHVlLCBMUFNUUiBscHN6VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hWYWx1ZSwgTFBEV09SRCBscGRSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBXU1RSCWxwc3pWYWx1ZVc7CglMUEJZVEUJbHBiRGF0YVc7CglEV09SRAlyZXQsbHBjYkRhdGFXOwoJRFdPUkQgZHdUeXBlOwoKCVRSQUNFXyhyZWcpKCIoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSwKCQlscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhKTsKCglscHN6VmFsdWVXID0gKExQV1NUUil4bWFsbG9jKCpscGNjaFZhbHVlKjIpOwoJaWYgKGxwYkRhdGEpIHsKCQlscGJEYXRhVyA9IChMUEJZVEUpeG1hbGxvYygqbHBjYkRhdGEqMik7CgkJbHBjYkRhdGFXID0gKmxwY2JEYXRhOwoJfSBlbHNlCgkJbHBiRGF0YVcgPSBOVUxMOwoKCXJldCA9IFJlZ0VudW1WYWx1ZVcoIGhrZXksIGlWYWx1ZSwgbHBzelZhbHVlVywgbHBjY2hWYWx1ZSwgCgkJCQlscGRSZXNlcnZlZCwgJmR3VHlwZSwgbHBiRGF0YVcsICZscGNiRGF0YVcgKTsKCglpZiAobHBkd1R5cGUpCgkJKmxwZHdUeXBlID0gZHdUeXBlOwoKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MpIHsKCQlsc3RyY3B5V3RvQShscHN6VmFsdWUsbHBzelZhbHVlVyk7CgkJaWYgKGxwYkRhdGEpIHsKCQkJaWYgKCgxPDxkd1R5cGUpICYgVU5JQ09OVk1BU0spIHsKCQkJCWxzdHJjcHlXdG9BKGxwYkRhdGEsKExQV1NUUilscGJEYXRhVyk7CgkJCX0gZWxzZSB7CgkJCQlpZiAobHBjYkRhdGFXID4gKmxwY2JEYXRhKSB7CgkJCQkJKmxwY2JEYXRhID0gbHBjYkRhdGFXOwoJCQkJCXJldAk9IEVSUk9SX01PUkVfREFUQTsKCQkJCX0gZWxzZQoJCQkJCW1lbWNweShscGJEYXRhLGxwYkRhdGFXLGxwY2JEYXRhVyk7CgkJCX0KCQkJKmxwY2JEYXRhID0gbHBjYkRhdGFXOwoJCX0KCX0KICAgIGlmIChscGJEYXRhVykgZnJlZShscGJEYXRhVyk7CiAgICBpZiAobHBzelZhbHVlVykgZnJlZShscHN6VmFsdWVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1WYWx1ZTE2IFtLRVJORUwuMjIzXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1WYWx1ZTE2KCBIS0VZIGhrZXksIERXT1JEIGlWYWx1ZSwgTFBTVFIgbHBzelZhbHVlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoVmFsdWUsIExQRFdPUkQgbHBkUmVzZXJ2ZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1R5cGUsIExQQllURSBscGJEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewogICAgVFJBQ0VfKHJlZykoIigleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLGhrZXksaVZhbHVlLGxwc3pWYWx1ZSxscGNjaFZhbHVlLAogICAgICAgICAgbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YSk7CiAgICByZXR1cm4gUmVnRW51bVZhbHVlQSggaGtleSwgaVZhbHVlLCBscHN6VmFsdWUsIGxwY2NoVmFsdWUsIGxwZFJlc2VydmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwZHdUeXBlLCBscGJEYXRhLCBscGNiRGF0YSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDbG9zZUtleSBbU0hFTEwuM10gW0tFUk5FTC4yMjBdIFtBRFZBUEkzMi4xMjZdCiAqIFJlbGVhc2VzIHRoZSBoYW5kbGUgb2YgdGhlIHNwZWNpZmllZCBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgW0ldIEhhbmRsZSBvZiBrZXkgdG8gY2xvc2UKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdDbG9zZUtleSggSEtFWSBoa2V5ICkKewogICAgVFJBQ0VfKHJlZykoIigleClcbiIsaGtleSk7CgogICAgLyogVGhlIHN0YW5kYXJkIGhhbmRsZXMgYXJlIGFsbG93ZWQgdG8gc3VjY2VlZCwgZXZlbiB0aG91Z2ggdGhleSBhcmUgbm90CiAgICAgICBjbG9zZWQgKi8KICAgIGlmIChpc19zdGFuZGFyZF9oa2V5KGhrZXkpKQogICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwoKICAgIHJldHVybiByZW1vdmVfaGFuZGxlKGhrZXkpOwp9CgoKLyogCiAqIERlbGV0ZSByZWdpc3RyeSBrZXkKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZUtleTE2IC0+IFJlZ0RlbGV0ZUtleTMyQSAtPiBSZWdEZWxldGVLZXkzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVLZXkzMlcgW0FEVkFQSTMyLjEzNF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldIEhhbmRsZSB0byBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5IFtJXSBOYW1lIG9mIHN1YmtleSB0byBkZWxldGUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSApCnsKCUxQS0VZU1RSVUNUCSpscGxwUHJldktleSxscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIFN1YmtleSBwYXJhbSBjYW5ub3QgYmUgTlVMTCAqLwogICAgaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkKICAgICAgICByZXR1cm4gRVJST1JfQkFES0VZOwoKICAgIC8qIFdlIG5lZWQgdG8ga25vdyB0aGUgcHJldmlvdXMga2V5IGluIHRoZSBoaWVyLiAqLwoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7CglscHhrZXkJPSBscE5leHRLZXk7Cgl3aGlsZSAoaTx3cGMtMSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlUUkFDRV8ocmVnKSgiICBTY2FubmluZyBbJXNdXG4iLAoJCQkJICAgICBkZWJ1Z3N0cl93KGxweGtleS0+a2V5bmFtZSkpOwoJCQlpZiAoIWxzdHJjbXBpVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJCWJyZWFrOwoJCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJCX0KCQlpZiAoIWxweGtleSkgewoJCQlGUkVFX0tFWV9QQVRIOwoJCQlUUkFDRV8ocmVnKSgiICBOb3QgZm91bmQuXG4iKTsKCQkJLyogbm90IGZvdW5kIGlzIHN1Y2Nlc3MgKi8KCQkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CgkJfQoJCWkrKzsKCQlscE5leHRLZXkJPSBscHhrZXk7Cgl9CglscHhrZXkJPSBscE5leHRLZXktPm5leHRzdWI7CglscGxwUHJldktleSA9ICYobHBOZXh0S2V5LT5uZXh0c3ViKTsKCXdoaWxlIChscHhrZXkpIHsKCQlUUkFDRV8ocmVnKSgiICBTY2FubmluZyBbJXNdXG4iLAoJCQkgICAgIGRlYnVnc3RyX3cobHB4a2V5LT5rZXluYW1lKSk7CgkJaWYgKCFsc3RyY21waVcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCWJyZWFrOwoJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCWxweGtleQkJPSBscHhrZXktPm5leHQ7Cgl9CgoJaWYgKCFscHhrZXkpIHsKCQlGUkVFX0tFWV9QQVRIOwoJCVdBUk5fKHJlZykoIiAgTm90IGZvdW5kLlxuIik7CgkJcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoJfQoKCWlmIChscHhrZXktPm5leHRzdWIpIHsKCQlGUkVFX0tFWV9QQVRIOwoJCVdBUk5fKHJlZykoIiAgTm90IGVtcHR5LlxuIik7CgkJcmV0dXJuIEVSUk9SX0NBTlRXUklURTsKCX0KCSpscGxwUHJldktleQk9IGxweGtleS0+bmV4dDsKCWZyZWUobHB4a2V5LT5rZXluYW1lKTsKCWlmIChscHhrZXktPmNsYXNzKQoJCWZyZWUobHB4a2V5LT5jbGFzcyk7CglpZiAobHB4a2V5LT52YWx1ZXMpCgkJZnJlZShscHhrZXktPnZhbHVlcyk7CglmcmVlKGxweGtleSk7CglGUkVFX0tFWV9QQVRIOwoJVFJBQ0VfKHJlZykoIiAgRG9uZS5cbiIpOwoJcmV0dXJuCUVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZUtleTMyQSBbQURWQVBJMzIuMTMzXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXkgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVc7CiAgICBEV09SRCAgcmV0OwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSk7CiAgICBscHN6U3ViS2V5VyA9IGxwc3pTdWJLZXk/c3RyZHVwQTJXKGxwc3pTdWJLZXkpOk5VTEw7CiAgICByZXQgPSBSZWdEZWxldGVLZXlXKCBoa2V5LCBscHN6U3ViS2V5VyApOwogICAgaWYobHBzelN1YktleVcpIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlS2V5MTYgW1NIRUxMLjRdIFtLRVJORUwuMjE5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5ICkKewogICAgVFJBQ0VfKHJlZykoIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpKTsKICAgIHJldHVybiBSZWdEZWxldGVLZXlBKCBoa2V5LCBscHN6U3ViS2V5ICk7Cn0KCgovKiAKICogRGVsZXRlIHJlZ2lzdHJ5IHZhbHVlCiAqCiAqIENhbGxwYXRoOgogKiBSZWdEZWxldGVWYWx1ZTE2IC0+IFJlZ0RlbGV0ZVZhbHVlMzJBIC0+IFJlZ0RlbGV0ZVZhbHVlMzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlVmFsdWUzMlcgW0FEVkFQSTMyLjEzNl0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICBbSV0KICogICAgbHBzelZhbHVlIFtJXQogKgogKiBSRVRVUk5TCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWVXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelZhbHVlICkKewoJRFdPUkQJCWk7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscHN6VmFsdWUpKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglpZiAobHBzelZhbHVlKSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmICgJbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmCgkJCQkhbHN0cmNtcGlXKGxwa2V5LT52YWx1ZXNbaV0ubmFtZSxscHN6VmFsdWUpCgkJCSkKCQkJCWJyZWFrOwoJfSBlbHNlIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJfQoKICAgIGlmIChpID09IGxwa2V5LT5ucm9mdmFsdWVzKQogICAgICAgIHJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsKCgl2YWwJPSBscGtleS0+dmFsdWVzK2k7CglpZiAodmFsLT5uYW1lKSBmcmVlKHZhbC0+bmFtZSk7CglpZiAodmFsLT5kYXRhKSBmcmVlKHZhbC0+ZGF0YSk7CgltZW1jcHkoCQoJCWxwa2V5LT52YWx1ZXMraSwKCQlscGtleS0+dmFsdWVzK2krMSwKCQlzaXplb2YoS0VZVkFMVUUpKihscGtleS0+bnJvZnZhbHVlcy1pLTEpCgkpOwoJbHBrZXktPnZhbHVlcwk9IChMUEtFWVZBTFVFKXhyZWFsbG9jKAoJCQkJbHBrZXktPnZhbHVlcywKCQkJCShscGtleS0+bnJvZnZhbHVlcy0xKSpzaXplb2YoS0VZVkFMVUUpCgkJCSk7CglscGtleS0+bnJvZnZhbHVlcy0tOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZVZhbHVlMzJBIFtBRFZBUEkzMi4xMzVdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWVBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6VmFsdWUgKQp7CiAgICBMUFdTVFIgbHBzelZhbHVlVzsKICAgIERXT1JEICByZXQ7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZSkpOwogICAgbHBzelZhbHVlVyA9IGxwc3pWYWx1ZT9zdHJkdXBBMlcobHBzelZhbHVlKTpOVUxMOwogICAgcmV0ID0gUmVnRGVsZXRlVmFsdWVXKCBoa2V5LCBscHN6VmFsdWVXICk7CiAgICBpZihscHN6VmFsdWVXKSBmcmVlKGxwc3pWYWx1ZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlVmFsdWUxNiBbS0VSTkVMLjIyMl0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTE2KCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZSApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMpXG4iLCBoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlKSk7CiAgICByZXR1cm4gUmVnRGVsZXRlVmFsdWVBKCBoa2V5LCBscHN6VmFsdWUgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRmx1c2hLZXkgW0tFUk5FTC4yMjddIFtBRFZBUEkzMi4xNDNdCiAqIEltbWVkaWF0ZWx5IHdyaXRlcyBrZXkgdG8gcmVnaXN0cnkuCiAqIE9ubHkgcmV0dXJucyBhZnRlciBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gdG8gZGlzay4KICoKICogRklYTUU6IGRvZXMgaXQgcmVhbGx5IHdhaXQgdW50aWwgZGF0YSBpcyB3cml0dGVuID8KICoKICogSSBndWVzcyB0aGF0IHdlIGNhbiByZW1vdmUgdGhlIFJFR19PUFRJT05fVEFJTlRFRCBmbGFnIGZyb20gZXZlcnkga2V5CiAqIHdyaXR0ZW4gaWYgdGhpcyBmdW5jdGlvbiByZWFsbHkgd29ya3MgKGFuZCBvbmx5IGlmICEpLgogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byB3cml0ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0ZsdXNoS2V5KCBIS0VZIGhrZXkgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRV8ocmVnKSgiKCV4KVxuIiwgaGtleSk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfQkFES0VZOwoKCVNIRUxMX1NhdmVSZWdpc3RyeUJyYW5jaChmaW5kX3Jvb3Rfa2V5KGxwa2V5KSwgVFJVRSk7CiAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKiBGSVhNRTogbHBjY2hYWFhYIC4uLiBpcyB0aGlzIGNvdW50aW5nIGluIFdDSEFSUyBvciBpbiBCWVRFcyA/PyAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlJbmZvS2V5MzJXIFtBRFZBUEkzMi4xNTNdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgICAgICAgIFtJXSBIYW5kbGUgdG8ga2V5IHRvIHF1ZXJ5CiAqICAgIGxwc3pDbGFzcyAgICAgICAgICAgICAgW09dIEJ1ZmZlciBmb3IgY2xhc3Mgc3RyaW5nCiAqICAgIGxwY2NoQ2xhc3MgICAgICAgICAgICAgW09dIFNpemUgb2YgY2xhc3Mgc3RyaW5nIGJ1ZmZlcgogKiAgICBscGR3UmVzZXJ2ZWQgICAgICAgICAgIFtJXSBSZXNlcnZlZAogKiAgICBscGNTdWJLZXlzICAgICAgICAgICAgIFtJXSBCdWZmZXIgZm9yIG51bWJlciBvZiBzdWJrZXlzCiAqICAgIGxwY2NoTWF4U3ViS2V5ICAgICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCBzdWJrZXkgbmFtZSBsZW5ndGgKICogICAgbHBjY2hNYXhDbGFzcyAgICAgICAgICBbT10gQnVmZmVyIGZvciBsb25nZXN0IGNsYXNzIHN0cmluZyBsZW5ndGgKICogICAgbHBjVmFsdWVzICAgICAgICAgICAgICBbT10gQnVmZmVyIGZvciBudW1iZXIgb2YgdmFsdWUgZW50cmllcwogKiAgICBscGNjaE1heFZhbHVlTmFtZSAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3QgdmFsdWUgbmFtZSBsZW5ndGgKICogICAgbHBjY2JNYXhWYWx1ZURhdGEgICAgICBbT10gQnVmZmVyIGZvciBsb25nZXN0IHZhbHVlIGRhdGEgbGVuZ3RoCiAqICAgIGxwY2JTZWN1cml0eURlc2NyaXB0b3IgW09dIEJ1ZmZlciBmb3Igc2VjdXJpdHkgZGVzY3JpcHRvciBsZW5ndGgKICogICAgZnQKICogLSB3aW45NSBhbGxvd3MgbHBzekNsYXNzIHRvIGJlIHZhbGlkIGFuZCBscGNjaENsYXNzIHRvIGJlIE5VTEwgCiAqIC0gd2lubnQgcmV0dXJucyBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiBpZiBscHN6Q2xhc3MgaXMgdmFsaWQgYW5kCiAqICAgbHBjY2hDbGFzcyBpcyBOVUxMCiAqIC0gYm90aCBhbGxvdyBscHN6Q2xhc3MgdG8gYmUgTlVMTCBhbmQgbHBjY2hDbGFzcyB0byBiZSBOVUxMIAogKiAoaXQncyBoYXJkIHRvIHRlc3QgdmFsaWRpdHksIHNvIHRlc3QgIU5VTEwgaW5zdGVhZCkKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeUluZm9LZXlXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6Q2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoQ2xhc3MsIExQRFdPUkQgbHBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY1N1YktleXMsIExQRFdPUkQgbHBjY2hNYXhTdWJrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hNYXhDbGFzcywgTFBEV09SRCBscGNWYWx1ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hNYXhWYWx1ZU5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NiTWF4VmFsdWVEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yLCBGSUxFVElNRSAqZnQgKQp7CglMUEtFWVNUUlVDVAlscGtleSxscHhrZXk7CglpbnQJCW5yb2ZrZXlzLG1heHN1YmtleSxtYXhjbGFzcyxtYXh2bmFtZSxtYXh2ZGF0YTsKCWludAkJaTsKCglUUkFDRV8ocmVnKSgiKCV4LCVwLCVsZCwlcCwlcCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsCgkJaGtleSwgbHBzekNsYXNzLCBscGNjaENsYXNzPypscGNjaENsYXNzOjAsbHBkd1Jlc2VydmVkLAoJCWxwY1N1YktleXMsbHBjY2hNYXhTdWJrZXksbHBjVmFsdWVzLGxwY2NoTWF4VmFsdWVOYW1lLAoJCWxwY2NiTWF4VmFsdWVEYXRhLGxwY2JTZWN1cml0eURlc2NyaXB0b3IsZnQKCSk7CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscGtleSkKCQlyZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CglpZiAobHBzekNsYXNzKSB7CiAgIAkgICAgICAgIGlmIChWRVJTSU9OX0dldFZlcnNpb24oKSA9PSBOVDQwICYmIGxwY2NoQ2xhc3MgPT0gTlVMTCkgewoJCSAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgkJfQoJCS8qIGVpdGhlciBscGNjaENsYXNzIGlzIHZhbGlkIG9yIHRoaXMgaXMgd2luOTUgYW5kIGxwY2NoQ2xhc3MKCQkgICBjb3VsZCBiZSBpbnZhbGlkICovCgkJaWYgKGxwa2V5LT5jbGFzcykgewoJCSAgICAgICAgRFdPUkQgY2xhc3NMZW4gPSBsc3RybGVuVyhscGtleS0+Y2xhc3MpOwoKCQkJaWYgKGxwY2NoQ2xhc3MgJiYgY2xhc3NMZW4rMT4qbHBjY2hDbGFzcykgewoJCQkJKmxwY2NoQ2xhc3M9Y2xhc3NMZW4rMTsKCQkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJCX0KCQkJaWYgKGxwY2NoQ2xhc3MpCgkJCSAgICAqbHBjY2hDbGFzcz1jbGFzc0xlbjsKCQkJbWVtY3B5KGxwc3pDbGFzcyxscGtleS0+Y2xhc3MsIGNsYXNzTGVuKjIgKyAyKTsKCQl9IGVsc2UgewoJCQkqbHBzekNsYXNzCT0gMDsKCQkJaWYgKGxwY2NoQ2xhc3MpCgkJCSAgICAqbHBjY2hDbGFzcwk9IDA7CgkJfQoJfSBlbHNlIHsKCQlpZiAobHBjY2hDbGFzcykKCQkJKmxwY2NoQ2xhc3MJPSBsc3RybGVuVyhscGtleS0+Y2xhc3MpOwoJfQoJbHB4a2V5PWxwa2V5LT5uZXh0c3ViOwoJbnJvZmtleXM9bWF4c3Via2V5PW1heGNsYXNzPW1heHZuYW1lPW1heHZkYXRhPTA7Cgl3aGlsZSAobHB4a2V5KSB7CgkJbnJvZmtleXMrKzsKCQlpZiAobHN0cmxlblcobHB4a2V5LT5rZXluYW1lKT5tYXhzdWJrZXkpCgkJCW1heHN1YmtleT1sc3RybGVuVyhscHhrZXktPmtleW5hbWUpOwoJCWlmIChscHhrZXktPmNsYXNzICYmIGxzdHJsZW5XKGxweGtleS0+Y2xhc3MpPm1heGNsYXNzKQoJCQltYXhjbGFzcz1sc3RybGVuVyhscHhrZXktPmNsYXNzKTsKCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQlMUEtFWVZBTFVFCXZhbD1scGtleS0+dmFsdWVzK2k7CgoJCWlmICh2YWwtPm5hbWUgJiYgbHN0cmxlblcodmFsLT5uYW1lKT5tYXh2bmFtZSkKCQkJbWF4dm5hbWU9bHN0cmxlblcodmFsLT5uYW1lKTsKCQlpZiAodmFsLT5sZW4+bWF4dmRhdGEpCgkJCW1heHZkYXRhPXZhbC0+bGVuOwoJfQoJaWYgKCFtYXhjbGFzcykgbWF4Y2xhc3MJPSAxOwoJaWYgKCFtYXh2bmFtZSkgbWF4dm5hbWUJPSAxOwoJaWYgKGxwY1ZhbHVlcykKCQkqbHBjVmFsdWVzCT0gbHBrZXktPm5yb2Z2YWx1ZXM7CglpZiAobHBjU3ViS2V5cykKCQkqbHBjU3ViS2V5cwk9IG5yb2ZrZXlzOwoJaWYgKGxwY2NoTWF4U3Via2V5KQoJCSpscGNjaE1heFN1YmtleQk9IG1heHN1YmtleTsKCWlmIChscGNjaE1heENsYXNzKQoJCSpscGNjaE1heENsYXNzCT0gbWF4Y2xhc3M7CglpZiAobHBjY2hNYXhWYWx1ZU5hbWUpCgkJKmxwY2NoTWF4VmFsdWVOYW1lPSBtYXh2bmFtZTsKCWlmIChscGNjYk1heFZhbHVlRGF0YSkKCQkqbHBjY2JNYXhWYWx1ZURhdGE9IG1heHZkYXRhOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5SW5mb0tleTMyQSBbQURWQVBJMzIuMTUyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5SW5mb0tleUEoIEhLRVkgaGtleSwgTFBTVFIgbHBzekNsYXNzLCBMUERXT1JEIGxwY2NoQ2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1Jlc2VydmVkLCBMUERXT1JEIGxwY1N1YktleXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hNYXhTdWJrZXksIExQRFdPUkQgbHBjY2hNYXhDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNWYWx1ZXMsIExQRFdPUkQgbHBjY2hNYXhWYWx1ZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2JNYXhWYWx1ZURhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JTZWN1cml0eURlc2NyaXB0b3IsIEZJTEVUSU1FICpmdCApCnsKCUxQV1NUUgkJbHBzekNsYXNzVyA9IE5VTEw7CglEV09SRAkJcmV0OwoKCVRSQUNFXyhyZWcpKCIoJXgsJXAsJWxkLCVwLCVwLCVwLCVwLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LCBscHN6Q2xhc3MsIGxwY2NoQ2xhc3M/KmxwY2NoQ2xhc3M6MCxscGR3UmVzZXJ2ZWQsCgkJbHBjU3ViS2V5cyxscGNjaE1heFN1YmtleSxscGNWYWx1ZXMsbHBjY2hNYXhWYWx1ZU5hbWUsCgkJbHBjY2JNYXhWYWx1ZURhdGEsbHBjYlNlY3VyaXR5RGVzY3JpcHRvcixmdAoJKTsKCWlmIChscHN6Q2xhc3MpIHsKCQlpZiAobHBjY2hDbGFzcykgewoJCSAgICBscHN6Q2xhc3NXICA9IChMUFdTVFIpeG1hbGxvYygoKmxwY2NoQ2xhc3MpICogMik7CgkJfSBlbHNlIGlmIChWRVJTSU9OX0dldFZlcnNpb24oKSA9PSBXSU45NSkgewoJCSAgICAvKiB3aW45NSAgYWxsb3dzIGxwY2NoQ2xhc3MgdG8gYmUgbnVsbCAqLwoJCSAgICAvKiB3ZSBkb24ndCBrbm93IGhvdyBiaWcgbHBzekNsYXNzIGlzLCB3b3VsZCAKCQkgICAgICAgTUFYX1BBVEhOQU1FX0xFTiBiZSB0aGUgY29ycmVjdCBkZWZhdWx0PyAqLwoJCSAgICBscHN6Q2xhc3NXICA9IChMUFdTVFIpeG1hbGxvYyhNQVhfUEFUSE5BTUVfTEVOKjIpOyAKCQl9CgoJfSBlbHNlCgkJbHBzekNsYXNzVyAgPSBOVUxMOwoJcmV0PVJlZ1F1ZXJ5SW5mb0tleVcoCgkJaGtleSwKCQlscHN6Q2xhc3NXLAoJCWxwY2NoQ2xhc3MsCgkJbHBkd1Jlc2VydmVkLAoJCWxwY1N1YktleXMsCgkJbHBjY2hNYXhTdWJrZXksCgkJbHBjY2hNYXhDbGFzcywKCQlscGNWYWx1ZXMsCgkJbHBjY2hNYXhWYWx1ZU5hbWUsCgkJbHBjY2JNYXhWYWx1ZURhdGEsCgkJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCQlmdAoJKTsKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MgJiYgbHBzekNsYXNzKQoJCWxzdHJjcHlXdG9BKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnkzMlcgW0FEVkFQSTMyLjEyOF0KICoKICogUEFSQU1TCiAqICAgIGxwTWFjaGluZU5hbWUgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiByZW1vdGUgY29tcHV0ZXIKICogICAgaEhleSAgICAgICAgICBbSV0gUHJlZGVmaW5lZCByZWdpc3RyeSBoYW5kbGUKICogICAgcGhrUmVzdWx0ICAgICBbSV0gQWRkcmVzcyBvZiBidWZmZXIgZm9yIHJlbW90ZSByZWdpc3RyeSBoYW5kbGUKICovCkxPTkcgV0lOQVBJIFJlZ0Nvbm5lY3RSZWdpc3RyeVcoIExQQ1dTVFIgbHBNYWNoaW5lTmFtZSwgSEtFWSBoS2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEhLRVkgcGhrUmVzdWx0ICkKewogICAgVFJBQ0VfKHJlZykoIiglcywleCwlcCk6IHN0dWJcbiIsZGVidWdzdHJfdyhscE1hY2hpbmVOYW1lKSxoS2V5LHBoa1Jlc3VsdCk7CgogICAgaWYgKCFscE1hY2hpbmVOYW1lIHx8ICEqbHBNYWNoaW5lTmFtZSkgewogICAgICAgIC8qIFVzZSB0aGUgbG9jYWwgbWFjaGluZSBuYW1lICovCiAgICAgICAgcmV0dXJuIFJlZ09wZW5LZXkxNiggaEtleSwgIiIsIHBoa1Jlc3VsdCApOwogICAgfQoKICAgIEZJWE1FXyhyZWcpKCJDYW5ub3QgY29ubmVjdCB0byAlc1xuIixkZWJ1Z3N0cl93KGxwTWFjaGluZU5hbWUpKTsKICAgIHJldHVybiBFUlJPUl9CQURfTkVUUEFUSDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ29ubmVjdFJlZ2lzdHJ5MzJBIFtBRFZBUEkzMi4xMjddCiAqLwpMT05HIFdJTkFQSSBSZWdDb25uZWN0UmVnaXN0cnlBKCBMUENTVFIgbWFjaGluZSwgSEtFWSBoa2V5LCBMUEhLRVkgcmVza2V5ICkKewogICAgRFdPUkQgcmV0OwogICAgTFBXU1RSIG1hY2hpbmVXID0gc3RyZHVwQTJXKG1hY2hpbmUpOwogICAgcmV0ID0gUmVnQ29ubmVjdFJlZ2lzdHJ5VyggbWFjaGluZVcsIGhrZXksIHJlc2tleSApOwogICAgZnJlZShtYWNoaW5lVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdHZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTQ0XQogKiBSZXRyaWV2ZXMgYSBjb3B5IG9mIHNlY3VyaXR5IGRlc2NyaXB0b3IgcHJvdGVjdGluZyB0aGUgcmVnaXN0cnkga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgICAgICAgIFtJXSAgIE9wZW4gaGFuZGxlIG9mIGtleSB0byBzZXQKICogICAgU2VjdXJpdHlJbmZvcm1hdGlvbiAgICBbSV0gICBEZXNjcmlwdG9yIGNvbnRlbnRzCiAqICAgIHBTZWN1cml0eURlc2NyaXB0b3IgICAgW09dICAgQWRkcmVzcyBvZiBkZXNjcmlwdG9yIGZvciBrZXkKICogICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciBbSS9PXSBBZGRyZXNzIG9mIHNpemUgb2YgYnVmZmVyIGFuZCBkZXNjcmlwdGlvbgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KTE9ORyBXSU5BUEkgUmVnR2V0S2V5U2VjdXJpdHkoIEhLRVkgaGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRUNVUklUWV9JTkZPUk1BVElPTiBTZWN1cml0eUluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxTZWN1cml0eUluZm9ybWF0aW9uLHBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yPypscGNiU2VjdXJpdHlEZXNjcmlwdG9yOjApOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIEZJWE1FOiBDaGVjayBmb3IgdmFsaWQgU2VjdXJpdHlJbmZvcm1hdGlvbiB2YWx1ZXMgKi8KCiAgICBpZiAoKmxwY2JTZWN1cml0eURlc2NyaXB0b3IgPCBzaXplb2YoU0VDVVJJVFlfREVTQ1JJUFRPUikpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVI7CgogICAgRklYTUVfKHJlZykoIigleCwlbGQsJXAsJWxkKTogc3R1YlxuIixoa2V5LFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICBwU2VjdXJpdHlEZXNjcmlwdG9yLGxwY2JTZWN1cml0eURlc2NyaXB0b3I/KmxwY2JTZWN1cml0eURlc2NyaXB0b3I6MCk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0xvYWRLZXkzMlcgW0FEVkFQSTMyLj8/P10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5IFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5CiAqICAgIGxwc3pGaWxlICAgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIHJlZ2lzdHJ5IGluZm9ybWF0aW9uCiAqLwpMT05HIFdJTkFQSSBSZWdMb2FkS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQQ1dTVFIgbHBzekZpbGUgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxkZWJ1Z3N0cl93KGxwc3pGaWxlKSk7CgogICAgLyogRG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkgfHwgIWxwc3pGaWxlIHx8ICEqbHBzekZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FXyhyZWcpKCIoJXgsJXMsJXMpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSwKICAgICAgICAgIGRlYnVnc3RyX3cobHBzekZpbGUpKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTG9hZEtleTMyQSBbQURWQVBJMzIuPz8/XQogKi8KTE9ORyBXSU5BUEkgUmVnTG9hZEtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQQ1NUUiBscHN6RmlsZSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwc3pTdWJLZXlXID0gc3RyZHVwQTJXKGxwc3pTdWJLZXkpOwogICAgTFBXU1RSIGxwc3pGaWxlVyA9IHN0cmR1cEEyVyhscHN6RmlsZSk7CiAgICByZXQgPSBSZWdMb2FkS2V5VyggaGtleSwgbHBzelN1YktleVcsIGxwc3pGaWxlVyApOwogICAgaWYobHBzekZpbGVXKSBmcmVlKGxwc3pGaWxlVyk7CiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdOb3RpZnlDaGFuZ2VLZXlWYWx1ZSBbQURWQVBJMzIuPz8/XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgIFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdhdGNoCiAqICAgIGZXYXRjaFN1YlRyZWUgICBbSV0gRmxhZyBmb3Igc3Via2V5IG5vdGlmaWNhdGlvbgogKiAgICBmZHdOb3RpZnlGaWx0ZXIgW0ldIENoYW5nZXMgdG8gYmUgcmVwb3J0ZWQKICogICAgaEV2ZW50ICAgICAgICAgIFtJXSBIYW5kbGUgb2Ygc2lnbmFsZWQgZXZlbnQKICogICAgZkFzeW5jICAgICAgICAgIFtJXSBGbGFnIGZvciBhc3luY2hyb25vdXMgcmVwb3J0aW5nCiAqLwpMT05HIFdJTkFQSSBSZWdOb3RpZnlDaGFuZ2VLZXlWYWx1ZSggSEtFWSBoa2V5LCBCT09MIGZXYXRjaFN1YlRyZWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZmR3Tm90aWZ5RmlsdGVyLCBIQU5ETEUgaEV2ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBmQXN5bmMgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJWksJWxkLCV4LCVpKVxuIixoa2V5LGZXYXRjaFN1YlRyZWUsZmR3Tm90aWZ5RmlsdGVyLAogICAgICAgICAgaEV2ZW50LGZBc3luYyk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUVfKHJlZykoIigleCwlaSwlbGQsJXgsJWkpOiBzdHViXG4iLGhrZXksZldhdGNoU3ViVHJlZSxmZHdOb3RpZnlGaWx0ZXIsCiAgICAgICAgICBoRXZlbnQsZkFzeW5jKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnVW5Mb2FkS2V5MzJXIFtBRFZBUEkzMi4xNzNdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwU3ViS2V5IFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5IHRvIHVubG9hZAogKi8KTE9ORyBXSU5BUEkgUmVnVW5Mb2FkS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwU3ViS2V5ICkKewogICAgRklYTUVfKHJlZykoIigleCwlcyk6IHN0dWJcbiIsaGtleSwgZGVidWdzdHJfdyhscFN1YktleSkpOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1VuTG9hZEtleTMyQSBbQURWQVBJMzIuMTcyXQogKi8KTE9ORyBXSU5BUEkgUmVnVW5Mb2FkS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXkgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscFN1YktleVcgPSBzdHJkdXBBMlcobHBTdWJLZXkpOwogICAgcmV0ID0gUmVnVW5Mb2FkS2V5VyggaGtleSwgbHBTdWJLZXlXICk7CiAgICBpZihscFN1YktleVcpIGZyZWUobHBTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldEtleVNlY3VyaXR5IFtBRFZBUEkzMi4xNjddCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgIFtJXSBPcGVuIGhhbmRsZSBvZiBrZXkgdG8gc2V0CiAqICAgIFNlY3VyaXR5SW5mbyAgW0ldIERlc2NyaXB0b3IgY29udGVudHMKICogICAgcFNlY3VyaXR5RGVzYyBbSV0gQWRkcmVzcyBvZiBkZXNjcmlwdG9yIGZvciBrZXkKICovCkxPTkcgV0lOQVBJIFJlZ1NldEtleVNlY3VyaXR5KCBIS0VZIGhrZXksIFNFQ1VSSVRZX0lORk9STUFUSU9OIFNlY3VyaXR5SW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTRUNVUklUWV9ERVNDUklQVE9SIHBTZWN1cml0eURlc2MgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVsZCwlcClcbiIsaGtleSxTZWN1cml0eUluZm8scFNlY3VyaXR5RGVzYyk7CgogICAgLyogSXQgc2VlbXMgdG8gcGVyZm9ybSB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKChTZWN1cml0eUluZm8gJiBPV05FUl9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgR1JPVVBfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIERBQ0xfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIFNBQ0xfU0VDVVJJVFlfSU5GT1JNQVRJT04pKSB7CiAgICAgICAgLyogUGFyYW0gT0sgKi8KICAgIH0gZWxzZQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBpZiAoIXBTZWN1cml0eURlc2MpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FXyhyZWcpKCI6KCV4LCVsZCwlcCk6IHN0dWJcbiIsaGtleSxTZWN1cml0eUluZm8scFNlY3VyaXR5RGVzYyk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NhdmVLZXkzMlcgW0FEVkFQSTMyLjE2Nl0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICBbSV0gSGFuZGxlIG9mIGtleSB3aGVyZSBzYXZlIGJlZ2lucwogKiAgICBscEZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgdG8gc2F2ZSB0bwogKiAgICBzYSAgICAgW0ldIEFkZHJlc3Mgb2Ygc2VjdXJpdHkgc3RydWN0dXJlCiAqLwpMT05HIFdJTkFQSSBSZWdTYXZlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwRmlsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBzYSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXApXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwRmlsZSksIHNhKTsKCiAgICAvKiBJdCBhcHBlYXJzIHRvIGRvIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoIWxwRmlsZSB8fCAhKmxwRmlsZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUVfKHJlZykoIigleCwlcywlcCk6IHN0dWJcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBGaWxlKSwgc2EpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTYXZlS2V5MzJBIFtBRFZBUEkzMi4xNjVdCiAqLwpMT05HIFdJTkFQSSBSZWdTYXZlS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBGaWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIHNhICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBGaWxlVyA9IHN0cmR1cEEyVyhscEZpbGUpOwogICAgcmV0ID0gUmVnU2F2ZUtleVcoIGhrZXksIGxwRmlsZVcsIHNhICk7CiAgICBmcmVlKGxwRmlsZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleTMyVyBbQURWQVBJMzIuMTY0XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICBbSV0gSGFuZGxlIG9mIGtleSB3aGVyZSByZXN0b3JlIGJlZ2lucwogKiAgICBscEZpbGUgIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGNvbnRhaW5pbmcgc2F2ZWQgdHJlZQogKiAgICBkd0ZsYWdzIFtJXSBPcHRpb25hbCBmbGFncwogKi8KTE9ORyBXSU5BUEkgUmVnUmVzdG9yZUtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscEZpbGUsIERXT1JEIGR3RmxhZ3MgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl93KGxwRmlsZSksZHdGbGFncyk7CgogICAgLyogSXQgc2VlbXMgdG8gZG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBGaWxlIHx8ICEqbHBGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRV8ocmVnKSgiKCV4LCVzLCVsZCk6IHN0dWJcbiIsaGtleSxkZWJ1Z3N0cl93KGxwRmlsZSksZHdGbGFncyk7CgogICAgLyogQ2hlY2sgZm9yIGZpbGUgZXhpc3RlbmNlICovCgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1Jlc3RvcmVLZXkzMkEgW0FEVkFQSTMyLjE2M10KICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscEZpbGUsIERXT1JEIGR3RmxhZ3MgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscEZpbGVXID0gc3RyZHVwQTJXKGxwRmlsZSk7CiAgICByZXQgPSBSZWdSZXN0b3JlS2V5VyggaGtleSwgbHBGaWxlVywgZHdGbGFncyApOwogICAgaWYobHBGaWxlVykgZnJlZShscEZpbGVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1JlcGxhY2VLZXkzMlcgW0FEVkFQSTMyLjE2Ml0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwU3ViS2V5ICBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleQogKiAgICBscE5ld0ZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIGZpbGUgd2l0aCBuZXcgZGF0YQogKiAgICBscE9sZEZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgZm9yIGJhY2t1cCBmaWxlCiAqLwpMT05HIFdJTkFQSSBSZWdSZXBsYWNlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwU3ViS2V5LCBMUENXU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBscE9sZEZpbGUgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVzLCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBTdWJLZXkpLAogICAgICAgICAgZGVidWdzdHJfdyhscE5ld0ZpbGUpLGRlYnVnc3RyX3cobHBPbGRGaWxlKSk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUVfKHJlZykoIigleCwlcywlcywlcyk6IHN0dWJcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBTdWJLZXkpLCAKICAgICAgICAgIGRlYnVnc3RyX3cobHBOZXdGaWxlKSxkZWJ1Z3N0cl93KGxwT2xkRmlsZSkpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5MzJBIFtBRFZBUEkzMi4xNjFdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXBsYWNlS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXksIExQQ1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscE9sZEZpbGUgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscFN1YktleVcgPSBzdHJkdXBBMlcobHBTdWJLZXkpOwogICAgTFBXU1RSIGxwTmV3RmlsZVcgPSBzdHJkdXBBMlcobHBOZXdGaWxlKTsKICAgIExQV1NUUiBscE9sZEZpbGVXID0gc3RyZHVwQTJXKGxwT2xkRmlsZSk7CiAgICByZXQgPSBSZWdSZXBsYWNlS2V5VyggaGtleSwgbHBTdWJLZXlXLCBscE5ld0ZpbGVXLCBscE9sZEZpbGVXICk7CiAgICBmcmVlKGxwT2xkRmlsZVcpOwogICAgZnJlZShscE5ld0ZpbGVXKTsKICAgIGZyZWUobHBTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCg==