LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpZmRlZiBIQVZFX1NZU19FUlJOT19ICiNpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9mY250bC5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS93aW5lc3RyaW5nLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAiaGVhcC5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW52ZXJzaW9uLmgiCgpERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVnKQpERUNMQVJFX0RFQlVHX0NIQU5ORUwoc3RyaW5nKQoKc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCh2b2lkKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCi8qIE5PVEU6IGRvIG5vdCBhcHBlbmQgYSAvLiBsaW51eCcgbWtkaXIoKSBXSUxMIEZBSUwgaWYgeW91IGRvIHRoYXQgKi8KI2RlZmluZSBXSU5FX1BSRUZJWCAgICAgICAgICAgICAgICAgIi8ud2luZSIKI2RlZmluZSBTQVZFX1VTRVJTX0RFRkFVTFQgICAgICAgICAgRVRDRElSIi93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQgIEVUQ0RJUiIvd2luZS5zeXN0ZW1yZWciCgovKiByZWxhdGl2ZSBpbiB+dXNlci8ud2luZS8gOiAqLwojZGVmaW5lIFNBVkVfQ1VSUkVOVF9VU0VSICAgICAgICAgICAidXNlci5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUICAgICJ3aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FICAgICAgICAgICJzeXN0ZW0ucmVnIgoKI2RlZmluZSBLRVlfUkVHSVNUUlkgICAgICAgICAgICAgICAgIlNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeSIKI2RlZmluZSBWQUxfU0FWRVVQREFURUQgICAgICAgICAgICAgIlNhdmVPbmx5VXBkYXRlZEtleXMiCgovKiBvbmUgdmFsdWUgb2YgYSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZVkFMVUUKewogICAgTFBXU1RSICAgbmFtZTsgICAgICAgICAgLyogbmFtZSBvZiB2YWx1ZSAoVU5JQ09ERSkgb3IgTlVMTCBmb3Igd2luMzEgKi8KICAgIERXT1JEICAgIHR5cGU7ICAgICAgICAgIC8qIHR5cGUgb2YgdmFsdWUgKi8KICAgIERXT1JEICAgIGxlbjsgICAgICAgICAgIC8qIGxlbmd0aCBvZiBkYXRhIGluIEJZVEVzICovCiAgICBEV09SRCAgICBsYXN0bW9kaWZpZWQ7ICAvKiB0aW1lIG9mIHNlY29uZHMgc2luY2UgMS4xLjE5NzAgKi8KICAgIExQQllURSAgIGRhdGE7ICAgICAgICAgIC8qIGNvbnRlbnQsIG1heSBiZSBzdHJpbmdzLCBiaW5hcmllcywgZXRjLiAqLwp9IEtFWVZBTFVFLCpMUEtFWVZBTFVFOwoKLyogYSByZWdpc3RyeSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZU1RSVUNUCnsKICAgIExQV1NUUiAgICAgICAgICAgICAgIGtleW5hbWU7ICAgICAgIC8qIG5hbWUgb2YgVEhJUyBrZXkgKFVOSUNPREUpICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBmbGFnczsgICAgICAgICAvKiBmbGFncy4gKi8KICAgIExQV1NUUiAgICAgICAgICAgICAgIGNsYXNzOwogICAgLyogdmFsdWVzICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBucm9mdmFsdWVzOyAgICAvKiBuciBvZiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIExQS0VZVkFMVUUgICAgICAgICAgIHZhbHVlczsgICAgICAgIC8qIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgLyoga2V5IG1hbmFnZW1lbnQgcG9pbnRlcnMgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHQ7ICAgICAgICAgIC8qIG5leHQga2V5IG9uIHNhbWUgaGllcmFyY2h5ICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0c3ViOyAgICAgICAvKiBrZXlzIHRoYXQgaGFuZyBiZWxvdyBUSElTIGtleSAqLwp9IEtFWVNUUlVDVCwgKkxQS0VZU1RSVUNUOwoKCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jbGFzc2VzX3Jvb3Q9TlVMTDsJLyogd2luZG93cyAzLjEgZ2xvYmFsIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF91c2VyPU5VTEw7CS8qIHVzZXIgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9sb2NhbF9tYWNoaW5lPU5VTEw7LyogbWFjaGluZSBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3VzZXJzPU5VTEw7CS8qIGFsbCB1c2Vycz8gKi8KCi8qIGR5bmFtaWMsIG5vdCBzYXZlZCAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfcGVyZm9ybWFuY2VfZGF0YT1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF9jb25maWc9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2R5bl9kYXRhPU5VTEw7CgovKiB3aGF0IHZhbHVldHlwZXMgZG8gd2UgbmVlZCB0byBjb252ZXJ0PyAqLwojZGVmaW5lIFVOSUNPTlZNQVNLCSgoMTw8UkVHX1NaKXwoMTw8UkVHX01VTFRJX1NaKXwoMTw8UkVHX0VYUEFORF9TWikpCgoKc3RhdGljIHN0cnVjdCBvcGVuaGFuZGxlIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCVJFR1NBTQkJYWNjZXNzbWFzazsKfSAgKm9wZW5oYW5kbGVzPU5VTEw7CnN0YXRpYyBpbnQJbnJvZm9wZW5oYW5kbGVzPTA7Ci8qIFN0YXJ0cyBhZnRlciAxIGJlY2F1c2UgMCwxIGFyZSByZXNlcnZlZCBmb3IgV2luMTYgKi8KLyogTm90ZTogU2hvdWxkIGFsd2F5cyBiZSBldmVuLCBhcyBXaW45NSBBRFZBUEkzMi5ETEwgcmVzZXJ2ZXMgb2RkCiAgICAgICAgIEhLRVlzIGZvciByZW1vdGUgcmVnaXN0cnkgYWNjZXNzICovCnN0YXRpYyBpbnQJY3VycmVudGhhbmRsZT0yOwoKCi8qCiAqIFFVRVNUSU9OCiAqICAgQXJlIHRoZXNlIGRvaW5nIHRoZSBzYW1lIGFzIEhFQVBfc3RyZHVwQXRvVyBhbmQgSEVBUF9zdHJkdXBXdG9BPwogKiAgIElmIHNvLCBjYW4gd2UgcmVtb3ZlIHRoZW0/CiAqIEFOU1dFUgogKiAgIE5vLCB0aGUgbWVtb3J5IGhhbmRsaW5nIGZ1bmN0aW9ucyBhcmUgY2FsbGVkIHZlcnkgb2Z0ZW4gaW4gaGVyZSwgCiAqICAganVzdCByZXBsYWNpbmcgdGhlbSBieSBIZWFwQWxsb2MoU3lzdGVtSGVhcCwuLi4pIG1ha2VzIHJlZ2lzdHJ5CiAqICAgbG9hZGluZyAxMDAgdGltZXMgc2xvd2VyLiAtTU0KICovCnN0YXRpYyBMUFdTVFIgc3RyZHVwQTJXKExQQ1NUUiBzcmMpCnsKICAgIGlmKHNyYykgewoJTFBXU1RSIGRlc3Q9eG1hbGxvYygyKnN0cmxlbihzcmMpKzIpOwoJbHN0cmNweUF0b1coZGVzdCxzcmMpOwoJcmV0dXJuIGRlc3Q7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIExQV1NUUiBzdHJkdXBXKExQQ1dTVFIgYSkgewoJTFBXU1RSCWI7CglpbnQJbGVuOwoKICAgIGlmKGEpIHsKCWxlbj1zaXplb2YoV0NIQVIpKihsc3RybGVuVyhhKSsxKTsKCWI9KExQV1NUUil4bWFsbG9jKGxlbik7CgltZW1jcHkoYixhLGxlbik7CglyZXR1cm4gYjsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgpMUFdTVFIgc3RyY3Z0QTJXKExQQ1NUUiBzcmMsIGludCBuY2hhcnMpCgp7CiAgIExQV1NUUiBkZXN0ID0geG1hbGxvYyAoMiAqIG5jaGFycyArIDIpOwoKICAgbHN0cmNweW5BdG9XKGRlc3Qsc3JjLG5jaGFycysxKTsKICAgZGVzdFtuY2hhcnNdID0gMDsKICAgcmV0dXJuIGRlc3Q7Cn0KLyoKICogd2UgbmVlZCB0byBjb252ZXJ0IEEgdG8gVyB3aXRoICdcMCcgaW4gc3RyaW5ncyAoTVVMVElfU1opIAogKi8KCnN0YXRpYyBMUFdTVFIgIGxtZW1jcHluQXRvVyggTFBXU1RSIGRzdCwgTFBDU1RSIHNyYywgSU5UIG4gKQp7CUxQV1NUUiBwID0gZHN0OwoKCVRSQUNFXyhyZWcpKCJcIiVzXCIgJWlcbiIsc3JjLCBuKTsKCgl3aGlsZSAobi0tID4gMCkgKnArKyA9IChXQ0hBUikodW5zaWduZWQgY2hhcikqc3JjKys7CgoJcmV0dXJuIGRzdDsKfQpzdGF0aWMgTFBTVFIgbG1lbWNweW5XdG9BKCBMUFNUUiBkc3QsIExQQ1dTVFIgc3JjLCBJTlQgbiApCnsJTFBTVFIgcCA9IGRzdDsKCglUUkFDRV8oc3RyaW5nKSgiTFwiJXNcIiAlaVxuIixkZWJ1Z3N0cl93KHNyYyksIG4pOwoKCXdoaWxlIChuLS0gPiAwKSAqcCsrID0gKENIQVIpKnNyYysrOwoKCXJldHVybiBkc3Q7Cn0KCnN0YXRpYyB2b2lkIGRlYnVnX3ByaW50X3ZhbHVlIChMUEJZVEUgbHBiRGF0YSwgTFBLRVlWQUxVRSBrZXkpCnsKICBpZiAoVFJBQ0VfT04ocmVnKSAmJiBscGJEYXRhKSAKICB7IAogICAgc3dpdGNoKGtleS0+dHlwZSkKICAgIHsgCiAgICAgIGNhc2UgUkVHX0VYUEFORF9TWjoKICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgVFJBQ0VfKHJlZykoIiBWYWx1ZSAlcywgRGF0YShzeik9JXNcbiIsIAogICAgICAgICAgZGVidWdzdHJfdyhrZXktPm5hbWUpLCAKICAgICAgICAgIGRlYnVnc3RyX3coKExQQ1dTVFIpbHBiRGF0YSkpOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgVFJBQ0VfKHJlZykoIiBWYWx1ZSAlcywgRGF0YShkd29yZCk9MHglMDhseFxuIiwKICAgICAgICAgIGRlYnVnc3RyX3coa2V5LT5uYW1lKSwgCiAgICAgICAgICAoRFdPUkQpKmxwYkRhdGEpOwogICAgICAgIGJyZWFrOwogICAgCiAgICAgIGNhc2UgUkVHX01VTFRJX1NaOgogICAgICB7IAogICAgICAgIGludCBpOwogICAgICAgIExQQ1dTVFIgcHRyID0gKExQQ1dTVFIpbHBiRGF0YTsKICAgICAgICBmb3IgKGk9MDtwdHJbMF07aSsrKQogICAgICAgIHsgCiAgICAgICAgICBUUkFDRV8ocmVnKSgiIFZhbHVlICVzLCBNVUxUSV9TWiglaT0lcylcbiIsIAogICAgICAgICAgICBkZWJ1Z3N0cl93KGtleS0+bmFtZSksIAogICAgICAgICAgICBpLCAKICAgICAgICAgICAgZGVidWdzdHJfdyhwdHIpKTsKCiAgICAgICAgICBwdHIgKz0gbHN0cmxlblcocHRyKSsxOwogICAgICAgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgICAgIGRlZmF1bHQ6CiAgICAgIHsgCiAgICAgICAgY2hhciBzelRlbXBbMTAwXTsgICAgICAvKiAzKjMyICsgMyArIDEgKi8KICAgICAgICBpbnQgaTsKICAgICAgICBmb3IgKCBpID0gMDsgaSA8IGtleS0+bGVuIDsgaSsrKSAgICAgIAogICAgICAgIHsgCiAgICAgICAgICBzcHJpbnRmICgmKHN6VGVtcFtpKjNdKSwiJTAyeCAiLCBscGJEYXRhW2ldKTsKICAgICAgICAgIGlmIChpPj0zMSkKICAgICAgICAgIHsgCiAgICAgICAgICAgIHNwcmludGYgKCYoc3pUZW1wW2kqMyszXSksIi4uLiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgVFJBQ0VfKHJlZykoIiBWYWx1ZSAlcywgRGF0YShyYXcpPSglcylcbiIsIAogICAgICAgICAgZGVidWdzdHJfdyhrZXktPm5hbWUpLCAKICAgICAgICAgIHN6VGVtcCk7ICAgICAgICAgICAgICAgICAgCiAgICAgIH0KICAgIH0gLyogc3dpdGNoICovCiAgfSAvKiBpZiAqLwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBpc19zdGFuZGFyZF9oa2V5IFtJbnRlcm5hbF0KICogRGV0ZXJtaW5lcyBpZiBhIGhrZXkgaXMgYSBzdGFuZGFyZCBrZXkKICovCnN0YXRpYyBCT09MIGlzX3N0YW5kYXJkX2hrZXkoIEhLRVkgaGtleSApCnsKICAgIHN3aXRjaChoa2V5KSB7CiAgICAgICAgY2FzZSAweDAwMDAwMDAwOgogICAgICAgIGNhc2UgMHgwMDAwMDAwMToKICAgICAgICBjYXNlIEhLRVlfQ0xBU1NFU19ST09UOgogICAgICAgIGNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKICAgICAgICBjYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgogICAgICAgIGNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgogICAgICAgIGNhc2UgSEtFWV9VU0VSUzoKICAgICAgICBjYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKICAgICAgICBjYXNlIEhLRVlfRFlOX0RBVEE6CiAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBhZGRfaGFuZGxlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIGFkZF9oYW5kbGUoIEhLRVkgaGtleSwgTFBLRVlTVFJVQ1QgbHBrZXksIFJFR1NBTSBhY2Nlc3NtYXNrICkKewogICAgaW50IGk7CgogICAgVFJBQ0VfKHJlZykoIigweCV4LCVwLDB4JWx4KVxuIixoa2V5LGxwa2V5LGFjY2Vzc21hc2spOwogICAgLyogQ2hlY2sgZm9yIGR1cGxpY2F0ZXMgKi8KICAgIGZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykgewogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5scGtleT09bHBrZXkpIHsKICAgICAgICAgICAgLyogVGhpcyBpcyBub3QgcmVhbGx5IGFuIGVycm9yIC0gdGhlIHVzZXIgaXMgYWxsb3dlZCB0byBjcmVhdGUKICAgICAgICAgICAgICAgdHdvIChvciBtb3JlKSBoYW5kbGVzIHRvIHRoZSBzYW1lIGtleSAqLwogICAgICAgICAgICAvKldBUk4ocmVnLCAiQWRkaW5nIGtleSAlcCB0d2ljZVxuIixscGtleSk7Ki8KICAgICAgICB9CiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpIHsKICAgICAgICAgICAgV0FSTl8ocmVnKSgiQWRkaW5nIGhhbmRsZSAleCB0d2ljZVxuIixoa2V5KTsKICAgICAgICB9CiAgICB9CiAgICBvcGVuaGFuZGxlcz14cmVhbGxvYyggb3BlbmhhbmRsZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcysxKSk7CgogICAgb3BlbmhhbmRsZXNbaV0ubHBrZXkgPSBscGtleTsKICAgIG9wZW5oYW5kbGVzW2ldLmhrZXkgPSBoa2V5OwogICAgb3BlbmhhbmRsZXNbaV0uYWNjZXNzbWFzayA9IGFjY2Vzc21hc2s7CiAgICBucm9mb3BlbmhhbmRsZXMrKzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZ2V0X2hhbmRsZSBbSW50ZXJuYWxdCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogUG9pbnRlciB0byBrZXkKICogICAgRmFpbHVyZTogTlVMTAogKi8Kc3RhdGljIExQS0VZU1RSVUNUIGdldF9oYW5kbGUoIEhLRVkgaGtleSApCnsKICAgIGludCBpOwoKICAgIGZvciAoaT0wOyBpPG5yb2ZvcGVuaGFuZGxlczsgaSsrKQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5ID09IGhrZXkpCiAgICAgICAgICAgIHJldHVybiBvcGVuaGFuZGxlc1tpXS5scGtleTsKICAgIFdBUk5fKHJlZykoIkNvdWxkIG5vdCBmaW5kIGhhbmRsZSAweCV4XG4iLGhrZXkpOwogICAgcmV0dXJuIE5VTEw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIHJlbW92ZV9oYW5kbGUgW0ludGVybmFsXQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byByZW1vdmUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVSUk9SX0lOVkFMSURfSEFORExFCiAqLwpzdGF0aWMgRFdPUkQgcmVtb3ZlX2hhbmRsZSggSEtFWSBoa2V5ICkKewogICAgaW50IGk7CgogICAgZm9yIChpPTA7aTxucm9mb3BlbmhhbmRsZXM7aSsrKQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KQogICAgICAgICAgICBicmVhazsKCiAgICBpZiAoaSA9PSBucm9mb3BlbmhhbmRsZXMpIHsKICAgICAgICBXQVJOXyhyZWcpKCJDb3VsZCBub3QgZmluZCBoYW5kbGUgMHgleFxuIixoa2V5KTsKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CiAgICB9CgogICAgbWVtY3B5KCBvcGVuaGFuZGxlcytpLAogICAgICAgICAgICBvcGVuaGFuZGxlcytpKzEsCiAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy1pLTEpCiAgICApOwogICAgb3BlbmhhbmRsZXM9eHJlYWxsb2Mob3BlbmhhbmRsZXMsc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLTEpKTsKICAgIG5yb2ZvcGVuaGFuZGxlcy0tOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogbG9va3VwX2hrZXkgW0ludGVybmFsXQogKiAKICogSnVzdCBhcyB0aGUgbmFtZSBzYXlzLiBDcmVhdGVzIHRoZSByb290IGtleXMgb24gZGVtYW5kLCBzbyB3ZSBjYW4gY2FsbCB0aGUKICogUmVnKiBmdW5jdGlvbnMgYXQgYW55IHRpbWUuCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogUG9pbnRlciB0byBrZXkgc3RydWN0dXJlCiAqICAgIEZhaWx1cmU6IE5VTEwKICovCiNkZWZpbmUgQUREX1JPT1RfS0VZKHh4KSBcCgl4eCA9IChMUEtFWVNUUlVDVCl4bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTtcCgltZW1zZXQoeHgsJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7XAoJeHgtPmtleW5hbWU9IHN0cmR1cEEyVygiPHNob3VsZF9ub3RfYXBwZWFyX2FueXdoZXJlPiIpOwoKc3RhdGljIExQS0VZU1RSVUNUIGxvb2t1cF9oa2V5KCBIS0VZIGhrZXkgKQp7CiAgc3dpdGNoIChoa2V5KSB7CiAgLyogMCBhbmQgMSBhcmUgdmFsaWQgcm9vdGtleXMgaW4gd2luMTYgc2hlbGwuZGxsIGFuZCBhcmUgdXNlZCBieQogICAqIHNvbWUgcHJvZ3JhbXMuIERvIG5vdCByZW1vdmUgdGhvc2UgY2FzZXMuIC1NTQogICAqLwogCWNhc2UgMHgwMDAwMDAwMDoKICBjYXNlIDB4MDAwMDAwMDE6CiAgY2FzZSBIS0VZX0NMQVNTRVNfUk9PVDogCiAgewogICAgaWYgKCFrZXlfY2xhc3Nlc19yb290KSAKICAgIHsKICAgICAgSEtFWQljbF9yX2hrZXk7CgogICAgICAvKiBjYWxscyBsb29rdXBfaGtleSByZWN1cnNpdmVseSwgVFdJQ0UgKi8KICAgICAgaWYgKCBSZWdDcmVhdGVLZXkxNigKICAgICAgICAgICAgSEtFWV9MT0NBTF9NQUNISU5FLAogICAgICAgICAgICAiU09GVFdBUkVcXENsYXNzZXMiLAogICAgICAgICAgICAmY2xfcl9oa2V5KSAhPSBFUlJPUl9TVUNDRVNTKSAKICAgICAgewogICAgICAgIEVSUl8ocmVnKSgiQ291bGQgbm90IGNyZWF0ZSBIS0xNXFxTT0ZUV0FSRVxcQ2xhc3Nlcy4gVGhpcyBpcyBpbXBvc3NpYmxlLlxuIik7CiAgICAgICAgZXhpdCgxKTsKICAgICAgfQoKICAgICAga2V5X2NsYXNzZXNfcm9vdCA9IGxvb2t1cF9oa2V5KGNsX3JfaGtleSk7CiAgICB9CiAgICByZXR1cm4ga2V5X2NsYXNzZXNfcm9vdDsKICB9CgogIGNhc2UgSEtFWV9DVVJSRU5UX1VTRVI6CiAgICBpZiAoIWtleV9jdXJyZW50X3VzZXIpIHsKICAgICAgQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X3VzZXIpOwogICAgfQogICAgcmV0dXJuIGtleV9jdXJyZW50X3VzZXI7CgogIGNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgogICAgaWYgKCFrZXlfbG9jYWxfbWFjaGluZSkgewogICAgICBBRERfUk9PVF9LRVkoa2V5X2xvY2FsX21hY2hpbmUpOwogICAgICBSRUdJU1RSWV9Jbml0KCk7CiAgICB9CiAgICByZXR1cm4ga2V5X2xvY2FsX21hY2hpbmU7CgogIGNhc2UgSEtFWV9VU0VSUzoKICAgIGlmICgha2V5X3VzZXJzKSB7CiAgICAgIEFERF9ST09UX0tFWShrZXlfdXNlcnMpOwogICAgfQogICAgcmV0dXJuIGtleV91c2VyczsKCiAgY2FzZSBIS0VZX1BFUkZPUk1BTkNFX0RBVEE6CiAgICBpZiAoIWtleV9wZXJmb3JtYW5jZV9kYXRhKSB7CiAgICAgIEFERF9ST09UX0tFWShrZXlfcGVyZm9ybWFuY2VfZGF0YSk7CiAgICB9CiAgICByZXR1cm4ga2V5X3BlcmZvcm1hbmNlX2RhdGE7CgogIGNhc2UgSEtFWV9EWU5fREFUQToKICAgIGlmICgha2V5X2R5bl9kYXRhKSB7CiAgICAgIEFERF9ST09UX0tFWShrZXlfZHluX2RhdGEpOwogICAgfQogICAgcmV0dXJuIGtleV9keW5fZGF0YTsKCiAgY2FzZSBIS0VZX0NVUlJFTlRfQ09ORklHOgogICAgaWYgKCFrZXlfY3VycmVudF9jb25maWcpIHsKICAgICAgQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X2NvbmZpZyk7CiAgICB9CiAgICByZXR1cm4ga2V5X2N1cnJlbnRfY29uZmlnOwoKICBkZWZhdWx0OgogICAgcmV0dXJuIGdldF9oYW5kbGUoaGtleSk7CgogIH0KICAvKk5PVFJFQUNIRUQqLwp9CgoKLyoKICogcmVjdXJzaXZlbHkgc2VhcmNoZXMgZm9yIGxwa2V5X3RvX2ZpbmQgaW4gdGhlIHJvb3Qga2V5IGJyYW5jaAogKiBnaXZlbiBpbiBscGN1cnJrZXkuCiAqLwpzdGF0aWMgaW50IHN1YmtleV9mb3VuZChMUEtFWVNUUlVDVCBscGN1cnJrZXksIExQS0VZU1RSVUNUIGxwa2V5X3RvX2ZpbmQpCnsKCXdoaWxlIChscGN1cnJrZXkpCgl7CgkJaWYgKGxwY3VycmtleSA9PSBscGtleV90b19maW5kKQoJCQlyZXR1cm4gMTsKCQlpZiAoc3Via2V5X2ZvdW5kKGxwY3VycmtleS0+bmV4dHN1YiwgbHBrZXlfdG9fZmluZCkpCgkJCXJldHVybiAxOwoKCQlscGN1cnJrZXkgPSBscGN1cnJrZXktPm5leHQ7Cgl9CgoJVFJBQ0VfKHJlZykoIk5vIGtleSBmb3VuZCBpbiB0aGlzIHJvb3Qga2V5IGJyYW5jaFxuIik7CglyZXR1cm4gMDsKfQoKCi8qCiAqIGZpbmRzIHRoZSBjb3JyZXNwb25kaW5nIHJvb3Qga2V5IGZvciBhIHN1YiBrZXksIGkuZS4gZS5nLiBIS0VZX0NMQVNTRVNfUk9PVC4KICovIApzdGF0aWMgSEtFWSBmaW5kX3Jvb3Rfa2V5KExQS0VZU1RSVUNUIGxwa2V5KQp7Cgl0eXBlZGVmIHN0cnVjdCB0YWdST09UX0tFWVMgewogICAgCQlLRVlTVFJVQ1QgKmxwa2V5OwogICAgCQlIS0VZIGhrZXk7Cgl9IFJPT1RfS0VZUzsKCVJPT1RfS0VZUyByb290X2tleXNbNF07CglpbnQgaTsKCglyb290X2tleXNbMF0ubHBrZXkgPSBrZXlfY2xhc3Nlc19yb290OwoJcm9vdF9rZXlzWzBdLmhrZXkgPSBIS0VZX0NMQVNTRVNfUk9PVDsKCXJvb3Rfa2V5c1sxXS5scGtleSA9IGtleV9jdXJyZW50X3VzZXI7Cglyb290X2tleXNbMV0uaGtleSA9IEhLRVlfQ1VSUkVOVF9VU0VSOwoJcm9vdF9rZXlzWzJdLmxwa2V5ID0ga2V5X2xvY2FsX21hY2hpbmU7Cglyb290X2tleXNbMl0uaGtleSA9IEhLRVlfTE9DQUxfTUFDSElORTsKCXJvb3Rfa2V5c1szXS5scGtleSA9IGtleV91c2VyczsKCXJvb3Rfa2V5c1szXS5oa2V5ID0gSEtFWV9VU0VSUzsKCglmb3IgKGk9MDsgaTw0O2krKykKCXsKCQlpZiAoc3Via2V5X2ZvdW5kKHJvb3Rfa2V5c1tpXS5scGtleSwgbHBrZXkpKQoJCQkJcmV0dXJuIHJvb3Rfa2V5c1tpXS5oa2V5OwkJCQkKCX0KCUVSUl8ocmVnKSgiRGlkbid0IGZpbmQgY29ycmVzcG9uZGluZyByb290IGtleSBlbnRyeSAhIFNlYXJjaCBzdHJhdGVneSBicm9rZW4gPz9cbiIpOwoJcmV0dXJuIDA7CiN1bmRlZiBST09UX0tFWVMKfQojdW5kZWYgQUREX1JPT1RfS0VZCi8qIHNvIHdlIGRvbid0IGFjY2lkZW50bHkgYWNjZXNzIHRoZW0gLi4uICovCiNkZWZpbmUga2V5X2N1cnJlbnRfY29uZmlnIE5VTEwgTlVMTAojZGVmaW5lIGtleV9jdXJyZW50X3VzZXIgTlVMTCBOVUxMCiNkZWZpbmUga2V5X3VzZXJzIE5VTEwgTlVMTAojZGVmaW5lIGtleV9sb2NhbF9tYWNoaW5lIE5VTEwgTlVMTAojZGVmaW5lIGtleV9jbGFzc2VzX3Jvb3QgTlVMTCBOVUxMCiNkZWZpbmUga2V5X2R5bl9kYXRhIE5VTEwgTlVMTAojZGVmaW5lIGtleV9wZXJmb3JtYW5jZV9kYXRhIE5VTEwgTlVMTAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBzcGxpdF9rZXlwYXRoIFtJbnRlcm5hbF0KICogc3BsaXRzIHRoZSB1bmljb2RlIHN0cmluZyAnd3AnIGludG8gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KICogdGhlIGFycmF5IGlzIGFsbG9jYXRlZCBieSB0aGlzIGZ1bmN0aW9uLiAKICogRnJlZSB0aGUgYXJyYXkgdXNpbmcgRlJFRV9LRVlfUEFUSAogKgogKiBQQVJBTVMKICogICAgd3AgIFtJXSBTdHJpbmcgdG8gc3BsaXQgdXAKICogICAgd3B2IFtPXSBBcnJheSBvZiBwb2ludGVycyB0byBzdHJpbmdzCiAqICAgIHdwYyBbT10gTnVtYmVyIG9mIGNvbXBvbmVudHMKICovCnN0YXRpYyB2b2lkIHNwbGl0X2tleXBhdGgoIExQQ1dTVFIgd3AsIExQV1NUUiAqKndwdiwgaW50ICp3cGMpCnsKICAgIGludAlpLGosbGVuOwogICAgTFBXU1RSIHdzOwoKICAgIFRSQUNFXyhyZWcpKCIoJXMsJXAsJXApXG4iLGRlYnVnc3RyX3cod3ApLHdwdix3cGMpOwoKICAgIHdzCT0gSEVBUF9zdHJkdXBXKCBTeXN0ZW1IZWFwLCAwLCB3cCApOwoKICAgIC8qIFdlIGtub3cgd2UgaGF2ZSBhdCBsZWFzdCBvbmUgc3Vic3RyaW5nICovCiAgICAqd3BjID0gMTsKCiAgICAvKiBSZXBsYWNlIGVhY2ggYmFja3NsYXNoIHdpdGggTlVMTCwgYW5kIGluY3JlbWVudCB0aGUgY291bnQgKi8KICAgIGZvciAoaT0wO3dzW2ldO2krKykgewogICAgICAgIGlmICh3c1tpXT09J1xcJykgewogICAgICAgICAgICB3c1tpXT0wOwogICAgICAgICAgICAoKndwYykrKzsKICAgICAgICB9CiAgICB9CgogICAgbGVuID0gaTsKCiAgICAvKiBBbGxvY2F0ZSB0aGUgc3BhY2UgZm9yIHRoZSBhcnJheSBvZiBwb2ludGVycywgbGVhdmluZyByb29tIGZvciB0aGUKICAgICAgIE5VTEwgYXQgdGhlIGVuZCAqLwogICAgKndwdiA9IChMUFdTVFIqKUhlYXBBbGxvYyggU3lzdGVtSGVhcCwgMCwgc2l6ZW9mKExQV1NUUikqKCp3cGMrMikpOwogICAgKCp3cHYpWzBdPSB3czsKCiAgICAvKiBBc3NpZ24gZWFjaCBwb2ludGVyIHRvIHRoZSBhcHByb3ByaWF0ZSBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZyAqLwogICAgaiA9IDE7CiAgICBmb3IgKGk9MTtpPGxlbjtpKyspCiAgICAgICAgaWYgKHdzW2ktMV09PTApIHsKICAgICAgICAgICAgKCp3cHYpW2orK109d3MraTsKICAgICAgICAgICAgLyogVFJBQ0UocmVnLCAiIFN1Yml0ZW0gJWQgPSAlc1xuIixqLTEsZGVidWdzdHJfdygoKndwdilbai0xXSkpOyAqLwogICAgICAgIH0KCiAgICAoKndwdilbal09TlVMTDsKfQojZGVmaW5lIEZSRUVfS0VZX1BBVEggSGVhcEZyZWUoU3lzdGVtSGVhcCwwLHdwc1swXSk7SGVhcEZyZWUoU3lzdGVtSGVhcCwwLHdwcyk7CgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJFR0lTVFJZX0luaXQgW0ludGVybmFsXQogKiBSZWdpc3RyeSBpbml0aWFsaXNhdGlvbiwgYWxsb2NhdGVzIHNvbWUgZGVmYXVsdCBrZXlzLiAKICovCnN0YXRpYyB2b2lkIFJFR0lTVFJZX0luaXQodm9pZCkgewoJSEtFWQloa2V5OwoJY2hhcglidWZbMjAwXTsKCglUUkFDRV8ocmVnKSgiKHZvaWQpXG4iKTsKCglSZWdDcmVhdGVLZXkxNihIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIkhBUkRXQVJFXFxERVNDUklQVElPTlxcU3lzdGVtIiwmaGtleSk7CglSZWdTZXRWYWx1ZUV4QShoa2V5LCJJZGVudGlmaWVyIiwwLFJFR19TWiwiU3lzdGVtVHlwZSBXSU5FIixzdHJsZW4oIlN5c3RlbVR5cGUgV0lORSIpKTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKCS8qIFxcU09GVFdBUkVcXE1pY3Jvc29mdFxcV2luZG93IE5UXFxDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50QnVpbGROdW1iZXIKCSAqCQkJCQkJQ3VycmVudFR5cGUKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE93bmVyCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPcmdhbml6YXRpb24KCSAqCgkgKi8KCS8qIFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTTk1QXFxQYXJhbWV0ZXJzXFxSRkMxMTU2QWdlbnQKCSAqIAkJCQkJc3RyaW5nCVN5c0NvbnRhY3QKCSAqIAkJCQkJc3RyaW5nCVN5c0xvY2F0aW9uCgkgKiAJCQkJCQlTeXNTZXJ2aWNlcwoJICovCQkJCQkJCglpZiAoLTEhPWdldGhvc3RuYW1lKGJ1ZiwyMDApKSB7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxDb250cm9sXFxDb21wdXRlck5hbWVcXENvbXB1dGVyTmFtZSIsJmhrZXkpOwoJCVJlZ1NldFZhbHVlRXgxNihoa2V5LCJDb21wdXRlck5hbWUiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSsxKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKiogU0FWRSBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBSRUdJU1RSWV9TQVZFX1ZFUlNJT04JMHgwMDAwMDAwMQoKLyogUmVnaXN0cnkgc2F2ZWZvcm1hdDoKICogSWYgeW91IGNoYW5nZSBpdCwgaW5jcmVhc2UgYWJvdmUgbnVtYmVyIGJ5IDEsIHdoaWNoIHdpbGwgZmx1c2gKICogb2xkIHJlZ2lzdHJ5IGRhdGFiYXNlIGZpbGVzLgogKiAKICogR2xvYmFsOgogKiAJIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIKICogCXN1YmtleXMuLi4uCiAqIFN1YmtleXM6CiAqIAlrZXluYW1lCiAqCQl2YWx1ZW5hbWU9bGFzdG1vZGlmaWVkLHR5cGUsZGF0YQogKgkJLi4uCiAqCQlzdWJrZXlzCiAqCS4uLgogKiBrZXluYW1lLHZhbHVlbmFtZSxzdHJpbmdkYXRhOgogKgl0aGUgdXN1YWwgYXNjaWkgY2hhcmFjdGVycyBmcm9tIDB4MDAtMHhmZiAod2VsbCwgbm90IDB4MDApCiAqCWFuZCBcdVhYWFggYXMgVU5JQ09ERSB2YWx1ZSBYWFhYIHdpdGggWFhYWD4weGZmCiAqCSggIj1cXFx0IiBlc2NhcGVkIGluIFx1WFhYWCBmb3JtLikKICogdHlwZSxsYXN0bW9kaWZpZWQ6IAogKglpbnQKICogCiAqIEZJWE1FOiBkb2Vzbid0IHNhdmUgJ2NsYXNzJyAod2hhdCBkb2VzIGl0IG1lYW4gYW55d2F5PyksIG5vciBmbGFncy4KICoKICogW0hLRVlfQ1VSUkVOVF9VU0VSXFxTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnldCiAqIFNhdmVPbmx5VXBkYXRlZEtleXM9eWVzCiAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZV9jaGVja190YWludGVkIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3NhdmVfY2hlY2tfdGFpbnRlZCggTFBLRVlTVFJVQ1QgbHBrZXkgKQp7CglpbnQJCXRhaW50ZWQ7CgoJaWYgKCFscGtleSkKCQlyZXR1cm4gMDsKCWlmIChscGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1RBSU5URUQpCgkJdGFpbnRlZCA9IDE7CgllbHNlCgkJdGFpbnRlZCA9IDA7Cgl3aGlsZSAobHBrZXkpIHsKCQlpZiAoX3NhdmVfY2hlY2tfdGFpbnRlZChscGtleS0+bmV4dHN1YikpIHsKCQkJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCQkJdGFpbnRlZCA9IDE7CgkJfQoJCWxwa2V5CT0gbHBrZXktPm5leHQ7Cgl9CglyZXR1cm4gdGFpbnRlZDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZV9VU1RSSU5HIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9zYXZlX1VTVFJJTkcoIEZJTEUgKkYsIExQV1NUUiB3c3RyLCBpbnQgZXNjYXBlZXEgKQp7CglMUFdTVFIJczsKCWludAlkb2VzY2FwZTsKCglpZiAod3N0cj09TlVMTCkKCQlyZXR1cm47CglzPXdzdHI7Cgl3aGlsZSAoKnMpIHsKCQlkb2VzY2FwZT0wOwoJCWlmICgqcz4weGZmKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKCpzPT0nXG4nKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKGVzY2FwZWVxICYmICpzPT0nPScpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoKnM9PSdcXCcpCiAgICAgICAgICAgICAgICAgICAgICAgIGZwdXRjKCpzLEYpOyAvKiBpZiBcXCB0aGVuIHB1dCBpdCB0d2ljZS4gKi8KCQlpZiAoZG9lc2NhcGUpCgkJCWZwcmludGYoRiwiXFx1JTA0eCIsKigodW5zaWduZWQgc2hvcnQqKXMpKTsKCQllbHNlCgkJCWZwdXRjKCpzLEYpOwoJCXMrKzsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXN1YmtleSBbSW50ZXJuYWxdCiAqCiAqIE5PVEVTCiAqICBSRUdfTVVMVElfU1ogaXMgaGFuZGxlZCBhcyBiaW5hcnkgKGxpa2UgaW4gd2luOTUpIChqcykKICovCnN0YXRpYyBpbnQgX3NhdmVzdWJrZXkoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgbGV2ZWwsIGludCBhbGwgKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWksdGFicyxqOwoKCWxweGtleQk9IGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJIShscHhrZXktPmZsYWdzICYgUkVHX09QVElPTl9WT0xBVElMRSkgJiYKCQkJKGFsbCB8fCAobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkpCgkJKSB7CgkJCWZvciAodGFicz1sZXZlbDt0YWJzLS07KQoJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJX3NhdmVfVVNUUklORyhGLGxweGtleS0+a2V5bmFtZSwxKTsKCQkJZnB1dHMoIlxuIixGKTsKCQkJZm9yIChpPTA7aTxscHhrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJCQlMUEtFWVZBTFVFCXZhbD1scHhrZXktPnZhbHVlcytpOwoKCQkJCWZvciAodGFicz1sZXZlbCsxO3RhYnMtLTspCgkJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJCV9zYXZlX1VTVFJJTkcoRix2YWwtPm5hbWUsMCk7CgkJCQlmcHV0YygnPScsRik7CgkJCQlmcHJpbnRmKEYsIiVsZCwlbGQsIix2YWwtPnR5cGUsdmFsLT5sYXN0bW9kaWZpZWQpOwoJCQkJaWYgKCB2YWwtPnR5cGUgPT0gUkVHX1NaIHx8IHZhbC0+dHlwZSA9PSBSRUdfRVhQQU5EX1NaICkKCQkJCQlfc2F2ZV9VU1RSSU5HKEYsKExQV1NUUil2YWwtPmRhdGEsMCk7CgkJCQllbHNlCgkJCQkJZm9yIChqPTA7ajx2YWwtPmxlbjtqKyspCgkJCQkJCWZwcmludGYoRiwiJTAyeCIsKigodW5zaWduZWQgY2hhciopdmFsLT5kYXRhK2opKTsKCQkJCWZwdXRzKCJcbiIsRik7CgkJCX0KCQkJLyogZGVzY2VuZCByZWN1cnNpdmVseSAqLwoJCQlpZiAoIV9zYXZlc3Via2V5KEYsbHB4a2V5LT5uZXh0c3ViLGxldmVsKzEsYWxsKSkKCQkJCXJldHVybiAwOwoJCX0KCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlc3VicmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3NhdmVzdWJyZWcoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgYWxsICkKewoJZnByaW50ZihGLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWRcbiIsUkVHSVNUUllfU0FWRV9WRVJTSU9OKTsKCV9zYXZlX2NoZWNrX3RhaW50ZWQobHBrZXktPm5leHRzdWIpOwoJcmV0dXJuIF9zYXZlc3Via2V5KEYsbHBrZXktPm5leHRzdWIsMCxhbGwpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgQk9PTCBfc2F2ZXJlZyggTFBLRVlTVFJVQ1QgbHBrZXksIGNoYXIgKmZuLCBpbnQgYWxsICkKewoJRklMRQkqRjsKCglGPWZvcGVuKGZuLCJ3Iik7CglpZiAoRj09TlVMTCkgewoJCVdBUk5fKHJlZykoIkNvdWxkbid0IG9wZW4gJXMgZm9yIHdyaXRpbmc6ICVzXG4iLAoJCQlmbixzdHJlcnJvcihlcnJubykKCQkpOwoJCXJldHVybiBGQUxTRTsKCX0KCWlmICghX3NhdmVzdWJyZWcoRixscGtleSxhbGwpKSB7CgkJZmNsb3NlKEYpOwoJCXVubGluayhmbik7CgkJV0FSTl8ocmVnKSgiRmFpbGVkIHRvIHNhdmUga2V5cywgcGVyaGFwcyBubyBtb3JlIGRpc2tzcGFjZSBmb3IgJXM/XG4iLGZuKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglmY2xvc2UoRik7CiAgICAgICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX1NhdmVSZWdpc3RyeUJyYW5jaCBbSW50ZXJuYWxdCiAqCiAqIFNhdmVzIG1haW4gcmVnaXN0cnkgYnJhbmNoIHNwZWNpZmllZCBieSBoa2V5LgogKi8Kc3RhdGljIHZvaWQgU0hFTExfU2F2ZVJlZ2lzdHJ5QnJhbmNoKEhLRVkgaGtleSwgaW50IGFsbCkKewogICAgY2hhciAgICpmbiwgKmhvbWUsICp0bXA7CgogICAgLyogRklYTUU6IGRvZXMgdGhpcyBjaGVjayBhcHBseSB0byBhbGwga2V5cyB3cml0dGVuIGJlbG93ID8gKi8KICAgIGlmICghKGhvbWUgPSBnZXRlbnYoICJIT01FIiApKSkKICAgICAgICB7CiAgICAgICAgRVJSXyhyZWcpKCJGYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVsZC5cbiIsKGxvbmcpIGdldHVpZCgpKTsKICAgICAgICByZXR1cm47CiAgICB9CgoJLyogSEtFWV9MT0NBTF9NQUNISU5FIGNvbnRhaW5zIHRoZSBIS0VZX0NMQVNTRVNfUk9PVCBicmFuY2ggKi8KCWlmIChoa2V5ID09IEhLRVlfQ0xBU1NFU19ST09UKQoJCWhrZXkgPSBIS0VZX0xPQ0FMX01BQ0hJTkU7CgoJc3dpdGNoIChoa2V5KQogICAgewoJCWNhc2UgSEtFWV9DVVJSRU5UX1VTRVI6CgkJCXsKCQkJCWludCB1c2VkQ2ZnVXNlciA9IDA7CgogICAgZm4gPSB4bWFsbG9jKCBNQVhfUEFUSE5BTUVfTEVOICk7IAoJCQkJaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyAoICJSZWdpc3RyeSIsICJVc2VyRmlsZU5hbWUiLCAiIiwKCQkJCQkJCQkJCQkJZm4sIE1BWF9QQVRITkFNRV9MRU4gLSAxKSkKICAgIHsKICAgICAgICBfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUiksZm4sYWxsKTsKICAgICAgICB1c2VkQ2ZnVXNlciA9IDE7CiAgICB9CiAgICBmcmVlIChmbik7CgogICAgaWYgKHVzZWRDZmdVc2VyICE9IDEpCiAgICB7CiAgICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJsZW4oU0FWRV9DVVJSRU5UX1VTRVIpICsgMiApOwogICAgICAgIHN0cmNweShmbixob21lKTsKICAgICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgpOwogIAogICAgICAgIC8qIGNyZWF0ZSB0aGUgZGlyZWN0b3J5LiBkb24ndCBjYXJlIGFib3V0IGVycm9yY29kZXMuICovCiAgICAgICAgbWtkaXIoZm4sMDc1NSk7IC8qIGRyd3hyLXhyLXggKi8KICAgICAgICBzdHJjYXQoZm4sIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwoKICAgICAgICB0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwogICAgICAgIHN0cmNweSh0bXAsZm4pOwogICAgICAgIHN0cmNhdCh0bXAsIi50bXAiKTsKICAKICAgICAgICBpZiAoX3NhdmVyZWcobG9va3VwX2hrZXkoSEtFWV9DVVJSRU5UX1VTRVIpLHRtcCxhbGwpKSB7CiAgICAgICAgICAgIGlmICgtMT09cmVuYW1lKHRtcCxmbikpIHsKICAgICAgICAgICAgICAgIHBlcnJvcigicmVuYW1lIHRtcCByZWdpc3RyeSIpOwogICAgICAgICAgICAgICAgdW5saW5rKHRtcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZnJlZSh0bXApOwogICAgICAgIGZyZWUoZm4pOwogICAgfQoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgoJCQl7CgkJCQlpbnQgdXNlZENmZ0xNID0gMDsKCQkJCS8qIFRyeSBmaXJzdCBzYXZpbmcgYWNjb3JkaW5nIHRvIHRoZSBkZWZpbmVkIGxvY2F0aW9uIGluIC53aW5lcmMgKi8KICAgIGZuID0geG1hbGxvYyAoIE1BWF9QQVRITkFNRV9MRU4pOwoJCQkJaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyAoICJSZWdpc3RyeSIsCgkJCQkJCSJMb2NhbE1hY2hpbmVGaWxlTmFtZSIsCSIiLCBmbiwgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKQogICAgewogICAgICAgIF9zYXZlcmVnKGxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSksIGZuLCBhbGwpOwogICAgICAgIHVzZWRDZmdMTSA9IDE7CiAgICB9CiAgICBmcmVlIChmbik7CgogICAgaWYgKCB1c2VkQ2ZnTE0gIT0gMSkKICAgIHsKCQkJCQlmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKGhvbWUpICsgc3RybGVuKFdJTkVfUFJFRklYKSArCgkJCQkJCQkJCSAgIHN0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpICsgMik7CiAgICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICAgIHN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfTUFDSElORSk7CgogICAgICAgIHRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CiAgICAgICAgc3RyY3B5KHRtcCxmbik7CiAgICAgICAgc3RyY2F0KHRtcCwiLnRtcCIpOwoKICAgICAgICBpZiAoX3NhdmVyZWcobG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSx0bXAsYWxsKSkgewogICAgICAgICAgICBpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CiAgICAgICAgICAgICAgICBwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKICAgICAgICAgICAgICAgIHVubGluayh0bXApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZyZWUodG1wKTsKICAgICAgICBmcmVlKGZuKTsKICAgIH0KCQkJfQoJCQlicmVhazsKCQljYXNlIEhLRVlfVVNFUlM6CgkJCWZuPShjaGFyKil4bWFsbG9jKCBzdHJsZW4oaG9tZSkgKyBzdHJsZW4oV0lORV9QUkVGSVgpICsKCQkJCQkJCSAgIHN0cmxlbihTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpICsgMik7CgogICAgc3RyY3B5KGZuLGhvbWUpOwogICAgc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKTsKCiAgICB0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwogICAgc3RyY3B5KHRtcCxmbik7c3RyY2F0KHRtcCwiLnRtcCIpOwogICAgaWYgKCBfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX1VTRVJTKSx0bXAsRkFMU0UpKSB7CiAgICAgICAgaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewogICAgICAgICAgICBwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKICAgICAgICAgICAgdW5saW5rKHRtcCk7CiAgICAgICAgfQogICAgfQogICAgZnJlZSh0bXApOwogICAgZnJlZShmbik7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCUVSUl8ocmVnKSgidW5rbm93bi9pbnZhbGlkIGtleSBoYW5kbGUgIVxuIik7CgkJfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEVMTF9TYXZlUmVnaXN0cnkgW0ludGVybmFsXQogKi8Kdm9pZCBTSEVMTF9TYXZlUmVnaXN0cnkoIHZvaWQgKQp7CiAgICBjaGFyICAgYnVmWzRdOwogICAgSEtFWSAgIGhrZXk7CiAgICBpbnQgICAgYWxsOwoKICAgIFRSQUNFXyhyZWcpKCIodm9pZClcbiIpOwoKICAgIGFsbD0wOwogICAgaWYgKFJlZ09wZW5LZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpIT1FUlJPUl9TVUNDRVNTKSAKICAgIHsKICAgICAgICBzdHJjcHkoYnVmLCJ5ZXMiKTsKICAgIH0gCiAgICBlbHNlIAogICAgewogICAgICAgIERXT1JEIGxlbixqdW5rLHR5cGU7CgogICAgICAgIGxlbj00OwogICAgICAgIGlmICgoRVJST1JfU1VDQ0VTUyE9UmVnUXVlcnlWYWx1ZUV4QSggaGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBTF9TQVZFVVBEQVRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZqdW5rLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbGVuKSkgfHwgKHR5cGUhPVJFR19TWikpCiAgICAgICAgewogICAgICAgICAgICBzdHJjcHkoYnVmLCJ5ZXMiKTsKICAgICAgICB9CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7Cn0KCiAgICBpZiAobHN0cmNtcGlBKGJ1ZiwieWVzIikpCgkJYWxsID0gMTsKCglTSEVMTF9TYXZlUmVnaXN0cnlCcmFuY2goSEtFWV9DVVJSRU5UX1VTRVIsIGFsbCk7CglTSEVMTF9TYXZlUmVnaXN0cnlCcmFuY2goSEtFWV9MT0NBTF9NQUNISU5FLCBhbGwpOwoJU0hFTExfU2F2ZVJlZ2lzdHJ5QnJhbmNoKEhLRVlfVVNFUlMsIGFsbCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqIExPQUQgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmluZF9vcl9hZGRfa2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBMUEtFWVNUUlVDVCBfZmluZF9vcl9hZGRfa2V5KCBMUEtFWVNUUlVDVCBscGtleSwgTFBXU1RSIGtleW5hbWUgKQp7CglMUEtFWVNUUlVDVAlscHhrZXksKmxwbHBrZXk7CgoJaWYgKCgha2V5bmFtZSkgfHwgKGtleW5hbWVbMF09PTApKSB7CgkJZnJlZShrZXluYW1lKTsKCQlyZXR1cm4gbHBrZXk7Cgl9CglscGxwa2V5PSAmKGxwa2V5LT5uZXh0c3ViKTsKCWxweGtleQk9ICpscGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJdG9sb3dlcihscHhrZXktPmtleW5hbWVbMF0pPT10b2xvd2VyKGtleW5hbWVbMF0pICYmIAoJCQkhbHN0cmNtcGlXKGxweGtleS0+a2V5bmFtZSxrZXluYW1lKQoJCSkKCQkJYnJlYWs7CgkJbHBscGtleQk9ICYobHB4a2V5LT5uZXh0KTsKCQlscHhrZXkJPSAqbHBscGtleTsKCX0KCWlmIChscHhrZXk9PU5VTEwpIHsKCQkqbHBscGtleSA9IChMUEtFWVNUUlVDVCl4bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTsKCQlscHhrZXkJPSAqbHBscGtleTsKCQltZW1zZXQobHB4a2V5LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpOwoJCWxweGtleS0+a2V5bmFtZQk9IGtleW5hbWU7Cgl9IGVsc2UKCQlmcmVlKGtleW5hbWUpOwoJcmV0dXJuIGxweGtleTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmluZF9vcl9hZGRfdmFsdWUgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX2ZpbmRfb3JfYWRkX3ZhbHVlKCBMUEtFWVNUUlVDVCBscGtleSwgTFBXU1RSIG5hbWUsIERXT1JEIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGRhdGEsIERXT1JEIGxlbiwgRFdPUkQgbGFzdG1vZGlmaWVkICkKewoJTFBLRVlWQUxVRQl2YWw9TlVMTDsKCWludAkJaTsKCglpZiAobmFtZSAmJiAhKm5hbWUpIHsvKiBlbXB0eSBzdHJpbmcgZXF1YWxzIGRlZmF1bHQgKE5VTEwpIHZhbHVlICovCgkJZnJlZShuYW1lKTsKCQluYW1lID0gTlVMTDsKCX0KCglmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykgewoJCXZhbD1scGtleS0+dmFsdWVzK2k7CgkJaWYgKG5hbWU9PU5VTEwpIHsKCQkJaWYgKHZhbC0+bmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJCX0gZWxzZSB7CgkJCWlmICgJdmFsLT5uYW1lIT1OVUxMICYmCgkJCQl0b2xvd2VyKHZhbC0+bmFtZVswXSk9PXRvbG93ZXIobmFtZVswXSkgJiYKCQkJCSFsc3RyY21waVcodmFsLT5uYW1lLG5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJCX0KCX0KCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewoJCWxwa2V5LT52YWx1ZXMgPSB4cmVhbGxvYygKCQkJbHBrZXktPnZhbHVlcywKCQkJKCsrbHBrZXktPm5yb2Z2YWx1ZXMpKnNpemVvZihLRVlWQUxVRSkKCQkpOwoJCXZhbD1scGtleS0+dmFsdWVzK2k7CgkJbWVtc2V0KHZhbCwnXDAnLHNpemVvZihLRVlWQUxVRSkpOwoJCXZhbC0+bmFtZSA9IG5hbWU7Cgl9IGVsc2UgewoJCWlmIChuYW1lKQoJCQlmcmVlKG5hbWUpOwoJfQoJaWYgKHZhbC0+bGFzdG1vZGlmaWVkPGxhc3Rtb2RpZmllZCkgewoJCXZhbC0+bGFzdG1vZGlmaWVkPWxhc3Rtb2RpZmllZDsKCQl2YWwtPnR5cGUgPSB0eXBlOwoKICAgICAgICAgICAgICAgIGlmICgodHlwZSA9PSBSRUdfU1ogfHwgdHlwZSA9PSBSRUdfRVhQQU5EX1NaKSAmJiAhZGF0YSl7CgogICAgICAgICAgICAgICAgICAgIGRhdGE9eG1hbGxvYyhzaXplb2YoV0NIQVIpKTsKICAgICAgICAgICAgICAgICAgICBtZW1zZXQoZGF0YSwwLHNpemVvZihXQ0hBUikpOwogICAgICAgICAgICAgICAgICAgIGxlbiA9c2l6ZW9mKFdDSEFSKTsKICAgICAgICAgICAgICAgIH0KCgkJdmFsLT5sZW4gID0gbGVuOwoJCWlmICh2YWwtPmRhdGEpIAoJCQlmcmVlKHZhbC0+ZGF0YSk7CgkJdmFsLT5kYXRhID0gZGF0YTsKCX0gZWxzZQoJCWZyZWUoZGF0YSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfbGluZSBbSW50ZXJuYWxdCiAqCiAqIHJlYWRzIGEgbGluZSBpbmNsdWRpbmcgZHluYW1pY2FsbHkgZW5sYXJnaW5nIHRoZSByZWFkYnVmZmVyIGFuZCB0aHJvd2luZwogKiBhd2F5IGNvbW1lbnRzCiAqLwpzdGF0aWMgaW50IF93aW5lX3JlYWRfbGluZSggRklMRSAqRiwgY2hhciAqKmJ1ZiwgaW50ICpsZW4gKQp7CgljaGFyCSpzLCpjdXJyZWFkOwoJaW50CW15bGVuLGN1cm9mZjsKCgljdXJyZWFkCT0gKmJ1ZjsKCW15bGVuCT0gKmxlbjsKCSoqYnVmCT0gJ1wwJzsKCXdoaWxlICgxKSB7CgkJd2hpbGUgKDEpIHsKCQkJcz1mZ2V0cyhjdXJyZWFkLG15bGVuLEYpOwoJCQlpZiAocz09TlVMTCkKCQkJCXJldHVybiAwOyAvKiBFT0YgKi8KCQkJaWYgKE5VTEw9PShzPXN0cmNocihjdXJyZWFkLCdcbicpKSkgewoJCQkJLyogYnVmZmVyIHdhc24ndCBsYXJnZSBlbm91Z2ggKi8KCQkJCWN1cm9mZgk9IHN0cmxlbigqYnVmKTsKCQkJCSpidWYJPSB4cmVhbGxvYygqYnVmLCpsZW4qMik7CgkJCQljdXJyZWFkCT0gKmJ1ZiArIGN1cm9mZjsKCQkJCW15bGVuCT0gKmxlbjsJLyogd2UgZmlsbGVkIHVwIHRoZSBidWZmZXIgYW5kIAoJCQkJCQkgKiBnb3QgbmV3ICcqbGVuJyBieXRlcyB0byBmaWxsCgkJCQkJCSAqLwoJCQkJKmxlbgk9ICpsZW4gKiAyOwoJCQl9IGVsc2UgewoJCQkJKnM9J1wwJzsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCS8qIHRocm93IGF3YXkgY29tbWVudHMgKi8KCQlpZiAoKipidWY9PScjJyB8fCAqKmJ1Zj09JzsnKSB7CgkJCWN1cnJlYWQJPSAqYnVmOwoJCQlteWxlbgk9ICpsZW47CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAocykgCS8qIGdvdCBlbmQgb2YgbGluZSAqLwoJCQlicmVhazsKCX0KCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9yZWFkX1VTVFJJTkcgW0ludGVybmFsXQogKgogKiBjb252ZXJ0cyBhIGNoYXIqIGludG8gYSBVTklDT0RFIHN0cmluZyAodXAgdG8gYSBzcGVjaWFsIGNoYXIpCiAqIGFuZCByZXR1cm5zIHRoZSBwb3NpdGlvbiBleGFjdGx5IGFmdGVyIHRoYXQgc3RyaW5nCiAqLwpzdGF0aWMgY2hhciogX3dpbmVfcmVhZF9VU1RSSU5HKCBjaGFyICpidWYsIExQV1NUUiAqc3RyICkKewoJY2hhcgkqczsKCUxQV1NUUgl3czsKCgkvKiByZWFkIHVwIHRvICI9IiBvciAiXDAiIG9yICJcbiIgKi8KCXMJPSBidWY7CglpZiAoKnMgPT0gJz0nKSB7CgkJLyogZW1wdHkgc3RyaW5nIGlzIHRoZSB3aW4zLjEgZGVmYXVsdCB2YWx1ZShOVUxMKSovCgkJKnN0cgk9IE5VTEw7CgkJcmV0dXJuIHM7Cgl9Cgkqc3RyCT0gKExQV1NUUil4bWFsbG9jKDIqc3RybGVuKGJ1ZikrMik7Cgl3cwk9ICpzdHI7Cgl3aGlsZSAoKnMgJiYgKCpzIT0nXG4nKSAmJiAoKnMhPSc9JykpIHsKCQlpZiAoKnMhPSdcXCcpCgkJCSp3cysrPSooKHVuc2lnbmVkIGNoYXIqKXMrKyk7CgkJZWxzZSB7CgkJCXMrKzsKCQkJaWYgKCEqcykgewoJCQkJLyogRGFuZ2xpbmcgXCAuLi4gbWF5IG9ubHkgaGFwcGVuIGlmIGEgcmVnaXN0cnkKCQkJCSAqIHdyaXRlIHdhcyBzaG9ydC4gRklYTUU6IFdoYXQgZG8gdG8/CgkJCQkgKi8KCQkJCSBicmVhazsKCQkJfQoJCQlpZiAoKnM9PSdcXCcpIHsKCQkJCSp3cysrPSdcXCc7CgkJCQlzKys7CgkJCQljb250aW51ZTsKCQkJfQoJCQlpZiAoKnMhPSd1JykgewoJCQkJV0FSTl8ocmVnKSgiTm9uIHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlIFxcJWMgZm91bmQgaW4gfCVzfFxuIiwqcyxidWYpOwoJCQkJKndzKys9J1xcJzsKCQkJCSp3cysrPSpzKys7CgkJCX0gZWxzZSB7CgkJCQljaGFyCXhidWZbNV07CgkJCQlpbnQJd2M7CgoJCQkJcysrOwoJCQkJbWVtY3B5KHhidWYscyw0KTt4YnVmWzRdPSdcMCc7CgkJCQlpZiAoIXNzY2FuZih4YnVmLCIleCIsJndjKSkKCQkJCQlXQVJOXyhyZWcpKCJTdHJhbmdlIGVzY2FwZSBzZXF1ZW5jZSAlcyBmb3VuZCBpbiB8JXN8XG4iLHhidWYsYnVmKTsKCQkJCXMrPTQ7CgkJCQkqd3MrKwk9KHVuc2lnbmVkIHNob3J0KXdjOwoJCQl9CgkJfQoJfQoJKndzCT0gMDsKCXdzCT0gKnN0cjsKCWlmICgqd3MpCgkJKnN0cgk9IHN0cmR1cFcoKnN0cik7CgllbHNlCgkJKnN0cgk9IE5VTEw7CglmcmVlKHdzKTsKCXJldHVybiBzOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2Fkc3Via2V5IFtJbnRlcm5hbF0KICoKICogTk9URVMKICogICAgSXQgc2VlbXMgbGlrZSB0aGlzIGlzIHJldHVybmluZyBhIGJvb2xlYW4uICBTaG91bGQgaXQ/CiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogMQogKiAgICBGYWlsdXJlOiAwCiAqLwpzdGF0aWMgaW50IF93aW5lX2xvYWRzdWJrZXkoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgbGV2ZWwsIGNoYXIgKipidWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICpidWZsZW4sIERXT1JEIG9wdGZsYWcgKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWk7CgljaGFyCQkqczsKCUxQV1NUUgkJbmFtZTsKCiAgICBUUkFDRV8ocmVnKSgiKCVwLCVwLCVkLCVzLCVkLCVseClcbiIsIEYsIGxwa2V5LCBsZXZlbCwgZGVidWdzdHJfYSgqYnVmKSwKICAgICAgICAgICpidWZsZW4sIG9wdGZsYWcpOwoKICAgIGxwa2V5LT5mbGFncyB8PSBvcHRmbGFnOwoKICAgIC8qIEdvb2QuICBXZSBhbHJlYWR5IGdvdCBhIGxpbmUgaGVyZSAuLi4gc28gcGFyc2UgaXQgKi8KICAgIGxweGtleSA9IE5VTEw7CiAgICB3aGlsZSAoMSkgewogICAgICAgIGk9MDtzPSpidWY7CiAgICAgICAgd2hpbGUgKCpzPT0nXHQnKSB7CiAgICAgICAgICAgIHMrKzsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KICAgICAgICBpZiAoaT5sZXZlbCkgewogICAgICAgICAgICBpZiAobHB4a2V5PT1OVUxMKSB7CiAgICAgICAgICAgICAgICBXQVJOXyhyZWcpKCJHb3QgYSBzdWJoaWVyYXJjaHkgd2l0aG91dCByZXNwLiBrZXk/XG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF93aW5lX2xvYWRzdWJrZXkoRixscHhrZXksbGV2ZWwrMSxidWYsYnVmbGVuLG9wdGZsYWcpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoJCS8qIGxldCB0aGUgY2FsbGVyIGhhbmRsZSB0aGlzIGxpbmUgKi8KCQlpZiAoaTxsZXZlbCB8fCAqKmJ1Zj09J1wwJykKCQkJcmV0dXJuIDE7CgoJCS8qIGl0IGNhbiBiZTogYSB2YWx1ZSBvciBhIGtleW5hbWUuIFBhcnNlIHRoZSBuYW1lIGZpcnN0ICovCgkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywmbmFtZSk7CgoJCS8qIHN3aXRjaCgpIGRlZmF1bHQ6IGhhY2sgdG8gYXZvaWQgZ290b3MgKi8KCQlzd2l0Y2ggKDApIHsKCQlkZWZhdWx0OgoJCQlpZiAoKnM9PSdcMCcpIHsKCQkJCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoJCQl9IGVsc2UgewoJCQkJTFBCWVRFCQlkYXRhOwoJCQkJaW50CQlsZW4sbGFzdG1vZGlmaWVkLHR5cGU7CgoJCQkJaWYgKCpzIT0nPScpIHsKCQkJCQlXQVJOXyhyZWcpKCJVbmV4cGVjdGVkIGNoYXJhY3RlcjogJWNcbiIsKnMpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJcysrOwoJCQkJaWYgKDIhPXNzY2FuZihzLCIlZCwlZCwiLCZ0eXBlLCZsYXN0bW9kaWZpZWQpKSB7CgkJCQkJV0FSTl8ocmVnKSgiSGF2ZW4ndCB1bmRlcnN0b29kIHBvc3NpYmxlIHZhbHVlIGluIHwlc3wsIHNraXBwaW5nLlxuIiwqYnVmKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCS8qIHNraXAgdGhlIDIgLCAqLwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlpZiAodHlwZSA9PSBSRUdfU1ogfHwgdHlwZSA9PSBSRUdfRVhQQU5EX1NaKSB7CgkJCQkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywoTFBXU1RSKikmZGF0YSk7CgkJCQkJaWYgKGRhdGEpCgkJCQkJCWxlbiA9IGxzdHJsZW5XKChMUFdTVFIpZGF0YSkqMisyOwoJCQkJCWVsc2UJCgkJCQkJCWxlbiA9IDA7CgkJCQl9IGVsc2UgewoJCQkJCWxlbj1zdHJsZW4ocykvMjsKCQkJCQlkYXRhID0gKExQQllURSl4bWFsbG9jKGxlbisxKTsKCQkJCQlmb3IgKGk9MDtpPGxlbjtpKyspIHsKCQkJCQkJZGF0YVtpXT0wOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXT0oKnMtJzAnKTw8NDsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV09KCpzLSdhJysnXHhhJyk8PDQ7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nQScrJ1x4YScpPDw0OwoJCQkJCQlzKys7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldfD0qcy0nMCc7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nYScrJ1x4YSc7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nQScrJ1x4YSc7CgkJCQkJCXMrKzsKCQkJCQl9CgkJCQl9CgkJCQlfZmluZF9vcl9hZGRfdmFsdWUobHBrZXksbmFtZSx0eXBlLGRhdGEsbGVuLGxhc3Rtb2RpZmllZCk7CgkJCX0KCQl9CgkJLyogcmVhZCB0aGUgbmV4dCBsaW5lICovCgkJaWYgKCFfd2luZV9yZWFkX2xpbmUoRixidWYsYnVmbGVuKSkKCQkJcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHN1YnJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93aW5lX2xvYWRzdWJyZWcoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBEV09SRCBvcHRmbGFnICkKewoJaW50CXZlcjsKCWNoYXIJKmJ1ZjsKCWludAlidWZsZW47CgoJYnVmPXhtYWxsb2MoMTApO2J1Zmxlbj0xMDsKCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghc3NjYW5mKGJ1ZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIiwmdmVyKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICh2ZXIhPVJFR0lTVFJZX1NBVkVfVkVSU0lPTikgewoJCVRSQUNFXyhyZWcpKCJPbGQgZm9ybWF0ICglZCkgcmVnaXN0cnkgZm91bmQsIGlnbm9yaW5nIGl0LiAoYnVmIHdhcyAlcykuXG4iLHZlcixidWYpOwoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfbG9hZHN1YmtleShGLGxwa2V5LDAsJmJ1ZiwmYnVmbGVuLG9wdGZsYWcpKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJZnJlZShidWYpOwoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3dpbmVfbG9hZHJlZyggTFBLRVlTVFJVQ1QgbHBrZXksIGNoYXIgKmZuLCBEV09SRCBvcHRmbGFnICkKewogICAgRklMRSAqRjsKCiAgICBUUkFDRV8ocmVnKSgiKCVwLCVzLCVseClcbiIsbHBrZXksZGVidWdzdHJfYShmbiksb3B0ZmxhZyk7CgogICAgRiA9IGZvcGVuKGZuLCJyYiIpOwogICAgaWYgKEY9PU5VTEwpIHsKICAgICAgICBXQVJOXyhyZWcpKCJDb3VsZG4ndCBvcGVuICVzIGZvciByZWFkaW5nOiAlc1xuIixmbixzdHJlcnJvcihlcnJubykgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoIV93aW5lX2xvYWRzdWJyZWcoRixscGtleSxvcHRmbGFnKSkgewogICAgICAgIGZjbG9zZShGKTsKICAgICAgICB1bmxpbmsoZm4pOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGZjbG9zZShGKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmx1c2hfcmVnaXN0cnkgW0ludGVybmFsXQogKiAKICogVGhpcyBmdW5jdGlvbiBhbGxvdyB0byBmbHVzaCBzZWN0aW9uIG9mIHRoZSBpbnRlcm5hbCByZWdpc3RyeS4gIEl0IGlzIG1haW5seQogKiBpbXBsZW1lbnRzIHRvIGZpeCBhIHByb2JsZW0gd2l0aCB0aGUgZ2xvYmFsIEhLVSBhbmQgdGhlIGxvY2FsIEhLVS4KICogVGhvc2UgdHdvIGZpbGVzIGFyZSByZWFkIHRvIGJ1aWxkIHRoZSBIS1VcLkRlZmF1bHQgYnJhbmNoIHRvIGZpbmFseSBjb3B5CiAqIHRoaXMgYnJhbmNoIG9udG8gSEtDVSBoaXZlLCBvbmNlIHRoaXMgaXMgZG9uZSwgaWYgd2Uga2VlcCB0aGUgSEtVIGhpdmUgYXMgaXMsIAogKiBhbGwgdGhlIGdsb2JhbCBIS1UgYXJlIHNhdmVkIG9udG8gdGhlIHVzZXIncyBwZXJzb25hbCB2ZXJzaW9uIG9mIEhLVSBoaXZlLgogKiB3aGljaCBpcyBiYWQuLi4KICovCgogLyogRm9yd2FyZCBkZWNsYXJhdGlvbiBvZiByZWN1c2l2ZSBhZ2VudCAqLwpzdGF0aWMgdm9pZCBfZmx1c2hfcmVnKExQS0VZU1RSVUNUIGZyb20pOwoKc3RhdGljIHZvaWQgX2ZsdXNoX3JlZ2lzdHJ5KCBMUEtFWVNUUlVDVCBmcm9tICkKewogIC8qIG1ha2Ugc3VyZSB3ZSBoYXZlIHNvbWV0aGluZy4uLiAqLwogIGlmIChmcm9tID09IE5VTEwpCiAgICByZXR1cm47CgogIC8qIExhdW5jaCB0aGUgcmVjdXNpdmUgYWdlbnQgb24gc3ViIGJyYW5jaGVzICovCiAgX2ZsdXNoX3JlZyggZnJvbS0+bmV4dHN1YiApOwogIF9mbHVzaF9yZWcoIGZyb20tPm5leHQgKTsKCiAgLyogSW5pdGlhbGl6ZSBwb2ludGVycyAqLwogIGZyb20tPm5leHRzdWIgPSBOVUxMOwogIGZyb20tPm5leHQgICAgPSBOVUxMOwp9CnN0YXRpYyB2b2lkIF9mbHVzaF9yZWcoIExQS0VZU1RSVUNUIGZyb20gKQp7CglpbnQJajsKCiAgLyogbWFrZSBzdXJlIHdlIGhhdmUgc29tZXRoaW5nLi4uICovCiAgaWYgKGZyb20gPT0gTlVMTCkKICAgIHJldHVybjsKCiAgLyogCiAgICogZG8gdGhlIHNhbWUgZm9yIHRoZSBjaGlsZCBrZXlzIAogICAqLwogIGlmIChmcm9tLT5uZXh0c3ViICE9IE5VTEwpCiAgICBfZmx1c2hfcmVnKGZyb20tPm5leHRzdWIpOwoKICAvKiAKICAgKiBkbyB0aGUgc2FtZSBmb3IgdGhlIHNpYmxpbmcga2V5cyAKICAgKi8KICBpZiAoZnJvbS0+bmV4dCAhPSBOVUxMKQogICAgX2ZsdXNoX3JlZyhmcm9tLT5uZXh0KTsKCiAgLyoKICAgKiBpdGVyYXRlIHRocm91Z2ggdGhpcyBrZXkncyB2YWx1ZXMgYW5kIGRlbGV0ZSB0aGVtCiAgICovCiAgZm9yIChqPTA7ajxmcm9tLT5ucm9mdmFsdWVzO2orKykgCiAgewogICAgZnJlZSggKGZyb20tPnZhbHVlcytqKS0+bmFtZSk7CiAgICBmcmVlKCAoZnJvbS0+dmFsdWVzK2opLT5kYXRhKTsKICB9CgogIC8qCiAgICogZnJlZSB0aGUgc3RydWN0dXJlCiAgICovCiAgaWYgKCBmcm9tICE9IE5VTEwgKQogICAgZnJlZShmcm9tKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2NvcHlfcmVnaXN0cnkgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX2NvcHlfcmVnaXN0cnkoIExQS0VZU1RSVUNUIGZyb20sIExQS0VZU1RSVUNUIHRvICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlqOwoJTFBLRVlWQUxVRQl2YWxmcm9tOwoKCWZyb209ZnJvbS0+bmV4dHN1YjsKCXdoaWxlIChmcm9tKSB7CgkJbHB4a2V5ID0gX2ZpbmRfb3JfYWRkX2tleSh0byxzdHJkdXBXKGZyb20tPmtleW5hbWUpKTsKCgkJZm9yIChqPTA7ajxmcm9tLT5ucm9mdmFsdWVzO2orKykgewoJCQlMUFdTVFIJbmFtZTsKCQkJTFBCWVRFCWRhdGE7CgoJCQl2YWxmcm9tID0gZnJvbS0+dmFsdWVzK2o7CgkJCW5hbWU9dmFsZnJvbS0+bmFtZTsKCQkJaWYgKG5hbWUpIG5hbWU9c3RyZHVwVyhuYW1lKTsKCQkJZGF0YT0oTFBCWVRFKXhtYWxsb2ModmFsZnJvbS0+bGVuKTsKCQkJbWVtY3B5KGRhdGEsdmFsZnJvbS0+ZGF0YSx2YWxmcm9tLT5sZW4pOwoKCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJCQkJbHB4a2V5LAoJCQkJbmFtZSwKCQkJCXZhbGZyb20tPnR5cGUsCgkJCQlkYXRhLAoJCQkJdmFsZnJvbS0+bGVuLAoJCQkJdmFsZnJvbS0+bGFzdG1vZGlmaWVkCgkJCSk7CgkJfQoJCV9jb3B5X3JlZ2lzdHJ5KGZyb20sbHB4a2V5KTsKCQlmcm9tID0gZnJvbS0+bmV4dDsKCX0KfQoKCi8qIFdJTkRPV1MgOTUgUkVHSVNUUlkgTE9BREVSICovCi8qIAogKiBTdHJ1Y3R1cmUgb2YgYSB3aW45NSByZWdpc3RyeSBkYXRhYmFzZS4KICogbWFpbiBoZWFkZXI6CiAqIDAgOgkiQ1JFRyIJLSBtYWdpYwogKiA0IDoJRFdPUkQgdmVyc2lvbgogKiA4IDoJRFdPUkQgb2Zmc2V0X29mX1JHREJfcGFydAogKiAwQy4uMEY6CT8gKHNvbWVvbmUgZmlsbCBpbiBwbGVhc2UpCiAqIDEwOiAgV09SRAludW1iZXIgb2YgUkdEQiBibG9ja3MKICogMTI6ICBXT1JECT8KICogMTQ6ICBXT1JECWFsd2F5cyAwMDAwPwogKiAxNjogIFdPUkQJYWx3YXlzIDAwMDE/CiAqIDE4Li4xRjoJPyAoc29tZW9uZSBmaWxsIGluIHBsZWFzZSkKICoKICogMjA6IFJHS05fc2VjdGlvbjoKICogICBoZWFkZXI6CiAqIAkwIDoJCSJSR0tOIgktIG1hZ2ljCiAqICAgICAgNCA6IERXT1JECW9mZnNldCB0byBmaXJzdCBSR0RCIHNlY3Rpb24KICogICAgICA4IDogRFdPUkQJb2Zmc2V0IHRvIHRoZSByb290IHJlY29yZAogKiAJQy4uMHgxQjogCT8gKGZpbGwgaW4pCiAqICAgICAgMHgyMCAuLi4gb2Zmc2V0X29mX1JHREJfcGFydDogRGlzayBLZXkgRW50cnkgc3RydWN0dXJlcwogKgogKiAgIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZToKICoJMDA6IERXT1JECS0gRnJlZSBlbnRyeSBpbmRpY2F0b3IoPykKICoJMDQ6IERXT1JECS0gSGFzaCA9IHN1bSBvZiBieXRlcyBvZiBrZXluYW1lCiAqCTA4OiBEV09SRAktIFJvb3Qga2V5IGluZGljYXRvcj8gdW5rbm93biwgYnV0IHVzdWFsbHkgMHhGRkZGRkZGRiBvbiB3aW45NSBzeXN0ZW1zCiAqCTBDOiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBQcmV2aW91c0xldmVsIEtleS4KICoJMTA6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIE5leHQgU3VibGV2ZWwgS2V5LgogKgkxNDogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgTmV4dCBLZXkgKG9uIHNhbWUgbGV2ZWwpLgogKiBES0VQPjE4OiBXT1JECS0gTnIsIExvdyBTaWduaWZpY2FudCBwYXJ0LgogKgkxQTogV09SRAktIE5yLCBIaWdoIFNpZ25pZmljYW50IHBhcnQuCiAqCiAqIFRoZSBkaXNrIGFkZHJlc3MgYWx3YXlzIHBvaW50cyB0byB0aGUgbnIgcGFydCBvZiB0aGUgcHJldmlvdXMga2V5IGVudHJ5IAogKiBvZiB0aGUgcmVmZXJlbmNlZCBrZXkuIERvbid0IGFzayBtZSB3aHksIG9yIGV2ZW4gaWYgSSBnb3QgdGhpcyBjb3JyZWN0CiAqIGZyb20gc3RhcmluZyBhdCAxa2cgb2YgaGV4ZHVtcHMuIChES0VQKQogKgogKiBUaGUgSGlnaCBzaWduaWZpY2FudCBwYXJ0IG9mIHRoZSBzdHJ1Y3R1cmUgc2VlbXMgdG8gZXF1YWwgdGhlIG51bWJlcgogKiBvZiB0aGUgUkdEQiBzZWN0aW9uLiBUaGUgbG93IHNpZ25pZmljYW50IHBhcnQgaXMgYSB1bmlxdWUgSUQgd2l0aGluCiAqIHRoYXQgUkdEQiBzZWN0aW9uCiAqCiAqIFRoZXJlIGFyZSB0d28gbWlub3IgY29ycmVjdGlvbnMgdG8gdGhlIHBvc2l0aW9uIG9mIHRoYXQgc3RydWN0dXJlLgogKiAxLiBJZiB0aGUgYWRkcmVzcyBpcyB4eHgwMTQgb3IgeHh4MDE4IGl0IHdpbGwgYmUgYWxpZ25lZCB0byB4eHgwMWMgQU5EIAogKiAgICB0aGUgREtFIHJlcmVhZCBmcm9tIHRoZXJlLgogKiAyLiBJZiB0aGUgYWRkcmVzcyBpcyB4eHhGRnggaXQgd2lsbCBiZSBhbGlnbmVkIHRvICh4eHgrMSkwMDAuCiAqIENQUyAtIEkgaGF2ZSBub3QgZXhwZXJpZW5jZWQgdGhlIGFib3ZlIHBoZW5vbWVub24gaW4gbXkgcmVnaXN0cnkgZmlsZXMKICoKICogUkdEQl9zZWN0aW9uOgogKiAJMDA6CQkiUkdEQiIJLSBtYWdpYwogKgkwNDogRFdPUkQJb2Zmc2V0IHRvIG5leHQgUkdEQiBzZWN0aW9uCiAqCTA4OiBEV09SRAk/CiAqCTBDOiBXT1JECWFsd2F5cyAwMDBkPwogKgkwRTogV09SRAlSR0RCIGJsb2NrIG51bWJlcgogKgkxMDoJRFdPUkQJPyAoZXF1YWxzIHZhbHVlIGF0IG9mZnNldCA0IC0gdmFsdWUgYXQgb2Zmc2V0IDgpCiAqCTE0Li4xRjoJCT8KICoJMjAuLi4uLjoJZGlzayBrZXlzCiAqCiAqIGRpc2sga2V5OgogKiAJMDA6IAlEV09SRAluZXh0a2V5b2Zmc2V0CS0gb2Zmc2V0IHRvIHRoZSBuZXh0IGRpc2sga2V5IHN0cnVjdHVyZQogKgkwODogCVdPUkQJbnJMUwkJLSBsb3cgc2lnbmlmaWNhbnQgcGFydCBvZiBOUgogKgkwQTogCVdPUkQJbnJIUwkJLSBoaWdoIHNpZ25pZmljYW50IHBhcnQgb2YgTlIKICoJMEM6IAlEV09SRAlieXRlc3VzZWQJLSBieXRlcyB1c2VkIGluIHRoaXMgc3RydWN0dXJlLgogKgkxMDogCVdPUkQJbmFtZV9sZW4JLSBsZW5ndGggb2YgbmFtZSBpbiBieXRlcy4gd2l0aG91dCBcMAogKgkxMjogCVdPUkQJbnJfb2ZfdmFsdWVzCS0gbnVtYmVyIG9mIHZhbHVlcy4KICoJMTQ6IAljaGFyCW5hbWVbbmFtZV9sZW5dCS0gbmFtZSBzdHJpbmcuIE5vIFwwLgogKgkxNCtuYW1lX2xlbjogZGlzayB2YWx1ZXMKICoJbmV4dGtleW9mZnNldDogLi4uIG5leHQgZGlzayBrZXkKICoKICogZGlzayB2YWx1ZToKICoJMDA6CURXT1JECXR5cGUJCS0gdmFsdWUgdHlwZSAoaG1tLCBjb3VsZCBiZSBXT1JEIHRvbykKICoJMDQ6CURXT1JECQkJLSB1bmtub3duLCB1c3VhbGx5IDAKICoJMDg6CVdPUkQJbmFtZWxlbgkJLSBsZW5ndGggb2YgTmFtZS4gMCBtZWFucyBuYW1lPU5VTEwKICoJMEM6CVdPUkQJZGF0YWxlbgkJLSBsZW5ndGggb2YgRGF0YS4KICoJMTA6CWNoYXIJbmFtZVtuYW1lbGVuXQktIG5hbWUsIG5vIFwwCiAqCTEwK25hbWVsZW46IEJZVEUJZGF0YVtkYXRhbGVuXSAtIGRhdGEsIHdpdGhvdXQgXDAgaWYgc3RyaW5nCiAqCTEwK25hbWVsZW4rZGF0YWxlbjogbmV4dCB2YWx1ZXMgb3IgZGlzayBrZXkKICoKICogRGlzayBrZXlzIGFyZSBsYXllZCBvdXQgZmxhdCAuLi4gQnV0LCBzb21ldGltZXMsIG5yTFMgYW5kIG5ySFMgYXJlIGJvdGgKICogMHhGRkZGLCB3aGljaCBtZWFucyBza2lwcGluZyBvdmVyIG5leHRrZXlvZmZzZXQgYnl0ZXMgKGluY2x1ZGluZyB0aGlzCiAqIHN0cnVjdHVyZSkgYW5kIHJlYWRpbmcgYW5vdGhlciBSR0RCX3NlY3Rpb24uCiAqIHJlcGVhdCB1bnRpbCBlbmQgb2YgZmlsZS4KICoKICogQW4gaW50ZXJlc3RpbmcgcmVsYXRpb25zaGlwIGV4aXN0cyBpbiBSR0RCX3NlY3Rpb24uIFRoZSB2YWx1ZSBhdCBvZmZzZXQKICogMTAgZXF1YWxzIHRoZSB2YWx1ZSBhdCBvZmZzZXQgNCBtaW51cyB0aGUgdmFsdWUgYXQgb2Zmc2V0IDguIEkgaGF2ZSBubwogKiBpZGVhIGF0IHRoZSBtb21lbnQgd2hhdCB0aGlzIG1lYW5zLiAgKEtldmluIENvemVucykKICoKICogRklYTUU6IHRoaXMgZGVzY3JpcHRpb24gbmVlZHMgc29tZSBzZXJpb3VzIGhlbHAsIHllcy4KICovCgpzdHJ1Y3QJX3c5NWtleXZhbHVlIHsKCXVuc2lnbmVkIGxvbmcJCXR5cGU7Cgl1bnNpZ25lZCBzaG9ydAkJZGF0YWxlbjsKCWNoYXIJCQkqbmFtZTsKCXVuc2lnbmVkIGNoYXIJCSpkYXRhOwoJdW5zaWduZWQgbG9uZwkJeDE7CglpbnQJCQlsYXN0bW9kaWZpZWQ7Cn07CgpzdHJ1Y3QgCV93OTVrZXkgewoJY2hhcgkJCSpuYW1lOwoJaW50CQkJbnJvZnZhbHM7CglzdHJ1Y3QJX3c5NWtleXZhbHVlCSp2YWx1ZXM7CglzdHJ1Y3QgX3c5NWtleQkJKnByZXZsdmw7CglzdHJ1Y3QgX3c5NWtleQkJKm5leHRzdWI7CglzdHJ1Y3QgX3c5NWtleQkJKm5leHQ7Cn07CgoKc3RydWN0IF93OTVfaW5mbyB7CiAgY2hhciAqcmdrbmJ1ZmZlcjsKICBpbnQgIHJna25zaXplOwogIGNoYXIgKnJnZGJidWZmZXI7CiAgaW50ICByZ2Ric2l6ZTsKICBpbnQgIGRlcHRoOwogIGludCAgbGFzdG1vZGlmaWVkOwp9OwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9wcm9jZXNzS2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBMUEtFWVNUUlVDVCBfdzk1X3Byb2Nlc3NLZXkgKCBMUEtFWVNUUlVDVCBscGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5yTFMsIGludCBuck1TLCBzdHJ1Y3QgX3c5NV9pbmZvICppbmZvICkKCnsKICAvKiBEaXNrIEtleSBIZWFkZXIgc3RydWN0dXJlIChSR0RCIHBhcnQpICovCglzdHJ1Y3QJZGtoIHsKICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcJCW5leHRrZXlvZmY7IAoJCXVuc2lnbmVkIHNob3J0CQluckxTOwoJCXVuc2lnbmVkIHNob3J0CQluck1TOwoJCXVuc2lnbmVkIGxvbmcJCWJ5dGVzdXNlZDsKCQl1bnNpZ25lZCBzaG9ydAkJa2V5bmFtZWxlbjsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsdWVzOwoJCXVuc2lnbmVkIGxvbmcJCXh4MTsKCQkvKiBrZXluYW1lICovCgkJLyogZGlzayBrZXkgdmFsdWVzIG9yIG5vdGhpbmcgKi8KCX07CgkvKiBEaXNrIEtleSBWYWx1ZSBzdHJ1Y3R1cmUgKi8KCXN0cnVjdAlka3YgewoJCXVuc2lnbmVkIGxvbmcJCXR5cGU7CgkJdW5zaWduZWQgbG9uZwkJeDE7CgkJdW5zaWduZWQgc2hvcnQJCXZhbG5hbWVsZW47CgkJdW5zaWduZWQgc2hvcnQJCXZhbGRhdGFsZW47CgkJLyogdmFsbmFtZSwgdmFsZGF0YSAqLwoJfTsKCgkKCXN0cnVjdAlka2ggZGtoOwoJaW50CWJ5dGVzcmVhZCA9IDA7CgljaGFyICAgICpyZ2RiZGF0YSA9IGluZm8tPnJnZGJidWZmZXI7CglpbnQgICAgIG5ieXRlcyA9IGluZm8tPnJnZGJzaXplOwoJY2hhciAgICAqY3VyZGF0YSA9IHJnZGJkYXRhOwoJY2hhciAgICAqZW5kID0gcmdkYmRhdGEgKyBuYnl0ZXM7CglpbnQgICAgIG9mZl9uZXh0X3JnZGI7CgljaGFyICAgICpuZXh0ID0gcmdkYmRhdGE7CglpbnQgICAgIG5yZ2RiLCBpOwoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJCglkbyB7CgkgIGN1cmRhdGEgPSBuZXh0OwoJICBpZiAoc3RybmNtcChjdXJkYXRhLCAiUkdEQiIsIDQpKSByZXR1cm4gKE5VTEwpOwoJICAgIAoJICBtZW1jcHkoJm9mZl9uZXh0X3JnZGIsY3VyZGF0YSs0LDQpOwoJICBuZXh0ID0gY3VyZGF0YSArIG9mZl9uZXh0X3JnZGI7CgkgIG5yZ2RiID0gKGludCkgKigoc2hvcnQgKiljdXJkYXRhICsgNyk7CgoJfSB3aGlsZSAobnJnZGIgIT0gbnJNUyAmJiAobmV4dCA8IGVuZCkpOwoKCS8qIGN1cmRhdGEgbm93IHBvaW50cyB0byB0aGUgc3RhcnQgb2YgdGhlIHJpZ2h0IFJHREIgc2VjdGlvbiAqLwoJY3VyZGF0YSArPSAweDIwOwoKI2RlZmluZSBYUkVBRCh3aGVyZXRvLGxlbikgXAoJaWYgKChjdXJkYXRhICsgbGVuKSA8PSBlbmQpIHtcCgkJbWVtY3B5KHdoZXJldG8sY3VyZGF0YSxsZW4pO1wKCQljdXJkYXRhKz1sZW47XAoJCWJ5dGVzcmVhZCs9bGVuO1wKCX0KCgl3aGlsZSAoY3VyZGF0YSA8IG5leHQpIHsKCSAgc3RydWN0CWRraCAqeGRraCA9IChzdHJ1Y3QgZGtoKiljdXJkYXRhOwoKCSAgYnl0ZXNyZWFkICs9IHNpemVvZihka2gpOyAvKiBGSVhNRS4uLiBuZXh0a2V5b2ZmPyAqLwoJICBpZiAoeGRraC0+bnJMUyA9PSBuckxTKSB7CgkgIAltZW1jcHkoJmRraCx4ZGtoLHNpemVvZihka2gpKTsKCSAgCWN1cmRhdGEgKz0gc2l6ZW9mKGRraCk7CgkgIAlicmVhazsKCSAgfQoJICBjdXJkYXRhICs9IHhka2gtPm5leHRrZXlvZmY7Cgl9OwoKCWlmIChka2gubnJMUyAhPSBuckxTKSByZXR1cm4gKE5VTEwpOwoKCWlmIChucmdkYiAhPSBka2gubnJNUykKCSAgcmV0dXJuIChOVUxMKTsKCiAgICAgICAgYXNzZXJ0KChka2gua2V5bmFtZWxlbjwyKSB8fCBjdXJkYXRhWzBdKTsKCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LHN0cmN2dEEyVyhjdXJkYXRhLCBka2gua2V5bmFtZWxlbikpOwoJY3VyZGF0YSArPSBka2gua2V5bmFtZWxlbjsKCglmb3IgKGk9MDtpPCBka2gudmFsdWVzOyBpKyspIHsKCSAgc3RydWN0IGRrdiBka3Y7CgkgIExQQllURSBkYXRhOwoJICBpbnQgbGVuOwoJICBMUFdTVFIgbmFtZTsKCgkgIFhSRUFEKCZka3Ysc2l6ZW9mKGRrdikpOwoKCSAgbmFtZSA9IHN0cmN2dEEyVyhjdXJkYXRhLCBka3YudmFsbmFtZWxlbik7CgkgIGN1cmRhdGEgKz0gZGt2LnZhbG5hbWVsZW47CgoJICBpZiAoKDEgPDwgZGt2LnR5cGUpICYgVU5JQ09OVk1BU0spIHsKCSAgICBkYXRhID0gKExQQllURSkgc3RyY3Z0QTJXKGN1cmRhdGEsIGRrdi52YWxkYXRhbGVuKTsKCSAgICBsZW4gPSAyKihka3YudmFsZGF0YWxlbiArIDEpOwoJICB9IGVsc2UgewoJICAgIC8qIEkgZG9uJ3QgdGhpbmsgd2Ugd2FudCB0byBOVUxMIHRlcm1pbmF0ZSBhbGwgZGF0YSAqLwoJICAgIGRhdGEgPSB4bWFsbG9jKGRrdi52YWxkYXRhbGVuKTsKCSAgICBtZW1jcHkgKGRhdGEsIGN1cmRhdGEsIGRrdi52YWxkYXRhbGVuKTsKCSAgICBsZW4gPSBka3YudmFsZGF0YWxlbjsKCSAgfQoKCSAgY3VyZGF0YSArPSBka3YudmFsZGF0YWxlbjsKCSAgCgkgIF9maW5kX29yX2FkZF92YWx1ZSgKCQkJICAgICBscHhrZXksCgkJCSAgICAgbmFtZSwKCQkJICAgICBka3YudHlwZSwKCQkJICAgICBkYXRhLAoJCQkgICAgIGxlbiwKCQkJICAgICBpbmZvLT5sYXN0bW9kaWZpZWQKCQkJICAgICApOwoJfQoJcmV0dXJuIChscHhrZXkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfd2Fsa3Jna24gW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3c5NV93YWxrcmdrbiggTFBLRVlTVFJVQ1QgcHJldmtleSwgY2hhciAqb2ZmLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IF93OTVfaW5mbyAqaW5mbyApCgp7CiAgLyogRGlzayBLZXkgRW50cnkgc3RydWN0dXJlIChSR0tOIHBhcnQpICovCiAgc3RydWN0CWRrZSB7CiAgICB1bnNpZ25lZCBsb25nCQl4MTsKICAgIHVuc2lnbmVkIGxvbmcJCXgyOwogICAgdW5zaWduZWQgbG9uZwkJeDM7Lyp1c3VhbGx5IDB4RkZGRkZGRkYgKi8KICAgIHVuc2lnbmVkIGxvbmcJCXByZXZsdmw7CiAgICB1bnNpZ25lZCBsb25nCQluZXh0c3ViOwogICAgdW5zaWduZWQgbG9uZwkJbmV4dDsKICAgIHVuc2lnbmVkIHNob3J0CQluckxTOwogICAgdW5zaWduZWQgc2hvcnQJCW5yTVM7CiAgfSAqZGtlID0gKHN0cnVjdCBka2UgKilvZmY7CiAgTFBLRVlTVFJVQ1QgIGxweGtleTsKCiAgaWYgKGRrZSA9PSBOVUxMKSB7CiAgICBka2UgPSAoc3RydWN0IGRrZSAqKSAoKGNoYXIgKilpbmZvLT5yZ2tuYnVmZmVyKTsKICB9CgogIGxweGtleSA9IF93OTVfcHJvY2Vzc0tleShwcmV2a2V5LCBka2UtPm5yTFMsIGRrZS0+bnJNUywgaW5mbyk7CiAgLyogWFhYIDwtLSBUaGlzIGlzIGEgaGFjayovCiAgaWYgKCFscHhrZXkpIHsKICAgIGxweGtleSA9IHByZXZrZXk7CiAgfQoKICBpZiAoZGtlLT5uZXh0c3ViICE9IC0xICYmIAogICAgICAoKGRrZS0+bmV4dHN1YiAtIDB4MjApIDwgaW5mby0+cmdrbnNpemUpIAogICAgICAmJiAoZGtlLT5uZXh0c3ViID4gMHgyMCkpIHsKICAgIAogICAgX3c5NV93YWxrcmdrbihscHhrZXksIAoJCSAgaW5mby0+cmdrbmJ1ZmZlciArIGRrZS0+bmV4dHN1YiAtIDB4MjAsIAoJCSAgaW5mbyk7CiAgfQogIAogIGlmIChka2UtPm5leHQgIT0gLTEgJiYgCiAgICAgICgoZGtlLT5uZXh0IC0gMHgyMCkgPCBpbmZvLT5yZ2tuc2l6ZSkgJiYgCiAgICAgIChka2UtPm5leHQgPiAweDIwKSkgewogICAgX3c5NV93YWxrcmdrbihwcmV2a2V5LCAgCgkJICBpbmZvLT5yZ2tuYnVmZmVyICsgZGtlLT5uZXh0IC0gMHgyMCwKCQkgIGluZm8pOwogIH0KCiAgcmV0dXJuOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvYWRyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3c5NV9sb2FkcmVnKCBjaGFyKiBmbiwgTFBLRVlTVFJVQ1QgbHBrZXkgKQp7CglIRklMRQkJaGZkOwoJY2hhcgkJbWFnaWNbNV07Cgl1bnNpZ25lZCBsb25nCXdoZXJlLHZlcnNpb24scmdkYnNlY3Rpb24sZW5kOwoJc3RydWN0ICAgICAgICAgIF93OTVfaW5mbyBpbmZvOwoJT0ZTVFJVQ1QJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZkaW5mbzsKCglUUkFDRV8ocmVnKSgiTG9hZGluZyBXaW45NSByZWdpc3RyeSBkYXRhYmFzZSAnJXMnXG4iLGZuKTsKCWhmZD1PcGVuRmlsZShmbiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmZD09SEZJTEVfRVJST1IpCgkJcmV0dXJuOwoJbWFnaWNbNF09MDsKCWlmICg0IT1fbHJlYWQoaGZkLG1hZ2ljLDQpKQoJCXJldHVybjsKCWlmIChzdHJjbXAobWFnaWMsIkNSRUciKSkgewoJCVdBUk5fKHJlZykoIiVzIGlzIG5vdCBhIHc5NSByZWdpc3RyeS5cbiIsZm4pOwoJCXJldHVybjsKCX0KCWlmICg0IT1fbHJlYWQoaGZkLCZ2ZXJzaW9uLDQpKQoJCXJldHVybjsKCWlmICg0IT1fbHJlYWQoaGZkLCZyZ2Ric2VjdGlvbiw0KSkKCQlyZXR1cm47CglpZiAoLTE9PV9sbHNlZWsoaGZkLDB4MjAsU0VFS19TRVQpKQoJCXJldHVybjsKCWlmICg0IT1fbHJlYWQoaGZkLG1hZ2ljLDQpKQoJCXJldHVybjsKCWlmIChzdHJjbXAobWFnaWMsIlJHS04iKSkgewoJCVdBUk5fKHJlZykoInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJXNcbiIsIG1hZ2ljKTsKCQlyZXR1cm47Cgl9CgoJLyogU1RFUCAxOiBLZXlsaW5rIHN0cnVjdHVyZXMgKi8KCWlmICgtMT09X2xsc2VlayhoZmQsMHg0MCxTRUVLX1NFVCkpCgkJcmV0dXJuOwoJd2hlcmUJPSAweDQwOwoJZW5kCT0gcmdkYnNlY3Rpb247CgoJaW5mby5yZ2tuc2l6ZSA9IGVuZCAtIHdoZXJlOwoJaW5mby5yZ2tuYnVmZmVyID0gKGNoYXIqKXhtYWxsb2MoaW5mby5yZ2tuc2l6ZSk7CglpZiAoaW5mby5yZ2tuc2l6ZSAhPSBfbHJlYWQoaGZkLGluZm8ucmdrbmJ1ZmZlcixpbmZvLnJna25zaXplKSkKCQlyZXR1cm47CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZmQsJmhmZGluZm8pKQoJCXJldHVybjsKCgllbmQgPSBoZmRpbmZvLm5GaWxlU2l6ZUxvdzsKCWluZm8ubGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmRpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCglpZiAoLTE9PV9sbHNlZWsoaGZkLHJnZGJzZWN0aW9uLFNFRUtfU0VUKSkKCQlyZXR1cm47CgoJaW5mby5yZ2RiYnVmZmVyID0gKGNoYXIqKXhtYWxsb2MoZW5kLXJnZGJzZWN0aW9uKTsKCWluZm8ucmdkYnNpemUgPSBlbmQgLSByZ2Ric2VjdGlvbjsKCglpZiAoaW5mby5yZ2Ric2l6ZSAhPV9scmVhZChoZmQsaW5mby5yZ2RiYnVmZmVyLGluZm8ucmdkYnNpemUpKQoJCXJldHVybjsKCV9sY2xvc2UoaGZkKTsKCglfdzk1X3dhbGtyZ2tuKGxwa2V5LCBOVUxMLCAmaW5mbyk7CgoJZnJlZSAoaW5mby5yZ2RiYnVmZmVyKTsKCWZyZWUgKGluZm8ucmdrbmJ1ZmZlcik7Cn0KCgovKiBXSU5ET1dTIDMxIFJFR0lTVFJZIExPQURFUiwgc3VwcGxpZWQgYnkgVG9yIFNq+HdhbGwsIHRvckBzbi5ubyAqLwoKLyoKICAgIHJlZ2hhY2sgLSB3aW5kb3dzIDMuMTEgcmVnaXN0cnkgZGF0YSBmb3JtYXQgZGVtbyBwcm9ncmFtLgoKICAgIFRoZSByZWcuZGF0IGZpbGUgaGFzIDMgcGFydHMsIGEgaGVhZGVyLCBhIHRhYmxlIG9mIDgtYnl0ZSBlbnRyaWVzIHRoYXQgaXMKICAgIGEgY29tYmluZWQgaGFzaCB0YWJsZSBhbmQgdHJlZSBkZXNjcmlwdGlvbiwgYW5kIGZpbmFsbHkgYSB0ZXh0IHRhYmxlLgoKICAgIFRoZSBoZWFkZXIgaXMgb2J2aW91cyBmcm9tIHRoZSBzdHJ1Y3QgaGVhZGVyLiBUaGUgdGFib2ZmMSBhbmQgdGFib2ZmMgogICAgZmllbGRzIGFyZSBhbHdheXMgMHgyMCwgYW5kIHRoZWlyIHVzYWdlIGlzIHVua25vd24uCgogICAgVGhlIDgtYnl0ZSBlbnRyeSB0YWJsZSBoYXMgdmFyaW91cyBlbnRyeSB0eXBlcy4KCiAgICB0YWJlbnRbMF0gaXMgYSByb290IGluZGV4LiBUaGUgc2Vjb25kIHdvcmQgaGFzIHRoZSBpbmRleCBvZiB0aGUgcm9vdCBvZgogICAgICAgICAgICB0aGUgZGlyZWN0b3J5LgogICAgdGFiZW50WzEuLmhhc2hzaXplXSBpcyBhIGhhc2ggdGFibGUuIFRoZSBmaXJzdCB3b3JkIGluIHRoZSBoYXNoIGVudHJ5IGlzCiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUga2V5L3ZhbHVlIHRoYXQgaGFzIHRoYXQgaGFzaC4gRGF0YSB3aXRoIHRoZSBzYW1lCiAgICAgICAgICAgIGhhc2ggdmFsdWUgYXJlIG9uIGEgY2lyY3VsYXIgbGlzdC4gVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZQogICAgICAgICAgICBoYXNoIGVudHJ5IGFyZSBhbHdheXMgemVyby4KICAgIHRhYmVudFtoYXNoc2l6ZS4udGFiY250XSBpcyB0aGUgdHJlZSBzdHJ1Y3R1cmUuIFRoZXJlIGFyZSB0d28ga2luZHMgb2YKICAgICAgICAgICAgZW50cnk6IGRpcmVudCBhbmQga2V5ZW50L3ZhbGVudC4gVGhleSBhcmUgaWRlbnRpZmllZCBieSBjb250ZXh0LgogICAgdGFiZW50W2ZyZWVpZHhdIGlzIHRoZSBmaXJzdCBmcmVlIGVudHJ5LiBUaGUgZmlyc3Qgd29yZCBpbiBhIGZyZWUgZW50cnkKICAgICAgICAgICAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGZyZWUgZW50cnkuIFRoZSBsYXN0IGhhcyAwIGFzIGEgbGluay4KICAgICAgICAgICAgVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZSBmcmVlIGxpc3QgYXJlIHByb2JhYmx5IGlycmVsZXZhbnQuCgogICAgRW50cmllcyBpbiB0ZXh0IHRhYmxlIGFyZSBwcmVjZWVkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewoJY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCgl1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7Cgl1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7Cgl1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCgl1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgKi8Kdm9pZApfX3czMV9kdW1wdHJlZSgJdW5zaWduZWQgc2hvcnQgaWR4LAoJCXVuc2lnbmVkIGNoYXIgKnR4dCwKCQlzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYiwKCQlzdHJ1Y3QgX3czMV9oZWFkZXIgKmhlYWQsCgkJTFBLRVlTVFJVQ1QJbHBrZXksCgkJdGltZV90CQlsYXN0bW9kaWZpZWQsCgkJaW50CQlsZXZlbAopIHsKCXN0cnVjdCBfdzMxX2RpcmVudAkqZGlyOwoJc3RydWN0IF93MzFfa2V5ZW50CSprZXk7CglzdHJ1Y3QgX3czMV92YWxlbnQJKnZhbDsKCUxQS0VZU1RSVUNUCQl4bHBrZXkgPSBOVUxMOwoJTFBXU1RSCQkJbmFtZSx2YWx1ZTsKCXN0YXRpYyBjaGFyCQl0YWlsWzQwMF07CgoJd2hpbGUgKGlkeCE9MCkgewoJCWRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgoJCWlmIChkaXItPmtleV9pZHgpIHsKCQkJa2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKCQkJbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKCQkJdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKCQkJLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZSAKCQkJICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwoJCQkgKi8KCQkJaWYgKCFsZXZlbCAmJiAhbHN0cmNtcEEodGFpbCwiLmNsYXNzZXMiKSkgewoJCQkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLGxwa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQkJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJCQkJY29udGludWU7CgkJCX0KCQkJbmFtZT1zdHJkdXBBMlcodGFpbCk7CgoJCQl4bHBrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxuYW1lKTsKCgkJCS8qIG9ubHkgYWRkIGlmIGxlYWYgbm9kZSBvciB2YWx1ZWQgbm9kZSAqLwoJCQlpZiAoZGlyLT52YWx1ZV9pZHghPTB8fGRpci0+Y2hpbGRfaWR4PT0wKSB7CgkJCQlpZiAoZGlyLT52YWx1ZV9pZHgpIHsKCQkJCQl2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CgkJCQkJbWVtY3B5KHRhaWwsJnR4dFt2YWwtPnN0cmluZ19vZmZdLHZhbC0+bGVuZ3RoKTsKCQkJCQl0YWlsW3ZhbC0+bGVuZ3RoXT0nXDAnOwoJCQkJCXZhbHVlPXN0cmR1cEEyVyh0YWlsKTsKCQkJCQlfZmluZF9vcl9hZGRfdmFsdWUoeGxwa2V5LE5VTEwsUkVHX1NaLChMUEJZVEUpdmFsdWUsbHN0cmxlblcodmFsdWUpKjIrMixsYXN0bW9kaWZpZWQpOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJVFJBQ0VfKHJlZykoInN0cmFuZ2U6IG5vIGRpcmVjdG9yeSBrZXkgbmFtZSwgaWR4PSUwNHhcbiIsIGlkeCk7CgkJfQoJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCx4bHBrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzMxX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kdm9pZCBfdzMxX2xvYWRyZWcodm9pZCkgewoJSEZJTEUJCQloZjsKCXN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwoJc3RydWN0IF93MzFfdGFiZW50CSp0YWI7Cgl1bnNpZ25lZCBjaGFyCQkqdHh0OwoJaW50CQkJbGVuOwoJT0ZTVFJVQ1QJCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmaW5mbzsKCXRpbWVfdAkJCWxhc3Rtb2RpZmllZDsKCUxQS0VZU1RSVUNUCQlscGtleTsKCglUUkFDRV8ocmVnKSgiKHZvaWQpXG4iKTsKCgloZiA9IE9wZW5GaWxlKCJyZWcuZGF0Iiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmPT1IRklMRV9FUlJPUikKCQlyZXR1cm47CgoJLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCglpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQoaGYsJmhlYWQsc2l6ZW9mKGhlYWQpKSkgewoJCUVSUl8ocmVnKSgicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSE9MCkgewoJCUVSUl8ocmVnKSgicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCglsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwoJLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwoJdGFiID0geG1hbGxvYyhsZW4pOwoJaWYgKGxlbiE9X2xyZWFkKGhmLHRhYixsZW4pKSB7CgkJRVJSXyhyZWcpKCJjb3VsZG4ndCByZWFkICVkIGJ5dGVzLlxuIixsZW4pOyAKCQlmcmVlKHRhYik7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCS8qIHJlYWQgdGV4dCAqLwoJdHh0ID0geG1hbGxvYyhoZWFkLnRleHRzaXplKTsKCWlmICgtMT09X2xsc2VlayhoZixoZWFkLnRleHRvZmYsU0VFS19TRVQpKSB7CgkJRVJSXyhyZWcpKCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWlmIChoZWFkLnRleHRzaXplIT1fbHJlYWQoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CgkJRVJSXyhyZWcpKCJ0ZXh0YmxvY2sgdG9vIHNob3J0ICglZCBpbnN0ZWFkIG9mICVsZCkuXG4iLGxlbixoZWFkLnRleHRzaXplKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZiwmaGZpbmZvKSkgewoJCUVSUl8ocmVnKSgiR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUgZmFpbGVkPy5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoSEtFWV9DTEFTU0VTX1JPT1QpOwoJX193MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLDApOwoJZnJlZSh0YWIpOwoJZnJlZSh0eHQpOwoJX2xjbG9zZShoZik7CglyZXR1cm47Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEVMTF9Mb2FkUmVnaXN0cnkgW0ludGVybmFsXQogKi8Kdm9pZCBTSEVMTF9Mb2FkUmVnaXN0cnkoIHZvaWQgKQp7CiAgY2hhcgkgICAgICAqZm4sICpob21lOwogIExQS0VZU1RSVUNUCWxwa2V5LCBIS0NVLCBIS1UsIEhLTE07CiAgSEtFWQkJICAgIGhrZXk7CgogIFRSQUNFXyhyZWcpKCIodm9pZClcbiIpOwoKICBIS0NVID0gbG9va3VwX2hrZXkoSEtFWV9DVVJSRU5UX1VTRVIpOwogIEhLVSAgPSBsb29rdXBfaGtleShIS0VZX1VTRVJTKTsKICBIS0xNID0gbG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKTsKCiAgLyogTG9hZCB3aW5kb3dzIDMuMSBlbnRyaWVzICovCiAgX3czMV9sb2FkcmVnKCk7CiAgLyogTG9hZCB3aW5kb3dzIDk1IGVudHJpZXMgKi8KICBfdzk1X2xvYWRyZWcoIkM6XFxzeXN0ZW0uMXN0IiwJSEtMTSk7CiAgX3c5NV9sb2FkcmVnKCJzeXN0ZW0uZGF0IiwJSEtMTSk7CiAgX3c5NV9sb2FkcmVnKCJ1c2VyLmRhdCIsCUhLVSk7CgogIC8qIAogICAqIExvYWQgdGhlIGdsb2JhbCBIS1UgaGl2ZSBkaXJlY3RseSBmcm9tIHN5c2NvbmZkaXIKICAgKi8gCiAgX3dpbmVfbG9hZHJlZyggSEtVLCBTQVZFX1VTRVJTX0RFRkFVTFQsIDApOwoKICAvKiAKICAgKiBMb2FkIHRoZSBnbG9iYWwgbWFjaGluZSBkZWZhdWx0cyBkaXJlY3RseSBmb3JtIHN5c2NvbmZkaXIKICAgKi8KICBfd2luZV9sb2FkcmVnKCBIS0xNLCBTQVZFX0xPQ0FMX01BQ0hJTkVfREVGQVVMVCwgMCk7CgogIC8qCiAgICogTG9hZCB0aGUgdXNlciBzYXZlZCByZWdpc3RyaWVzIAogICAqLwogIGlmICgoaG9tZSA9IGdldGVudiggIkhPTUUiICkpKQogIHsKICAgIC8qIAogICAgICogTG9hZCB1c2VyJ3MgcGVyc29uYWwgdmVyc2lvbnMgb2YgZ2xvYmFsIEhLVS8uRGVmYXVsdCBrZXlzCiAgICAgKi8KICAgIGZuPShjaGFyKil4bWFsbG9jKAogICAgICAgICAgICAgICAgc3RybGVuKGhvbWUpKwogICAgICAgICAgICAgICAgc3RybGVuKFdJTkVfUFJFRklYKSsKICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpKzIpOwoKICAgIHN0cmNweShmbiwgaG9tZSk7CiAgICBzdHJjYXQoZm4sIFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKTsKICAgIF93aW5lX2xvYWRyZWcoSEtVLCBmbiwgUkVHX09QVElPTl9UQUlOVEVEKTsgCiAgICBmcmVlKGZuKTsKCiAgICAvKiAKICAgICAqIExvYWQgSEtDVSwgYXR0ZW1wdCB0byBnZXQgdGhlIHJlZ2lzdHJ5IGxvY2F0aW9uIGZyb20gdGhlIGNvbmZpZyAKICAgICAqIGZpbGUgZmlyc3QsIGlmIGV4aXN0LCBsb2FkIGFuZCBrZWVwIGdvaW5nLgogICAgICovICAgICAgCiAgICBmbiA9IHhtYWxsb2MoIE1BWF9QQVRITkFNRV9MRU4gKTsgCiAgICBpZiAoIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZygKICAgICAgICAgICJSZWdpc3RyeSIsIAogICAgICAgICAgIlVzZXJGaWxlTmFtZSIsIAogICAgICAgICAgIiIsIAogICAgICAgICAgZm4sIAogICAgICAgICAgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKSAKICAgIHsKICAgICAgX3dpbmVfbG9hZHJlZyhIS0NVLGZuLDApOwogICAgfQogIAlmcmVlIChmbik7CgogICAgZm49KGNoYXIqKXhtYWxsb2MoCiAgICAgICAgICAgICAgICBzdHJsZW4oaG9tZSkrCiAgICAgICAgICAgICAgICBzdHJsZW4oV0lORV9QUkVGSVgpKwogICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfQ1VSUkVOVF9VU0VSKSsyKTsKCiAgICBzdHJjcHkoZm4sIGhvbWUpOwogICAgc3RyY2F0KGZuLCBXSU5FX1BSRUZJWCIvIlNBVkVfQ1VSUkVOVF9VU0VSKTsKICAgIF93aW5lX2xvYWRyZWcoSEtDVSwgZm4sIFJFR19PUFRJT05fVEFJTlRFRCk7CiAgICBmcmVlKGZuKTsKCiAgICAvKiAKICAgICAqIExvYWQgSEtMTSwgYXR0ZW1wdCB0byBnZXQgdGhlIHJlZ2lzdHJ5IGxvY2F0aW9uIGZyb20gdGhlIGNvbmZpZyAKICAgICAqIGZpbGUgZmlyc3QsIGlmIGV4aXN0LCBsb2FkIGFuZCBrZWVwIGdvaW5nLgogICAgICovICAgICAgCiAgICBmbiA9IHhtYWxsb2MgKCBNQVhfUEFUSE5BTUVfTEVOKTsKICAgIGlmICggUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKAogICAgICAgICAgIlJlZ2lzdHJ5IiwgCiAgICAgICAgICAiTG9jYWxNYWNoaW5lRmlsZU5hbWUiLCAKICAgICAgICAgICIiLCAKICAgICAgICAgIGZuLCAKICAgICAgICAgIE1BWF9QQVRITkFNRV9MRU4gLSAxKSkKICAgIHsKICAgICAgICBfd2luZV9sb2FkcmVnKEhLTE0sIGZuLCAwKTsKICAgIH0KICAgIGZyZWUoZm4pOwoKICAgIGZuPShjaGFyKil4bWFsbG9jKAogICAgICAgICAgICAgICAgc3RybGVuKGhvbWUpKwogICAgICAgICAgICAgICAgc3RybGVuKFdJTkVfUFJFRklYKSsKICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwoKICAgIHN0cmNweShmbixob21lKTsKICAgIHN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfTUFDSElORSk7CiAgICBfd2luZV9sb2FkcmVnKEhLTE0sIGZuLCBSRUdfT1BUSU9OX1RBSU5URUQpOwogICAgZnJlZShmbik7CiAgfQogIGVsc2UKICB7CiAgICBXQVJOXyhyZWcpKCJGYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVsZC5cbiIsKGxvbmcpIGdldHVpZCgpKTsKICB9CgogIC8qIAogICAqIE9idGFpbiB0aGUgaGFuZGxlIG9mIHRoZSBIS1VcLkRlZmF1bHQga2V5LgogICAqIGluIG9yZGVyIHRvIGNvcHkgSEtVXC5EZWZhdWx0XCogb250byBIS0VZX0NVUlJFTlRfVVNFUiAKICAgKi8KICBSZWdDcmVhdGVLZXkxNihIS0VZX1VTRVJTLCIuRGVmYXVsdCIsJmhrZXkpOwogIGxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgaWYoIWxwa2V5KQogICAgIFdBUk5fKHJlZykoIkNvdWxkIG5vdCBjcmVhdGUgZ2xvYmFsIHVzZXIgZGVmYXVsdCBrZXlcbiIpOwogIGVsc2UKICAgIF9jb3B5X3JlZ2lzdHJ5KGxwa2V5LCBIS0NVICk7CgogIFJlZ0Nsb3NlS2V5KGhrZXkpOwoKICAvKiAKICAgKiBTaW5jZSBIS1UgaXMgYnVpbHQgZnJvbSB0aGUgZ2xvYmFsIEhLVSBhbmQgdGhlIGxvY2FsIHVzZXIgSEtVIGZpbGUgd2UgbXVzdAogICAqIGZsdXNoIHRoZSBIS1UgdHJlZSB3ZSBoYXZlIGJ1aWx0IGF0IHRoaXMgcG9pbnQgb3RoZXJ3aXNlIHRoZSBwYXJ0IGJyb3VnaHQKICAgKiBpbiBmcm9tIHRoZSBnbG9iYWwgSEtVIGlzIHNhdmVkIGludG8gdGhlIGxvY2FsIEhLVS4gIFRvIGF2b2lkIHRoaXMgCiAgICogdXNlbGVzcyBkdXBwbGljYXRpb24gb2YgSEtVIGtleXMgd2UgcmVyZWFkIHRoZSBsb2NhbCBIS1Uga2V5LgogICAqLwoKICAvKiBBbGx3YXlzIGZsdXNoIHRoZSBIS1UgaGl2ZSBhbmQgcmVsb2FkIGl0IG9ubHkgd2l0aCB1c2VyJ3MgcGVyc29uYWwgSEtVICovCiAgX2ZsdXNoX3JlZ2lzdHJ5KEhLVSk7IAoKICAvKiBSZWxvYWQgdXNlcidzIGxvY2FsIEhLVSBoaXZlICovCiAgaWYgKGhvbWUpCiAgewogICAgICBmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKGhvbWUpICsgc3RybGVuKFdJTkVfUFJFRklYKQogICAgICAgICAgICAgICAgICAgICAgICAgKyBzdHJsZW4oU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKSArIDIpOwogICAgICAKICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpOwoKICAgICAgX3dpbmVfbG9hZHJlZyggSEtVLCBmbiwgUkVHX09QVElPTl9UQUlOVEVEKTsKCiAgICAgIGZyZWUoZm4pOwogIH0KCiAgLyogCiAgICogTWFrZSBzdXJlIHRoZSB1cGRhdGUgbW9kZSBpcyB0aGVyZQogICAqLwogIGlmIChFUlJPUl9TVUNDRVNTPT1SZWdDcmVhdGVLZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpKSAKICB7CiAgICBEV09SRAlqdW5rLHR5cGUsbGVuOwogICAgY2hhcglkYXRhWzVdOwoKICAgIGxlbj00OwogICAgaWYgKCgJUmVnUXVlcnlWYWx1ZUV4QSgKICAgICAgICAgICAgaGtleSwKICAgICAgICAgICAgVkFMX1NBVkVVUERBVEVELAogICAgICAgICAgICAmanVuaywKICAgICAgICAgICAgJnR5cGUsCiAgICAgICAgICAgIGRhdGEsCiAgICAgICAgICAgICZsZW4pICE9IEVSUk9SX1NVQ0NFU1MpIHx8ICh0eXBlICE9IFJFR19TWikpCiAgICB7CiAgICAgIFJlZ1NldFZhbHVlRXhBKGhrZXksVkFMX1NBVkVVUERBVEVELDAsUkVHX1NaLCJ5ZXMiLDQpOwogICAgfQoKICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKiogQVBJIEZVTkNUSU9OUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qCiAqIE9wZW4gS2V5cy4KICoKICogQWxsIGZ1bmN0aW9ucyBhcmUgc3R1YnMgdG8gUmVnT3BlbktleUV4MzJXIHdoZXJlIGFsbCB0aGUKICogbWFnaWMgaGFwcGVucy4gCiAqCiAqIENhbGxwYXRoOgogKiBSZWdPcGVuS2V5MTYgLT4gUmVnT3BlbktleTMyQSAtPiBSZWdPcGVuS2V5RXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdPcGVuS2V5MzJXICAgLT4gUmVnT3BlbktleUV4MzJXIAogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXlFeDMyVyBbQURWQVBJMzIuMTUwXQogKiBPcGVucyB0aGUgc3BlY2lmaWVkIGtleQogKgogKiBVbmxpa2UgUmVnQ3JlYXRlS2V5RXgsIHRoaXMgZG9lcyBub3QgY3JlYXRlIHRoZSBrZXkgaWYgaXQgZG9lcyBub3QgZXhpc3QuCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBzelN1YktleSBbSV0gTmFtZSBvZiBzdWJrZXkgdG8gb3BlbgogKiAgICBkd1Jlc2VydmVkIFtJXSBSZXNlcnZlZCAtIG11c3QgYmUgemVybwogKiAgICBzYW1EZXNpcmVkIFtJXSBTZWN1cml0eSBhY2Nlc3MgbWFzawogKiAgICByZXRrZXkgICAgIFtPXSBBZGRyZXNzIG9mIGhhbmRsZSBvZiBvcGVuIGtleQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXlFeFcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdTQU0gc2FtRGVzaXJlZCwgTFBIS0VZIHJldGtleSApCnsKCUxQS0VZU1RSVUNUCWxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKICAgIFRSQUNFXyhyZWcpKCIoMHgleCwlcywlbGQsJWx4LCVwKVxuIiwgaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGR3UmVzZXJ2ZWQsCiAgICAgICAgICBzYW1EZXNpcmVkLHJldGtleSk7CgogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBOZXh0S2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KSB7CiAgICAgICAgLyogRWl0aGVyIE5VTEwgb3IgcG9pbnRlciB0byBlbXB0eSBzdHJpbmcsIHNvIHJldHVybiBhIG5ldyBoYW5kbGUKICAgICAgICAgICB0byB0aGUgb3JpZ2luYWwgaGtleSAqLwogICAgICAgIGN1cnJlbnRoYW5kbGUgKz0gMjsKICAgICAgICBhZGRfaGFuZGxlKGN1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwogICAgICAgICpyZXRrZXk9Y3VycmVudGhhbmRsZTsKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAobHBzelN1YktleVswXSA9PSAnXFwnKSB7CiAgICAgICAgV0FSTl8ocmVnKSgiU3Via2V5ICVzIG11c3Qgbm90IGJlZ2luIHdpdGggYmFja3NsYXNoLlxuIixkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpKTsKICAgICAgICByZXR1cm4gRVJST1JfQkFEX1BBVEhOQU1FOwogICAgfQoKCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSA9IDA7Cgl3aGlsZSAoKGk8d3BjKSAmJiAod3BzW2ldWzBdPT0nXDAnKSkgaSsrOwoJbHB4a2V5ID0gbHBOZXh0S2V5OwoKICAgIHdoaWxlICh3cHNbaV0pIHsKICAgICAgICBscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwogICAgICAgIHdoaWxlIChscHhrZXkpIHsKICAgICAgICAgICAgaWYgKCFsc3RyY21waVcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxweGtleT1scHhrZXktPm5leHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWxweGtleSkgewogICAgICAgICAgICBUUkFDRV8ocmVnKSgiQ291bGQgbm90IGZpbmQgc3Via2V5ICVzXG4iLGRlYnVnc3RyX3cod3BzW2ldKSk7CiAgICAgICAgICAgIEZSRUVfS0VZX1BBVEg7CiAgICAgICAgICAgIHJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsKICAgICAgICB9CiAgICAgICAgaSsrOwogICAgICAgIGxwTmV4dEtleSA9IGxweGtleTsKICAgIH0KCiAgICBjdXJyZW50aGFuZGxlICs9IDI7CiAgICBhZGRfaGFuZGxlKGN1cnJlbnRoYW5kbGUsbHB4a2V5LHNhbURlc2lyZWQpOwogICAgKnJldGtleSA9IGN1cnJlbnRoYW5kbGU7CiAgICBUUkFDRV8ocmVnKSgiICBSZXR1cm5pbmcgJXhcbiIsIGN1cnJlbnRoYW5kbGUpOwogICAgRlJFRV9LRVlfUEFUSDsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5RXgzMkEgW0FEVkFQSTMyLjE0OV0KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5RXhBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdTQU0gc2FtRGVzaXJlZCwgTFBIS0VZIHJldGtleSApCnsKICAgIExQV1NUUiBscHN6U3ViS2V5VyA9IHN0cmR1cEEyVyhscHN6U3ViS2V5KTsKICAgIERXT1JEIHJldDsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVsZCwlbHgsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxkd1Jlc2VydmVkLAogICAgICAgICAgc2FtRGVzaXJlZCxyZXRrZXkpOwogICAgcmV0ID0gUmVnT3BlbktleUV4VyggaGtleSwgbHBzelN1YktleVcsIGR3UmVzZXJ2ZWQsIHNhbURlc2lyZWQsIHJldGtleSApOwogICAgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5MzJXIFtBRFZBUEkzMi4xNTFdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBzelN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleSB0byBvcGVuCiAqICAgIHJldGtleSAgICAgW09dIEFkZHJlc3Mgb2YgaGFuZGxlIG9mIG9wZW4ga2V5CiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICByZXR1cm4gUmVnT3BlbktleUV4VyggaGtleSwgbHBzelN1YktleSwgMCwgS0VZX0FMTF9BQ0NFU1MsIHJldGtleSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5MzJBIFtBRFZBUEkzMi4xNDhdCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBEV09SRCByZXQ7CiAgICBMUFdTVFIgbHBzelN1YktleVcgPSBzdHJkdXBBMlcobHBzelN1YktleSk7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldCA9ICBSZWdPcGVuS2V5VyggaGtleSwgbHBzelN1YktleVcsIHJldGtleSApOwogICAgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5MTYgW1NIRUxMLjFdIFtLRVJORUwuMjE3XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0dXJuIFJlZ09wZW5LZXlBKCBoa2V5LCBscHN6U3ViS2V5LCByZXRrZXkgKTsKfQoKCi8qIAogKiBDcmVhdGUga2V5cwogKiAKICogQWxsIHRob3NlIGZ1bmN0aW9ucyBjb252ZXJ0IHRoZWlyIHJlc3BlY3RpdmUgCiAqIGFyZ3VtZW50cyBhbmQgY2FsbCBSZWdDcmVhdGVLZXlFeFcgYXQgdGhlIGVuZC4KICoKICogV2Ugc3RheSBhd2F5IGZyb20gdGhlIEV4IGZ1bmN0aW9ucyBhcyBsb25nIGFzIHBvc3NpYmxlIGJlY2F1c2UgdGhlcmUgYXJlCiAqIGRpZmZlcmVuY2VzIGluIHRoZSByZXR1cm4gdmFsdWVzCiAqCiAqIENhbGxwYXRoOgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnQ3JlYXRlS2V5RXgzMkEgXAogKiBSZWdDcmVhdGVLZXkxNiAtPiBSZWdDcmVhdGVLZXkzMkEgLT4gUmVnQ3JlYXRlS2V5MzJXICAgLT4gUmVnQ3JlYXRlS2V5RXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXlFeDMyVyBbQURWQVBJMzIuMTMxXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgIFtJXSBIYW5kbGUgb2YgYW4gb3BlbiBrZXkKICogICAgbHBzelN1YktleSAgIFtJXSBBZGRyZXNzIG9mIHN1YmtleSBuYW1lCiAqICAgIGR3UmVzZXJ2ZWQgICBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIDAKICogICAgbHBzekNsYXNzICAgIFtJXSBBZGRyZXNzIG9mIGNsYXNzIHN0cmluZwogKiAgICBmZHdPcHRpb25zICAgW0ldIFNwZWNpYWwgb3B0aW9ucyBmbGFnCiAqICAgIHNhbURlc2lyZWQgICBbSV0gRGVzaXJlZCBzZWN1cml0eSBhY2Nlc3MKICogICAgbHBTZWNBdHRyaWJzIFtJXSBBZGRyZXNzIG9mIGtleSBzZWN1cml0eSBzdHJ1Y3R1cmUKICogICAgcmV0a2V5ICAgICAgIFtPXSBBZGRyZXNzIG9mIGJ1ZmZlciBmb3Igb3BlbmVkIGhhbmRsZQogKiAgICBscERpc3BvcyAgICAgW09dIFJlY2VpdmVzIFJFR19DUkVBVEVEX05FV19LRVkgb3IgUkVHX09QRU5FRF9FWElTVElOR19LRVkKICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXlFeFcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1Jlc2VydmVkLCBMUFdTVFIgbHBzekNsYXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBmZHdPcHRpb25zLCBSRUdTQU0gc2FtRGVzaXJlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgbHBTZWNBdHRyaWJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEhLRVkgcmV0a2V5LCBMUERXT1JEIGxwRGlzcG9zICkKewoJTFBLRVlTVFJVQ1QJKmxwbHBQcmV2S2V5LGxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJWxkLCVzLCVseCwlbHgsJXAsJXAsJXApXG4iLCBoa2V5LAoJCWRlYnVnc3RyX3cobHBzelN1YktleSksIGR3UmVzZXJ2ZWQsIGRlYnVnc3RyX3cobHBzekNsYXNzKSwKCQlmZHdPcHRpb25zLCBzYW1EZXNpcmVkLCBscFNlY0F0dHJpYnMsIHJldGtleSwgbHBEaXNwb3MpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIENoZWNrIGZvciB2YWxpZCBvcHRpb25zICovCiAgICBzd2l0Y2goZmR3T3B0aW9ucykgewogICAgICAgIGNhc2UgUkVHX09QVElPTl9OT05fVk9MQVRJTEU6CiAgICAgICAgY2FzZSBSRUdfT1BUSU9OX1ZPTEFUSUxFOgogICAgICAgIGNhc2UgUkVHX09QVElPTl9CQUNLVVBfUkVTVE9SRToKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwogICAgfQoKICAgIC8qIFNhbSBoYXMgdG8gYmUgYSBjb21iaW5hdGlvbiBvZiB0aGUgZm9sbG93aW5nICovCiAgICBpZiAoIShzYW1EZXNpcmVkICYgCiAgICAgICAgICAoS0VZX0FMTF9BQ0NFU1MgfCBLRVlfQ1JFQVRFX0xJTksgfCBLRVlfQ1JFQVRFX1NVQl9LRVkgfCAKICAgICAgICAgICBLRVlfRU5VTUVSQVRFX1NVQl9LRVlTIHwgS0VZX0VYRUNVVEUgfCBLRVlfTk9USUZZIHwKICAgICAgICAgICBLRVlfUVVFUllfVkFMVUUgfCBLRVlfUkVBRCB8IEtFWV9TRVRfVkFMVUUgfCBLRVlfV1JJVEUpKSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgoJaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkgewogICAgICAgICAgICAgICAgY3VycmVudGhhbmRsZSArPSAyOwoJCWFkZF9oYW5kbGUoY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgkJKnJldGtleT1jdXJyZW50aGFuZGxlOwogICAgICAgICAgICAgICAgVFJBQ0VfKHJlZykoIlJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CgkJbHBOZXh0S2V5LT5mbGFnc3w9UkVHX09QVElPTl9UQUlOVEVEOwoJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJfQoKICAgIGlmIChscHN6U3ViS2V5WzBdID09ICdcXCcpIHsKICAgICAgICBXQVJOXyhyZWcpKCJTdWJrZXkgJXMgbXVzdCBub3QgYmVnaW4gd2l0aCBiYWNrc2xhc2guXG4iLGRlYnVnc3RyX3cobHBzelN1YktleSkpOwogICAgICAgIHJldHVybiBFUlJPUl9CQURfUEFUSE5BTUU7CiAgICB9CgoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7Cgl3aGlsZSAoKGk8d3BjKSAmJiAod3BzW2ldWzBdPT0nXDAnKSkgaSsrOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKHdwc1tpXSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlpZiAoIWxzdHJjbXBpVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJCWJyZWFrOwoJCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJCX0KCQlpZiAoIWxweGtleSkKCQkJYnJlYWs7CgkJaSsrOwoJCWxwTmV4dEtleQk9IGxweGtleTsKCX0KCWlmIChscHhrZXkpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRoYW5kbGUgKz0gMjsKCQlhZGRfaGFuZGxlKGN1cnJlbnRoYW5kbGUsbHB4a2V5LHNhbURlc2lyZWQpOwoJCWxweGtleS0+ZmxhZ3MgIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCQkqcmV0a2V5CQk9IGN1cnJlbnRoYW5kbGU7CiAgICAgICAgICAgICAgICBUUkFDRV8ocmVnKSgiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCQlpZiAobHBEaXNwb3MpCgkJCSpscERpc3Bvcwk9IFJFR19PUEVORURfRVhJU1RJTkdfS0VZOwoJCUZSRUVfS0VZX1BBVEg7CgkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgl9CgoJLyogR29vZC4gIE5vdyB0aGUgaGFyZCBwYXJ0ICovCgl3aGlsZSAod3BzW2ldKSB7CgkJbHBscFByZXZLZXkJPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7CgkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCQlscHhrZXkJCT0gKmxwbHBQcmV2S2V5OwoJCX0KCQkqbHBscFByZXZLZXk9bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTsKCQlpZiAoISpscGxwUHJldktleSkgewoJCQlGUkVFX0tFWV9QQVRIOwogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRV8ocmVnKSgiUmV0dXJuaW5nIE9VVE9GTUVNT1JZXG4iKTsKCQkJcmV0dXJuIEVSUk9SX09VVE9GTUVNT1JZOwoJCX0KCQltZW1zZXQoKmxwbHBQcmV2S2V5LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpOwogICAgICAgICAgICAgICAgVFJBQ0VfKHJlZykoIkFkZGluZyAlc1xuIiwgZGVidWdzdHJfdyh3cHNbaV0pKTsKCQkoKmxwbHBQcmV2S2V5KS0+a2V5bmFtZQk9IHN0cmR1cFcod3BzW2ldKTsKCQkoKmxwbHBQcmV2S2V5KS0+bmV4dAk9IE5VTEw7CgkJKCpscGxwUHJldktleSktPm5leHRzdWIJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT52YWx1ZXMJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5ucm9mdmFsdWVzID0gMDsKCQkoKmxwbHBQcmV2S2V5KS0+ZmxhZ3MgCT0gUkVHX09QVElPTl9UQUlOVEVEOwoJCWlmIChscHN6Q2xhc3MpCgkJCSgqbHBscFByZXZLZXkpLT5jbGFzcyA9IHN0cmR1cFcobHBzekNsYXNzKTsKCQllbHNlCgkJCSgqbHBscFByZXZLZXkpLT5jbGFzcyA9IE5VTEw7CgkJbHBOZXh0S2V5CT0gKmxwbHBQcmV2S2V5OwoJCWkrKzsKCX0KICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CglhZGRfaGFuZGxlKGN1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwoKCS8qRklYTUU6IGZsYWcgaGFuZGxpbmcgY29ycmVjdD8gKi8KCWxwTmV4dEtleS0+ZmxhZ3M9IGZkd09wdGlvbnMgfFJFR19PUFRJT05fVEFJTlRFRDsKCWlmIChscHN6Q2xhc3MpCgkJbHBOZXh0S2V5LT5jbGFzcyA9IHN0cmR1cFcobHBzekNsYXNzKTsKCWVsc2UKCQlscE5leHRLZXktPmNsYXNzID0gTlVMTDsKCSpyZXRrZXkJCT0gY3VycmVudGhhbmRsZTsKICAgICAgICBUUkFDRV8ocmVnKSgiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCWlmIChscERpc3BvcykKCQkqbHBEaXNwb3MJPSBSRUdfQ1JFQVRFRF9ORVdfS0VZOwoJRlJFRV9LRVlfUEFUSDsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXlFeDMyQSBbQURWQVBJMzIuMTMwXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleUV4QSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiBscHN6Q2xhc3MsIERXT1JEIGZkd09wdGlvbnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR1NBTSBzYW1EZXNpcmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgbHBTZWNBdHRyaWJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEhLRVkgcmV0a2V5LCBMUERXT1JEIGxwRGlzcG9zICkKewogICAgTFBXU1RSIGxwc3pTdWJLZXlXLCBscHN6Q2xhc3NXOwogICAgRFdPUkQgIHJldDsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVsZCwlcywlbHgsJWx4LCVwLCVwLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSksCiAgICAgICAgICBkd1Jlc2VydmVkLGRlYnVnc3RyX2EobHBzekNsYXNzKSxmZHdPcHRpb25zLHNhbURlc2lyZWQsbHBTZWNBdHRyaWJzLAogICAgICAgICAgcmV0a2V5LGxwRGlzcG9zKTsKCiAgICBscHN6U3ViS2V5VyA9IGxwc3pTdWJLZXk/c3RyZHVwQTJXKGxwc3pTdWJLZXkpOk5VTEw7CiAgICBscHN6Q2xhc3NXID0gbHBzekNsYXNzP3N0cmR1cEEyVyhscHN6Q2xhc3MpOk5VTEw7CgogICAgcmV0ID0gUmVnQ3JlYXRlS2V5RXhXKCBoa2V5LCBscHN6U3ViS2V5VywgZHdSZXNlcnZlZCwgbHBzekNsYXNzVywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmR3T3B0aW9ucywgc2FtRGVzaXJlZCwgbHBTZWNBdHRyaWJzLCByZXRrZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwRGlzcG9zICk7CgogICAgaWYobHBzelN1YktleVcpIGZyZWUobHBzelN1YktleVcpOwogICAgaWYobHBzekNsYXNzVykgZnJlZShscHN6Q2xhc3NXKTsKCiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXkzMlcgW0FEVkFQSTMyLjEzMl0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIERXT1JEIGp1bms7CiAgICBMUEtFWVNUUlVDVAlscE5leHRLZXk7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcClcbiIsIGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxyZXRrZXkpOwoKICAgIC8qIFRoaXMgY2hlY2sgaXMgaGVyZSBiZWNhdXNlIHRoZSByZXR1cm4gdmFsdWUgaXMgZGlmZmVyZW50IHRoYW4gdGhlCiAgICAgICBvbmUgZnJvbSB0aGUgRXggZnVuY3Rpb25zICovCiAgICBscE5leHRLZXkgPSBsb29rdXBfaGtleShoa2V5KTsKICAgIGlmICghbHBOZXh0S2V5KQogICAgICAgIHJldHVybiBFUlJPUl9CQURLRVk7CgogICAgcmV0dXJuIFJlZ0NyZWF0ZUtleUV4VyggaGtleSwgbHBzelN1YktleSwgMCwgTlVMTCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfQUxMX0FDQ0VTUywgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0a2V5LCAmanVuayk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleTMyQSBbQURWQVBJMzIuMTI5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBEV09SRCByZXQ7CiAgICBMUFdTVFIgbHBzelN1YktleVc7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICBscHN6U3ViS2V5VyA9IGxwc3pTdWJLZXk/c3RyZHVwQTJXKGxwc3pTdWJLZXkpOk5VTEw7CiAgICByZXQgPSBSZWdDcmVhdGVLZXlXKCBoa2V5LCBscHN6U3ViS2V5VywgcmV0a2V5ICk7CiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXkxNiBbU0hFTEwuMl0gW0tFUk5FTC4yMThdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdDcmVhdGVLZXlBKCBoa2V5LCBscHN6U3ViS2V5LCByZXRrZXkgKTsKfQoKCi8qIAogKiBRdWVyeSBWYWx1ZSBGdW5jdGlvbnMKICogV2luMzIgZGlmZmVycyBiZXR3ZWVuIGtleW5hbWVzIGFuZCB2YWx1ZW5hbWVzLiAKICogbXVsdGlwbGUgdmFsdWVzIG1heSBiZWxvbmcgdG8gb25lIGtleSwgdGhlIHNwZWNpYWwgdmFsdWUKICogd2l0aCBuYW1lIE5VTEwgaXMgdGhlIGRlZmF1bHQgdmFsdWUgdXNlZCBieSB0aGUgd2luMzEKICogY29tcGF0IGZ1bmN0aW9ucy4KICoKICogQ2FsbHBhdGg6CiAqIFJlZ1F1ZXJ5VmFsdWUxNiAtPiBSZWdRdWVyeVZhbHVlMzJBIC0+IFJlZ1F1ZXJ5VmFsdWVFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUzMlcgLT4gUmVnUXVlcnlWYWx1ZUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZUV4MzJXIFtBRFZBUEkzMi4xNThdCiAqIFJldHJpZXZlcyB0eXBlIGFuZCBkYXRhIGZvciBhIHNwZWNpZmllZCBuYW1lIGFzc29jaWF0ZWQgd2l0aCBhbiBvcGVuIGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICBbSV0gICBIYW5kbGUgb2Yga2V5IHRvIHF1ZXJ5CiAqICAgIGxwVmFsdWVOYW1lICAgW0ldICAgTmFtZSBvZiB2YWx1ZSB0byBxdWVyeQogKiAgICBscGR3UmVzZXJ2ZWQgIFtJXSAgIFJlc2VydmVkIC0gbXVzdCBiZSBOVUxMCiAqICAgIGxwZHdUeXBlICAgICAgW09dICAgQWRkcmVzcyBvZiBidWZmZXIgZm9yIHZhbHVlIHR5cGUuICBJZiBOVUxMLCB0aGUgdHlwZQogKiAgICAgICAgICAgICAgICAgICAgICAgIGlzIG5vdCByZXF1aXJlZC4KICogICAgbHBiRGF0YSAgICAgICBbT10gICBBZGRyZXNzIG9mIGRhdGEgYnVmZmVyLiAgSWYgTlVMTCwgdGhlIGFjdHVhbCBkYXRhIGlzCiAqICAgICAgICAgICAgICAgICAgICAgICAgbm90IHJlcXVpcmVkLgogKiAgICBscGNiRGF0YSAgICAgIFtJL09dIEFkZHJlc3Mgb2YgZGF0YSBidWZmZXIgc2l6ZQogKgogKiBSRVRVUk5TIAogKiAgICBFUlJPUl9TVUNDRVNTOiAgIFN1Y2Nlc3MKICogICAgRVJST1JfTU9SRV9EQVRBOiAhISEgaWYgdGhlIHNwZWNpZmllZCBidWZmZXIgaXMgbm90IGJpZyBlbm91Z2ggdG8gaG9sZCB0aGUgZGF0YQogKiAJCSAgICAgICBidWZmZXIgaXMgbGVmdCB1bnRvdWNoZWQuIFRoZSBNUy1kb2N1bWVudGF0aW9uIGlzIHdyb25nIChqcykgISEhCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwVmFsdWVOYW1lLAoJCQkgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBkd1R5cGUsCgkJCSAgICAgICBMUEJZVEUgbHBiRGF0YSwgTFBEV09SRCBscGNiRGF0YSApCnsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJaW50CQlpOwoJRFdPUkQJCXJldDsKCglUUkFDRV8ocmVnKSgiKDB4JXgsJXMsJXAsJXAsJXAsJXA9JWxkKVxuIiwgaGtleSwgZGVidWdzdHJfdyhscFZhbHVlTmFtZSksCiAgICAgICAgICBscGR3UmVzZXJ2ZWQsIGxwZHdUeXBlLCBscGJEYXRhLCBscGNiRGF0YSwgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CgoJaWYgKCFscGtleSkKCSAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKCWlmICgobHBiRGF0YSAmJiAhIGxwY2JEYXRhKSB8fCBscGR3UmVzZXJ2ZWQpCgkgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCgkvKiBBbiBlbXB0eSBuYW1lIHN0cmluZyBpcyBlcXVpdmFsZW50IHRvIE5VTEwgKi8KCWlmIChscFZhbHVlTmFtZSAmJiAhKmxwVmFsdWVOYW1lKQoJICBscFZhbHVlTmFtZSA9IE5VTEw7CgoJaWYgKGxwVmFsdWVOYW1lPT1OVUxMKSAKCXsgLyogVXNlIGtleSdzIHVubmFtZWQgb3IgZGVmYXVsdCB2YWx1ZSwgaWYgYW55ICovCgkgIGZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJICAgIGlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkgICAgICBicmVhazsKCX0gCgllbHNlIAoJeyAvKiBTZWFyY2ggZm9yIHRoZSBrZXkgbmFtZSAqLwoJICBmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCSAgICBpZiAoIGxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJiAhbHN0cmNtcGlXKGxwVmFsdWVOYW1lLGxwa2V5LT52YWx1ZXNbaV0ubmFtZSkpCgkgICAgICBicmVhazsKCX0KCglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIAoJeyBUUkFDRV8ocmVnKSgiIEtleSBub3QgZm91bmRcbiIpOwoJICBpZiAobHBWYWx1ZU5hbWU9PU5VTEwpIAoJICB7IC8qIEVtcHR5IGtleW5hbWUgbm90IGZvdW5kICovCgkgICAgaWYgKGxwYkRhdGEpIAoJICAgIHsgKihXQ0hBUiopbHBiRGF0YSA9IDA7CgkgICAgICAqbHBjYkRhdGEJPSAyOwoJICAgIH0KCSAgICBpZiAobHBkd1R5cGUpCgkgICAgICAqbHBkd1R5cGUJPSBSRUdfU1o7CgkgICAgVFJBQ0VfKHJlZykoIiBSZXR1cm5pbmcgYW4gZW1wdHkgc3RyaW5nXG4iKTsKCSAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKCSAgfQoJICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7Cgl9CgoJcmV0ID0gRVJST1JfU1VDQ0VTUzsKCglpZiAobHBkd1R5cGUpIAkJCQkJLyogdHlwZSByZXF1aXJlZCA/Ki8KCSAgKmxwZHdUeXBlID0gbHBrZXktPnZhbHVlc1tpXS50eXBlOwoKCWlmIChscGJEYXRhKQkJCQkJLyogZGF0YSByZXF1aXJlZCA/Ki8KCXsgaWYgKCpscGNiRGF0YSA+PSBscGtleS0+dmFsdWVzW2ldLmxlbikJLyogYnVmZmVyIGxhcmdlIGVub3VnaHQgPyovCgkgICAgbWVtY3B5KGxwYkRhdGEsbHBrZXktPnZhbHVlc1tpXS5kYXRhLGxwa2V5LT52YWx1ZXNbaV0ubGVuKTsKCSAgZWxzZSB7CgkgICAgKmxwY2JEYXRhID0gbHBrZXktPnZhbHVlc1tpXS5sZW47CgkgICAgcmV0ID0gRVJST1JfTU9SRV9EQVRBOwoJICB9Cgl9CgoJaWYgKGxwY2JEYXRhKSAJCQkJCS8qIHNpemUgcmVxdWlyZWQgPyovCgl7ICpscGNiRGF0YSA9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwoJfQoKCWRlYnVnX3ByaW50X3ZhbHVlICggbHBiRGF0YSwgJmxwa2V5LT52YWx1ZXNbaV0pOwoKCVRSQUNFXyhyZWcpKCIgKHJldD0lbHgsIHR5cGU9JWx4LCBsZW49JWxkKVxuIiwgcmV0LCBscGR3VHlwZT8qbHBkd1R5cGU6MCxscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZTMyVyBbQURWQVBJMzIuMTU5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBXU1RSIGxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBMT05HIGxwY2JEYXRhICkKewoJSEtFWQl4aGtleTsKCURXT1JECXJldCxscGR3VHlwZTsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGxwc3pEYXRhLAogICAgICAgICAgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIC8qIE9ubHkgb3BlbiBzdWJrZXksIGlmIHdlIHJlYWxseSBkbyBkZXNjZW5kICovCiAgICBpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewogICAgICAgIHJldCA9IFJlZ09wZW5LZXlXKCBoa2V5LCBscHN6U3ViS2V5LCAmeGhrZXkgKTsKICAgICAgICBpZiAocmV0ICE9IEVSUk9SX1NVQ0NFU1MpIHsKICAgICAgICAgICAgV0FSTl8ocmVnKSgiQ291bGQgbm90IG9wZW4gJXNcbiIsIGRlYnVnc3RyX3cobHBzelN1YktleSkpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgIH0gZWxzZQogICAgICAgIHhoa2V5ID0gaGtleTsKCiAgICBscGR3VHlwZSA9IFJFR19TWjsKICAgIHJldCA9IFJlZ1F1ZXJ5VmFsdWVFeFcoIHhoa2V5LCBOVUxMLCBOVUxMLCAmbHBkd1R5cGUsIChMUEJZVEUpbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwY2JEYXRhICk7CiAgICBpZiAoeGhrZXkgIT0gaGtleSkKICAgICAgICBSZWdDbG9zZUtleSh4aGtleSk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlRXgzMkEgW0FEVkFQSTMyLjE1N10KICoKICogTk9URVM6CiAqIHRoZSBkb2N1bWFudGF0aW9uIGlzIHdyb25nOiBpZiB0aGUgYnVmZmVyIGlzIHRvIHNtYWxsIGl0IHJlbWFpbnMgdW50b3VjaGVkIAogKgogKiBGSVhNRTogY2hlY2sgcmV0dXJudmFsdWUgKGxlbikgZm9yIGFuIGVtcHR5IGtleQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeEEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pWYWx1ZU5hbWUsCgkJCSAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGR3VHlwZSwKCQkJICAgICAgIExQQllURSBscGJEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBXU1RSCWxwc3pWYWx1ZU5hbWVXOwoJTFBCWVRFCW15YnVmID0gTlVMTDsKCURXT1JECXJldCwgbXl0eXBlLCBteWxlbiA9IDA7CgoJVFJBQ0VfKHJlZykoIigleCwlcywlcCwlcCwlcCwlcD0lbGQpXG4iLCBoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlTmFtZSksCiAgICAgICAgICBscGR3UmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YSxscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgoJaWYgKCFscGNiRGF0YSAmJiBscGJEYXRhKQkJCS8qIGJ1ZmZlciB3aXRob3V0IHNpemUgaXMgaWxsZWdhbCAqLwoJeyAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoJfQoKCWxwc3pWYWx1ZU5hbWVXID0gbHBzelZhbHVlTmFtZSA/IHN0cmR1cEEyVyhscHN6VmFsdWVOYW1lKSA6IE5VTEw7CQoJCgkvKiBnZXQganVzdCB0aGUgdHlwZSBmaXJzdCAqLwoJcmV0ID0gUmVnUXVlcnlWYWx1ZUV4VyggaGtleSwgbHBzelZhbHVlTmFtZVcsIGxwZHdSZXNlcnZlZCwgJm15dHlwZSwgTlVMTCwgTlVMTCApOwoJCglpZiAoIHJldCAhPSBFUlJPUl9TVUNDRVNTICkJCQkvKiBmYWlsZWQgPz8gKi8KCXsgaWYobHBzelZhbHVlTmFtZVcpIGZyZWUobHBzelZhbHVlTmFtZVcpOwoJICByZXR1cm4gcmV0OwoJfQoJCglpZiAobHBjYkRhdGEpCQkJCQkvKiBhdCBsZWFzdCBsZW5ndGggcmVxdWVzdGVkPyAqLwoJeyBpZiAoVU5JQ09OVk1BU0sgJiAoMTw8KG15dHlwZSkpKQkJLyogc3RyaW5nIHJlcXVlc3RlZD8gKi8KCSAgeyBpZiAobHBiRGF0YSApCQkJCS8qIHZhbHVlIHJlcXVlc3RlZD8gKi8KCSAgICB7IG15bGVuID0gMiooICpscGNiRGF0YSApOwoJICAgICAgbXlidWYgPSAoTFBCWVRFKXhtYWxsb2MoIG15bGVuICk7CgkgICAgfQoKCSAgICByZXQgPSBSZWdRdWVyeVZhbHVlRXhXKCBoa2V5LCBscHN6VmFsdWVOYW1lVywgbHBkd1Jlc2VydmVkLCBscGR3VHlwZSwgbXlidWYsICZteWxlbiApOwoKCSAgICBpZiAocmV0ID09IEVSUk9SX1NVQ0NFU1MgKQoJICAgIHsgaWYgKCBscGJEYXRhICkKCSAgICAgIHsgbG1lbWNweW5XdG9BKGxwYkRhdGEsIChMUFdTVFIpbXlidWYsIG15bGVuLzIpOwoJICAgICAgfQoJICAgIH0KCgkgICAgKmxwY2JEYXRhID0gbXlsZW4vMjsJCQkvKiBzaXplIGlzIGluIGJ5dGUhICovCgkgIH0KCSAgZWxzZQkJCQkJCS8qIG5vIHN0cmluZ3MsIGNhbGwgaXQgc3RyYWlnaHQgKi8KCSAgeyByZXQgPSBSZWdRdWVyeVZhbHVlRXhXKCBoa2V5LCBscHN6VmFsdWVOYW1lVywgbHBkd1Jlc2VydmVkLCBscGR3VHlwZSwgbHBiRGF0YSwgbHBjYkRhdGEgKTsKCSAgfQoJfQoJCglpZiAobHBkd1R5cGUpCQkJCQkvKiB0eXBlIHdoZW4gcmVxdWVzdGVkICovCgl7ICpscGR3VHlwZSA9IG15dHlwZTsKCX0KCglUUkFDRV8ocmVnKSgiIChyZXQ9JWx4LHR5cGU9JWx4LCBsZW49JWxkKVxuIiwgcmV0LG15dHlwZSxscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgkKCWlmKG15YnVmKSBmcmVlKG15YnVmKTsKCWlmKGxwc3pWYWx1ZU5hbWVXKSBmcmVlKGxwc3pWYWx1ZU5hbWVXKTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWVFeDE2IFtLRVJORUwuMjI1XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGxwYkRhdGEsIExQRFdPUkQgbHBjYkRhdGEgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVwLCVwLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeEEoIGhrZXksIGxwc3pWYWx1ZU5hbWUsIGxwZHdSZXNlcnZlZCwgbHBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscGJEYXRhLCBscGNiRGF0YSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlMzJBIFtBRFZBUEkzMi4xNTZdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQU1RSIGxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBMT05HIGxwY2JEYXRhICkKewogICAgSEtFWSB4aGtleTsKICAgIERXT1JEIHJldCwgZHdUeXBlOwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSksbHBzekRhdGEsCiAgICAgICAgICBscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgogICAgaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKICAgICAgICByZXQgPSBSZWdPcGVuS2V5MTYoIGhrZXksIGxwc3pTdWJLZXksICZ4aGtleSApOwogICAgICAgIGlmKCByZXQgIT0gRVJST1JfU1VDQ0VTUyApCiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICB9IGVsc2UKICAgICAgICB4aGtleSA9IGhrZXk7CgogICAgZHdUeXBlID0gUkVHX1NaOwogICAgcmV0ID0gUmVnUXVlcnlWYWx1ZUV4QSggeGhrZXksIE5VTEwsTlVMTCwgJmR3VHlwZSwgKExQQllURSlscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBjYkRhdGEgKTsKICAgIGlmKCB4aGtleSAhPSBoa2V5ICkKICAgICAgICBSZWdDbG9zZUtleSggeGhrZXkgKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWUxNiBbU0hFTEwuNl0gW0tFUk5FTC4yMjRdCiAqCiAqIE5PVEVTCiAqICAgIElzIHRoaXMgSEFDSyBzdGlsbCBhcHBsaWNhYmxlPwogKgogKiBIQUNLCiAqICAgIFRoZSAxNmJpdCBSZWdRdWVyeVZhbHVlIGRvZXNuJ3QgaGFuZGxlIHNlbGVjdG9yYmxvY2tzIGFueXdheSwgc28gd2UganVzdAogKiAgICBtYXNrIG91dCB0aGUgaGlnaCAxNiBiaXQuICBUaGlzIChub3Qgc28gbXVjaCBpbmNpZGVudGx5KSBob3BlZnVsbHkgZml4ZXMKICogICAgQWxkdXMgRkg0KQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUxNiggSEtFWSBoa2V5LCBMUFNUUiBscHN6U3ViS2V5LCBMUFNUUiBscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSksbHBzekRhdGEsCiAgICAgICAgICBscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgogICAgaWYgKGxwY2JEYXRhKQogICAgICAgICpscGNiRGF0YSAmPSAweEZGRkY7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUEoaGtleSxscHN6U3ViS2V5LGxwc3pEYXRhLGxwY2JEYXRhKTsKfQoKCi8qCiAqIFNldHRpbmcgdmFsdWVzIG9mIFJlZ2lzdHJ5IGtleXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ1NldFZhbHVlMTYgLT4gUmVnU2V0VmFsdWUzMkEgLT4gUmVnU2V0VmFsdWVFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnU2V0VmFsdWUzMlcgICAtPiBSZWdTZXRWYWx1ZUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWVFeDMyVyBbQURWQVBJMzIuMTcwXQogKiBTZXRzIHRoZSBkYXRhIGFuZCB0eXBlIG9mIGEgdmFsdWUgdW5kZXIgYSByZWdpc3RlciBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldIEhhbmRsZSBvZiBrZXkgdG8gc2V0IHZhbHVlIGZvcgogKiAgICBscHN6VmFsdWVOYW1lIFtJXSBOYW1lIG9mIHZhbHVlIHRvIHNldAogKiAgICBkd1Jlc2VydmVkICAgIFtJXSBSZXNlcnZlZCAtIG11c3QgYmUgemVybwogKiAgICBkd1R5cGUgICAgICAgIFtJXSBGbGFnIGZvciB2YWx1ZSB0eXBlCiAqICAgIGxwYkRhdGEgICAgICAgW0ldIEFkZHJlc3Mgb2YgdmFsdWUgZGF0YQogKiAgICBjYkRhdGEgICAgICAgIFtJXSBTaXplIG9mIHZhbHVlIGRhdGEKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICoKICogTk9URVMKICogICB3aW45NSBkb2VzIG5vdCBjYXJlIGFib3V0IGNiRGF0YSBmb3IgUkVHX1NaIGFuZCBmaW5kcyBvdXQgdGhlIGxlbiBieSBpdHNlbGYgKGpzKSAKICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pWYWx1ZU5hbWUsIAoJCQkgICAgIERXT1JEIGR3UmVzZXJ2ZWQsIERXT1JEIGR3VHlwZSwKCQkJICAgICBDT05TVCBCWVRFICpscGJEYXRhLCBEV09SRCBjYkRhdGEpCnsKCUxQS0VZU1RSVUNUIGxwa2V5OwoJaW50IGk7CgoJVFJBQ0VfKHJlZykoIigleCwlcywlbGQsJWxkLCVwLCVsZClcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBzelZhbHVlTmFtZSksCiAgICAgICAgICBkd1Jlc2VydmVkLCBkd1R5cGUsIGxwYkRhdGEsIGNiRGF0YSk7CgoJbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwoKCWlmICghbHBrZXkpCiAgICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCglpZiAobHBzelZhbHVlTmFtZT09TlVMTCkgewogICAgICAgICAgICAgLyogU2V0cyB0eXBlIGFuZCBuYW1lIGZvciBrZXkncyB1bm5hbWVkIG9yIGRlZmF1bHQgdmFsdWUgKi8KCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJfSBlbHNlIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKAlscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYKCQkJCSFsc3RyY21waVcobHBzelZhbHVlTmFtZSxscGtleS0+dmFsdWVzW2ldLm5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CgkJbHBrZXktPnZhbHVlcyA9IChMUEtFWVZBTFVFKXhyZWFsbG9jKAoJCQkJCWxwa2V5LT52YWx1ZXMsCgkJCQkJKGxwa2V5LT5ucm9mdmFsdWVzKzEpKnNpemVvZihLRVlWQUxVRSkKCQkJCSk7CgkJbHBrZXktPm5yb2Z2YWx1ZXMrKzsKCQltZW1zZXQobHBrZXktPnZhbHVlcytpLCdcMCcsc2l6ZW9mKEtFWVZBTFVFKSk7Cgl9CglpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKSB7CgkJaWYgKGxwc3pWYWx1ZU5hbWUpCgkJCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSA9IHN0cmR1cFcobHBzelZhbHVlTmFtZSk7CgkJZWxzZQoJCQlscGtleS0+dmFsdWVzW2ldLm5hbWUgPSBOVUxMOwoJfQoKCWlmIChkd1R5cGUgPT0gUkVHX1NaKQoJICBjYkRhdGEgPSAyICogKGxzdHJsZW5XICgoTFBDV1NUUilscGJEYXRhKSArIDEpOwoJICAKCWxwa2V5LT52YWx1ZXNbaV0ubGVuCT0gY2JEYXRhOwoJbHBrZXktPnZhbHVlc1tpXS50eXBlCT0gZHdUeXBlOwoJaWYgKGxwa2V5LT52YWx1ZXNbaV0uZGF0YSAhPU5VTEwpCgkJZnJlZShscGtleS0+dmFsdWVzW2ldLmRhdGEpOwoJbHBrZXktPnZhbHVlc1tpXS5kYXRhCT0gKExQQllURSl4bWFsbG9jKGNiRGF0YSk7CglscGtleS0+dmFsdWVzW2ldLmxhc3Rtb2RpZmllZCA9IHRpbWUoTlVMTCk7CgltZW1jcHkobHBrZXktPnZhbHVlc1tpXS5kYXRhLGxwYkRhdGEsY2JEYXRhKTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZUV4MzJBIFtBRFZBUEkzMi4xNjldCiAqCiAqIE5PVEVTCiAqICAgd2luOTUgZG9lcyBub3QgY2FyZSBhYm91dCBjYkRhdGEgZm9yIFJFR19TWiBhbmQgZmluZHMgb3V0IHRoZSBsZW4gYnkgaXRzZWxmIChqcykgCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeEEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pWYWx1ZU5hbWUsCgkJCSAgICAgRFdPUkQgZHdSZXNlcnZlZCwgRFdPUkQgZHdUeXBlLAoJCQkgICAgIENPTlNUIEJZVEUgKmxwYkRhdGEsIERXT1JEIGNiRGF0YSApCnsKCUxQQllURQlidWY7CglMUFdTVFIJbHBzelZhbHVlTmFtZVc7CglEV09SRAlyZXQ7CgoJaWYgKCFscGJEYXRhKQoJCXJldHVybiAoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwoJCQoJVFJBQ0VfKHJlZykoIigleCwlcywlbGQsJWxkLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgZHdSZXNlcnZlZCxkd1R5cGUsbHBiRGF0YSxjYkRhdGEpOwoKCWlmICgoMTw8ZHdUeXBlKSAmIFVOSUNPTlZNQVNLKSAKCXsgaWYgKGR3VHlwZSA9PSBSRUdfU1opCgkgICAgY2JEYXRhID0gc3RybGVuICgoTFBDU1RSKWxwYkRhdGEpKzE7CgoJICBidWYgPSAoTFBCWVRFKXhtYWxsb2MoIGNiRGF0YSAqMiApOwoJICBsbWVtY3B5bkF0b1cgKChMUFZPSUQpYnVmLCBscGJEYXRhLCBjYkRhdGEgKTsKCSAgY2JEYXRhPTIqY2JEYXRhOwoJfSAKCWVsc2UKCSAgYnVmPShMUEJZVEUpbHBiRGF0YTsKCglpZiAobHBzelZhbHVlTmFtZSkKCSAgbHBzelZhbHVlTmFtZVcgPSBzdHJkdXBBMlcobHBzelZhbHVlTmFtZSk7CgllbHNlCgkgIGxwc3pWYWx1ZU5hbWVXID0gTlVMTDsKCglyZXQ9UmVnU2V0VmFsdWVFeFcoaGtleSxscHN6VmFsdWVOYW1lVyxkd1Jlc2VydmVkLGR3VHlwZSxidWYsY2JEYXRhKTsKCglpZiAobHBzelZhbHVlTmFtZVcpCgkgIGZyZWUobHBzelZhbHVlTmFtZVcpOwoKCWlmIChidWYhPWxwYkRhdGEpCgkgIGZyZWUoYnVmKTsKCglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZUV4MTYgW0tFUk5FTC4yMjZdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZU5hbWUsIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsIERXT1JEIGNiRGF0YSApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsZHdUeXBlLGxwYkRhdGEsY2JEYXRhKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUV4QSggaGtleSwgbHBzelZhbHVlTmFtZSwgZHdSZXNlcnZlZCwgZHdUeXBlLCBscGJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNiRGF0YSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZTMyVwlbQURWQVBJMzIuMTcxXQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIGxwc3pEYXRhLCBEV09SRCBjYkRhdGEgKQp7CglIS0VZCXhoa2V5OwoJRFdPUkQJcmV0OwoKCVRSQUNFXyhyZWcpKCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsCgkJaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGR3VHlwZSxkZWJ1Z3N0cl93KGxwc3pEYXRhKSxjYkRhdGEKCSk7CglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldD1SZWdDcmVhdGVLZXlXKGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleT1oa2V5OwoJaWYgKGR3VHlwZSE9UkVHX1NaKSB7CgkJVFJBQ0VfKHJlZykoImR3VHlwZT0lbGQgLSBDaGFuZ2luZyB0byBSRUdfU1pcbiIsZHdUeXBlKTsKCQlkd1R5cGU9UkVHX1NaOwoJfQoJaWYgKGNiRGF0YSE9Mipsc3RybGVuVyhscHN6RGF0YSkrMikgewoJCVRSQUNFXyhyZWcpKCJMZW49JWxkICE9IHN0cmxlbiglcykrMT0lZCFcbiIsCgkJCWNiRGF0YSxkZWJ1Z3N0cl93KGxwc3pEYXRhKSwyKmxzdHJsZW5XKGxwc3pEYXRhKSsyCgkJKTsKCQljYkRhdGE9Mipsc3RybGVuVyhscHN6RGF0YSkrMjsKCX0KCXJldD1SZWdTZXRWYWx1ZUV4Vyh4aGtleSxOVUxMLDAsZHdUeXBlLChMUEJZVEUpbHBzekRhdGEsY2JEYXRhKTsKCWlmIChoa2V5IT14aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZTMyQSBbQURWQVBJMzIuMTY4XQogKgogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgRFdPUkQgZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscHN6RGF0YSwgRFdPUkQgY2JEYXRhICkKewoJRFdPUkQJcmV0OwoJSEtFWQl4aGtleTsKCglUUkFDRV8ocmVnKSgiKCV4LCVzLCVsZCwlcywlbGQpXG4iLGhrZXksbHBzelN1YktleSxkd1R5cGUsbHBzekRhdGEsY2JEYXRhKTsKCWlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CgkJcmV0PVJlZ0NyZWF0ZUtleTE2KGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleT1oa2V5OwoKCWlmIChkd1R5cGUhPVJFR19TWikgewoJCVRSQUNFXyhyZWcpKCJkd1R5cGU9JWxkIVxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT1zdHJsZW4obHBzekRhdGEpKzEpCgkJY2JEYXRhPXN0cmxlbihscHN6RGF0YSkrMTsKCXJldD1SZWdTZXRWYWx1ZUV4QSh4aGtleSxOVUxMLDAsZHdUeXBlLChMUEJZVEUpbHBzekRhdGEsY2JEYXRhKTsKCWlmICh4aGtleSE9aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZTE2IFtLRVJORUwuMjIxXSBbU0hFTEwuNV0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRAlkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBzekRhdGEsIERXT1JEIGNiRGF0YSApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGR3VHlwZSwKICAgICAgICAgIGRlYnVnc3RyX2EobHBzekRhdGEpLGNiRGF0YSk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVBKGhrZXksbHBzelN1YktleSxkd1R5cGUsbHBzekRhdGEsY2JEYXRhKTsKfQoKCi8qIAogKiBLZXkgRW51bWVyYXRpb24KICoKICogQ2FsbHBhdGg6CiAqIFJlZ0VudW1LZXkxNiAtPiBSZWdFbnVtS2V5MzJBIC0+IFJlZ0VudW1LZXlFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ0VudW1LZXkzMlcgICAtPiBSZWdFbnVtS2V5RXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5RXgzMlcgW0FEVkFQSTMyLjEzOV0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICBbSV0gSGFuZGxlIHRvIGtleSB0byBlbnVtZXJhdGUKICogICAgaVN1YktleSAgICAgIFtJXSBJbmRleCBvZiBzdWJrZXkgdG8gZW51bWVyYXRlCiAqICAgIGxwc3pOYW1lICAgICBbT10gQnVmZmVyIGZvciBzdWJrZXkgbmFtZQogKiAgICBscGNjaE5hbWUgICAgW09dIFNpemUgb2Ygc3Via2V5IGJ1ZmZlcgogKiAgICBscGR3UmVzZXJ2ZWQgW0ldIFJlc2VydmVkCiAqICAgIGxwc3pDbGFzcyAgICBbT10gQnVmZmVyIGZvciBjbGFzcyBzdHJpbmcKICogICAgbHBjY2hDbGFzcyAgIFtPXSBTaXplIG9mIGNsYXNzIGJ1ZmZlcgogKiAgICBmdCAgICAgICAgICAgW09dIFRpbWUga2V5IGxhc3Qgd3JpdHRlbiB0bwogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlFeFcoIEhLRVkgaGtleSwgRFdPUkQgaVN1YmtleSwgTFBXU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTmFtZSwgTFBEV09SRCBscGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBscHN6Q2xhc3MsIExQRFdPUkQgbHBjY2hDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVUSU1FICpmdCApCnsKCUxQS0VZU1RSVUNUCWxwa2V5LGxweGtleTsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVsZCwlcCwlbGQsJXAsJXAsJXAsJXApXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSwKICAgICAgICAgICpscGNjaE5hbWUsbHBkd1Jlc2VydmVkLGxwc3pDbGFzcyxscGNjaENsYXNzLGZ0KTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglpZiAoIWxwa2V5LT5uZXh0c3ViKQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoJbHB4a2V5PWxwa2V5LT5uZXh0c3ViOwoKICAgIC8qIFRyYXZlcnNlIHRoZSBzdWJrZXlzICovCgl3aGlsZSAoaVN1YmtleSAmJiBscHhrZXkpIHsKCQlpU3Via2V5LS07CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCglpZiAoaVN1YmtleSB8fCAhbHB4a2V5KQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoJaWYgKGxzdHJsZW5XKGxweGtleS0+a2V5bmFtZSkrMT4qbHBjY2hOYW1lKSB7CgkJKmxwY2NoTmFtZSA9IGxzdHJsZW5XKGxweGtleS0+a2V5bmFtZSkrMTsKCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJfQoJbWVtY3B5KGxwc3pOYW1lLGxweGtleS0+a2V5bmFtZSxsc3RybGVuVyhscHhrZXktPmtleW5hbWUpKjIrMik7CgogICAgICAgIGlmICgqbHBjY2hOYW1lKQogICAgICAgICAgICAqbHBjY2hOYW1lID0gbHN0cmxlblcobHBzek5hbWUpOwoKCWlmIChscHN6Q2xhc3MpIHsKCQkvKiBGSVhNRTogd2hhdCBzaG91bGQgd2Ugd3JpdGUgaW50byBpdD8gKi8KCQkqbHBzekNsYXNzCT0gMDsKCQkqbHBjY2hDbGFzcwk9IDI7Cgl9CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleTMyVyBbQURWQVBJMzIuMTQwXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlXKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQV1NUUiBscHN6TmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBGSUxFVElNRQlmdDsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwogICAgcmV0dXJuIFJlZ0VudW1LZXlFeFcoaGtleSxpU3Via2V5LGxwc3pOYW1lLCZscGNjaE5hbWUsTlVMTCxOVUxMLE5VTEwsJmZ0KTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleUV4MzJBIFtBRFZBUEkzMi4xMzhdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleUV4QSggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE5hbWUsIExQRFdPUkQgbHBkd1Jlc2VydmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgbHBzekNsYXNzLCBMUERXT1JEIGxwY2NoQ2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFVElNRSAqZnQgKQp7CglEV09SRAlyZXQsbHBjY2hOYW1lVyxscGNjaENsYXNzVzsKCUxQV1NUUglscHN6TmFtZVcsbHBzekNsYXNzVzsKCgoJVFJBQ0VfKHJlZykoIigleCwlbGQsJXAsJWxkLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlTdWJrZXksbHBzek5hbWUsKmxwY2NoTmFtZSxscGR3UmVzZXJ2ZWQsbHBzekNsYXNzLGxwY2NoQ2xhc3MsZnQKCSk7CglpZiAobHBzek5hbWUpIHsKCQlscHN6TmFtZVcJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoTmFtZSoyKTsKCQlscGNjaE5hbWVXCT0gKmxwY2NoTmFtZTsKCX0gZWxzZSB7CgkJbHBzek5hbWVXCT0gTlVMTDsKCQlscGNjaE5hbWVXIAk9IDA7Cgl9CglpZiAobHBzekNsYXNzKSB7CgkJbHBzekNsYXNzVwkJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoQ2xhc3MqMik7CgkJbHBjY2hDbGFzc1cJPSAqbHBjY2hDbGFzczsKCX0gZWxzZSB7CgkJbHBzekNsYXNzVwk9MDsKCQlscGNjaENsYXNzVz0wOwoJfQoJcmV0PVJlZ0VudW1LZXlFeFcoCgkJaGtleSwKCQlpU3Via2V5LAoJCWxwc3pOYW1lVywKCQkmbHBjY2hOYW1lVywKCQlscGR3UmVzZXJ2ZWQsCgkJbHBzekNsYXNzVywKCQkmbHBjY2hDbGFzc1csCgkJZnQKCSk7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJbHN0cmNweVd0b0EobHBzek5hbWUsbHBzek5hbWVXKTsKCQkqbHBjY2hOYW1lPXN0cmxlbihscHN6TmFtZSk7CgkJaWYgKGxwc3pDbGFzc1cpIHsKCQkJbHN0cmNweVd0b0EobHBzekNsYXNzLGxwc3pDbGFzc1cpOwoJCQkqbHBjY2hDbGFzcz1zdHJsZW4obHBzekNsYXNzKTsKCQl9Cgl9CglpZiAobHBzek5hbWVXKQoJCWZyZWUobHBzek5hbWVXKTsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5MzJBIFtBRFZBUEkzMi4xMzddCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleUEoIEhLRVkgaGtleSwgRFdPUkQgaVN1YmtleSwgTFBTVFIgbHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBGSUxFVElNRQlmdDsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwogICAgcmV0dXJuIFJlZ0VudW1LZXlFeEEoIGhrZXksIGlTdWJrZXksIGxwc3pOYW1lLCAmbHBjY2hOYW1lLCBOVUxMLCBOVUxMLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICZmdCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5MTYgW1NIRUxMLjddIFtLRVJORUwuMjE2XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXkxNiggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbHBjY2hOYW1lICkKewogICAgVFJBQ0VfKHJlZykoIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKICAgIHJldHVybiBSZWdFbnVtS2V5QSggaGtleSwgaVN1YmtleSwgbHBzek5hbWUsIGxwY2NoTmFtZSk7Cn0KCgovKiAKICogRW51bWVyYXRlIFJlZ2lzdHJ5IFZhbHVlcwogKgogKiBDYWxscGF0aDoKICogUmVnRW51bVZhbHVlMTYgLT4gUmVnRW51bVZhbHVlMzJBIC0+IFJlZ0VudW1WYWx1ZTMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1WYWx1ZTMyVyBbQURWQVBJMzIuMTQyXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgW0ldIEhhbmRsZSB0byBrZXkgdG8gcXVlcnkKICogICAgaVZhbHVlICAgICAgW0ldIEluZGV4IG9mIHZhbHVlIHRvIHF1ZXJ5CiAqICAgIGxwc3pWYWx1ZSAgIFtPXSBWYWx1ZSBzdHJpbmcKICogICAgbHBjY2hWYWx1ZSAgW0kvT10gU2l6ZSBvZiB2YWx1ZSBidWZmZXIgKGluIHdjaGFycykKICogICAgbHBkUmVzZXJ2ZWQgW0ldIFJlc2VydmVkCiAqICAgIGxwZHdUeXBlICAgIFtPXSBUeXBlIGNvZGUKICogICAgbHBiRGF0YSAgICAgW09dIFZhbHVlIGRhdGEKICogICAgbHBjYkRhdGEgICAgW0kvT10gU2l6ZSBvZiBkYXRhIGJ1ZmZlciAoaW4gYnl0ZXMpCiAqCiAqIE5vdGU6ICB3aWRlIGNoYXJhY3RlciBmdW5jdGlvbnMgdGhhdCB0YWtlIGFuZC9vciByZXR1cm4gImNoYXJhY3RlciBjb3VudHMiCiAqICB1c2UgVENIQVIgKHRoYXQgaXMgdW5zaWduZWQgc2hvcnQgb3IgY2hhcikgbm90IGJ5dGUgY291bnRzLgogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1WYWx1ZVcoIEhLRVkgaGtleSwgRFdPUkQgaVZhbHVlLCBMUFdTVFIgbHBzelZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoVmFsdWUsIExQRFdPUkQgbHBkUmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1R5cGUsIExQQllURSBscGJEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJTFBLRVlWQUxVRQl2YWw7CgoJVFJBQ0VfKHJlZykoIigleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLGhrZXksaVZhbHVlLGRlYnVnc3RyX3cobHBzelZhbHVlKSwKICAgICAgICAgIGxwY2NoVmFsdWUsbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YSk7CgoJbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwoJCglpZiAoIWxwY2JEYXRhICYmIGxwYkRhdGEpCgkJcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoJCQoJaWYgKCFscGtleSkKCQlyZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJaWYgKGxwa2V5LT5ucm9mdmFsdWVzIDw9IGlWYWx1ZSkKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCgl2YWwgPSAmKGxwa2V5LT52YWx1ZXNbaVZhbHVlXSk7CgoJaWYgKHZhbC0+bmFtZSkgewoJICAgICAgICBpZiAobHN0cmxlblcodmFsLT5uYW1lKSsxPipscGNjaFZhbHVlKSB7CgkJCSpscGNjaFZhbHVlID0gbHN0cmxlblcodmFsLT5uYW1lKSsxOwoJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCX0KCQltZW1jcHkobHBzelZhbHVlLHZhbC0+bmFtZSwyICogKGxzdHJsZW5XKHZhbC0+bmFtZSkrMSkgKTsKCQkqbHBjY2hWYWx1ZT1sc3RybGVuVyh2YWwtPm5hbWUpOwoJfSBlbHNlIHsKCQkqbHBzelZhbHVlCT0gMDsKCQkqbHBjY2hWYWx1ZQk9IDA7Cgl9CgoJLyogQ2FuIGJlIE5VTEwgaWYgdGhlIHR5cGUgY29kZSBpcyBub3QgcmVxdWlyZWQgKi8KCWlmIChscGR3VHlwZSkKCQkqbHBkd1R5cGUgPSB2YWwtPnR5cGU7CgoJaWYgKGxwYkRhdGEpIHsKCQlpZiAodmFsLT5sZW4+KmxwY2JEYXRhKSB7CgkJCSpscGNiRGF0YSA9IHZhbC0+bGVuOwoJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCX0KCQltZW1jcHkobHBiRGF0YSx2YWwtPmRhdGEsdmFsLT5sZW4pOwoJCSpscGNiRGF0YSA9IHZhbC0+bGVuOwoJfQoKCWRlYnVnX3ByaW50X3ZhbHVlICggdmFsLT5kYXRhLCB2YWwgKTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUzMkEgW0FEVkFQSTMyLjE0MV0KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWVBKCBIS0VZIGhrZXksIERXT1JEIGlWYWx1ZSwgTFBTVFIgbHBzelZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoVmFsdWUsIExQRFdPUkQgbHBkUmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1R5cGUsIExQQllURSBscGJEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKCUxQV1NUUglscHN6VmFsdWVXOwoJTFBCWVRFCWxwYkRhdGFXOwoJRFdPUkQJcmV0LGxwY2JEYXRhVzsKCURXT1JEIGR3VHlwZTsKCglUUkFDRV8ocmVnKSgiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsCgkJbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YSk7CgoJbHBzelZhbHVlVyA9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hWYWx1ZSoyKTsKCWlmIChscGJEYXRhKSB7CgkJbHBiRGF0YVcgPSAoTFBCWVRFKXhtYWxsb2MoKmxwY2JEYXRhKjIpOwoJCWxwY2JEYXRhVyA9ICpscGNiRGF0YTsKCX0gZWxzZQoJCWxwYkRhdGFXID0gTlVMTDsKCglyZXQgPSBSZWdFbnVtVmFsdWVXKCBoa2V5LCBpVmFsdWUsIGxwc3pWYWx1ZVcsIGxwY2NoVmFsdWUsIAoJCQkJbHBkUmVzZXJ2ZWQsICZkd1R5cGUsIGxwYkRhdGFXLCAmbHBjYkRhdGFXICk7CgoJaWYgKGxwZHdUeXBlKQoJCSpscGR3VHlwZSA9IGR3VHlwZTsKCglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJbHN0cmNweVd0b0EobHBzelZhbHVlLGxwc3pWYWx1ZVcpOwoJCWlmIChscGJEYXRhKSB7CgkJCWlmICgoMTw8ZHdUeXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJCQlsc3RyY3B5V3RvQShscGJEYXRhLChMUFdTVFIpbHBiRGF0YVcpOwoJCQl9IGVsc2UgewoJCQkJaWYgKGxwY2JEYXRhVyA+ICpscGNiRGF0YSkgewoJCQkJCSpscGNiRGF0YSA9IGxwY2JEYXRhVzsKCQkJCQlyZXQJPSBFUlJPUl9NT1JFX0RBVEE7CgkJCQl9IGVsc2UKCQkJCQltZW1jcHkobHBiRGF0YSxscGJEYXRhVyxscGNiRGF0YVcpOwoJCQl9CgkJCSpscGNiRGF0YSA9IGxwY2JEYXRhVzsKCQl9Cgl9CiAgICBpZiAobHBiRGF0YVcpIGZyZWUobHBiRGF0YVcpOwogICAgaWYgKGxwc3pWYWx1ZVcpIGZyZWUobHBzelZhbHVlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUxNiBbS0VSTkVMLjIyM10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUxNiggSEtFWSBoa2V5LCBEV09SRCBpVmFsdWUsIExQU1RSIGxwc3pWYWx1ZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaFZhbHVlLCBMUERXT1JEIGxwZFJlc2VydmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSwKICAgICAgICAgIGxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEpOwogICAgcmV0dXJuIFJlZ0VudW1WYWx1ZUEoIGhrZXksIGlWYWx1ZSwgbHBzelZhbHVlLCBscGNjaFZhbHVlLCBscGRSZXNlcnZlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBscGR3VHlwZSwgbHBiRGF0YSwgbHBjYkRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ2xvc2VLZXkgW1NIRUxMLjNdIFtLRVJORUwuMjIwXSBbQURWQVBJMzIuMTI2XQogKiBSZWxlYXNlcyB0aGUgaGFuZGxlIG9mIHRoZSBzcGVjaWZpZWQga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIGNsb3NlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnQ2xvc2VLZXkoIEhLRVkgaGtleSApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXgpXG4iLGhrZXkpOwoKICAgIC8qIFRoZSBzdGFuZGFyZCBoYW5kbGVzIGFyZSBhbGxvd2VkIHRvIHN1Y2NlZWQsIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIG5vdAogICAgICAgY2xvc2VkICovCiAgICBpZiAoaXNfc3RhbmRhcmRfaGtleShoa2V5KSkKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKCiAgICByZXR1cm4gcmVtb3ZlX2hhbmRsZShoa2V5KTsKfQoKCi8qIAogKiBEZWxldGUgcmVnaXN0cnkga2V5CiAqCiAqIENhbGxwYXRoOgogKiBSZWdEZWxldGVLZXkxNiAtPiBSZWdEZWxldGVLZXkzMkEgLT4gUmVnRGVsZXRlS2V5MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlS2V5MzJXIFtBRFZBUEkzMi4xMzRdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgIFtJXSBIYW5kbGUgdG8gb3BlbiBrZXkKICogICAgbHBzelN1YktleSBbSV0gTmFtZSBvZiBzdWJrZXkgdG8gZGVsZXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXkgKQp7CglMUEtFWVNUUlVDVAkqbHBscFByZXZLZXksbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpKTsKCiAgICBscE5leHRLZXkgPSBsb29rdXBfaGtleShoa2V5KTsKICAgIGlmICghbHBOZXh0S2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICAvKiBTdWJrZXkgcGFyYW0gY2Fubm90IGJlIE5VTEwgKi8KICAgIGlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0JBREtFWTsKCiAgICAvKiBXZSBuZWVkIHRvIGtub3cgdGhlIHByZXZpb3VzIGtleSBpbiB0aGUgaGllci4gKi8KCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKGk8d3BjLTEpIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJVFJBQ0VfKHJlZykoIiAgU2Nhbm5pbmcgWyVzXVxuIiwKCQkJCSAgICAgZGVidWdzdHJfdyhscHhrZXktPmtleW5hbWUpKTsKCQkJaWYgKCFsc3RyY21waVcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCQlicmVhazsKCQkJbHB4a2V5PWxweGtleS0+bmV4dDsKCQl9CgkJaWYgKCFscHhrZXkpIHsKCQkJRlJFRV9LRVlfUEFUSDsKCQkJVFJBQ0VfKHJlZykoIiAgTm90IGZvdW5kLlxuIik7CgkJCS8qIG5vdCBmb3VuZCBpcyBzdWNjZXNzICovCgkJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJCX0KCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJbHB4a2V5CT0gbHBOZXh0S2V5LT5uZXh0c3ViOwoJbHBscFByZXZLZXkgPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7Cgl3aGlsZSAobHB4a2V5KSB7CgkJVFJBQ0VfKHJlZykoIiAgU2Nhbm5pbmcgWyVzXVxuIiwKCQkJICAgICBkZWJ1Z3N0cl93KGxweGtleS0+a2V5bmFtZSkpOwoJCWlmICghbHN0cmNtcGlXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQlicmVhazsKCQlscGxwUHJldktleQk9ICYobHB4a2V5LT5uZXh0KTsKCQlscHhrZXkJCT0gbHB4a2V5LT5uZXh0OwoJfQoKCWlmICghbHB4a2V5KSB7CgkJRlJFRV9LRVlfUEFUSDsKCQlXQVJOXyhyZWcpKCIgIE5vdCBmb3VuZC5cbiIpOwoJCXJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsKCX0KCglpZiAobHB4a2V5LT5uZXh0c3ViKSB7CgkJRlJFRV9LRVlfUEFUSDsKCQlXQVJOXyhyZWcpKCIgIE5vdCBlbXB0eS5cbiIpOwoJCXJldHVybiBFUlJPUl9DQU5UV1JJVEU7Cgl9CgkqbHBscFByZXZLZXkJPSBscHhrZXktPm5leHQ7CglmcmVlKGxweGtleS0+a2V5bmFtZSk7CglpZiAobHB4a2V5LT5jbGFzcykKCQlmcmVlKGxweGtleS0+Y2xhc3MpOwoJaWYgKGxweGtleS0+dmFsdWVzKQoJCWZyZWUobHB4a2V5LT52YWx1ZXMpOwoJZnJlZShscHhrZXkpOwoJRlJFRV9LRVlfUEFUSDsKCVRSQUNFXyhyZWcpKCIgIERvbmUuXG4iKTsKCXJldHVybglFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVLZXkzMkEgW0FEVkFQSTMyLjEzM10KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5ICkKewogICAgTFBXU1RSIGxwc3pTdWJLZXlXOwogICAgRFdPUkQgIHJldDsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkpOwogICAgbHBzelN1YktleVcgPSBscHN6U3ViS2V5P3N0cmR1cEEyVyhscHN6U3ViS2V5KTpOVUxMOwogICAgcmV0ID0gUmVnRGVsZXRlS2V5VyggaGtleSwgbHBzelN1YktleVcgKTsKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZUtleTE2IFtTSEVMTC40XSBbS0VSTkVMLjIxOV0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSk7CiAgICByZXR1cm4gUmVnRGVsZXRlS2V5QSggaGtleSwgbHBzelN1YktleSApOwp9CgoKLyogCiAqIERlbGV0ZSByZWdpc3RyeSB2YWx1ZQogKgogKiBDYWxscGF0aDoKICogUmVnRGVsZXRlVmFsdWUxNiAtPiBSZWdEZWxldGVWYWx1ZTMyQSAtPiBSZWdEZWxldGVWYWx1ZTMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZVZhbHVlMzJXIFtBRFZBUEkzMi4xMzZdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgW0ldCiAqICAgIGxwc3pWYWx1ZSBbSV0KICoKICogUkVUVVJOUwogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pWYWx1ZSApCnsKCURXT1JECQlpOwoJTFBLRVlTVFJVQ1QJbHBrZXk7CglMUEtFWVZBTFVFCXZhbDsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelZhbHVlKSk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJaWYgKGxwc3pWYWx1ZSkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXBpVyhscGtleS0+dmFsdWVzW2ldLm5hbWUsbHBzelZhbHVlKQoJCQkpCgkJCQlicmVhazsKCX0gZWxzZSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCX0KCiAgICBpZiAoaSA9PSBscGtleS0+bnJvZnZhbHVlcykKICAgICAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7CgoJdmFsCT0gbHBrZXktPnZhbHVlcytpOwoJaWYgKHZhbC0+bmFtZSkgZnJlZSh2YWwtPm5hbWUpOwoJaWYgKHZhbC0+ZGF0YSkgZnJlZSh2YWwtPmRhdGEpOwoJbWVtY3B5KAkKCQlscGtleS0+dmFsdWVzK2ksCgkJbHBrZXktPnZhbHVlcytpKzEsCgkJc2l6ZW9mKEtFWVZBTFVFKSoobHBrZXktPm5yb2Z2YWx1ZXMtaS0xKQoJKTsKCWxwa2V5LT52YWx1ZXMJPSAoTFBLRVlWQUxVRSl4cmVhbGxvYygKCQkJCWxwa2V5LT52YWx1ZXMsCgkJCQkobHBrZXktPm5yb2Z2YWx1ZXMtMSkqc2l6ZW9mKEtFWVZBTFVFKQoJCQkpOwoJbHBrZXktPm5yb2Z2YWx1ZXMtLTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVWYWx1ZTMyQSBbQURWQVBJMzIuMTM1XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelZhbHVlICkKewogICAgTFBXU1RSIGxwc3pWYWx1ZVc7CiAgICBEV09SRCAgcmV0OwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWUpKTsKICAgIGxwc3pWYWx1ZVcgPSBscHN6VmFsdWU/c3RyZHVwQTJXKGxwc3pWYWx1ZSk6TlVMTDsKICAgIHJldCA9IFJlZ0RlbGV0ZVZhbHVlVyggaGtleSwgbHBzelZhbHVlVyApOwogICAgaWYobHBzelZhbHVlVykgZnJlZShscHN6VmFsdWVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZVZhbHVlMTYgW0tFUk5FTC4yMjJdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUxNiggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWUgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzKVxuIiwgaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZSkpOwogICAgcmV0dXJuIFJlZ0RlbGV0ZVZhbHVlQSggaGtleSwgbHBzelZhbHVlICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0ZsdXNoS2V5IFtLRVJORUwuMjI3XSBbQURWQVBJMzIuMTQzXQogKiBJbW1lZGlhdGVseSB3cml0ZXMga2V5IHRvIHJlZ2lzdHJ5LgogKiBPbmx5IHJldHVybnMgYWZ0ZXIgZGF0YSBoYXMgYmVlbiB3cml0dGVuIHRvIGRpc2suCiAqCiAqIEZJWE1FOiBkb2VzIGl0IHJlYWxseSB3YWl0IHVudGlsIGRhdGEgaXMgd3JpdHRlbiA/CiAqCiAqIEkgZ3Vlc3MgdGhhdCB3ZSBjYW4gcmVtb3ZlIHRoZSBSRUdfT1BUSU9OX1RBSU5URUQgZmxhZyBmcm9tIGV2ZXJ5IGtleQogKiB3cml0dGVuIGlmIHRoaXMgZnVuY3Rpb24gcmVhbGx5IHdvcmtzIChhbmQgb25seSBpZiAhKS4KICoKICogUEFSQU1TCiAqICAgIGhrZXkgW0ldIEhhbmRsZSBvZiBrZXkgdG8gd3JpdGUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdGbHVzaEtleSggSEtFWSBoa2V5ICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0VfKHJlZykoIigleClcbiIsIGhrZXkpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0JBREtFWTsKCglTSEVMTF9TYXZlUmVnaXN0cnlCcmFuY2goZmluZF9yb290X2tleShscGtleSksIFRSVUUpOwogICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyogRklYTUU6IGxwY2NoWFhYWCAuLi4gaXMgdGhpcyBjb3VudGluZyBpbiBXQ0hBUlMgb3IgaW4gQllURXMgPz8gKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5SW5mb0tleTMyVyBbQURWQVBJMzIuMTUzXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgICAgICAgICBbSV0gSGFuZGxlIHRvIGtleSB0byBxdWVyeQogKiAgICBscHN6Q2xhc3MgICAgICAgICAgICAgIFtPXSBCdWZmZXIgZm9yIGNsYXNzIHN0cmluZwogKiAgICBscGNjaENsYXNzICAgICAgICAgICAgIFtPXSBTaXplIG9mIGNsYXNzIHN0cmluZyBidWZmZXIKICogICAgbHBkd1Jlc2VydmVkICAgICAgICAgICBbSV0gUmVzZXJ2ZWQKICogICAgbHBjU3ViS2V5cyAgICAgICAgICAgICBbSV0gQnVmZmVyIGZvciBudW1iZXIgb2Ygc3Via2V5cwogKiAgICBscGNjaE1heFN1YktleSAgICAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3Qgc3Via2V5IG5hbWUgbGVuZ3RoCiAqICAgIGxwY2NoTWF4Q2xhc3MgICAgICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCBjbGFzcyBzdHJpbmcgbGVuZ3RoCiAqICAgIGxwY1ZhbHVlcyAgICAgICAgICAgICAgW09dIEJ1ZmZlciBmb3IgbnVtYmVyIG9mIHZhbHVlIGVudHJpZXMKICogICAgbHBjY2hNYXhWYWx1ZU5hbWUgICAgICBbT10gQnVmZmVyIGZvciBsb25nZXN0IHZhbHVlIG5hbWUgbGVuZ3RoCiAqICAgIGxwY2NiTWF4VmFsdWVEYXRhICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCB2YWx1ZSBkYXRhIGxlbmd0aAogKiAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yIFtPXSBCdWZmZXIgZm9yIHNlY3VyaXR5IGRlc2NyaXB0b3IgbGVuZ3RoCiAqICAgIGZ0CiAqIC0gd2luOTUgYWxsb3dzIGxwc3pDbGFzcyB0byBiZSB2YWxpZCBhbmQgbHBjY2hDbGFzcyB0byBiZSBOVUxMIAogKiAtIHdpbm50IHJldHVybnMgRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgaWYgbHBzekNsYXNzIGlzIHZhbGlkIGFuZAogKiAgIGxwY2NoQ2xhc3MgaXMgTlVMTAogKiAtIGJvdGggYWxsb3cgbHBzekNsYXNzIHRvIGJlIE5VTEwgYW5kIGxwY2NoQ2xhc3MgdG8gYmUgTlVMTCAKICogKGl0J3MgaGFyZCB0byB0ZXN0IHZhbGlkaXR5LCBzbyB0ZXN0ICFOVUxMIGluc3RlYWQpCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlJbmZvS2V5VyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzekNsYXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaENsYXNzLCBMUERXT1JEIGxwZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNTdWJLZXlzLCBMUERXT1JEIGxwY2NoTWF4U3Via2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTWF4Q2xhc3MsIExQRFdPUkQgbHBjVmFsdWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTWF4VmFsdWVOYW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjYk1heFZhbHVlRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwgRklMRVRJTUUgKmZ0ICkKewoJTFBLRVlTVFJVQ1QJbHBrZXksbHB4a2V5OwoJaW50CQlucm9ma2V5cyxtYXhzdWJrZXksbWF4Y2xhc3MsbWF4dm5hbWUsbWF4dmRhdGE7CglpbnQJCWk7CgoJVFJBQ0VfKHJlZykoIigleCwlcCwlbGQsJXAsJXAsJXAsJXAsJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksIGxwc3pDbGFzcywgbHBjY2hDbGFzcz8qbHBjY2hDbGFzczowLGxwZHdSZXNlcnZlZCwKCQlscGNTdWJLZXlzLGxwY2NoTWF4U3Via2V5LGxwY1ZhbHVlcyxscGNjaE1heFZhbHVlTmFtZSwKCQlscGNjYk1heFZhbHVlRGF0YSxscGNiU2VjdXJpdHlEZXNjcmlwdG9yLGZ0CgkpOwoJbHBrZXkgPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoJaWYgKGxwc3pDbGFzcykgewogICAJICAgICAgICBpZiAoVkVSU0lPTl9HZXRWZXJzaW9uKCkgPT0gTlQ0MCAmJiBscGNjaENsYXNzID09IE5VTEwpIHsKCQkgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoJCX0KCQkvKiBlaXRoZXIgbHBjY2hDbGFzcyBpcyB2YWxpZCBvciB0aGlzIGlzIHdpbjk1IGFuZCBscGNjaENsYXNzCgkJICAgY291bGQgYmUgaW52YWxpZCAqLwoJCWlmIChscGtleS0+Y2xhc3MpIHsKCQkgICAgICAgIERXT1JEIGNsYXNzTGVuID0gbHN0cmxlblcobHBrZXktPmNsYXNzKTsKCgkJCWlmIChscGNjaENsYXNzICYmIGNsYXNzTGVuKzE+KmxwY2NoQ2xhc3MpIHsKCQkJCSpscGNjaENsYXNzPWNsYXNzTGVuKzE7CgkJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCQl9CgkJCWlmIChscGNjaENsYXNzKQoJCQkgICAgKmxwY2NoQ2xhc3M9Y2xhc3NMZW47CgkJCW1lbWNweShscHN6Q2xhc3MsbHBrZXktPmNsYXNzLCBjbGFzc0xlbioyICsgMik7CgkJfSBlbHNlIHsKCQkJKmxwc3pDbGFzcwk9IDA7CgkJCWlmIChscGNjaENsYXNzKQoJCQkgICAgKmxwY2NoQ2xhc3MJPSAwOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGxwY2NoQ2xhc3MpCgkJCSpscGNjaENsYXNzCT0gbHN0cmxlblcobHBrZXktPmNsYXNzKTsKCX0KCWxweGtleT1scGtleS0+bmV4dHN1YjsKCW5yb2ZrZXlzPW1heHN1YmtleT1tYXhjbGFzcz1tYXh2bmFtZT1tYXh2ZGF0YT0wOwoJd2hpbGUgKGxweGtleSkgewoJCW5yb2ZrZXlzKys7CgkJaWYgKGxzdHJsZW5XKGxweGtleS0+a2V5bmFtZSk+bWF4c3Via2V5KQoJCQltYXhzdWJrZXk9bHN0cmxlblcobHB4a2V5LT5rZXluYW1lKTsKCQlpZiAobHB4a2V5LT5jbGFzcyAmJiBsc3RybGVuVyhscHhrZXktPmNsYXNzKT5tYXhjbGFzcykKCQkJbWF4Y2xhc3M9bHN0cmxlblcobHB4a2V5LT5jbGFzcyk7CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJTFBLRVlWQUxVRQl2YWw9bHBrZXktPnZhbHVlcytpOwoKCQlpZiAodmFsLT5uYW1lICYmIGxzdHJsZW5XKHZhbC0+bmFtZSk+bWF4dm5hbWUpCgkJCW1heHZuYW1lPWxzdHJsZW5XKHZhbC0+bmFtZSk7CgkJaWYgKHZhbC0+bGVuPm1heHZkYXRhKQoJCQltYXh2ZGF0YT12YWwtPmxlbjsKCX0KCWlmICghbWF4Y2xhc3MpIG1heGNsYXNzCT0gMTsKCWlmICghbWF4dm5hbWUpIG1heHZuYW1lCT0gMTsKCWlmIChscGNWYWx1ZXMpCgkJKmxwY1ZhbHVlcwk9IGxwa2V5LT5ucm9mdmFsdWVzOwoJaWYgKGxwY1N1YktleXMpCgkJKmxwY1N1YktleXMJPSBucm9ma2V5czsKCWlmIChscGNjaE1heFN1YmtleSkKCQkqbHBjY2hNYXhTdWJrZXkJPSBtYXhzdWJrZXk7CglpZiAobHBjY2hNYXhDbGFzcykKCQkqbHBjY2hNYXhDbGFzcwk9IG1heGNsYXNzOwoJaWYgKGxwY2NoTWF4VmFsdWVOYW1lKQoJCSpscGNjaE1heFZhbHVlTmFtZT0gbWF4dm5hbWU7CglpZiAobHBjY2JNYXhWYWx1ZURhdGEpCgkJKmxwY2NiTWF4VmFsdWVEYXRhPSBtYXh2ZGF0YTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeUluZm9LZXkzMkEgW0FEVkFQSTMyLjE1Ml0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeUluZm9LZXlBKCBIS0VZIGhrZXksIExQU1RSIGxwc3pDbGFzcywgTFBEV09SRCBscGNjaENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGNTdWJLZXlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTWF4U3Via2V5LCBMUERXT1JEIGxwY2NoTWF4Q2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjVmFsdWVzLCBMUERXT1JEIGxwY2NoTWF4VmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NiTWF4VmFsdWVEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yLCBGSUxFVElNRSAqZnQgKQp7CglMUFdTVFIJCWxwc3pDbGFzc1cgPSBOVUxMOwoJRFdPUkQJCXJldDsKCglUUkFDRV8ocmVnKSgiKCV4LCVwLCVsZCwlcCwlcCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsCgkJaGtleSwgbHBzekNsYXNzLCBscGNjaENsYXNzPypscGNjaENsYXNzOjAsbHBkd1Jlc2VydmVkLAoJCWxwY1N1YktleXMsbHBjY2hNYXhTdWJrZXksbHBjVmFsdWVzLGxwY2NoTWF4VmFsdWVOYW1lLAoJCWxwY2NiTWF4VmFsdWVEYXRhLGxwY2JTZWN1cml0eURlc2NyaXB0b3IsZnQKCSk7CglpZiAobHBzekNsYXNzKSB7CgkJaWYgKGxwY2NoQ2xhc3MpIHsKCQkgICAgbHBzekNsYXNzVyAgPSAoTFBXU1RSKXhtYWxsb2MoKCpscGNjaENsYXNzKSAqIDIpOwoJCX0gZWxzZSBpZiAoVkVSU0lPTl9HZXRWZXJzaW9uKCkgPT0gV0lOOTUpIHsKCQkgICAgLyogd2luOTUgIGFsbG93cyBscGNjaENsYXNzIHRvIGJlIG51bGwgKi8KCQkgICAgLyogd2UgZG9uJ3Qga25vdyBob3cgYmlnIGxwc3pDbGFzcyBpcywgd291bGQgCgkJICAgICAgIE1BWF9QQVRITkFNRV9MRU4gYmUgdGhlIGNvcnJlY3QgZGVmYXVsdD8gKi8KCQkgICAgbHBzekNsYXNzVyAgPSAoTFBXU1RSKXhtYWxsb2MoTUFYX1BBVEhOQU1FX0xFTioyKTsgCgkJfQoKCX0gZWxzZQoJCWxwc3pDbGFzc1cgID0gTlVMTDsKCXJldD1SZWdRdWVyeUluZm9LZXlXKAoJCWhrZXksCgkJbHBzekNsYXNzVywKCQlscGNjaENsYXNzLAoJCWxwZHdSZXNlcnZlZCwKCQlscGNTdWJLZXlzLAoJCWxwY2NoTWF4U3Via2V5LAoJCWxwY2NoTWF4Q2xhc3MsCgkJbHBjVmFsdWVzLAoJCWxwY2NoTWF4VmFsdWVOYW1lLAoJCWxwY2NiTWF4VmFsdWVEYXRhLAoJCWxwY2JTZWN1cml0eURlc2NyaXB0b3IsCgkJZnQKCSk7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTICYmIGxwc3pDbGFzcykKCQlsc3RyY3B5V3RvQShscHN6Q2xhc3MsbHBzekNsYXNzVyk7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ29ubmVjdFJlZ2lzdHJ5MzJXIFtBRFZBUEkzMi4xMjhdCiAqCiAqIFBBUkFNUwogKiAgICBscE1hY2hpbmVOYW1lIFtJXSBBZGRyZXNzIG9mIG5hbWUgb2YgcmVtb3RlIGNvbXB1dGVyCiAqICAgIGhIZXkgICAgICAgICAgW0ldIFByZWRlZmluZWQgcmVnaXN0cnkgaGFuZGxlCiAqICAgIHBoa1Jlc3VsdCAgICAgW0ldIEFkZHJlc3Mgb2YgYnVmZmVyIGZvciByZW1vdGUgcmVnaXN0cnkgaGFuZGxlCiAqLwpMT05HIFdJTkFQSSBSZWdDb25uZWN0UmVnaXN0cnlXKCBMUENXU1RSIGxwTWFjaGluZU5hbWUsIEhLRVkgaEtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBIS0VZIHBoa1Jlc3VsdCApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXMsJXgsJXApOiBzdHViXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSksaEtleSxwaGtSZXN1bHQpOwoKICAgIGlmICghbHBNYWNoaW5lTmFtZSB8fCAhKmxwTWFjaGluZU5hbWUpIHsKICAgICAgICAvKiBVc2UgdGhlIGxvY2FsIG1hY2hpbmUgbmFtZSAqLwogICAgICAgIHJldHVybiBSZWdPcGVuS2V5MTYoIGhLZXksICIiLCBwaGtSZXN1bHQgKTsKICAgIH0KCiAgICBGSVhNRV8ocmVnKSgiQ2Fubm90IGNvbm5lY3QgdG8gJXNcbiIsZGVidWdzdHJfdyhscE1hY2hpbmVOYW1lKSk7CiAgICByZXR1cm4gRVJST1JfQkFEX05FVFBBVEg7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyQSBbQURWQVBJMzIuMTI3XQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5QSggTFBDU1RSIG1hY2hpbmUsIEhLRVkgaGtleSwgTFBIS0VZIHJlc2tleSApCnsKICAgIERXT1JEIHJldDsKICAgIExQV1NUUiBtYWNoaW5lVyA9IHN0cmR1cEEyVyhtYWNoaW5lKTsKICAgIHJldCA9IFJlZ0Nvbm5lY3RSZWdpc3RyeVcoIG1hY2hpbmVXLCBoa2V5LCByZXNrZXkgKTsKICAgIGZyZWUobWFjaGluZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnR2V0S2V5U2VjdXJpdHkgW0FEVkFQSTMyLjE0NF0KICogUmV0cmlldmVzIGEgY29weSBvZiBzZWN1cml0eSBkZXNjcmlwdG9yIHByb3RlY3RpbmcgdGhlIHJlZ2lzdHJ5IGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgICAgICAgICBbSV0gICBPcGVuIGhhbmRsZSBvZiBrZXkgdG8gc2V0CiAqICAgIFNlY3VyaXR5SW5mb3JtYXRpb24gICAgW0ldICAgRGVzY3JpcHRvciBjb250ZW50cwogKiAgICBwU2VjdXJpdHlEZXNjcmlwdG9yICAgIFtPXSAgIEFkZHJlc3Mgb2YgZGVzY3JpcHRvciBmb3Iga2V5CiAqICAgIGxwY2JTZWN1cml0eURlc2NyaXB0b3IgW0kvT10gQWRkcmVzcyBvZiBzaXplIG9mIGJ1ZmZlciBhbmQgZGVzY3JpcHRpb24KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkxPTkcgV0lOQVBJIFJlZ0dldEtleVNlY3VyaXR5KCBIS0VZIGhrZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0VDVVJJVFlfSU5GT1JNQVRJT04gU2VjdXJpdHlJbmZvcm1hdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTRUNVUklUWV9ERVNDUklQVE9SIHBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JTZWN1cml0eURlc2NyaXB0b3IgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksU2VjdXJpdHlJbmZvcm1hdGlvbixwU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvcj8qbHBjYlNlY3VyaXR5RGVzY3JpcHRvcjowKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICAvKiBGSVhNRTogQ2hlY2sgZm9yIHZhbGlkIFNlY3VyaXR5SW5mb3JtYXRpb24gdmFsdWVzICovCgogICAgaWYgKCpscGNiU2VjdXJpdHlEZXNjcmlwdG9yIDwgc2l6ZW9mKFNFQ1VSSVRZX0RFU0NSSVBUT1IpKQogICAgICAgIHJldHVybiBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSOwoKICAgIEZJWE1FXyhyZWcpKCIoJXgsJWxkLCVwLCVsZCk6IHN0dWJcbiIsaGtleSxTZWN1cml0eUluZm9ybWF0aW9uLAogICAgICAgICAgcFNlY3VyaXR5RGVzY3JpcHRvcixscGNiU2VjdXJpdHlEZXNjcmlwdG9yPypscGNiU2VjdXJpdHlEZXNjcmlwdG9yOjApOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdMb2FkS2V5MzJXIFtBRFZBUEkzMi4/Pz9dCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBzelN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleQogKiAgICBscHN6RmlsZSAgIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGZvciByZWdpc3RyeSBpbmZvcm1hdGlvbgogKi8KTE9ORyBXSU5BUEkgUmVnTG9hZEtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBMUENXU1RSIGxwc3pGaWxlICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksZGVidWdzdHJfdyhscHN6RmlsZSkpOwoKICAgIC8qIERvIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5IHx8ICFscHN6RmlsZSB8fCAhKmxwc3pGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRV8ocmVnKSgiKCV4LCVzLCVzKTogc3R1YlxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwc3pGaWxlKSk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0xvYWRLZXkzMkEgW0FEVkFQSTMyLj8/P10KICovCkxPTkcgV0lOQVBJIFJlZ0xvYWRLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUENTVFIgbHBzekZpbGUgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscHN6U3ViS2V5VyA9IHN0cmR1cEEyVyhscHN6U3ViS2V5KTsKICAgIExQV1NUUiBscHN6RmlsZVcgPSBzdHJkdXBBMlcobHBzekZpbGUpOwogICAgcmV0ID0gUmVnTG9hZEtleVcoIGhrZXksIGxwc3pTdWJLZXlXLCBscHN6RmlsZVcgKTsKICAgIGlmKGxwc3pGaWxlVykgZnJlZShscHN6RmlsZVcpOwogICAgaWYobHBzelN1YktleVcpIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTm90aWZ5Q2hhbmdlS2V5VmFsdWUgW0FEVkFQSTMyLj8/P10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICBbSV0gSGFuZGxlIG9mIGtleSB0byB3YXRjaAogKiAgICBmV2F0Y2hTdWJUcmVlICAgW0ldIEZsYWcgZm9yIHN1YmtleSBub3RpZmljYXRpb24KICogICAgZmR3Tm90aWZ5RmlsdGVyIFtJXSBDaGFuZ2VzIHRvIGJlIHJlcG9ydGVkCiAqICAgIGhFdmVudCAgICAgICAgICBbSV0gSGFuZGxlIG9mIHNpZ25hbGVkIGV2ZW50CiAqICAgIGZBc3luYyAgICAgICAgICBbSV0gRmxhZyBmb3IgYXN5bmNocm9ub3VzIHJlcG9ydGluZwogKi8KTE9ORyBXSU5BUEkgUmVnTm90aWZ5Q2hhbmdlS2V5VmFsdWUoIEhLRVkgaGtleSwgQk9PTCBmV2F0Y2hTdWJUcmVlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGZkd05vdGlmeUZpbHRlciwgSEFORExFIGhFdmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgZkFzeW5jICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVpLCVsZCwleCwlaSlcbiIsaGtleSxmV2F0Y2hTdWJUcmVlLGZkd05vdGlmeUZpbHRlciwKICAgICAgICAgIGhFdmVudCxmQXN5bmMpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FXyhyZWcpKCIoJXgsJWksJWxkLCV4LCVpKTogc3R1YlxuIixoa2V5LGZXYXRjaFN1YlRyZWUsZmR3Tm90aWZ5RmlsdGVyLAogICAgICAgICAgaEV2ZW50LGZBc3luYyk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1VuTG9hZEtleTMyVyBbQURWQVBJMzIuMTczXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscFN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleSB0byB1bmxvYWQKICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSApCnsKICAgIEZJWE1FXyhyZWcpKCIoJXgsJXMpOiBzdHViXG4iLGhrZXksIGRlYnVnc3RyX3cobHBTdWJLZXkpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXkzMkEgW0FEVkFQSTMyLjE3Ml0KICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5ICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBTdWJLZXlXID0gc3RyZHVwQTJXKGxwU3ViS2V5KTsKICAgIHJldCA9IFJlZ1VuTG9hZEtleVcoIGhrZXksIGxwU3ViS2V5VyApOwogICAgaWYobHBTdWJLZXlXKSBmcmVlKGxwU3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTY3XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICBbSV0gT3BlbiBoYW5kbGUgb2Yga2V5IHRvIHNldAogKiAgICBTZWN1cml0eUluZm8gIFtJXSBEZXNjcmlwdG9yIGNvbnRlbnRzCiAqICAgIHBTZWN1cml0eURlc2MgW0ldIEFkZHJlc3Mgb2YgZGVzY3JpcHRvciBmb3Iga2V5CiAqLwpMT05HIFdJTkFQSSBSZWdTZXRLZXlTZWN1cml0eSggSEtFWSBoa2V5LCBTRUNVUklUWV9JTkZPUk1BVElPTiBTZWN1cml0eUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU0VDVVJJVFlfREVTQ1JJUFRPUiBwU2VjdXJpdHlEZXNjICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0VfKHJlZykoIigleCwlbGQsJXApXG4iLGhrZXksU2VjdXJpdHlJbmZvLHBTZWN1cml0eURlc2MpOwoKICAgIC8qIEl0IHNlZW1zIHRvIHBlcmZvcm0gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICgoU2VjdXJpdHlJbmZvICYgT1dORVJfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIEdST1VQX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBEQUNMX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBTQUNMX1NFQ1VSSVRZX0lORk9STUFUSU9OKSkgewogICAgICAgIC8qIFBhcmFtIE9LICovCiAgICB9IGVsc2UKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgaWYgKCFwU2VjdXJpdHlEZXNjKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRV8ocmVnKSgiOigleCwlbGQsJXApOiBzdHViXG4iLGhrZXksU2VjdXJpdHlJbmZvLHBTZWN1cml0eURlc2MpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTYXZlS2V5MzJXIFtBRFZBUEkzMi4xNjZdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgc2F2ZSBiZWdpbnMKICogICAgbHBGaWxlIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIHRvIHNhdmUgdG8KICogICAgc2EgICAgIFtJXSBBZGRyZXNzIG9mIHNlY3VyaXR5IHN0cnVjdHVyZQogKi8KTE9ORyBXSU5BUEkgUmVnU2F2ZUtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscEZpbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgc2EgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVwKVxuIiwgaGtleSwgZGVidWdzdHJfdyhscEZpbGUpLCBzYSk7CgogICAgLyogSXQgYXBwZWFycyB0byBkbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscEZpbGUgfHwgISpscEZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FXyhyZWcpKCIoJXgsJXMsJXApOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwRmlsZSksIHNhKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2F2ZUtleTMyQSBbQURWQVBJMzIuMTY1XQogKi8KTE9ORyBXSU5BUEkgUmVnU2F2ZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwRmlsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBzYSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwRmlsZVcgPSBzdHJkdXBBMlcobHBGaWxlKTsKICAgIHJldCA9IFJlZ1NhdmVLZXlXKCBoa2V5LCBscEZpbGVXLCBzYSApOwogICAgZnJlZShscEZpbGVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1Jlc3RvcmVLZXkzMlcgW0FEVkFQSTMyLjE2NF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgcmVzdG9yZSBiZWdpbnMKICogICAgbHBGaWxlICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBjb250YWluaW5nIHNhdmVkIHRyZWUKICogICAgZHdGbGFncyBbSV0gT3B0aW9uYWwgZmxhZ3MKICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcywlbGQpXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIEl0IHNlZW1zIHRvIGRvIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoIWxwRmlsZSB8fCAhKmxwRmlsZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUVfKHJlZykoIigleCwlcywlbGQpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIENoZWNrIGZvciBmaWxlIGV4aXN0ZW5jZSAqLwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5MzJBIFtBRFZBUEkzMi4xNjNdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBGaWxlVyA9IHN0cmR1cEEyVyhscEZpbGUpOwogICAgcmV0ID0gUmVnUmVzdG9yZUtleVcoIGhrZXksIGxwRmlsZVcsIGR3RmxhZ3MgKTsKICAgIGlmKGxwRmlsZVcpIGZyZWUobHBGaWxlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5MzJXIFtBRFZBUEkzMi4xNjJdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscFN1YktleSAgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkKICogICAgbHBOZXdGaWxlIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGZvciBmaWxlIHdpdGggbmV3IGRhdGEKICogICAgbHBPbGRGaWxlIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGZvciBiYWNrdXAgZmlsZQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSwgTFBDV1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbHBPbGRGaWxlICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcywlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwU3ViS2V5KSwKICAgICAgICAgIGRlYnVnc3RyX3cobHBOZXdGaWxlKSxkZWJ1Z3N0cl93KGxwT2xkRmlsZSkpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FXyhyZWcpKCIoJXgsJXMsJXMsJXMpOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwU3ViS2V5KSwgCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleTMyQSBbQURWQVBJMzIuMTYxXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5LCBMUENTVFIgbHBOZXdGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBPbGRGaWxlICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBTdWJLZXlXID0gc3RyZHVwQTJXKGxwU3ViS2V5KTsKICAgIExQV1NUUiBscE5ld0ZpbGVXID0gc3RyZHVwQTJXKGxwTmV3RmlsZSk7CiAgICBMUFdTVFIgbHBPbGRGaWxlVyA9IHN0cmR1cEEyVyhscE9sZEZpbGUpOwogICAgcmV0ID0gUmVnUmVwbGFjZUtleVcoIGhrZXksIGxwU3ViS2V5VywgbHBOZXdGaWxlVywgbHBPbGRGaWxlVyApOwogICAgZnJlZShscE9sZEZpbGVXKTsKICAgIGZyZWUobHBOZXdGaWxlVyk7CiAgICBmcmVlKGxwU3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9Cgo=