LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpZmRlZiBIQVZFX1NZU19FUlJOT19ICiNpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9mY250bC5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS93aW5lc3RyaW5nLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAiaGVhcC5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW52ZXJzaW9uLmgiCgpERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVnKQpERUNMQVJFX0RFQlVHX0NIQU5ORUwoc3RyaW5nKQoKc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCh2b2lkKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCi8qIE5PVEU6IGRvIG5vdCBhcHBlbmQgYSAvLiBsaW51eCcgbWtkaXIoKSBXSUxMIEZBSUwgaWYgeW91IGRvIHRoYXQgKi8KI2RlZmluZSBXSU5FX1BSRUZJWCAgICAgICAgICAgICAgICAgIi8ud2luZSIKI2RlZmluZSBTQVZFX1VTRVJTX0RFRkFVTFQgICAgICAgICAgRVRDRElSIi93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQgIEVUQ0RJUiIvd2luZS5zeXN0ZW1yZWciCgovKiByZWxhdGl2ZSBpbiB+dXNlci8ud2luZS8gOiAqLwojZGVmaW5lIFNBVkVfQ1VSUkVOVF9VU0VSICAgICAgICAgICAidXNlci5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUICAgICJ3aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FICAgICAgICAgICJzeXN0ZW0ucmVnIgoKI2RlZmluZSBLRVlfUkVHSVNUUlkgICAgICAgICAgICAgICAgIlNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeSIKI2RlZmluZSBWQUxfU0FWRVVQREFURUQgICAgICAgICAgICAgIlNhdmVPbmx5VXBkYXRlZEtleXMiCgovKiBvbmUgdmFsdWUgb2YgYSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZVkFMVUUKewogICAgTFBXU1RSICAgbmFtZTsgICAgICAgICAgLyogbmFtZSBvZiB2YWx1ZSAoVU5JQ09ERSkgb3IgTlVMTCBmb3Igd2luMzEgKi8KICAgIERXT1JEICAgIHR5cGU7ICAgICAgICAgIC8qIHR5cGUgb2YgdmFsdWUgKi8KICAgIERXT1JEICAgIGxlbjsgICAgICAgICAgIC8qIGxlbmd0aCBvZiBkYXRhIGluIEJZVEVzICovCiAgICBEV09SRCAgICBsYXN0bW9kaWZpZWQ7ICAvKiB0aW1lIG9mIHNlY29uZHMgc2luY2UgMS4xLjE5NzAgKi8KICAgIExQQllURSAgIGRhdGE7ICAgICAgICAgIC8qIGNvbnRlbnQsIG1heSBiZSBzdHJpbmdzLCBiaW5hcmllcywgZXRjLiAqLwp9IEtFWVZBTFVFLCpMUEtFWVZBTFVFOwoKLyogYSByZWdpc3RyeSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZU1RSVUNUCnsKICAgIExQV1NUUiAgICAgICAgICAgICAgIGtleW5hbWU7ICAgICAgIC8qIG5hbWUgb2YgVEhJUyBrZXkgKFVOSUNPREUpICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBmbGFnczsgICAgICAgICAvKiBmbGFncy4gKi8KICAgIExQV1NUUiAgICAgICAgICAgICAgIGNsYXNzOwogICAgLyogdmFsdWVzICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBucm9mdmFsdWVzOyAgICAvKiBuciBvZiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIExQS0VZVkFMVUUgICAgICAgICAgIHZhbHVlczsgICAgICAgIC8qIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgLyoga2V5IG1hbmFnZW1lbnQgcG9pbnRlcnMgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHQ7ICAgICAgICAgIC8qIG5leHQga2V5IG9uIHNhbWUgaGllcmFyY2h5ICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0c3ViOyAgICAgICAvKiBrZXlzIHRoYXQgaGFuZyBiZWxvdyBUSElTIGtleSAqLwp9IEtFWVNUUlVDVCwgKkxQS0VZU1RSVUNUOwoKCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jbGFzc2VzX3Jvb3Q9TlVMTDsJLyogd2luZG93cyAzLjEgZ2xvYmFsIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF91c2VyPU5VTEw7CS8qIHVzZXIgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9sb2NhbF9tYWNoaW5lPU5VTEw7LyogbWFjaGluZSBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3VzZXJzPU5VTEw7CS8qIGFsbCB1c2Vycz8gKi8KCi8qIGR5bmFtaWMsIG5vdCBzYXZlZCAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfcGVyZm9ybWFuY2VfZGF0YT1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF9jb25maWc9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2R5bl9kYXRhPU5VTEw7CgovKiB3aGF0IHZhbHVldHlwZXMgZG8gd2UgbmVlZCB0byBjb252ZXJ0PyAqLwojZGVmaW5lIFVOSUNPTlZNQVNLCSgoMTw8UkVHX1NaKXwoMTw8UkVHX01VTFRJX1NaKXwoMTw8UkVHX0VYUEFORF9TWikpCgoKc3RhdGljIHN0cnVjdCBvcGVuaGFuZGxlIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCVJFR1NBTQkJYWNjZXNzbWFzazsKfSAgKm9wZW5oYW5kbGVzPU5VTEw7CnN0YXRpYyBpbnQJbnJvZm9wZW5oYW5kbGVzPTA7Ci8qIFN0YXJ0cyBhZnRlciAxIGJlY2F1c2UgMCwxIGFyZSByZXNlcnZlZCBmb3IgV2luMTYgKi8KLyogTm90ZTogU2hvdWxkIGFsd2F5cyBiZSBldmVuLCBhcyBXaW45NSBBRFZBUEkzMi5ETEwgcmVzZXJ2ZXMgb2RkCiAgICAgICAgIEhLRVlzIGZvciByZW1vdGUgcmVnaXN0cnkgYWNjZXNzICovCnN0YXRpYyBpbnQJY3VycmVudGhhbmRsZT0yOwoKCi8qCiAqIFFVRVNUSU9OCiAqICAgQXJlIHRoZXNlIGRvaW5nIHRoZSBzYW1lIGFzIEhFQVBfc3RyZHVwQXRvVyBhbmQgSEVBUF9zdHJkdXBXdG9BPwogKiAgIElmIHNvLCBjYW4gd2UgcmVtb3ZlIHRoZW0/CiAqIEFOU1dFUgogKiAgIE5vLCB0aGUgbWVtb3J5IGhhbmRsaW5nIGZ1bmN0aW9ucyBhcmUgY2FsbGVkIHZlcnkgb2Z0ZW4gaW4gaGVyZSwgCiAqICAganVzdCByZXBsYWNpbmcgdGhlbSBieSBIZWFwQWxsb2MoU3lzdGVtSGVhcCwuLi4pIG1ha2VzIHJlZ2lzdHJ5CiAqICAgbG9hZGluZyAxMDAgdGltZXMgc2xvd2VyLiAtTU0KICovCnN0YXRpYyBMUFdTVFIgc3RyZHVwQTJXKExQQ1NUUiBzcmMpCnsKICAgIGlmKHNyYykgewoJTFBXU1RSIGRlc3Q9eG1hbGxvYygyKnN0cmxlbihzcmMpKzIpOwoJbHN0cmNweUF0b1coZGVzdCxzcmMpOwoJcmV0dXJuIGRlc3Q7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIExQV1NUUiBzdHJkdXBXKExQQ1dTVFIgYSkgewoJTFBXU1RSCWI7CglpbnQJbGVuOwoKICAgIGlmKGEpIHsKCWxlbj1zaXplb2YoV0NIQVIpKihsc3RybGVuVyhhKSsxKTsKCWI9KExQV1NUUil4bWFsbG9jKGxlbik7CgltZW1jcHkoYixhLGxlbik7CglyZXR1cm4gYjsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgpMUFdTVFIgc3RyY3Z0QTJXKExQQ1NUUiBzcmMsIGludCBuY2hhcnMpCgp7CiAgIExQV1NUUiBkZXN0ID0geG1hbGxvYyAoMiAqIG5jaGFycyArIDIpOwoKICAgbHN0cmNweW5BdG9XKGRlc3Qsc3JjLG5jaGFycysxKTsKICAgZGVzdFtuY2hhcnNdID0gMDsKICAgcmV0dXJuIGRlc3Q7Cn0KLyoKICogd2UgbmVlZCB0byBjb252ZXJ0IEEgdG8gVyB3aXRoICdcMCcgaW4gc3RyaW5ncyAoTVVMVElfU1opIAogKi8KCnN0YXRpYyBMUFdTVFIgIGxtZW1jcHluQXRvVyggTFBXU1RSIGRzdCwgTFBDU1RSIHNyYywgSU5UIG4gKQp7CUxQV1NUUiBwID0gZHN0OwoKCVRSQUNFXyhyZWcpKCJcIiVzXCIgJWlcbiIsc3JjLCBuKTsKCgl3aGlsZSAobi0tID4gMCkgKnArKyA9IChXQ0hBUikodW5zaWduZWQgY2hhcikqc3JjKys7CgoJcmV0dXJuIGRzdDsKfQpzdGF0aWMgTFBTVFIgbG1lbWNweW5XdG9BKCBMUFNUUiBkc3QsIExQQ1dTVFIgc3JjLCBJTlQgbiApCnsJTFBTVFIgcCA9IGRzdDsKCglUUkFDRV8oc3RyaW5nKSgiTFwiJXNcIiAlaVxuIixkZWJ1Z3N0cl93KHNyYyksIG4pOwoKCXdoaWxlIChuLS0gPiAwKSAqcCsrID0gKENIQVIpKnNyYysrOwoKCXJldHVybiBkc3Q7Cn0KCnN0YXRpYyB2b2lkIGRlYnVnX3ByaW50X3ZhbHVlIChMUEJZVEUgbHBiRGF0YSwgTFBLRVlWQUxVRSBrZXkpCnsKICBpZiAoVFJBQ0VfT04ocmVnKSAmJiBscGJEYXRhKSAKICB7IAogICAgc3dpdGNoKGtleS0+dHlwZSkKICAgIHsgCiAgICAgIGNhc2UgUkVHX0VYUEFORF9TWjoKICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgVFJBQ0VfKHJlZykoIiBWYWx1ZSAlcywgRGF0YShzeik9JXNcbiIsIAogICAgICAgICAgZGVidWdzdHJfdyhrZXktPm5hbWUpLCAKICAgICAgICAgIGRlYnVnc3RyX3coKExQQ1dTVFIpbHBiRGF0YSkpOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgVFJBQ0VfKHJlZykoIiBWYWx1ZSAlcywgRGF0YShkd29yZCk9MHglMDhseFxuIiwKICAgICAgICAgIGRlYnVnc3RyX3coa2V5LT5uYW1lKSwgCiAgICAgICAgICAoRFdPUkQpKmxwYkRhdGEpOwogICAgICAgIGJyZWFrOwogICAgCiAgICAgIGNhc2UgUkVHX01VTFRJX1NaOgogICAgICB7IAogICAgICAgIGludCBpOwogICAgICAgIExQQ1dTVFIgcHRyID0gKExQQ1dTVFIpbHBiRGF0YTsKICAgICAgICBmb3IgKGk9MDtwdHJbMF07aSsrKQogICAgICAgIHsgCiAgICAgICAgICBUUkFDRV8ocmVnKSgiIFZhbHVlICVzLCBNVUxUSV9TWiglaT0lcylcbiIsIAogICAgICAgICAgICBkZWJ1Z3N0cl93KGtleS0+bmFtZSksIAogICAgICAgICAgICBpLCAKICAgICAgICAgICAgZGVidWdzdHJfdyhwdHIpKTsKCiAgICAgICAgICBwdHIgKz0gbHN0cmxlblcocHRyKSsxOwogICAgICAgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgICAgIGRlZmF1bHQ6CiAgICAgIHsgCiAgICAgICAgY2hhciBzelRlbXBbMTAwXTsgICAgICAvKiAzKjMyICsgMyArIDEgKi8KICAgICAgICBpbnQgaTsKICAgICAgICBmb3IgKCBpID0gMDsgaSA8IGtleS0+bGVuIDsgaSsrKSAgICAgIAogICAgICAgIHsgCiAgICAgICAgICBzcHJpbnRmICgmKHN6VGVtcFtpKjNdKSwiJTAyeCAiLCBscGJEYXRhW2ldKTsKICAgICAgICAgIGlmIChpPj0zMSkKICAgICAgICAgIHsgCiAgICAgICAgICAgIHNwcmludGYgKCYoc3pUZW1wW2kqMyszXSksIi4uLiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgVFJBQ0VfKHJlZykoIiBWYWx1ZSAlcywgRGF0YShyYXcpPSglcylcbiIsIAogICAgICAgICAgZGVidWdzdHJfdyhrZXktPm5hbWUpLCAKICAgICAgICAgIHN6VGVtcCk7ICAgICAgICAgICAgICAgICAgCiAgICAgIH0KICAgIH0gLyogc3dpdGNoICovCiAgfSAvKiBpZiAqLwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBpc19zdGFuZGFyZF9oa2V5IFtJbnRlcm5hbF0KICogRGV0ZXJtaW5lcyBpZiBhIGhrZXkgaXMgYSBzdGFuZGFyZCBrZXkKICovCnN0YXRpYyBCT09MIGlzX3N0YW5kYXJkX2hrZXkoIEhLRVkgaGtleSApCnsKICAgIHN3aXRjaChoa2V5KSB7CiAgICAgICAgY2FzZSAweDAwMDAwMDAwOgogICAgICAgIGNhc2UgMHgwMDAwMDAwMToKICAgICAgICBjYXNlIEhLRVlfQ0xBU1NFU19ST09UOgogICAgICAgIGNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKICAgICAgICBjYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgogICAgICAgIGNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgogICAgICAgIGNhc2UgSEtFWV9VU0VSUzoKICAgICAgICBjYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKICAgICAgICBjYXNlIEhLRVlfRFlOX0RBVEE6CiAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBhZGRfaGFuZGxlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIGFkZF9oYW5kbGUoIEhLRVkgaGtleSwgTFBLRVlTVFJVQ1QgbHBrZXksIFJFR1NBTSBhY2Nlc3NtYXNrICkKewogICAgaW50IGk7CgogICAgVFJBQ0VfKHJlZykoIigweCV4LCVwLDB4JWx4KVxuIixoa2V5LGxwa2V5LGFjY2Vzc21hc2spOwogICAgLyogQ2hlY2sgZm9yIGR1cGxpY2F0ZXMgKi8KICAgIGZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykgewogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5scGtleT09bHBrZXkpIHsKICAgICAgICAgICAgLyogVGhpcyBpcyBub3QgcmVhbGx5IGFuIGVycm9yIC0gdGhlIHVzZXIgaXMgYWxsb3dlZCB0byBjcmVhdGUKICAgICAgICAgICAgICAgdHdvIChvciBtb3JlKSBoYW5kbGVzIHRvIHRoZSBzYW1lIGtleSAqLwogICAgICAgICAgICAvKldBUk4ocmVnLCAiQWRkaW5nIGtleSAlcCB0d2ljZVxuIixscGtleSk7Ki8KICAgICAgICB9CiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpIHsKICAgICAgICAgICAgV0FSTl8ocmVnKSgiQWRkaW5nIGhhbmRsZSAleCB0d2ljZVxuIixoa2V5KTsKICAgICAgICB9CiAgICB9CiAgICBvcGVuaGFuZGxlcz14cmVhbGxvYyggb3BlbmhhbmRsZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcysxKSk7CgogICAgb3BlbmhhbmRsZXNbaV0ubHBrZXkgPSBscGtleTsKICAgIG9wZW5oYW5kbGVzW2ldLmhrZXkgPSBoa2V5OwogICAgb3BlbmhhbmRsZXNbaV0uYWNjZXNzbWFzayA9IGFjY2Vzc21hc2s7CiAgICBucm9mb3BlbmhhbmRsZXMrKzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZ2V0X2hhbmRsZSBbSW50ZXJuYWxdCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogUG9pbnRlciB0byBrZXkKICogICAgRmFpbHVyZTogTlVMTAogKi8Kc3RhdGljIExQS0VZU1RSVUNUIGdldF9oYW5kbGUoIEhLRVkgaGtleSApCnsKICAgIGludCBpOwoKICAgIGZvciAoaT0wOyBpPG5yb2ZvcGVuaGFuZGxlczsgaSsrKQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5ID09IGhrZXkpCiAgICAgICAgICAgIHJldHVybiBvcGVuaGFuZGxlc1tpXS5scGtleTsKICAgIFdBUk5fKHJlZykoIkNvdWxkIG5vdCBmaW5kIGhhbmRsZSAweCV4XG4iLGhrZXkpOwogICAgcmV0dXJuIE5VTEw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIHJlbW92ZV9oYW5kbGUgW0ludGVybmFsXQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byByZW1vdmUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVSUk9SX0lOVkFMSURfSEFORExFCiAqLwpzdGF0aWMgRFdPUkQgcmVtb3ZlX2hhbmRsZSggSEtFWSBoa2V5ICkKewogICAgaW50IGk7CgogICAgZm9yIChpPTA7aTxucm9mb3BlbmhhbmRsZXM7aSsrKQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KQogICAgICAgICAgICBicmVhazsKCiAgICBpZiAoaSA9PSBucm9mb3BlbmhhbmRsZXMpIHsKICAgICAgICBXQVJOXyhyZWcpKCJDb3VsZCBub3QgZmluZCBoYW5kbGUgMHgleFxuIixoa2V5KTsKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CiAgICB9CgogICAgbWVtY3B5KCBvcGVuaGFuZGxlcytpLAogICAgICAgICAgICBvcGVuaGFuZGxlcytpKzEsCiAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy1pLTEpCiAgICApOwogICAgb3BlbmhhbmRsZXM9eHJlYWxsb2Mob3BlbmhhbmRsZXMsc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLTEpKTsKICAgIG5yb2ZvcGVuaGFuZGxlcy0tOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogbG9va3VwX2hrZXkgW0ludGVybmFsXQogKiAKICogSnVzdCBhcyB0aGUgbmFtZSBzYXlzLiBDcmVhdGVzIHRoZSByb290IGtleXMgb24gZGVtYW5kLCBzbyB3ZSBjYW4gY2FsbCB0aGUKICogUmVnKiBmdW5jdGlvbnMgYXQgYW55IHRpbWUuCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogUG9pbnRlciB0byBrZXkgc3RydWN0dXJlCiAqICAgIEZhaWx1cmU6IE5VTEwKICovCiNkZWZpbmUgQUREX1JPT1RfS0VZKHh4KSBcCgl4eCA9IChMUEtFWVNUUlVDVCl4bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTtcCgltZW1zZXQoeHgsJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7XAoJeHgtPmtleW5hbWU9IHN0cmR1cEEyVygiPHNob3VsZF9ub3RfYXBwZWFyX2FueXdoZXJlPiIpOwoKc3RhdGljIExQS0VZU1RSVUNUIGxvb2t1cF9oa2V5KCBIS0VZIGhrZXkgKQp7CiAgc3dpdGNoIChoa2V5KSB7CiAgLyogMCBhbmQgMSBhcmUgdmFsaWQgcm9vdGtleXMgaW4gd2luMTYgc2hlbGwuZGxsIGFuZCBhcmUgdXNlZCBieQogICAqIHNvbWUgcHJvZ3JhbXMuIERvIG5vdCByZW1vdmUgdGhvc2UgY2FzZXMuIC1NTQogICAqLwogCWNhc2UgMHgwMDAwMDAwMDoKICBjYXNlIDB4MDAwMDAwMDE6CiAgY2FzZSBIS0VZX0NMQVNTRVNfUk9PVDogCiAgewogICAgaWYgKCFrZXlfY2xhc3Nlc19yb290KSAKICAgIHsKICAgICAgSEtFWQljbF9yX2hrZXk7CgogICAgICAvKiBjYWxscyBsb29rdXBfaGtleSByZWN1cnNpdmVseSwgVFdJQ0UgKi8KICAgICAgaWYgKCBSZWdDcmVhdGVLZXkxNigKICAgICAgICAgICAgSEtFWV9MT0NBTF9NQUNISU5FLAogICAgICAgICAgICAiU09GVFdBUkVcXENsYXNzZXMiLAogICAgICAgICAgICAmY2xfcl9oa2V5KSAhPSBFUlJPUl9TVUNDRVNTKSAKICAgICAgewogICAgICAgIEVSUl8ocmVnKSgiQ291bGQgbm90IGNyZWF0ZSBIS0xNXFxTT0ZUV0FSRVxcQ2xhc3Nlcy4gVGhpcyBpcyBpbXBvc3NpYmxlLlxuIik7CiAgICAgICAgZXhpdCgxKTsKICAgICAgfQoKICAgICAga2V5X2NsYXNzZXNfcm9vdCA9IGxvb2t1cF9oa2V5KGNsX3JfaGtleSk7CiAgICB9CiAgICByZXR1cm4ga2V5X2NsYXNzZXNfcm9vdDsKICB9CgogIGNhc2UgSEtFWV9DVVJSRU5UX1VTRVI6CiAgICBpZiAoIWtleV9jdXJyZW50X3VzZXIpIHsKICAgICAgQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X3VzZXIpOwogICAgfQogICAgcmV0dXJuIGtleV9jdXJyZW50X3VzZXI7CgogIGNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgogICAgaWYgKCFrZXlfbG9jYWxfbWFjaGluZSkgewogICAgICBBRERfUk9PVF9LRVkoa2V5X2xvY2FsX21hY2hpbmUpOwogICAgICBSRUdJU1RSWV9Jbml0KCk7CiAgICB9CiAgICByZXR1cm4ga2V5X2xvY2FsX21hY2hpbmU7CgogIGNhc2UgSEtFWV9VU0VSUzoKICAgIGlmICgha2V5X3VzZXJzKSB7CiAgICAgIEFERF9ST09UX0tFWShrZXlfdXNlcnMpOwogICAgfQogICAgcmV0dXJuIGtleV91c2VyczsKCiAgY2FzZSBIS0VZX1BFUkZPUk1BTkNFX0RBVEE6CiAgICBpZiAoIWtleV9wZXJmb3JtYW5jZV9kYXRhKSB7CiAgICAgIEFERF9ST09UX0tFWShrZXlfcGVyZm9ybWFuY2VfZGF0YSk7CiAgICB9CiAgICByZXR1cm4ga2V5X3BlcmZvcm1hbmNlX2RhdGE7CgogIGNhc2UgSEtFWV9EWU5fREFUQToKICAgIGlmICgha2V5X2R5bl9kYXRhKSB7CiAgICAgIEFERF9ST09UX0tFWShrZXlfZHluX2RhdGEpOwogICAgfQogICAgcmV0dXJuIGtleV9keW5fZGF0YTsKCiAgY2FzZSBIS0VZX0NVUlJFTlRfQ09ORklHOgogICAgaWYgKCFrZXlfY3VycmVudF9jb25maWcpIHsKICAgICAgQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X2NvbmZpZyk7CiAgICB9CiAgICByZXR1cm4ga2V5X2N1cnJlbnRfY29uZmlnOwoKICBkZWZhdWx0OgogICAgcmV0dXJuIGdldF9oYW5kbGUoaGtleSk7CgogIH0KICAvKk5PVFJFQUNIRUQqLwp9CgoKLyoKICogcmVjdXJzaXZlbHkgc2VhcmNoZXMgZm9yIGxwa2V5X3RvX2ZpbmQgaW4gdGhlIHJvb3Qga2V5IGJyYW5jaAogKiBnaXZlbiBpbiBscGN1cnJrZXkuCiAqLwpzdGF0aWMgaW50IHN1YmtleV9mb3VuZChMUEtFWVNUUlVDVCBscGN1cnJrZXksIExQS0VZU1RSVUNUIGxwa2V5X3RvX2ZpbmQpCnsKCXdoaWxlIChscGN1cnJrZXkpCgl7CgkJaWYgKGxwY3VycmtleSA9PSBscGtleV90b19maW5kKQoJCQlyZXR1cm4gMTsKCQlpZiAoc3Via2V5X2ZvdW5kKGxwY3VycmtleS0+bmV4dHN1YiwgbHBrZXlfdG9fZmluZCkpCgkJCXJldHVybiAxOwoKCQlscGN1cnJrZXkgPSBscGN1cnJrZXktPm5leHQ7Cgl9CgoJVFJBQ0VfKHJlZykoIk5vIGtleSBmb3VuZCBpbiB0aGlzIHJvb3Qga2V5IGJyYW5jaFxuIik7CglyZXR1cm4gMDsKfQoKCi8qCiAqIGZpbmRzIHRoZSBjb3JyZXNwb25kaW5nIHJvb3Qga2V5IGZvciBhIHN1YiBrZXksIGkuZS4gZS5nLiBIS0VZX0NMQVNTRVNfUk9PVC4KICovIApzdGF0aWMgSEtFWSBmaW5kX3Jvb3Rfa2V5KExQS0VZU1RSVUNUIGxwa2V5KQp7Cgl0eXBlZGVmIHN0cnVjdCB0YWdST09UX0tFWVMgewogICAgCUtFWVNUUlVDVCAqbHBrZXk7CiAgICAJSEtFWSBoa2V5OwoJfSBST09UX0tFWVM7CiAgICBST09UX0tFWVMgcm9vdF9rZXlzW10gPSB7IHsga2V5X2NsYXNzZXNfcm9vdCwgSEtFWV9DTEFTU0VTX1JPT1QgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyBrZXlfY3VycmVudF91c2VyLCBIS0VZX0NVUlJFTlRfVVNFUiB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IGtleV9sb2NhbF9tYWNoaW5lLCBIS0VZX0xPQ0FMX01BQ0hJTkUgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyBrZXlfdXNlcnMsIEhLRVlfVVNFUlMgfSB9OwoJaW50IGk7CgoJZm9yIChpPTA7IGk8NDtpKyspCgl7CgkJaWYgKHN1YmtleV9mb3VuZChyb290X2tleXNbaV0ubHBrZXksIGxwa2V5KSkKCQkJCXJldHVybiByb290X2tleXNbaV0uaGtleTsJCQkJCgl9CglFUlJfKHJlZykoIkRpZG4ndCBmaW5kIGNvcnJlc3BvbmRpbmcgcm9vdCBrZXkgZW50cnkgISBTZWFyY2ggc3RyYXRlZ3kgYnJva2VuID8/XG4iKTsKCXJldHVybiAwOwojdW5kZWYgUk9PVF9LRVlTCn0KI3VuZGVmIEFERF9ST09UX0tFWQovKiBzbyB3ZSBkb24ndCBhY2NpZGVudGx5IGFjY2VzcyB0aGVtIC4uLiAqLwojZGVmaW5lIGtleV9jdXJyZW50X2NvbmZpZyBOVUxMIE5VTEwKI2RlZmluZSBrZXlfY3VycmVudF91c2VyIE5VTEwgTlVMTAojZGVmaW5lIGtleV91c2VycyBOVUxMIE5VTEwKI2RlZmluZSBrZXlfbG9jYWxfbWFjaGluZSBOVUxMIE5VTEwKI2RlZmluZSBrZXlfY2xhc3Nlc19yb290IE5VTEwgTlVMTAojZGVmaW5lIGtleV9keW5fZGF0YSBOVUxMIE5VTEwKI2RlZmluZSBrZXlfcGVyZm9ybWFuY2VfZGF0YSBOVUxMIE5VTEwKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogc3BsaXRfa2V5cGF0aCBbSW50ZXJuYWxdCiAqIHNwbGl0cyB0aGUgdW5pY29kZSBzdHJpbmcgJ3dwJyBpbnRvIGFuIGFycmF5IG9mIHN0cmluZ3MuCiAqIHRoZSBhcnJheSBpcyBhbGxvY2F0ZWQgYnkgdGhpcyBmdW5jdGlvbi4gCiAqIEZyZWUgdGhlIGFycmF5IHVzaW5nIEZSRUVfS0VZX1BBVEgKICoKICogUEFSQU1TCiAqICAgIHdwICBbSV0gU3RyaW5nIHRvIHNwbGl0IHVwCiAqICAgIHdwdiBbT10gQXJyYXkgb2YgcG9pbnRlcnMgdG8gc3RyaW5ncwogKiAgICB3cGMgW09dIE51bWJlciBvZiBjb21wb25lbnRzCiAqLwpzdGF0aWMgdm9pZCBzcGxpdF9rZXlwYXRoKCBMUENXU1RSIHdwLCBMUFdTVFIgKip3cHYsIGludCAqd3BjKQp7CiAgICBpbnQJaSxqLGxlbjsKICAgIExQV1NUUiB3czsKCiAgICBUUkFDRV8ocmVnKSgiKCVzLCVwLCVwKVxuIixkZWJ1Z3N0cl93KHdwKSx3cHYsd3BjKTsKCiAgICB3cwk9IEhFQVBfc3RyZHVwVyggU3lzdGVtSGVhcCwgMCwgd3AgKTsKCiAgICAvKiBXZSBrbm93IHdlIGhhdmUgYXQgbGVhc3Qgb25lIHN1YnN0cmluZyAqLwogICAgKndwYyA9IDE7CgogICAgLyogUmVwbGFjZSBlYWNoIGJhY2tzbGFzaCB3aXRoIE5VTEwsIGFuZCBpbmNyZW1lbnQgdGhlIGNvdW50ICovCiAgICBmb3IgKGk9MDt3c1tpXTtpKyspIHsKICAgICAgICBpZiAod3NbaV09PSdcXCcpIHsKICAgICAgICAgICAgd3NbaV09MDsKICAgICAgICAgICAgKCp3cGMpKys7CiAgICAgICAgfQogICAgfQoKICAgIGxlbiA9IGk7CgogICAgLyogQWxsb2NhdGUgdGhlIHNwYWNlIGZvciB0aGUgYXJyYXkgb2YgcG9pbnRlcnMsIGxlYXZpbmcgcm9vbSBmb3IgdGhlCiAgICAgICBOVUxMIGF0IHRoZSBlbmQgKi8KICAgICp3cHYgPSAoTFBXU1RSKilIZWFwQWxsb2MoIFN5c3RlbUhlYXAsIDAsIHNpemVvZihMUFdTVFIpKigqd3BjKzIpKTsKICAgICgqd3B2KVswXT0gd3M7CgogICAgLyogQXNzaWduIGVhY2ggcG9pbnRlciB0byB0aGUgYXBwcm9wcmlhdGUgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcgKi8KICAgIGogPSAxOwogICAgZm9yIChpPTE7aTxsZW47aSsrKQogICAgICAgIGlmICh3c1tpLTFdPT0wKSB7CiAgICAgICAgICAgICgqd3B2KVtqKytdPXdzK2k7CiAgICAgICAgICAgIC8qIFRSQUNFKHJlZywgIiBTdWJpdGVtICVkID0gJXNcbiIsai0xLGRlYnVnc3RyX3coKCp3cHYpW2otMV0pKTsgKi8KICAgICAgICB9CgogICAgKCp3cHYpW2pdPU5VTEw7Cn0KI2RlZmluZSBGUkVFX0tFWV9QQVRIIEhlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHNbMF0pO0hlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHMpOwoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSRUdJU1RSWV9Jbml0IFtJbnRlcm5hbF0KICogUmVnaXN0cnkgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBzb21lIGRlZmF1bHQga2V5cy4gCiAqLwpzdGF0aWMgdm9pZCBSRUdJU1RSWV9Jbml0KHZvaWQpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJVFJBQ0VfKHJlZykoIih2b2lkKVxuIik7CgoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9EWU5fREFUQSwiUGVyZlN0YXRzXFxTdGF0RGF0YSIsJmhrZXkpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgogICAgICAgIC8qIFRoaXMgd2FzIGFuIE9wZW4sIGJ1dCBzaW5jZSBpdCBpcyBjYWxsZWQgYmVmb3JlIHRoZSByZWFsIHJlZ2lzdHJpZXMKICAgICAgICAgICBhcmUgbG9hZGVkLCBpdCB3YXMgY2hhbmdlZCB0byBhIENyZWF0ZSAtIE1UQiA5ODA1MDcqLwoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJIQVJEV0FSRVxcREVTQ1JJUFRJT05cXFN5c3RlbSIsJmhrZXkpOwoJUmVnU2V0VmFsdWVFeEEoaGtleSwiSWRlbnRpZmllciIsMCxSRUdfU1osIlN5c3RlbVR5cGUgV0lORSIsc3RybGVuKCJTeXN0ZW1UeXBlIFdJTkUiKSk7CglSZWdDbG9zZUtleShoa2V5KTsKCgkvKiBcXFNPRlRXQVJFXFxNaWNyb3NvZnRcXFdpbmRvdyBOVFxcQ3VycmVudFZlcnNpb24KCSAqCQkJCQkJQ3VycmVudFZlcnNpb24KCSAqCQkJCQkJQ3VycmVudEJ1aWxkTnVtYmVyCgkgKgkJCQkJCUN1cnJlbnRUeXBlCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPd25lcgoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3JnYW5pemF0aW9uCgkgKgoJICovCgkvKiBTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxTZXJ2aWNlc1xcU05NUFxcUGFyYW1ldGVyc1xcUkZDMTE1NkFnZW50CgkgKiAJCQkJCXN0cmluZwlTeXNDb250YWN0CgkgKiAJCQkJCXN0cmluZwlTeXNMb2NhdGlvbgoJICogCQkJCQkJU3lzU2VydmljZXMKCSAqLwkJCQkJCQoJaWYgKC0xIT1nZXRob3N0bmFtZShidWYsMjAwKSkgewoJCVJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcQ29tcHV0ZXJOYW1lXFxDb21wdXRlck5hbWUiLCZoa2V5KTsKCQlSZWdTZXRWYWx1ZUV4MTYoaGtleSwiQ29tcHV0ZXJOYW1lIiwwLFJFR19TWixidWYsc3RybGVuKGJ1ZikrMSk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqIFNBVkUgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgUkVHSVNUUllfU0FWRV9WRVJTSU9OCTB4MDAwMDAwMDEKCi8qIFJlZ2lzdHJ5IHNhdmVmb3JtYXQ6CiAqIElmIHlvdSBjaGFuZ2UgaXQsIGluY3JlYXNlIGFib3ZlIG51bWJlciBieSAxLCB3aGljaCB3aWxsIGZsdXNoCiAqIG9sZCByZWdpc3RyeSBkYXRhYmFzZSBmaWxlcy4KICogCiAqIEdsb2JhbDoKICogCSJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWQiCiAqIAlzdWJrZXlzLi4uLgogKiBTdWJrZXlzOgogKiAJa2V5bmFtZQogKgkJdmFsdWVuYW1lPWxhc3Rtb2RpZmllZCx0eXBlLGRhdGEKICoJCS4uLgogKgkJc3Via2V5cwogKgkuLi4KICoga2V5bmFtZSx2YWx1ZW5hbWUsc3RyaW5nZGF0YToKICoJdGhlIHVzdWFsIGFzY2lpIGNoYXJhY3RlcnMgZnJvbSAweDAwLTB4ZmYgKHdlbGwsIG5vdCAweDAwKQogKglhbmQgXHVYWFhYIGFzIFVOSUNPREUgdmFsdWUgWFhYWCB3aXRoIFhYWFg+MHhmZgogKgkoICI9XFxcdCIgZXNjYXBlZCBpbiBcdVhYWFggZm9ybS4pCiAqIHR5cGUsbGFzdG1vZGlmaWVkOiAKICoJaW50CiAqIAogKiBGSVhNRTogZG9lc24ndCBzYXZlICdjbGFzcycgKHdoYXQgZG9lcyBpdCBtZWFuIGFueXdheT8pLCBub3IgZmxhZ3MuCiAqCiAqIFtIS0VZX0NVUlJFTlRfVVNFUlxcU29mdHdhcmVcXFRoZSBXSU5FIHRlYW1cXFdJTkVcXFJlZ2lzdHJ5XQogKiBTYXZlT25seVVwZGF0ZWRLZXlzPXllcwogKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVfY2hlY2tfdGFpbnRlZCBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF9zYXZlX2NoZWNrX3RhaW50ZWQoIExQS0VZU1RSVUNUIGxwa2V5ICkKewoJaW50CQl0YWludGVkOwoKCWlmICghbHBrZXkpCgkJcmV0dXJuIDA7CglpZiAobHBrZXktPmZsYWdzICYgUkVHX09QVElPTl9UQUlOVEVEKQoJCXRhaW50ZWQgPSAxOwoJZWxzZQoJCXRhaW50ZWQgPSAwOwoJd2hpbGUgKGxwa2V5KSB7CgkJaWYgKF9zYXZlX2NoZWNrX3RhaW50ZWQobHBrZXktPm5leHRzdWIpKSB7CgkJCWxwa2V5LT5mbGFncyB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJCXRhaW50ZWQgPSAxOwoJCX0KCQlscGtleQk9IGxwa2V5LT5uZXh0OwoJfQoJcmV0dXJuIHRhaW50ZWQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVfVVNUUklORyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfc2F2ZV9VU1RSSU5HKCBGSUxFICpGLCBMUFdTVFIgd3N0ciwgaW50IGVzY2FwZWVxICkKewoJTFBXU1RSCXM7CglpbnQJZG9lc2NhcGU7CgoJaWYgKHdzdHI9PU5VTEwpCgkJcmV0dXJuOwoJcz13c3RyOwoJd2hpbGUgKCpzKSB7CgkJZG9lc2NhcGU9MDsKCQlpZiAoKnM+MHhmZikKCQkJZG9lc2NhcGUgPSAxOwoJCWlmICgqcz09J1xuJykKCQkJZG9lc2NhcGUgPSAxOwoJCWlmIChlc2NhcGVlcSAmJiAqcz09Jz0nKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKCpzPT0nXFwnKQogICAgICAgICAgICAgICAgICAgICAgICBmcHV0YygqcyxGKTsgLyogaWYgXFwgdGhlbiBwdXQgaXQgdHdpY2UuICovCgkJaWYgKGRvZXNjYXBlKQoJCQlmcHJpbnRmKEYsIlxcdSUwNHgiLCooKHVuc2lnbmVkIHNob3J0KilzKSk7CgkJZWxzZQoJCQlmcHV0YygqcyxGKTsKCQlzKys7Cgl9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVzdWJrZXkgW0ludGVybmFsXQogKgogKiBOT1RFUwogKiAgUkVHX01VTFRJX1NaIGlzIGhhbmRsZWQgYXMgYmluYXJ5IChsaWtlIGluIHdpbjk1KSAoanMpCiAqLwpzdGF0aWMgaW50IF9zYXZlc3Via2V5KCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGxldmVsLCBpbnQgYWxsICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlpLHRhYnMsajsKCglscHhrZXkJPSBscGtleTsKCXdoaWxlIChscHhrZXkpIHsKCQlpZiAoCSEobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVk9MQVRJTEUpICYmCgkJCShhbGwgfHwgKGxweGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1RBSU5URUQpKQoJCSkgewoJCQlmb3IgKHRhYnM9bGV2ZWw7dGFicy0tOykKCQkJCWZwdXRjKCdcdCcsRik7CgkJCV9zYXZlX1VTVFJJTkcoRixscHhrZXktPmtleW5hbWUsMSk7CgkJCWZwdXRzKCJcbiIsRik7CgkJCWZvciAoaT0wO2k8bHB4a2V5LT5ucm9mdmFsdWVzO2krKykgewoJCQkJTFBLRVlWQUxVRQl2YWw9bHB4a2V5LT52YWx1ZXMraTsKCgkJCQlmb3IgKHRhYnM9bGV2ZWwrMTt0YWJzLS07KQoJCQkJCWZwdXRjKCdcdCcsRik7CgkJCQlfc2F2ZV9VU1RSSU5HKEYsdmFsLT5uYW1lLDApOwoJCQkJZnB1dGMoJz0nLEYpOwoJCQkJZnByaW50ZihGLCIlbGQsJWxkLCIsdmFsLT50eXBlLHZhbC0+bGFzdG1vZGlmaWVkKTsKCQkJCWlmICggdmFsLT50eXBlID09IFJFR19TWiB8fCB2YWwtPnR5cGUgPT0gUkVHX0VYUEFORF9TWiApCgkJCQkJX3NhdmVfVVNUUklORyhGLChMUFdTVFIpdmFsLT5kYXRhLDApOwoJCQkJZWxzZQoJCQkJCWZvciAoaj0wO2o8dmFsLT5sZW47aisrKQoJCQkJCQlmcHJpbnRmKEYsIiUwMngiLCooKHVuc2lnbmVkIGNoYXIqKXZhbC0+ZGF0YStqKSk7CgkJCQlmcHV0cygiXG4iLEYpOwoJCQl9CgkJCS8qIGRlc2NlbmQgcmVjdXJzaXZlbHkgKi8KCQkJaWYgKCFfc2F2ZXN1YmtleShGLGxweGtleS0+bmV4dHN1YixsZXZlbCsxLGFsbCkpCgkJCQlyZXR1cm4gMDsKCQl9CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXN1YnJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF9zYXZlc3VicmVnKCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGFsbCApCnsKCWZwcmludGYoRiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkXG4iLFJFR0lTVFJZX1NBVkVfVkVSU0lPTik7Cglfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKTsKCXJldHVybiBfc2F2ZXN1YmtleShGLGxwa2V5LT5uZXh0c3ViLDAsYWxsKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIEJPT0wgX3NhdmVyZWcoIExQS0VZU1RSVUNUIGxwa2V5LCBjaGFyICpmbiwgaW50IGFsbCApCnsKCUZJTEUJKkY7CgoJRj1mb3BlbihmbiwidyIpOwoJaWYgKEY9PU5VTEwpIHsKCQlXQVJOXyhyZWcpKCJDb3VsZG4ndCBvcGVuICVzIGZvciB3cml0aW5nOiAlc1xuIiwKCQkJZm4sc3RyZXJyb3IoZXJybm8pCgkJKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglpZiAoIV9zYXZlc3VicmVnKEYsbHBrZXksYWxsKSkgewoJCWZjbG9zZShGKTsKCQl1bmxpbmsoZm4pOwoJCVdBUk5fKHJlZykoIkZhaWxlZCB0byBzYXZlIGtleXMsIHBlcmhhcHMgbm8gbW9yZSBkaXNrc3BhY2UgZm9yICVzP1xuIixmbik7CgkJcmV0dXJuIEZBTFNFOwoJfQoJZmNsb3NlKEYpOwogICAgICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEVMTF9TYXZlUmVnaXN0cnlCcmFuY2ggW0ludGVybmFsXQogKgogKiBTYXZlcyBtYWluIHJlZ2lzdHJ5IGJyYW5jaCBzcGVjaWZpZWQgYnkgaGtleS4KICovCnN0YXRpYyB2b2lkIFNIRUxMX1NhdmVSZWdpc3RyeUJyYW5jaChIS0VZIGhrZXksIGludCBhbGwpCnsKICAgIGNoYXIgICAqZm4sICpob21lLCAqdG1wOwoKICAgIC8qIEZJWE1FOiBkb2VzIHRoaXMgY2hlY2sgYXBwbHkgdG8gYWxsIGtleXMgd3JpdHRlbiBiZWxvdyA/ICovCiAgICBpZiAoIShob21lID0gZ2V0ZW52KCAiSE9NRSIgKSkpCiAgICAgICAgewogICAgICAgIEVSUl8ocmVnKSgiRmFpbGVkIHRvIGdldCBob21lZGlyZWN0b3J5IG9mIFVJRCAlbGQuXG4iLChsb25nKSBnZXR1aWQoKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKCS8qIEhLRVlfTE9DQUxfTUFDSElORSBjb250YWlucyB0aGUgSEtFWV9DTEFTU0VTX1JPT1QgYnJhbmNoICovCglpZiAoaGtleSA9PSBIS0VZX0NMQVNTRVNfUk9PVCkKCQloa2V5ID0gSEtFWV9MT0NBTF9NQUNISU5FOwoKCXN3aXRjaCAoaGtleSkKICAgIHsKCQljYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgoJCQl7CgkJCQlpbnQgdXNlZENmZ1VzZXIgPSAwOwoKICAgIGZuID0geG1hbGxvYyggTUFYX1BBVEhOQU1FX0xFTiApOyAKCQkJCWlmIChQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcgKCAiUmVnaXN0cnkiLCAiVXNlckZpbGVOYW1lIiwgIiIsCgkJCQkJCQkJCQkJCWZuLCBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpCiAgICB7CiAgICAgICAgX3NhdmVyZWcobG9va3VwX2hrZXkoSEtFWV9DVVJSRU5UX1VTRVIpLGZuLGFsbCk7CiAgICAgICAgdXNlZENmZ1VzZXIgPSAxOwogICAgfQogICAgZnJlZSAoZm4pOwoKICAgIGlmICh1c2VkQ2ZnVXNlciAhPSAxKQogICAgewogICAgICAgIGZuPShjaGFyKil4bWFsbG9jKCBzdHJsZW4oaG9tZSkgKyBzdHJsZW4oV0lORV9QUkVGSVgpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfQ1VSUkVOVF9VU0VSKSArIDIgKTsKICAgICAgICBzdHJjcHkoZm4saG9tZSk7CiAgICAgICAgc3RyY2F0KGZuLFdJTkVfUFJFRklYKTsKICAKICAgICAgICAvKiBjcmVhdGUgdGhlIGRpcmVjdG9yeS4gZG9uJ3QgY2FyZSBhYm91dCBlcnJvcmNvZGVzLiAqLwogICAgICAgIG1rZGlyKGZuLDA3NTUpOyAvKiBkcnd4ci14ci14ICovCiAgICAgICAgc3RyY2F0KGZuLCIvIlNBVkVfQ1VSUkVOVF9VU0VSKTsKCiAgICAgICAgdG1wID0gKGNoYXIqKXhtYWxsb2Moc3RybGVuKGZuKStzdHJsZW4oIi50bXAiKSsxKTsKICAgICAgICBzdHJjcHkodG1wLGZuKTsKICAgICAgICBzdHJjYXQodG1wLCIudG1wIik7CiAgCiAgICAgICAgaWYgKF9zYXZlcmVnKGxvb2t1cF9oa2V5KEhLRVlfQ1VSUkVOVF9VU0VSKSx0bXAsYWxsKSkgewogICAgICAgICAgICBpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CiAgICAgICAgICAgICAgICBwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKICAgICAgICAgICAgICAgIHVubGluayh0bXApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZyZWUodG1wKTsKICAgICAgICBmcmVlKGZuKTsKICAgIH0KCQkJfQoJCQlicmVhazsKCQljYXNlIEhLRVlfTE9DQUxfTUFDSElORToKCQkJewoJCQkJaW50IHVzZWRDZmdMTSA9IDA7CgkJCQkvKiBUcnkgZmlyc3Qgc2F2aW5nIGFjY29yZGluZyB0byB0aGUgZGVmaW5lZCBsb2NhdGlvbiBpbiAud2luZXJjICovCiAgICBmbiA9IHhtYWxsb2MgKCBNQVhfUEFUSE5BTUVfTEVOKTsKCQkJCWlmIChQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcgKCAiUmVnaXN0cnkiLAoJCQkJCQkiTG9jYWxNYWNoaW5lRmlsZU5hbWUiLAkiIiwgZm4sIE1BWF9QQVRITkFNRV9MRU4gLSAxKSkKICAgIHsKICAgICAgICBfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpLCBmbiwgYWxsKTsKICAgICAgICB1c2VkQ2ZnTE0gPSAxOwogICAgfQogICAgZnJlZSAoZm4pOwoKICAgIGlmICggdXNlZENmZ0xNICE9IDEpCiAgICB7CgkJCQkJZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwoJCQkJCQkJCQkgICBzdHJsZW4oU0FWRV9MT0NBTF9NQUNISU5FKSArIDIpOwogICAgICAgIHN0cmNweShmbixob21lKTsKICAgICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwoKICAgICAgICB0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwogICAgICAgIHN0cmNweSh0bXAsZm4pOwogICAgICAgIHN0cmNhdCh0bXAsIi50bXAiKTsKCiAgICAgICAgaWYgKF9zYXZlcmVnKGxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSksdG1wLGFsbCkpIHsKICAgICAgICAgICAgaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewogICAgICAgICAgICAgICAgcGVycm9yKCJyZW5hbWUgdG1wIHJlZ2lzdHJ5Iik7CiAgICAgICAgICAgICAgICB1bmxpbmsodG1wKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmcmVlKHRtcCk7CiAgICAgICAgZnJlZShmbik7CiAgICB9CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBIS0VZX1VTRVJTOgoJCQlmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKGhvbWUpICsgc3RybGVuKFdJTkVfUFJFRklYKSArCgkJCQkJCQkgICBzdHJsZW4oU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKSArIDIpOwoKICAgIHN0cmNweShmbixob21lKTsKICAgIHN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCk7CgogICAgdG1wID0gKGNoYXIqKXhtYWxsb2Moc3RybGVuKGZuKStzdHJsZW4oIi50bXAiKSsxKTsKICAgIHN0cmNweSh0bXAsZm4pO3N0cmNhdCh0bXAsIi50bXAiKTsKICAgIGlmICggX3NhdmVyZWcobG9va3VwX2hrZXkoSEtFWV9VU0VSUyksdG1wLEZBTFNFKSkgewogICAgICAgIGlmICgtMT09cmVuYW1lKHRtcCxmbikpIHsKICAgICAgICAgICAgcGVycm9yKCJyZW5hbWUgdG1wIHJlZ2lzdHJ5Iik7CiAgICAgICAgICAgIHVubGluayh0bXApOwogICAgICAgIH0KICAgIH0KICAgIGZyZWUodG1wKTsKICAgIGZyZWUoZm4pOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlFUlJfKHJlZykoInVua25vd24vaW52YWxpZCBrZXkgaGFuZGxlICFcbiIpOwoJCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfU2F2ZVJlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnZvaWQgU0hFTExfU2F2ZVJlZ2lzdHJ5KCB2b2lkICkKewogICAgY2hhciAgIGJ1Zls0XTsKICAgIEhLRVkgICBoa2V5OwogICAgaW50ICAgIGFsbDsKCiAgICBUUkFDRV8ocmVnKSgiKHZvaWQpXG4iKTsKCiAgICBhbGw9MDsKICAgIGlmIChSZWdPcGVuS2V5MTYoSEtFWV9DVVJSRU5UX1VTRVIsS0VZX1JFR0lTVFJZLCZoa2V5KSE9RVJST1JfU1VDQ0VTUykgCiAgICB7CiAgICAgICAgc3RyY3B5KGJ1ZiwieWVzIik7CiAgICB9IAogICAgZWxzZSAKICAgIHsKICAgICAgICBEV09SRCBsZW4sanVuayx0eXBlOwoKICAgICAgICBsZW49NDsKICAgICAgICBpZiAoKEVSUk9SX1NVQ0NFU1MhPVJlZ1F1ZXJ5VmFsdWVFeEEoIGhrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUxfU0FWRVVQREFURUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmanVuaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmxlbikpIHx8ICh0eXBlIT1SRUdfU1opKQogICAgICAgIHsKICAgICAgICAgICAgc3RyY3B5KGJ1ZiwieWVzIik7CiAgICAgICAgfQogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwp9CgogICAgaWYgKGxzdHJjbXBpQShidWYsInllcyIpKQoJCWFsbCA9IDE7CgoJU0hFTExfU2F2ZVJlZ2lzdHJ5QnJhbmNoKEhLRVlfQ1VSUkVOVF9VU0VSLCBhbGwpOwoJU0hFTExfU2F2ZVJlZ2lzdHJ5QnJhbmNoKEhLRVlfTE9DQUxfTUFDSElORSwgYWxsKTsKCVNIRUxMX1NhdmVSZWdpc3RyeUJyYW5jaChIS0VZX1VTRVJTLCBhbGwpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKiBMT0FEIFJlZ2lzdHJ5IEZ1bmN0aW9uICoqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2ZpbmRfb3JfYWRkX2tleSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgX2ZpbmRfb3JfYWRkX2tleSggTFBLRVlTVFJVQ1QgbHBrZXksIExQV1NUUiBrZXluYW1lICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5LCpscGxwa2V5OwoKCWlmICgoIWtleW5hbWUpIHx8IChrZXluYW1lWzBdPT0wKSkgewoJCWZyZWUoa2V5bmFtZSk7CgkJcmV0dXJuIGxwa2V5OwoJfQoJbHBscGtleT0gJihscGtleS0+bmV4dHN1Yik7CglscHhrZXkJPSAqbHBscGtleTsKCXdoaWxlIChscHhrZXkpIHsKCQlpZiAoCXRvbG93ZXIobHB4a2V5LT5rZXluYW1lWzBdKT09dG9sb3dlcihrZXluYW1lWzBdKSAmJiAKCQkJIWxzdHJjbXBpVyhscHhrZXktPmtleW5hbWUsa2V5bmFtZSkKCQkpCgkJCWJyZWFrOwoJCWxwbHBrZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7Cgl9CglpZiAobHB4a2V5PT1OVUxMKSB7CgkJKmxwbHBrZXkgPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7CgkJbWVtc2V0KGxweGtleSwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTsKCQlscHhrZXktPmtleW5hbWUJPSBrZXluYW1lOwoJfSBlbHNlCgkJZnJlZShrZXluYW1lKTsKCXJldHVybiBscHhrZXk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2ZpbmRfb3JfYWRkX3ZhbHVlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9maW5kX29yX2FkZF92YWx1ZSggTFBLRVlTVFJVQ1QgbHBrZXksIExQV1NUUiBuYW1lLCBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBkYXRhLCBEV09SRCBsZW4sIERXT1JEIGxhc3Rtb2RpZmllZCApCnsKCUxQS0VZVkFMVUUJdmFsPU5VTEw7CglpbnQJCWk7CgoJaWYgKG5hbWUgJiYgISpuYW1lKSB7LyogZW1wdHkgc3RyaW5nIGVxdWFscyBkZWZhdWx0IChOVUxMKSB2YWx1ZSAqLwoJCWZyZWUobmFtZSk7CgkJbmFtZSA9IE5VTEw7Cgl9CgoJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCWlmIChuYW1lPT1OVUxMKSB7CgkJCWlmICh2YWwtPm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCQl9IGVsc2UgewoJCQlpZiAoCXZhbC0+bmFtZSE9TlVMTCAmJgoJCQkJdG9sb3dlcih2YWwtPm5hbWVbMF0pPT10b2xvd2VyKG5hbWVbMF0pICYmCgkJCQkhbHN0cmNtcGlXKHZhbC0+bmFtZSxuYW1lKQoJCQkpCgkJCQlicmVhazsKCQl9Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0geHJlYWxsb2MoCgkJCWxwa2V5LT52YWx1ZXMsCgkJCSgrK2xwa2V5LT5ucm9mdmFsdWVzKSpzaXplb2YoS0VZVkFMVUUpCgkJKTsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCW1lbXNldCh2YWwsJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCQl2YWwtPm5hbWUgPSBuYW1lOwoJfSBlbHNlIHsKCQlpZiAobmFtZSkKCQkJZnJlZShuYW1lKTsKCX0KCWlmICh2YWwtPmxhc3Rtb2RpZmllZDxsYXN0bW9kaWZpZWQpIHsKCQl2YWwtPmxhc3Rtb2RpZmllZD1sYXN0bW9kaWZpZWQ7CgkJdmFsLT50eXBlID0gdHlwZTsKCiAgICAgICAgICAgICAgICBpZiAoKHR5cGUgPT0gUkVHX1NaIHx8IHR5cGUgPT0gUkVHX0VYUEFORF9TWikgJiYgIWRhdGEpewoKICAgICAgICAgICAgICAgICAgICBkYXRhPXhtYWxsb2Moc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgICAgICAgICAgICAgbWVtc2V0KGRhdGEsMCxzaXplb2YoV0NIQVIpKTsKICAgICAgICAgICAgICAgICAgICBsZW4gPXNpemVvZihXQ0hBUik7CiAgICAgICAgICAgICAgICB9CgoJCXZhbC0+bGVuICA9IGxlbjsKCQlpZiAodmFsLT5kYXRhKSAKCQkJZnJlZSh2YWwtPmRhdGEpOwoJCXZhbC0+ZGF0YSA9IGRhdGE7Cgl9IGVsc2UKCQlmcmVlKGRhdGEpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9yZWFkX2xpbmUgW0ludGVybmFsXQogKgogKiByZWFkcyBhIGxpbmUgaW5jbHVkaW5nIGR5bmFtaWNhbGx5IGVubGFyZ2luZyB0aGUgcmVhZGJ1ZmZlciBhbmQgdGhyb3dpbmcKICogYXdheSBjb21tZW50cwogKi8Kc3RhdGljIGludCBfd2luZV9yZWFkX2xpbmUoIEZJTEUgKkYsIGNoYXIgKipidWYsIGludCAqbGVuICkKewoJY2hhcgkqcywqY3VycmVhZDsKCWludAlteWxlbixjdXJvZmY7CgoJY3VycmVhZAk9ICpidWY7CglteWxlbgk9ICpsZW47CgkqKmJ1Zgk9ICdcMCc7Cgl3aGlsZSAoMSkgewoJCXdoaWxlICgxKSB7CgkJCXM9ZmdldHMoY3VycmVhZCxteWxlbixGKTsKCQkJaWYgKHM9PU5VTEwpCgkJCQlyZXR1cm4gMDsgLyogRU9GICovCgkJCWlmIChOVUxMPT0ocz1zdHJjaHIoY3VycmVhZCwnXG4nKSkpIHsKCQkJCS8qIGJ1ZmZlciB3YXNuJ3QgbGFyZ2UgZW5vdWdoICovCgkJCQljdXJvZmYJPSBzdHJsZW4oKmJ1Zik7CgkJCQkqYnVmCT0geHJlYWxsb2MoKmJ1ZiwqbGVuKjIpOwoJCQkJY3VycmVhZAk9ICpidWYgKyBjdXJvZmY7CgkJCQlteWxlbgk9ICpsZW47CS8qIHdlIGZpbGxlZCB1cCB0aGUgYnVmZmVyIGFuZCAKCQkJCQkJICogZ290IG5ldyAnKmxlbicgYnl0ZXMgdG8gZmlsbAoJCQkJCQkgKi8KCQkJCSpsZW4JPSAqbGVuICogMjsKCQkJfSBlbHNlIHsKCQkJCSpzPSdcMCc7CgkJCQlicmVhazsKCQkJfQoJCX0KCQkvKiB0aHJvdyBhd2F5IGNvbW1lbnRzICovCgkJaWYgKCoqYnVmPT0nIycgfHwgKipidWY9PSc7JykgewoJCQljdXJyZWFkCT0gKmJ1ZjsKCQkJbXlsZW4JPSAqbGVuOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKHMpIAkvKiBnb3QgZW5kIG9mIGxpbmUgKi8KCQkJYnJlYWs7Cgl9CglyZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9VU1RSSU5HIFtJbnRlcm5hbF0KICoKICogY29udmVydHMgYSBjaGFyKiBpbnRvIGEgVU5JQ09ERSBzdHJpbmcgKHVwIHRvIGEgc3BlY2lhbCBjaGFyKQogKiBhbmQgcmV0dXJucyB0aGUgcG9zaXRpb24gZXhhY3RseSBhZnRlciB0aGF0IHN0cmluZwogKi8Kc3RhdGljIGNoYXIqIF93aW5lX3JlYWRfVVNUUklORyggY2hhciAqYnVmLCBMUFdTVFIgKnN0ciApCnsKCWNoYXIJKnM7CglMUFdTVFIJd3M7CgoJLyogcmVhZCB1cCB0byAiPSIgb3IgIlwwIiBvciAiXG4iICovCglzCT0gYnVmOwoJaWYgKCpzID09ICc9JykgewoJCS8qIGVtcHR5IHN0cmluZyBpcyB0aGUgd2luMy4xIGRlZmF1bHQgdmFsdWUoTlVMTCkqLwoJCSpzdHIJPSBOVUxMOwoJCXJldHVybiBzOwoJfQoJKnN0cgk9IChMUFdTVFIpeG1hbGxvYygyKnN0cmxlbihidWYpKzIpOwoJd3MJPSAqc3RyOwoJd2hpbGUgKCpzICYmICgqcyE9J1xuJykgJiYgKCpzIT0nPScpKSB7CgkJaWYgKCpzIT0nXFwnKQoJCQkqd3MrKz0qKCh1bnNpZ25lZCBjaGFyKilzKyspOwoJCWVsc2UgewoJCQlzKys7CgkJCWlmICghKnMpIHsKCQkJCS8qIERhbmdsaW5nIFwgLi4uIG1heSBvbmx5IGhhcHBlbiBpZiBhIHJlZ2lzdHJ5CgkJCQkgKiB3cml0ZSB3YXMgc2hvcnQuIEZJWE1FOiBXaGF0IGRvIHRvPwoJCQkJICovCgkJCQkgYnJlYWs7CgkJCX0KCQkJaWYgKCpzPT0nXFwnKSB7CgkJCQkqd3MrKz0nXFwnOwoJCQkJcysrOwoJCQkJY29udGludWU7CgkJCX0KCQkJaWYgKCpzIT0ndScpIHsKCQkJCVdBUk5fKHJlZykoIk5vbiB1bmljb2RlIGVzY2FwZSBzZXF1ZW5jZSBcXCVjIGZvdW5kIGluIHwlc3xcbiIsKnMsYnVmKTsKCQkJCSp3cysrPSdcXCc7CgkJCQkqd3MrKz0qcysrOwoJCQl9IGVsc2UgewoJCQkJY2hhcgl4YnVmWzVdOwoJCQkJaW50CXdjOwoKCQkJCXMrKzsKCQkJCW1lbWNweSh4YnVmLHMsNCk7eGJ1Zls0XT0nXDAnOwoJCQkJaWYgKCFzc2NhbmYoeGJ1ZiwiJXgiLCZ3YykpCgkJCQkJV0FSTl8ocmVnKSgiU3RyYW5nZSBlc2NhcGUgc2VxdWVuY2UgJXMgZm91bmQgaW4gfCVzfFxuIix4YnVmLGJ1Zik7CgkJCQlzKz00OwoJCQkJKndzKysJPSh1bnNpZ25lZCBzaG9ydCl3YzsKCQkJfQoJCX0KCX0KCSp3cwk9IDA7Cgl3cwk9ICpzdHI7CglpZiAoKndzKQoJCSpzdHIJPSBzdHJkdXBXKCpzdHIpOwoJZWxzZQoJCSpzdHIJPSBOVUxMOwoJZnJlZSh3cyk7CglyZXR1cm4gczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHN1YmtleSBbSW50ZXJuYWxdCiAqCiAqIE5PVEVTCiAqICAgIEl0IHNlZW1zIGxpa2UgdGhpcyBpcyByZXR1cm5pbmcgYSBib29sZWFuLiAgU2hvdWxkIGl0PwogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IDEKICogICAgRmFpbHVyZTogMAogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3Via2V5KCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGxldmVsLCBjaGFyICoqYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqYnVmbGVuLCBEV09SRCBvcHRmbGFnICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlpOwoJY2hhcgkJKnM7CglMUFdTVFIJCW5hbWU7CgogICAgVFJBQ0VfKHJlZykoIiglcCwlcCwlZCwlcywlZCwlbHgpXG4iLCBGLCBscGtleSwgbGV2ZWwsIGRlYnVnc3RyX2EoKmJ1ZiksCiAgICAgICAgICAqYnVmbGVuLCBvcHRmbGFnKTsKCiAgICBscGtleS0+ZmxhZ3MgfD0gb3B0ZmxhZzsKCiAgICAvKiBHb29kLiAgV2UgYWxyZWFkeSBnb3QgYSBsaW5lIGhlcmUgLi4uIHNvIHBhcnNlIGl0ICovCiAgICBscHhrZXkgPSBOVUxMOwogICAgd2hpbGUgKDEpIHsKICAgICAgICBpPTA7cz0qYnVmOwogICAgICAgIHdoaWxlICgqcz09J1x0JykgewogICAgICAgICAgICBzKys7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9CiAgICAgICAgaWYgKGk+bGV2ZWwpIHsKICAgICAgICAgICAgaWYgKGxweGtleT09TlVMTCkgewogICAgICAgICAgICAgICAgV0FSTl8ocmVnKSgiR290IGEgc3ViaGllcmFyY2h5IHdpdGhvdXQgcmVzcC4ga2V5P1xuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBfd2luZV9sb2Fkc3Via2V5KEYsbHB4a2V5LGxldmVsKzEsYnVmLGJ1ZmxlbixvcHRmbGFnKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKCQkvKiBsZXQgdGhlIGNhbGxlciBoYW5kbGUgdGhpcyBsaW5lICovCgkJaWYgKGk8bGV2ZWwgfHwgKipidWY9PSdcMCcpCgkJCXJldHVybiAxOwoKCQkvKiBpdCBjYW4gYmU6IGEgdmFsdWUgb3IgYSBrZXluYW1lLiBQYXJzZSB0aGUgbmFtZSBmaXJzdCAqLwoJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsJm5hbWUpOwoKCQkvKiBzd2l0Y2goKSBkZWZhdWx0OiBoYWNrIHRvIGF2b2lkIGdvdG9zICovCgkJc3dpdGNoICgwKSB7CgkJZGVmYXVsdDoKCQkJaWYgKCpzPT0nXDAnKSB7CgkJCQlscHhrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxuYW1lKTsKCQkJfSBlbHNlIHsKCQkJCUxQQllURQkJZGF0YTsKCQkJCWludAkJbGVuLGxhc3Rtb2RpZmllZCx0eXBlOwoKCQkJCWlmICgqcyE9Jz0nKSB7CgkJCQkJV0FSTl8ocmVnKSgiVW5leHBlY3RlZCBjaGFyYWN0ZXI6ICVjXG4iLCpzKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCXMrKzsKCQkJCWlmICgyIT1zc2NhbmYocywiJWQsJWQsIiwmdHlwZSwmbGFzdG1vZGlmaWVkKSkgewoJCQkJCVdBUk5fKHJlZykoIkhhdmVuJ3QgdW5kZXJzdG9vZCBwb3NzaWJsZSB2YWx1ZSBpbiB8JXN8LCBza2lwcGluZy5cbiIsKmJ1Zik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQkvKiBza2lwIHRoZSAyICwgKi8KCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlzPXN0cmNocihzLCcsJyk7cysrOwoJCQkJaWYgKHR5cGUgPT0gUkVHX1NaIHx8IHR5cGUgPT0gUkVHX0VYUEFORF9TWikgewoJCQkJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsKExQV1NUUiopJmRhdGEpOwoJCQkJCWlmIChkYXRhKQoJCQkJCQlsZW4gPSBsc3RybGVuVygoTFBXU1RSKWRhdGEpKjIrMjsKCQkJCQllbHNlCQoJCQkJCQlsZW4gPSAwOwoJCQkJfSBlbHNlIHsKCQkJCQlsZW49c3RybGVuKHMpLzI7CgkJCQkJZGF0YSA9IChMUEJZVEUpeG1hbGxvYyhsZW4rMSk7CgkJCQkJZm9yIChpPTA7aTxsZW47aSsrKSB7CgkJCQkJCWRhdGFbaV09MDsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV09KCpzLScwJyk8PDQ7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nYScrJ1x4YScpPDw0OwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ0EnKydceGEnKTw8NDsKCQkJCQkJcysrOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXXw9KnMtJzAnOwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ2EnKydceGEnOwoJCQkJCQlpZiAoKnM+PSdBJyAmJiAqczw9J0YnKQoJCQkJCQkJZGF0YVtpXXw9KnMtJ0EnKydceGEnOwoJCQkJCQlzKys7CgkJCQkJfQoJCQkJfQoJCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKGxwa2V5LG5hbWUsdHlwZSxkYXRhLGxlbixsYXN0bW9kaWZpZWQpOwoJCQl9CgkJfQoJCS8qIHJlYWQgdGhlIG5leHQgbGluZSAqLwoJCWlmICghX3dpbmVfcmVhZF9saW5lKEYsYnVmLGJ1ZmxlbikpCgkJCXJldHVybiAxOwogICAgfQogICAgcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3VicmVnKCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgRFdPUkQgb3B0ZmxhZyApCnsKCWludAl2ZXI7CgljaGFyCSpidWY7CglpbnQJYnVmbGVuOwoKCWJ1Zj14bWFsbG9jKDEwKTtidWZsZW49MTA7CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXNzY2FuZihidWYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAodmVyIT1SRUdJU1RSWV9TQVZFX1ZFUlNJT04pIHsKCQlUUkFDRV8ocmVnKSgiT2xkIGZvcm1hdCAoJWQpIHJlZ2lzdHJ5IGZvdW5kLCBpZ25vcmluZyBpdC4gKGJ1ZiB3YXMgJXMpLlxuIix2ZXIsYnVmKTsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIV93aW5lX2xvYWRzdWJrZXkoRixscGtleSwwLCZidWYsJmJ1ZmxlbixvcHRmbGFnKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWZyZWUoYnVmKTsKCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93aW5lX2xvYWRyZWcoIExQS0VZU1RSVUNUIGxwa2V5LCBjaGFyICpmbiwgRFdPUkQgb3B0ZmxhZyApCnsKICAgIEZJTEUgKkY7CgogICAgVFJBQ0VfKHJlZykoIiglcCwlcywlbHgpXG4iLGxwa2V5LGRlYnVnc3RyX2EoZm4pLG9wdGZsYWcpOwoKICAgIEYgPSBmb3BlbihmbiwicmIiKTsKICAgIGlmIChGPT1OVUxMKSB7CiAgICAgICAgV0FSTl8ocmVnKSgiQ291bGRuJ3Qgb3BlbiAlcyBmb3IgcmVhZGluZzogJXNcbiIsZm4sc3RyZXJyb3IoZXJybm8pICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKCFfd2luZV9sb2Fkc3VicmVnKEYsbHBrZXksb3B0ZmxhZykpIHsKICAgICAgICBmY2xvc2UoRik7CiAgICAgICAgdW5saW5rKGZuKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmY2xvc2UoRik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2ZsdXNoX3JlZ2lzdHJ5IFtJbnRlcm5hbF0KICogCiAqIFRoaXMgZnVuY3Rpb24gYWxsb3cgdG8gZmx1c2ggc2VjdGlvbiBvZiB0aGUgaW50ZXJuYWwgcmVnaXN0cnkuICBJdCBpcyBtYWlubHkKICogaW1wbGVtZW50cyB0byBmaXggYSBwcm9ibGVtIHdpdGggdGhlIGdsb2JhbCBIS1UgYW5kIHRoZSBsb2NhbCBIS1UuCiAqIFRob3NlIHR3byBmaWxlcyBhcmUgcmVhZCB0byBidWlsZCB0aGUgSEtVXC5EZWZhdWx0IGJyYW5jaCB0byBmaW5hbHkgY29weQogKiB0aGlzIGJyYW5jaCBvbnRvIEhLQ1UgaGl2ZSwgb25jZSB0aGlzIGlzIGRvbmUsIGlmIHdlIGtlZXAgdGhlIEhLVSBoaXZlIGFzIGlzLCAKICogYWxsIHRoZSBnbG9iYWwgSEtVIGFyZSBzYXZlZCBvbnRvIHRoZSB1c2VyJ3MgcGVyc29uYWwgdmVyc2lvbiBvZiBIS1UgaGl2ZS4KICogd2hpY2ggaXMgYmFkLi4uCiAqLwoKIC8qIEZvcndhcmQgZGVjbGFyYXRpb24gb2YgcmVjdXNpdmUgYWdlbnQgKi8Kc3RhdGljIHZvaWQgX2ZsdXNoX3JlZyhMUEtFWVNUUlVDVCBmcm9tKTsKCnN0YXRpYyB2b2lkIF9mbHVzaF9yZWdpc3RyeSggTFBLRVlTVFJVQ1QgZnJvbSApCnsKICAvKiBtYWtlIHN1cmUgd2UgaGF2ZSBzb21ldGhpbmcuLi4gKi8KICBpZiAoZnJvbSA9PSBOVUxMKQogICAgcmV0dXJuOwoKICAvKiBMYXVuY2ggdGhlIHJlY3VzaXZlIGFnZW50IG9uIHN1YiBicmFuY2hlcyAqLwogIF9mbHVzaF9yZWcoIGZyb20tPm5leHRzdWIgKTsKICBfZmx1c2hfcmVnKCBmcm9tLT5uZXh0ICk7CgogIC8qIEluaXRpYWxpemUgcG9pbnRlcnMgKi8KICBmcm9tLT5uZXh0c3ViID0gTlVMTDsKICBmcm9tLT5uZXh0ICAgID0gTlVMTDsKfQpzdGF0aWMgdm9pZCBfZmx1c2hfcmVnKCBMUEtFWVNUUlVDVCBmcm9tICkKewoJaW50CWo7CgogIC8qIG1ha2Ugc3VyZSB3ZSBoYXZlIHNvbWV0aGluZy4uLiAqLwogIGlmIChmcm9tID09IE5VTEwpCiAgICByZXR1cm47CgogIC8qIAogICAqIGRvIHRoZSBzYW1lIGZvciB0aGUgY2hpbGQga2V5cyAKICAgKi8KICBpZiAoZnJvbS0+bmV4dHN1YiAhPSBOVUxMKQogICAgX2ZsdXNoX3JlZyhmcm9tLT5uZXh0c3ViKTsKCiAgLyogCiAgICogZG8gdGhlIHNhbWUgZm9yIHRoZSBzaWJsaW5nIGtleXMgCiAgICovCiAgaWYgKGZyb20tPm5leHQgIT0gTlVMTCkKICAgIF9mbHVzaF9yZWcoZnJvbS0+bmV4dCk7CgogIC8qCiAgICogaXRlcmF0ZSB0aHJvdWdoIHRoaXMga2V5J3MgdmFsdWVzIGFuZCBkZWxldGUgdGhlbQogICAqLwogIGZvciAoaj0wO2o8ZnJvbS0+bnJvZnZhbHVlcztqKyspIAogIHsKICAgIGZyZWUoIChmcm9tLT52YWx1ZXMraiktPm5hbWUpOwogICAgZnJlZSggKGZyb20tPnZhbHVlcytqKS0+ZGF0YSk7CiAgfQoKICAvKgogICAqIGZyZWUgdGhlIHN0cnVjdHVyZQogICAqLwogIGlmICggZnJvbSAhPSBOVUxMICkKICAgIGZyZWUoZnJvbSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9jb3B5X3JlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9jb3B5X3JlZ2lzdHJ5KCBMUEtFWVNUUlVDVCBmcm9tLCBMUEtFWVNUUlVDVCB0byApCnsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJajsKCUxQS0VZVkFMVUUJdmFsZnJvbTsKCglmcm9tPWZyb20tPm5leHRzdWI7Cgl3aGlsZSAoZnJvbSkgewoJCWxweGtleSA9IF9maW5kX29yX2FkZF9rZXkodG8sc3RyZHVwVyhmcm9tLT5rZXluYW1lKSk7CgoJCWZvciAoaj0wO2o8ZnJvbS0+bnJvZnZhbHVlcztqKyspIHsKCQkJTFBXU1RSCW5hbWU7CgkJCUxQQllURQlkYXRhOwoKCQkJdmFsZnJvbSA9IGZyb20tPnZhbHVlcytqOwoJCQluYW1lPXZhbGZyb20tPm5hbWU7CgkJCWlmIChuYW1lKSBuYW1lPXN0cmR1cFcobmFtZSk7CgkJCWRhdGE9KExQQllURSl4bWFsbG9jKHZhbGZyb20tPmxlbik7CgkJCW1lbWNweShkYXRhLHZhbGZyb20tPmRhdGEsdmFsZnJvbS0+bGVuKTsKCgkJCV9maW5kX29yX2FkZF92YWx1ZSgKCQkJCWxweGtleSwKCQkJCW5hbWUsCgkJCQl2YWxmcm9tLT50eXBlLAoJCQkJZGF0YSwKCQkJCXZhbGZyb20tPmxlbiwKCQkJCXZhbGZyb20tPmxhc3Rtb2RpZmllZAoJCQkpOwoJCX0KCQlfY29weV9yZWdpc3RyeShmcm9tLGxweGtleSk7CgkJZnJvbSA9IGZyb20tPm5leHQ7Cgl9Cn0KCgovKiBXSU5ET1dTIDk1IFJFR0lTVFJZIExPQURFUiAqLwovKiAKICogU3RydWN0dXJlIG9mIGEgd2luOTUgcmVnaXN0cnkgZGF0YWJhc2UuCiAqIG1haW4gaGVhZGVyOgogKiAwIDoJIkNSRUciCS0gbWFnaWMKICogNCA6CURXT1JEIHZlcnNpb24KICogOCA6CURXT1JEIG9mZnNldF9vZl9SR0RCX3BhcnQKICogMEMuLjBGOgk/IChzb21lb25lIGZpbGwgaW4gcGxlYXNlKQogKiAxMDogIFdPUkQJbnVtYmVyIG9mIFJHREIgYmxvY2tzCiAqIDEyOiAgV09SRAk/CiAqIDE0OiAgV09SRAlhbHdheXMgMDAwMD8KICogMTY6ICBXT1JECWFsd2F5cyAwMDAxPwogKiAxOC4uMUY6CT8gKHNvbWVvbmUgZmlsbCBpbiBwbGVhc2UpCiAqCiAqIDIwOiBSR0tOX3NlY3Rpb246CiAqICAgaGVhZGVyOgogKiAJMCA6CQkiUkdLTiIJLSBtYWdpYwogKiAgICAgIDQgOiBEV09SRAlvZmZzZXQgdG8gZmlyc3QgUkdEQiBzZWN0aW9uCiAqICAgICAgOCA6IERXT1JECW9mZnNldCB0byB0aGUgcm9vdCByZWNvcmQKICogCUMuLjB4MUI6IAk/IChmaWxsIGluKQogKiAgICAgIDB4MjAgLi4uIG9mZnNldF9vZl9SR0RCX3BhcnQ6IERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZXMKICoKICogICBEaXNrIEtleSBFbnRyeSBTdHJ1Y3R1cmU6CiAqCTAwOiBEV09SRAktIEZyZWUgZW50cnkgaW5kaWNhdG9yKD8pCiAqCTA0OiBEV09SRAktIEhhc2ggPSBzdW0gb2YgYnl0ZXMgb2Yga2V5bmFtZQogKgkwODogRFdPUkQJLSBSb290IGtleSBpbmRpY2F0b3I/IHVua25vd24sIGJ1dCB1c3VhbGx5IDB4RkZGRkZGRkYgb24gd2luOTUgc3lzdGVtcwogKgkwQzogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgUHJldmlvdXNMZXZlbCBLZXkuCiAqCTEwOiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBOZXh0IFN1YmxldmVsIEtleS4KICoJMTQ6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIE5leHQgS2V5IChvbiBzYW1lIGxldmVsKS4KICogREtFUD4xODogV09SRAktIE5yLCBMb3cgU2lnbmlmaWNhbnQgcGFydC4KICoJMUE6IFdPUkQJLSBOciwgSGlnaCBTaWduaWZpY2FudCBwYXJ0LgogKgogKiBUaGUgZGlzayBhZGRyZXNzIGFsd2F5cyBwb2ludHMgdG8gdGhlIG5yIHBhcnQgb2YgdGhlIHByZXZpb3VzIGtleSBlbnRyeSAKICogb2YgdGhlIHJlZmVyZW5jZWQga2V5LiBEb24ndCBhc2sgbWUgd2h5LCBvciBldmVuIGlmIEkgZ290IHRoaXMgY29ycmVjdAogKiBmcm9tIHN0YXJpbmcgYXQgMWtnIG9mIGhleGR1bXBzLiAoREtFUCkKICoKICogVGhlIEhpZ2ggc2lnbmlmaWNhbnQgcGFydCBvZiB0aGUgc3RydWN0dXJlIHNlZW1zIHRvIGVxdWFsIHRoZSBudW1iZXIKICogb2YgdGhlIFJHREIgc2VjdGlvbi4gVGhlIGxvdyBzaWduaWZpY2FudCBwYXJ0IGlzIGEgdW5pcXVlIElEIHdpdGhpbgogKiB0aGF0IFJHREIgc2VjdGlvbgogKgogKiBUaGVyZSBhcmUgdHdvIG1pbm9yIGNvcnJlY3Rpb25zIHRvIHRoZSBwb3NpdGlvbiBvZiB0aGF0IHN0cnVjdHVyZS4KICogMS4gSWYgdGhlIGFkZHJlc3MgaXMgeHh4MDE0IG9yIHh4eDAxOCBpdCB3aWxsIGJlIGFsaWduZWQgdG8geHh4MDFjIEFORCAKICogICAgdGhlIERLRSByZXJlYWQgZnJvbSB0aGVyZS4KICogMi4gSWYgdGhlIGFkZHJlc3MgaXMgeHh4RkZ4IGl0IHdpbGwgYmUgYWxpZ25lZCB0byAoeHh4KzEpMDAwLgogKiBDUFMgLSBJIGhhdmUgbm90IGV4cGVyaWVuY2VkIHRoZSBhYm92ZSBwaGVub21lbm9uIGluIG15IHJlZ2lzdHJ5IGZpbGVzCiAqCiAqIFJHREJfc2VjdGlvbjoKICogCTAwOgkJIlJHREIiCS0gbWFnaWMKICoJMDQ6IERXT1JECW9mZnNldCB0byBuZXh0IFJHREIgc2VjdGlvbgogKgkwODogRFdPUkQJPwogKgkwQzogV09SRAlhbHdheXMgMDAwZD8KICoJMEU6IFdPUkQJUkdEQiBibG9jayBudW1iZXIKICoJMTA6CURXT1JECT8gKGVxdWFscyB2YWx1ZSBhdCBvZmZzZXQgNCAtIHZhbHVlIGF0IG9mZnNldCA4KQogKgkxNC4uMUY6CQk/CiAqCTIwLi4uLi46CWRpc2sga2V5cwogKgogKiBkaXNrIGtleToKICogCTAwOiAJRFdPUkQJbmV4dGtleW9mZnNldAktIG9mZnNldCB0byB0aGUgbmV4dCBkaXNrIGtleSBzdHJ1Y3R1cmUKICoJMDg6IAlXT1JECW5yTFMJCS0gbG93IHNpZ25pZmljYW50IHBhcnQgb2YgTlIKICoJMEE6IAlXT1JECW5ySFMJCS0gaGlnaCBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBDOiAJRFdPUkQJYnl0ZXN1c2VkCS0gYnl0ZXMgdXNlZCBpbiB0aGlzIHN0cnVjdHVyZS4KICoJMTA6IAlXT1JECW5hbWVfbGVuCS0gbGVuZ3RoIG9mIG5hbWUgaW4gYnl0ZXMuIHdpdGhvdXQgXDAKICoJMTI6IAlXT1JECW5yX29mX3ZhbHVlcwktIG51bWJlciBvZiB2YWx1ZXMuCiAqCTE0OiAJY2hhcgluYW1lW25hbWVfbGVuXQktIG5hbWUgc3RyaW5nLiBObyBcMC4KICoJMTQrbmFtZV9sZW46IGRpc2sgdmFsdWVzCiAqCW5leHRrZXlvZmZzZXQ6IC4uLiBuZXh0IGRpc2sga2V5CiAqCiAqIGRpc2sgdmFsdWU6CiAqCTAwOglEV09SRAl0eXBlCQktIHZhbHVlIHR5cGUgKGhtbSwgY291bGQgYmUgV09SRCB0b28pCiAqCTA0OglEV09SRAkJCS0gdW5rbm93biwgdXN1YWxseSAwCiAqCTA4OglXT1JECW5hbWVsZW4JCS0gbGVuZ3RoIG9mIE5hbWUuIDAgbWVhbnMgbmFtZT1OVUxMCiAqCTBDOglXT1JECWRhdGFsZW4JCS0gbGVuZ3RoIG9mIERhdGEuCiAqCTEwOgljaGFyCW5hbWVbbmFtZWxlbl0JLSBuYW1lLCBubyBcMAogKgkxMCtuYW1lbGVuOiBCWVRFCWRhdGFbZGF0YWxlbl0gLSBkYXRhLCB3aXRob3V0IFwwIGlmIHN0cmluZwogKgkxMCtuYW1lbGVuK2RhdGFsZW46IG5leHQgdmFsdWVzIG9yIGRpc2sga2V5CiAqCiAqIERpc2sga2V5cyBhcmUgbGF5ZWQgb3V0IGZsYXQgLi4uIEJ1dCwgc29tZXRpbWVzLCBuckxTIGFuZCBuckhTIGFyZSBib3RoCiAqIDB4RkZGRiwgd2hpY2ggbWVhbnMgc2tpcHBpbmcgb3ZlciBuZXh0a2V5b2Zmc2V0IGJ5dGVzIChpbmNsdWRpbmcgdGhpcwogKiBzdHJ1Y3R1cmUpIGFuZCByZWFkaW5nIGFub3RoZXIgUkdEQl9zZWN0aW9uLgogKiByZXBlYXQgdW50aWwgZW5kIG9mIGZpbGUuCiAqCiAqIEFuIGludGVyZXN0aW5nIHJlbGF0aW9uc2hpcCBleGlzdHMgaW4gUkdEQl9zZWN0aW9uLiBUaGUgdmFsdWUgYXQgb2Zmc2V0CiAqIDEwIGVxdWFscyB0aGUgdmFsdWUgYXQgb2Zmc2V0IDQgbWludXMgdGhlIHZhbHVlIGF0IG9mZnNldCA4LiBJIGhhdmUgbm8KICogaWRlYSBhdCB0aGUgbW9tZW50IHdoYXQgdGhpcyBtZWFucy4gIChLZXZpbiBDb3plbnMpCiAqCiAqIEZJWE1FOiB0aGlzIGRlc2NyaXB0aW9uIG5lZWRzIHNvbWUgc2VyaW91cyBoZWxwLCB5ZXMuCiAqLwoKc3RydWN0CV93OTVrZXl2YWx1ZSB7Cgl1bnNpZ25lZCBsb25nCQl0eXBlOwoJdW5zaWduZWQgc2hvcnQJCWRhdGFsZW47CgljaGFyCQkJKm5hbWU7Cgl1bnNpZ25lZCBjaGFyCQkqZGF0YTsKCXVuc2lnbmVkIGxvbmcJCXgxOwoJaW50CQkJbGFzdG1vZGlmaWVkOwp9OwoKc3RydWN0IAlfdzk1a2V5IHsKCWNoYXIJCQkqbmFtZTsKCWludAkJCW5yb2Z2YWxzOwoJc3RydWN0CV93OTVrZXl2YWx1ZQkqdmFsdWVzOwoJc3RydWN0IF93OTVrZXkJCSpwcmV2bHZsOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0c3ViOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0Owp9OwoKCnN0cnVjdCBfdzk1X2luZm8gewogIGNoYXIgKnJna25idWZmZXI7CiAgaW50ICByZ2tuc2l6ZTsKICBjaGFyICpyZ2RiYnVmZmVyOwogIGludCAgcmdkYnNpemU7CiAgaW50ICBkZXB0aDsKICBpbnQgIGxhc3Rtb2RpZmllZDsKfTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfcHJvY2Vzc0tleSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgX3c5NV9wcm9jZXNzS2V5ICggTFBLRVlTVFJVQ1QgbHBrZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuckxTLCBpbnQgbnJNUywgc3RydWN0IF93OTVfaW5mbyAqaW5mbyApCgp7CiAgLyogRGlzayBLZXkgSGVhZGVyIHN0cnVjdHVyZSAoUkdEQiBwYXJ0KSAqLwoJc3RydWN0CWRraCB7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nCQluZXh0a2V5b2ZmOyAKCQl1bnNpZ25lZCBzaG9ydAkJbnJMUzsKCQl1bnNpZ25lZCBzaG9ydAkJbnJNUzsKCQl1bnNpZ25lZCBsb25nCQlieXRlc3VzZWQ7CgkJdW5zaWduZWQgc2hvcnQJCWtleW5hbWVsZW47CgkJdW5zaWduZWQgc2hvcnQJCXZhbHVlczsKCQl1bnNpZ25lZCBsb25nCQl4eDE7CgkJLyoga2V5bmFtZSAqLwoJCS8qIGRpc2sga2V5IHZhbHVlcyBvciBub3RoaW5nICovCgl9OwoJLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlICovCglzdHJ1Y3QJZGt2IHsKCQl1bnNpZ25lZCBsb25nCQl0eXBlOwoJCXVuc2lnbmVkIGxvbmcJCXgxOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxuYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxkYXRhbGVuOwoJCS8qIHZhbG5hbWUsIHZhbGRhdGEgKi8KCX07CgoJCglzdHJ1Y3QJZGtoIGRraDsKCWludAlieXRlc3JlYWQgPSAwOwoJY2hhciAgICAqcmdkYmRhdGEgPSBpbmZvLT5yZ2RiYnVmZmVyOwoJaW50ICAgICBuYnl0ZXMgPSBpbmZvLT5yZ2Ric2l6ZTsKCWNoYXIgICAgKmN1cmRhdGEgPSByZ2RiZGF0YTsKCWNoYXIgICAgKmVuZCA9IHJnZGJkYXRhICsgbmJ5dGVzOwoJaW50ICAgICBvZmZfbmV4dF9yZ2RiOwoJY2hhciAgICAqbmV4dCA9IHJnZGJkYXRhOwoJaW50ICAgICBucmdkYiwgaTsKCUxQS0VZU1RSVUNUCWxweGtleTsKCQoJZG8gewoJICBjdXJkYXRhID0gbmV4dDsKCSAgaWYgKHN0cm5jbXAoY3VyZGF0YSwgIlJHREIiLCA0KSkgcmV0dXJuIChOVUxMKTsKCSAgICAKCSAgbWVtY3B5KCZvZmZfbmV4dF9yZ2RiLGN1cmRhdGErNCw0KTsKCSAgbmV4dCA9IGN1cmRhdGEgKyBvZmZfbmV4dF9yZ2RiOwoJICBucmdkYiA9IChpbnQpICooKHNob3J0ICopY3VyZGF0YSArIDcpOwoKCX0gd2hpbGUgKG5yZ2RiICE9IG5yTVMgJiYgKG5leHQgPCBlbmQpKTsKCgkvKiBjdXJkYXRhIG5vdyBwb2ludHMgdG8gdGhlIHN0YXJ0IG9mIHRoZSByaWdodCBSR0RCIHNlY3Rpb24gKi8KCWN1cmRhdGEgKz0gMHgyMDsKCiNkZWZpbmUgWFJFQUQod2hlcmV0byxsZW4pIFwKCWlmICgoY3VyZGF0YSArIGxlbikgPD0gZW5kKSB7XAoJCW1lbWNweSh3aGVyZXRvLGN1cmRhdGEsbGVuKTtcCgkJY3VyZGF0YSs9bGVuO1wKCQlieXRlc3JlYWQrPWxlbjtcCgl9CgoJd2hpbGUgKGN1cmRhdGEgPCBuZXh0KSB7CgkgIHN0cnVjdAlka2ggKnhka2ggPSAoc3RydWN0IGRraCopY3VyZGF0YTsKCgkgIGJ5dGVzcmVhZCArPSBzaXplb2YoZGtoKTsgLyogRklYTUUuLi4gbmV4dGtleW9mZj8gKi8KCSAgaWYgKHhka2gtPm5yTFMgPT0gbnJMUykgewoJICAJbWVtY3B5KCZka2gseGRraCxzaXplb2YoZGtoKSk7CgkgIAljdXJkYXRhICs9IHNpemVvZihka2gpOwoJICAJYnJlYWs7CgkgIH0KCSAgY3VyZGF0YSArPSB4ZGtoLT5uZXh0a2V5b2ZmOwoJfTsKCglpZiAoZGtoLm5yTFMgIT0gbnJMUykgcmV0dXJuIChOVUxMKTsKCglpZiAobnJnZGIgIT0gZGtoLm5yTVMpCgkgIHJldHVybiAoTlVMTCk7CgogICAgICAgIGFzc2VydCgoZGtoLmtleW5hbWVsZW48MikgfHwgY3VyZGF0YVswXSk7CglscHhrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxzdHJjdnRBMlcoY3VyZGF0YSwgZGtoLmtleW5hbWVsZW4pKTsKCWN1cmRhdGEgKz0gZGtoLmtleW5hbWVsZW47CgoJZm9yIChpPTA7aTwgZGtoLnZhbHVlczsgaSsrKSB7CgkgIHN0cnVjdCBka3YgZGt2OwoJICBMUEJZVEUgZGF0YTsKCSAgaW50IGxlbjsKCSAgTFBXU1RSIG5hbWU7CgoJICBYUkVBRCgmZGt2LHNpemVvZihka3YpKTsKCgkgIG5hbWUgPSBzdHJjdnRBMlcoY3VyZGF0YSwgZGt2LnZhbG5hbWVsZW4pOwoJICBjdXJkYXRhICs9IGRrdi52YWxuYW1lbGVuOwoKCSAgaWYgKCgxIDw8IGRrdi50eXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkgICAgZGF0YSA9IChMUEJZVEUpIHN0cmN2dEEyVyhjdXJkYXRhLCBka3YudmFsZGF0YWxlbik7CgkgICAgbGVuID0gMiooZGt2LnZhbGRhdGFsZW4gKyAxKTsKCSAgfSBlbHNlIHsKCSAgICAvKiBJIGRvbid0IHRoaW5rIHdlIHdhbnQgdG8gTlVMTCB0ZXJtaW5hdGUgYWxsIGRhdGEgKi8KCSAgICBkYXRhID0geG1hbGxvYyhka3YudmFsZGF0YWxlbik7CgkgICAgbWVtY3B5IChkYXRhLCBjdXJkYXRhLCBka3YudmFsZGF0YWxlbik7CgkgICAgbGVuID0gZGt2LnZhbGRhdGFsZW47CgkgIH0KCgkgIGN1cmRhdGEgKz0gZGt2LnZhbGRhdGFsZW47CgkgIAoJICBfZmluZF9vcl9hZGRfdmFsdWUoCgkJCSAgICAgbHB4a2V5LAoJCQkgICAgIG5hbWUsCgkJCSAgICAgZGt2LnR5cGUsCgkJCSAgICAgZGF0YSwKCQkJICAgICBsZW4sCgkJCSAgICAgaW5mby0+bGFzdG1vZGlmaWVkCgkJCSAgICAgKTsKCX0KCXJldHVybiAobHB4a2V5KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X3dhbGtyZ2tuIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93OTVfd2Fsa3Jna24oIExQS0VZU1RSVUNUIHByZXZrZXksIGNoYXIgKm9mZiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBfdzk1X2luZm8gKmluZm8gKQoKewogIC8qIERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZSAoUkdLTiBwYXJ0KSAqLwogIHN0cnVjdAlka2UgewogICAgdW5zaWduZWQgbG9uZwkJeDE7CiAgICB1bnNpZ25lZCBsb25nCQl4MjsKICAgIHVuc2lnbmVkIGxvbmcJCXgzOy8qdXN1YWxseSAweEZGRkZGRkZGICovCiAgICB1bnNpZ25lZCBsb25nCQlwcmV2bHZsOwogICAgdW5zaWduZWQgbG9uZwkJbmV4dHN1YjsKICAgIHVuc2lnbmVkIGxvbmcJCW5leHQ7CiAgICB1bnNpZ25lZCBzaG9ydAkJbnJMUzsKICAgIHVuc2lnbmVkIHNob3J0CQluck1TOwogIH0gKmRrZSA9IChzdHJ1Y3QgZGtlICopb2ZmOwogIExQS0VZU1RSVUNUICBscHhrZXk7CgogIGlmIChka2UgPT0gTlVMTCkgewogICAgZGtlID0gKHN0cnVjdCBka2UgKikgKChjaGFyICopaW5mby0+cmdrbmJ1ZmZlcik7CiAgfQoKICBscHhrZXkgPSBfdzk1X3Byb2Nlc3NLZXkocHJldmtleSwgZGtlLT5uckxTLCBka2UtPm5yTVMsIGluZm8pOwogIC8qIFhYWCA8LS0gVGhpcyBpcyBhIGhhY2sqLwogIGlmICghbHB4a2V5KSB7CiAgICBscHhrZXkgPSBwcmV2a2V5OwogIH0KCiAgaWYgKGRrZS0+bmV4dHN1YiAhPSAtMSAmJiAKICAgICAgKChka2UtPm5leHRzdWIgLSAweDIwKSA8IGluZm8tPnJna25zaXplKSAKICAgICAgJiYgKGRrZS0+bmV4dHN1YiA+IDB4MjApKSB7CiAgICAKICAgIF93OTVfd2Fsa3Jna24obHB4a2V5LCAKCQkgIGluZm8tPnJna25idWZmZXIgKyBka2UtPm5leHRzdWIgLSAweDIwLCAKCQkgIGluZm8pOwogIH0KICAKICBpZiAoZGtlLT5uZXh0ICE9IC0xICYmIAogICAgICAoKGRrZS0+bmV4dCAtIDB4MjApIDwgaW5mby0+cmdrbnNpemUpICYmIAogICAgICAoZGtlLT5uZXh0ID4gMHgyMCkpIHsKICAgIF93OTVfd2Fsa3Jna24ocHJldmtleSwgIAoJCSAgaW5mby0+cmdrbmJ1ZmZlciArIGRrZS0+bmV4dCAtIDB4MjAsCgkJICBpbmZvKTsKICB9CgogIHJldHVybjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93OTVfbG9hZHJlZyggY2hhciogZm4sIExQS0VZU1RSVUNUIGxwa2V5ICkKewoJSEZJTEUJCWhmZDsKCWNoYXIJCW1hZ2ljWzVdOwoJdW5zaWduZWQgbG9uZwl3aGVyZSx2ZXJzaW9uLHJnZGJzZWN0aW9uLGVuZDsKCXN0cnVjdCAgICAgICAgICBfdzk1X2luZm8gaW5mbzsKCU9GU1RSVUNUCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmZGluZm87CgoJVFJBQ0VfKHJlZykoIkxvYWRpbmcgV2luOTUgcmVnaXN0cnkgZGF0YWJhc2UgJyVzJ1xuIixmbik7CgloZmQ9T3BlbkZpbGUoZm4sJm9mcyxPRl9SRUFEKTsKCWlmIChoZmQ9PUhGSUxFX0VSUk9SKQoJCXJldHVybjsKCW1hZ2ljWzRdPTA7CglpZiAoNCE9X2xyZWFkKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJDUkVHIikpIHsKCQlXQVJOXyhyZWcpKCIlcyBpcyBub3QgYSB3OTUgcmVnaXN0cnkuXG4iLGZuKTsKCQlyZXR1cm47Cgl9CglpZiAoNCE9X2xyZWFkKGhmZCwmdmVyc2lvbiw0KSkKCQlyZXR1cm47CglpZiAoNCE9X2xyZWFkKGhmZCwmcmdkYnNlY3Rpb24sNCkpCgkJcmV0dXJuOwoJaWYgKC0xPT1fbGxzZWVrKGhmZCwweDIwLFNFRUtfU0VUKSkKCQlyZXR1cm47CglpZiAoNCE9X2xyZWFkKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJSR0tOIikpIHsKCQlXQVJOXyhyZWcpKCJzZWNvbmQgSUZGIGhlYWRlciBub3QgUkdLTiwgYnV0ICVzXG4iLCBtYWdpYyk7CgkJcmV0dXJuOwoJfQoKCS8qIFNURVAgMTogS2V5bGluayBzdHJ1Y3R1cmVzICovCglpZiAoLTE9PV9sbHNlZWsoaGZkLDB4NDAsU0VFS19TRVQpKQoJCXJldHVybjsKCXdoZXJlCT0gMHg0MDsKCWVuZAk9IHJnZGJzZWN0aW9uOwoKCWluZm8ucmdrbnNpemUgPSBlbmQgLSB3aGVyZTsKCWluZm8ucmdrbmJ1ZmZlciA9IChjaGFyKil4bWFsbG9jKGluZm8ucmdrbnNpemUpOwoJaWYgKGluZm8ucmdrbnNpemUgIT0gX2xyZWFkKGhmZCxpbmZvLnJna25idWZmZXIsaW5mby5yZ2tuc2l6ZSkpCgkJcmV0dXJuOwoKCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGZkLCZoZmRpbmZvKSkKCQlyZXR1cm47CgoJZW5kID0gaGZkaW5mby5uRmlsZVNpemVMb3c7CglpbmZvLmxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZkaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CgoJaWYgKC0xPT1fbGxzZWVrKGhmZCxyZ2Ric2VjdGlvbixTRUVLX1NFVCkpCgkJcmV0dXJuOwoKCWluZm8ucmdkYmJ1ZmZlciA9IChjaGFyKil4bWFsbG9jKGVuZC1yZ2Ric2VjdGlvbik7CglpbmZvLnJnZGJzaXplID0gZW5kIC0gcmdkYnNlY3Rpb247CgoJaWYgKGluZm8ucmdkYnNpemUgIT1fbHJlYWQoaGZkLGluZm8ucmdkYmJ1ZmZlcixpbmZvLnJnZGJzaXplKSkKCQlyZXR1cm47CglfbGNsb3NlKGhmZCk7CgoJX3c5NV93YWxrcmdrbihscGtleSwgTlVMTCwgJmluZm8pOwoKCWZyZWUgKGluZm8ucmdkYmJ1ZmZlcik7CglmcmVlIChpbmZvLnJna25idWZmZXIpOwp9CgoKLyogV0lORE9XUyAzMSBSRUdJU1RSWSBMT0FERVIsIHN1cHBsaWVkIGJ5IFRvciBTavh3YWxsLCB0b3JAc24ubm8gKi8KCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VlZGVkIGJ5IGEgd29yZCBhdCBvZmZzZXQtMi4gVGhpcyB3b3JkCiAgICBoYXMgdGhlIHZhbHVlICgyKmluZGV4KSsxLCB3aGVyZSBpbmRleCBpcyB0aGUgcmVmZXJyaW5nIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGluIHRoZSB0YWJsZS4gSSBoYXZlIG5vIHN1Z2dlc3Rpb24gZm9yIHRoZSAyKiBhbmQgdGhlICsxLgogICAgRm9sbG93aW5nIHRoZSB3b3JkLCB0aGVyZSBhcmUgTiBieXRlcyBvZiBkYXRhLCBhcyBwZXIgdGhlIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGxlbmd0aC4gVGhlIG9mZnNldCBvZiB0aGUga2V5ZW50L3ZhbGVudCBlbnRyeSBpcyBmcm9tIHRoZSBzdGFydAogICAgb2YgdGhlIHRleHQgdGFibGUgdG8gdGhlIGZpcnN0IGRhdGEgYnl0ZS4KCiAgICBUaGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbSBNaWNyb3NvZnQuIFRoZSBkYXRhIGZvcm1hdCBpcwogICAgZGVkdWNlZCBmcm9tIHRoZSByZWcuZGF0IGZpbGUgYnkgbWUuIE1pc3Rha2VzIG1heQogICAgaGF2ZSBiZWVuIG1hZGUuIEkgY2xhaW0gbm8gcmlnaHRzIGFuZCBnaXZlIG5vIGd1YXJhbnRlZXMgZm9yIHRoaXMgcHJvZ3JhbS4KCiAgICBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vCiovCgovKiByZWcuZGF0IGhlYWRlciBmb3JtYXQgKi8Kc3RydWN0IF93MzFfaGVhZGVyIHsKCWNoYXIJCWNvb2tpZVs4XTsJLyogJ1NIQ0MzLjEwJyAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYxOwkvKiBvZmZzZXQgb2YgaGFzaCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYyOwkvKiBvZmZzZXQgb2YgaW5kZXggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFiY250OwkJLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gaW5kZXggdGFibGUgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dG9mZjsJLyogb2Zmc2V0IG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0c2l6ZTsJLyogYnl0ZSBzaXplIG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgc2hvcnQJaGFzaHNpemU7CS8qIGhhc2ggc2l6ZSAqLwoJdW5zaWduZWQgc2hvcnQJZnJlZWlkeDsJLyogZnJlZSBpbmRleCAqLwp9OwoKLyogZ2VuZXJpYyBmb3JtYXQgb2YgdGFibGUgZW50cmllcyAqLwpzdHJ1Y3QgX3czMV90YWJlbnQgewoJdW5zaWduZWQgc2hvcnQgdzAsIHcxLCB3MiwgdzM7Cn07CgovKiBkaXJlY3RvcnkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9kaXJlbnQgewoJdW5zaWduZWQgc2hvcnQJc2libGluZ19pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHNpYmxpbmcgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAljaGlsZF9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGNoaWxkIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJa2V5X2lkeDsJLyogdGFibGUgaW5kZXggb2Yga2V5IGtleWVudCAqLwoJdW5zaWduZWQgc2hvcnQJdmFsdWVfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiB2YWx1ZSB2YWxlbnQgKi8KfTsKCi8qIGtleSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2tleWVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogdmFsdWUgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV92YWxlbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdG8gZGlzcGxheSBhIGRpcmVjdG9yeSB0cmVlICovCnZvaWQKX193MzFfZHVtcHRyZWUoCXVuc2lnbmVkIHNob3J0IGlkeCwKCQl1bnNpZ25lZCBjaGFyICp0eHQsCgkJc3RydWN0IF93MzFfdGFiZW50ICp0YWIsCgkJc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAoJCUxQS0VZU1RSVUNUCWxwa2V5LAoJCXRpbWVfdAkJbGFzdG1vZGlmaWVkLAoJCWludAkJbGV2ZWwKKSB7CglzdHJ1Y3QgX3czMV9kaXJlbnQJKmRpcjsKCXN0cnVjdCBfdzMxX2tleWVudAkqa2V5OwoJc3RydWN0IF93MzFfdmFsZW50CSp2YWw7CglMUEtFWVNUUlVDVAkJeGxwa2V5ID0gTlVMTDsKCUxQV1NUUgkJCW5hbWUsdmFsdWU7CglzdGF0aWMgY2hhcgkJdGFpbFs0MDBdOwoKCXdoaWxlIChpZHghPTApIHsKCQlkaXI9KHN0cnVjdCBfdzMxX2RpcmVudCopJnRhYltpZHhdOwoKCQlpZiAoZGlyLT5rZXlfaWR4KSB7CgkJCWtleSA9IChzdHJ1Y3QgX3czMV9rZXllbnQqKSZ0YWJbZGlyLT5rZXlfaWR4XTsKCgkJCW1lbWNweSh0YWlsLCZ0eHRba2V5LT5zdHJpbmdfb2ZmXSxrZXktPmxlbmd0aCk7CgkJCXRhaWxba2V5LT5sZW5ndGhdPSdcMCc7CgkJCS8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUgCgkJCSAqIHRvcGxldmVsIHN1YmRpcmVjdG9yeSBiZWxvbmcgdG8gXFNPRlRXQVJFXENsYXNzZXMKCQkJICovCgkJCWlmICghbGV2ZWwgJiYgIWxzdHJjbXBBKHRhaWwsIi5jbGFzc2VzIikpIHsKCQkJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxscGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJCQlpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCW5hbWU9c3RyZHVwQTJXKHRhaWwpOwoKCQkJeGxwa2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksbmFtZSk7CgoJCQkvKiBvbmx5IGFkZCBpZiBsZWFmIG5vZGUgb3IgdmFsdWVkIG5vZGUgKi8KCQkJaWYgKGRpci0+dmFsdWVfaWR4IT0wfHxkaXItPmNoaWxkX2lkeD09MCkgewoJCQkJaWYgKGRpci0+dmFsdWVfaWR4KSB7CgkJCQkJdmFsPShzdHJ1Y3QgX3czMV92YWxlbnQqKSZ0YWJbZGlyLT52YWx1ZV9pZHhdOwoJCQkJCW1lbWNweSh0YWlsLCZ0eHRbdmFsLT5zdHJpbmdfb2ZmXSx2YWwtPmxlbmd0aCk7CgkJCQkJdGFpbFt2YWwtPmxlbmd0aF09J1wwJzsKCQkJCQl2YWx1ZT1zdHJkdXBBMlcodGFpbCk7CgkJCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKHhscGtleSxOVUxMLFJFR19TWiwoTFBCWVRFKXZhbHVlLGxzdHJsZW5XKHZhbHVlKSoyKzIsbGFzdG1vZGlmaWVkKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCVRSQUNFXyhyZWcpKCJzdHJhbmdlOiBubyBkaXJlY3Rvcnkga2V5IG5hbWUsIGlkeD0lMDR4XG4iLCBpZHgpOwoJCX0KCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQseGxwa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQlpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3czMV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnZvaWQgX3czMV9sb2FkcmVnKHZvaWQpIHsKCUhGSUxFCQkJaGY7CglzdHJ1Y3QgX3czMV9oZWFkZXIJaGVhZDsKCXN0cnVjdCBfdzMxX3RhYmVudAkqdGFiOwoJdW5zaWduZWQgY2hhcgkJKnR4dDsKCWludAkJCWxlbjsKCU9GU1RSVUNUCQlvZnM7CglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmluZm87Cgl0aW1lX3QJCQlsYXN0bW9kaWZpZWQ7CglMUEtFWVNUUlVDVAkJbHBrZXk7CgoJVFJBQ0VfKHJlZykoIih2b2lkKVxuIik7CgoJaGYgPSBPcGVuRmlsZSgicmVnLmRhdCIsJm9mcyxPRl9SRUFEKTsKCWlmIChoZj09SEZJTEVfRVJST1IpCgkJcmV0dXJuOwoKCS8qIHJlYWQgJiBkdW1wIGhlYWRlciAqLwoJaWYgKHNpemVvZihoZWFkKSE9X2xyZWFkKGhmLCZoZWFkLHNpemVvZihoZWFkKSkpIHsKCQlFUlJfKHJlZykoInJlZy5kYXQgaXMgdG9vIHNob3J0LlxuIik7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoJaWYgKG1lbWNtcChoZWFkLmNvb2tpZSwgIlNIQ0MzLjEwIiwgc2l6ZW9mKGhlYWQuY29va2llKSkhPTApIHsKCQlFUlJfKHJlZykoInJlZy5kYXQgaGFzIGJhZCBzaWduYXR1cmUuXG4iKTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJbGVuID0gaGVhZC50YWJjbnQgKiBzaXplb2Yoc3RydWN0IF93MzFfdGFiZW50KTsKCS8qIHJlYWQgYW5kIGR1bXAgaW5kZXggdGFibGUgKi8KCXRhYiA9IHhtYWxsb2MobGVuKTsKCWlmIChsZW4hPV9scmVhZChoZix0YWIsbGVuKSkgewoJCUVSUl8ocmVnKSgiY291bGRuJ3QgcmVhZCAlZCBieXRlcy5cbiIsbGVuKTsgCgkJZnJlZSh0YWIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCgkvKiByZWFkIHRleHQgKi8KCXR4dCA9IHhtYWxsb2MoaGVhZC50ZXh0c2l6ZSk7CglpZiAoLTE9PV9sbHNlZWsoaGYsaGVhZC50ZXh0b2ZmLFNFRUtfU0VUKSkgewoJCUVSUl8ocmVnKSgiY291bGRuJ3Qgc2VlayB0byB0ZXh0YmxvY2suXG4iKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAoaGVhZC50ZXh0c2l6ZSE9X2xyZWFkKGhmLHR4dCxoZWFkLnRleHRzaXplKSkgewoJCUVSUl8ocmVnKSgidGV4dGJsb2NrIHRvbyBzaG9ydCAoJWQgaW5zdGVhZCBvZiAlbGQpLlxuIixsZW4saGVhZC50ZXh0c2l6ZSk7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGYsJmhmaW5mbykpIHsKCQlFUlJfKHJlZykoIkdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlIGZhaWxlZD8uXG4iKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CglsYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CglscGtleSA9IGxvb2t1cF9oa2V5KEhLRVlfQ0xBU1NFU19ST09UKTsKCV9fdzMxX2R1bXB0cmVlKHRhYlswXS53MSx0eHQsdGFiLCZoZWFkLGxwa2V5LGxhc3Rtb2RpZmllZCwwKTsKCWZyZWUodGFiKTsKCWZyZWUodHh0KTsKCV9sY2xvc2UoaGYpOwoJcmV0dXJuOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfTG9hZFJlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnZvaWQgU0hFTExfTG9hZFJlZ2lzdHJ5KCB2b2lkICkKewogIGNoYXIJICAgICAgKmZuLCAqaG9tZTsKICBMUEtFWVNUUlVDVAlscGtleSwgSEtDVSwgSEtVLCBIS0xNOwogIEhLRVkJCSAgICBoa2V5OwoKICBUUkFDRV8ocmVnKSgiKHZvaWQpXG4iKTsKCiAgSEtDVSA9IGxvb2t1cF9oa2V5KEhLRVlfQ1VSUkVOVF9VU0VSKTsKICBIS1UgID0gbG9va3VwX2hrZXkoSEtFWV9VU0VSUyk7CiAgSEtMTSA9IGxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSk7CgogIC8qIExvYWQgd2luZG93cyAzLjEgZW50cmllcyAqLwogIF93MzFfbG9hZHJlZygpOwogIC8qIExvYWQgd2luZG93cyA5NSBlbnRyaWVzICovCiAgX3c5NV9sb2FkcmVnKCJDOlxcc3lzdGVtLjFzdCIsCUhLTE0pOwogIF93OTVfbG9hZHJlZygic3lzdGVtLmRhdCIsCUhLTE0pOwogIF93OTVfbG9hZHJlZygidXNlci5kYXQiLAlIS1UpOwoKICAvKiAKICAgKiBMb2FkIHRoZSBnbG9iYWwgSEtVIGhpdmUgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyCiAgICovIAogIF93aW5lX2xvYWRyZWcoIEhLVSwgU0FWRV9VU0VSU19ERUZBVUxULCAwKTsKCiAgLyogCiAgICogTG9hZCB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgZGlyZWN0bHkgZm9ybSBzeXNjb25mZGlyCiAgICovCiAgX3dpbmVfbG9hZHJlZyggSEtMTSwgU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQsIDApOwoKICAvKgogICAqIExvYWQgdGhlIHVzZXIgc2F2ZWQgcmVnaXN0cmllcyAKICAgKi8KICBpZiAoKGhvbWUgPSBnZXRlbnYoICJIT01FIiApKSkKICB7CiAgICAvKiAKICAgICAqIExvYWQgdXNlcidzIHBlcnNvbmFsIHZlcnNpb25zIG9mIGdsb2JhbCBIS1UvLkRlZmF1bHQga2V5cwogICAgICovCiAgICBmbj0oY2hhciopeG1hbGxvYygKICAgICAgICAgICAgICAgIHN0cmxlbihob21lKSsKICAgICAgICAgICAgICAgIHN0cmxlbihXSU5FX1BSRUZJWCkrCiAgICAgICAgICAgICAgICBzdHJsZW4oU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKSsyKTsKCiAgICBzdHJjcHkoZm4sIGhvbWUpOwogICAgc3RyY2F0KGZuLCBXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCk7CiAgICBfd2luZV9sb2FkcmVnKEhLVSwgZm4sIFJFR19PUFRJT05fVEFJTlRFRCk7IAogICAgZnJlZShmbik7CgogICAgLyogCiAgICAgKiBMb2FkIEhLQ1UsIGF0dGVtcHQgdG8gZ2V0IHRoZSByZWdpc3RyeSBsb2NhdGlvbiBmcm9tIHRoZSBjb25maWcgCiAgICAgKiBmaWxlIGZpcnN0LCBpZiBleGlzdCwgbG9hZCBhbmQga2VlcCBnb2luZy4KICAgICAqLyAgICAgIAogICAgZm4gPSB4bWFsbG9jKCBNQVhfUEFUSE5BTUVfTEVOICk7IAogICAgaWYgKCBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoCiAgICAgICAgICAiUmVnaXN0cnkiLCAKICAgICAgICAgICJVc2VyRmlsZU5hbWUiLCAKICAgICAgICAgICIiLCAKICAgICAgICAgIGZuLCAKICAgICAgICAgIE1BWF9QQVRITkFNRV9MRU4gLSAxKSkgCiAgICB7CiAgICAgIF93aW5lX2xvYWRyZWcoSEtDVSxmbiwwKTsKICAgIH0KICAJZnJlZSAoZm4pOwoKICAgIGZuPShjaGFyKil4bWFsbG9jKAogICAgICAgICAgICAgICAgc3RybGVuKGhvbWUpKwogICAgICAgICAgICAgICAgc3RybGVuKFdJTkVfUFJFRklYKSsKICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikrMik7CgogICAgc3RyY3B5KGZuLCBob21lKTsKICAgIHN0cmNhdChmbiwgV0lORV9QUkVGSVgiLyJTQVZFX0NVUlJFTlRfVVNFUik7CiAgICBfd2luZV9sb2FkcmVnKEhLQ1UsIGZuLCBSRUdfT1BUSU9OX1RBSU5URUQpOwogICAgZnJlZShmbik7CgogICAgLyogCiAgICAgKiBMb2FkIEhLTE0sIGF0dGVtcHQgdG8gZ2V0IHRoZSByZWdpc3RyeSBsb2NhdGlvbiBmcm9tIHRoZSBjb25maWcgCiAgICAgKiBmaWxlIGZpcnN0LCBpZiBleGlzdCwgbG9hZCBhbmQga2VlcCBnb2luZy4KICAgICAqLyAgICAgIAogICAgZm4gPSB4bWFsbG9jICggTUFYX1BBVEhOQU1FX0xFTik7CiAgICBpZiAoIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZygKICAgICAgICAgICJSZWdpc3RyeSIsIAogICAgICAgICAgIkxvY2FsTWFjaGluZUZpbGVOYW1lIiwgCiAgICAgICAgICAiIiwgCiAgICAgICAgICBmbiwgCiAgICAgICAgICBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpCiAgICB7CiAgICAgICAgX3dpbmVfbG9hZHJlZyhIS0xNLCBmbiwgMCk7CiAgICB9CiAgICBmcmVlKGZuKTsKCiAgICBmbj0oY2hhciopeG1hbGxvYygKICAgICAgICAgICAgICAgIHN0cmxlbihob21lKSsKICAgICAgICAgICAgICAgIHN0cmxlbihXSU5FX1BSRUZJWCkrCiAgICAgICAgICAgICAgICBzdHJsZW4oU0FWRV9MT0NBTF9NQUNISU5FKSsyKTsKCiAgICBzdHJjcHkoZm4saG9tZSk7CiAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwogICAgX3dpbmVfbG9hZHJlZyhIS0xNLCBmbiwgUkVHX09QVElPTl9UQUlOVEVEKTsKICAgIGZyZWUoZm4pOwogIH0KICBlbHNlCiAgewogICAgV0FSTl8ocmVnKSgiRmFpbGVkIHRvIGdldCBob21lZGlyZWN0b3J5IG9mIFVJRCAlbGQuXG4iLChsb25nKSBnZXR1aWQoKSk7CiAgfQoKICAvKiAKICAgKiBPYnRhaW4gdGhlIGhhbmRsZSBvZiB0aGUgSEtVXC5EZWZhdWx0IGtleS4KICAgKiBpbiBvcmRlciB0byBjb3B5IEhLVVwuRGVmYXVsdFwqIG9udG8gSEtFWV9DVVJSRU5UX1VTRVIgCiAgICovCiAgUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUywiLkRlZmF1bHQiLCZoa2V5KTsKICBscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogIGlmKCFscGtleSkKICAgICBXQVJOXyhyZWcpKCJDb3VsZCBub3QgY3JlYXRlIGdsb2JhbCB1c2VyIGRlZmF1bHQga2V5XG4iKTsKICBlbHNlCiAgICBfY29weV9yZWdpc3RyeShscGtleSwgSEtDVSApOwoKICBSZWdDbG9zZUtleShoa2V5KTsKCiAgLyogCiAgICogU2luY2UgSEtVIGlzIGJ1aWx0IGZyb20gdGhlIGdsb2JhbCBIS1UgYW5kIHRoZSBsb2NhbCB1c2VyIEhLVSBmaWxlIHdlIG11c3QKICAgKiBmbHVzaCB0aGUgSEtVIHRyZWUgd2UgaGF2ZSBidWlsdCBhdCB0aGlzIHBvaW50IG90aGVyd2lzZSB0aGUgcGFydCBicm91Z2h0CiAgICogaW4gZnJvbSB0aGUgZ2xvYmFsIEhLVSBpcyBzYXZlZCBpbnRvIHRoZSBsb2NhbCBIS1UuICBUbyBhdm9pZCB0aGlzIAogICAqIHVzZWxlc3MgZHVwcGxpY2F0aW9uIG9mIEhLVSBrZXlzIHdlIHJlcmVhZCB0aGUgbG9jYWwgSEtVIGtleS4KICAgKi8KCiAgLyogQWxsd2F5cyBmbHVzaCB0aGUgSEtVIGhpdmUgYW5kIHJlbG9hZCBpdCBvbmx5IHdpdGggdXNlcidzIHBlcnNvbmFsIEhLVSAqLwogIF9mbHVzaF9yZWdpc3RyeShIS1UpOyAKCiAgLyogUmVsb2FkIHVzZXIncyBsb2NhbCBIS1UgaGl2ZSAqLwogIGlmIChob21lKQogIHsKICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkKICAgICAgICAgICAgICAgICAgICAgICAgICsgc3RybGVuKFNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCkgKyAyKTsKICAgICAgCiAgICAgIHN0cmNweShmbixob21lKTsKICAgICAgc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKTsKCiAgICAgIF93aW5lX2xvYWRyZWcoIEhLVSwgZm4sIFJFR19PUFRJT05fVEFJTlRFRCk7CgogICAgICBmcmVlKGZuKTsKICB9CgogIC8qIAogICAqIE1ha2Ugc3VyZSB0aGUgdXBkYXRlIG1vZGUgaXMgdGhlcmUKICAgKi8KICBpZiAoRVJST1JfU1VDQ0VTUz09UmVnQ3JlYXRlS2V5MTYoSEtFWV9DVVJSRU5UX1VTRVIsS0VZX1JFR0lTVFJZLCZoa2V5KSkgCiAgewogICAgRFdPUkQJanVuayx0eXBlLGxlbjsKICAgIGNoYXIJZGF0YVs1XTsKCiAgICBsZW49NDsKICAgIGlmICgoCVJlZ1F1ZXJ5VmFsdWVFeEEoCiAgICAgICAgICAgIGhrZXksCiAgICAgICAgICAgIFZBTF9TQVZFVVBEQVRFRCwKICAgICAgICAgICAgJmp1bmssCiAgICAgICAgICAgICZ0eXBlLAogICAgICAgICAgICBkYXRhLAogICAgICAgICAgICAmbGVuKSAhPSBFUlJPUl9TVUNDRVNTKSB8fCAodHlwZSAhPSBSRUdfU1opKQogICAgewogICAgICBSZWdTZXRWYWx1ZUV4QShoa2V5LFZBTF9TQVZFVVBEQVRFRCwwLFJFR19TWiwieWVzIiw0KTsKICAgIH0KCiAgICBSZWdDbG9zZUtleShoa2V5KTsKICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIEFQSSBGVU5DVElPTlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKgogKiBPcGVuIEtleXMuCiAqCiAqIEFsbCBmdW5jdGlvbnMgYXJlIHN0dWJzIHRvIFJlZ09wZW5LZXlFeDMyVyB3aGVyZSBhbGwgdGhlCiAqIG1hZ2ljIGhhcHBlbnMuIAogKgogKiBDYWxscGF0aDoKICogUmVnT3BlbktleTE2IC0+IFJlZ09wZW5LZXkzMkEgLT4gUmVnT3BlbktleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnT3BlbktleTMyVyAgIC0+IFJlZ09wZW5LZXlFeDMyVyAKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5RXgzMlcgW0FEVkFQSTMyLjE1MF0KICogT3BlbnMgdGhlIHNwZWNpZmllZCBrZXkKICoKICogVW5saWtlIFJlZ0NyZWF0ZUtleUV4LCB0aGlzIGRvZXMgbm90IGNyZWF0ZSB0aGUga2V5IGlmIGl0IGRvZXMgbm90IGV4aXN0LgogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIE5hbWUgb2Ygc3Via2V5IHRvIG9wZW4KICogICAgZHdSZXNlcnZlZCBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIHplcm8KICogICAgc2FtRGVzaXJlZCBbSV0gU2VjdXJpdHkgYWNjZXNzIG1hc2sKICogICAgcmV0a2V5ICAgICBbT10gQWRkcmVzcyBvZiBoYW5kbGUgb2Ygb3BlbiBrZXkKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5RXhXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHU0FNIHNhbURlc2lyZWQsIExQSEtFWSByZXRrZXkgKQp7CglMUEtFWVNUUlVDVAlscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCiAgICBUUkFDRV8ocmVnKSgiKDB4JXgsJXMsJWxkLCVseCwlcClcbiIsIGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxkd1Jlc2VydmVkLAogICAgICAgICAgc2FtRGVzaXJlZCxyZXRrZXkpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkgewogICAgICAgIC8qIEVpdGhlciBOVUxMIG9yIHBvaW50ZXIgdG8gZW1wdHkgc3RyaW5nLCBzbyByZXR1cm4gYSBuZXcgaGFuZGxlCiAgICAgICAgICAgdG8gdGhlIG9yaWdpbmFsIGhrZXkgKi8KICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CiAgICAgICAgYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKICAgICAgICAqcmV0a2V5PWN1cnJlbnRoYW5kbGU7CiAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CiAgICB9CgogICAgaWYgKGxwc3pTdWJLZXlbMF0gPT0gJ1xcJykgewogICAgICAgIFdBUk5fKHJlZykoIlN1YmtleSAlcyBtdXN0IG5vdCBiZWdpbiB3aXRoIGJhY2tzbGFzaC5cbiIsZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CiAgICAgICAgcmV0dXJuIEVSUk9SX0JBRF9QQVRITkFNRTsKICAgIH0KCglzcGxpdF9rZXlwYXRoKGxwc3pTdWJLZXksJndwcywmd3BjKTsKCWkgPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleSA9IGxwTmV4dEtleTsKCiAgICB3aGlsZSAod3BzW2ldKSB7CiAgICAgICAgbHB4a2V5PWxwTmV4dEtleS0+bmV4dHN1YjsKICAgICAgICB3aGlsZSAobHB4a2V5KSB7CiAgICAgICAgICAgIGlmICghbHN0cmNtcGlXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBscHhrZXk9bHB4a2V5LT5uZXh0OwogICAgICAgIH0KCiAgICAgICAgaWYgKCFscHhrZXkpIHsKICAgICAgICAgICAgVFJBQ0VfKHJlZykoIkNvdWxkIG5vdCBmaW5kIHN1YmtleSAlc1xuIixkZWJ1Z3N0cl93KHdwc1tpXSkpOwogICAgICAgICAgICBGUkVFX0tFWV9QQVRIOwogICAgICAgICAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7CiAgICAgICAgfQogICAgICAgIGkrKzsKICAgICAgICBscE5leHRLZXkgPSBscHhrZXk7CiAgICB9CgogICAgY3VycmVudGhhbmRsZSArPSAyOwogICAgYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKICAgICpyZXRrZXkgPSBjdXJyZW50aGFuZGxlOwogICAgVFJBQ0VfKHJlZykoIiAgUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKICAgIEZSRUVfS0VZX1BBVEg7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleUV4MzJBIFtBRFZBUEkzMi4xNDldCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleUV4QSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHU0FNIHNhbURlc2lyZWQsIExQSEtFWSByZXRrZXkgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVcgPSBzdHJkdXBBMlcobHBzelN1YktleSk7CiAgICBEV09SRCByZXQ7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcywlbGQsJWx4LCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSksZHdSZXNlcnZlZCwKICAgICAgICAgIHNhbURlc2lyZWQscmV0a2V5KTsKICAgIHJldCA9IFJlZ09wZW5LZXlFeFcoIGhrZXksIGxwc3pTdWJLZXlXLCBkd1Jlc2VydmVkLCBzYW1EZXNpcmVkLCByZXRrZXkgKTsKICAgIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleTMyVyBbQURWQVBJMzIuMTUxXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkgdG8gb3BlbgogKiAgICByZXRrZXkgICAgIFtPXSBBZGRyZXNzIG9mIGhhbmRsZSBvZiBvcGVuIGtleQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0dXJuIFJlZ09wZW5LZXlFeFcoIGhrZXksIGxwc3pTdWJLZXksIDAsIEtFWV9BTExfQUNDRVNTLCByZXRrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleTMyQSBbQURWQVBJMzIuMTQ4XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgRFdPUkQgcmV0OwogICAgTFBXU1RSIGxwc3pTdWJLZXlXID0gc3RyZHVwQTJXKGxwc3pTdWJLZXkpOwogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICByZXQgPSAgUmVnT3BlbktleVcoIGhrZXksIGxwc3pTdWJLZXlXLCByZXRrZXkgKTsKICAgIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleTE2IFtTSEVMTC4xXSBbS0VSTkVMLjIxN10KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdPcGVuS2V5QSggaGtleSwgbHBzelN1YktleSwgcmV0a2V5ICk7Cn0KCgovKiAKICogQ3JlYXRlIGtleXMKICogCiAqIEFsbCB0aG9zZSBmdW5jdGlvbnMgY29udmVydCB0aGVpciByZXNwZWN0aXZlIAogKiBhcmd1bWVudHMgYW5kIGNhbGwgUmVnQ3JlYXRlS2V5RXhXIGF0IHRoZSBlbmQuCiAqCiAqIFdlIHN0YXkgYXdheSBmcm9tIHRoZSBFeCBmdW5jdGlvbnMgYXMgbG9uZyBhcyBwb3NzaWJsZSBiZWNhdXNlIHRoZXJlIGFyZQogKiBkaWZmZXJlbmNlcyBpbiB0aGUgcmV0dXJuIHZhbHVlcwogKgogKiBDYWxscGF0aDoKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ0NyZWF0ZUtleUV4MzJBIFwKICogUmVnQ3JlYXRlS2V5MTYgLT4gUmVnQ3JlYXRlS2V5MzJBIC0+IFJlZ0NyZWF0ZUtleTMyVyAgIC0+IFJlZ0NyZWF0ZUtleUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ3JlYXRlS2V5RXgzMlcgW0FEVkFQSTMyLjEzMV0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICBbSV0gSGFuZGxlIG9mIGFuIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgICBbSV0gQWRkcmVzcyBvZiBzdWJrZXkgbmFtZQogKiAgICBkd1Jlc2VydmVkICAgW0ldIFJlc2VydmVkIC0gbXVzdCBiZSAwCiAqICAgIGxwc3pDbGFzcyAgICBbSV0gQWRkcmVzcyBvZiBjbGFzcyBzdHJpbmcKICogICAgZmR3T3B0aW9ucyAgIFtJXSBTcGVjaWFsIG9wdGlvbnMgZmxhZwogKiAgICBzYW1EZXNpcmVkICAgW0ldIERlc2lyZWQgc2VjdXJpdHkgYWNjZXNzCiAqICAgIGxwU2VjQXR0cmlicyBbSV0gQWRkcmVzcyBvZiBrZXkgc2VjdXJpdHkgc3RydWN0dXJlCiAqICAgIHJldGtleSAgICAgICBbT10gQWRkcmVzcyBvZiBidWZmZXIgZm9yIG9wZW5lZCBoYW5kbGUKICogICAgbHBEaXNwb3MgICAgIFtPXSBSZWNlaXZlcyBSRUdfQ1JFQVRFRF9ORVdfS0VZIG9yIFJFR19PUEVORURfRVhJU1RJTkdfS0VZCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5RXhXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdSZXNlcnZlZCwgTFBXU1RSIGxwc3pDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZmR3T3B0aW9ucywgUkVHU0FNIHNhbURlc2lyZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIGxwU2VjQXR0cmlicywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBIS0VZIHJldGtleSwgTFBEV09SRCBscERpc3BvcyApCnsKCUxQS0VZU1RSVUNUCSpscGxwUHJldktleSxscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVsZCwlcywlbHgsJWx4LCVwLCVwLCVwKVxuIiwgaGtleSwKCQlkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLCBkd1Jlc2VydmVkLCBkZWJ1Z3N0cl93KGxwc3pDbGFzcyksCgkJZmR3T3B0aW9ucywgc2FtRGVzaXJlZCwgbHBTZWNBdHRyaWJzLCByZXRrZXksIGxwRGlzcG9zKTsKCiAgICBscE5leHRLZXkgPSBsb29rdXBfaGtleShoa2V5KTsKICAgIGlmICghbHBOZXh0S2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICAvKiBDaGVjayBmb3IgdmFsaWQgb3B0aW9ucyAqLwogICAgc3dpdGNoKGZkd09wdGlvbnMpIHsKICAgICAgICBjYXNlIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFOgogICAgICAgIGNhc2UgUkVHX09QVElPTl9WT0xBVElMRToKICAgICAgICBjYXNlIFJFR19PUFRJT05fQkFDS1VQX1JFU1RPUkU6CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKICAgIH0KCiAgICAvKiBTYW0gaGFzIHRvIGJlIGEgY29tYmluYXRpb24gb2YgdGhlIGZvbGxvd2luZyAqLwogICAgaWYgKCEoc2FtRGVzaXJlZCAmIAogICAgICAgICAgKEtFWV9BTExfQUNDRVNTIHwgS0VZX0NSRUFURV9MSU5LIHwgS0VZX0NSRUFURV9TVUJfS0VZIHwgCiAgICAgICAgICAgS0VZX0VOVU1FUkFURV9TVUJfS0VZUyB8IEtFWV9FWEVDVVRFIHwgS0VZX05PVElGWSB8CiAgICAgICAgICAgS0VZX1FVRVJZX1ZBTFVFIHwgS0VZX1JFQUQgfCBLRVlfU0VUX1ZBTFVFIHwgS0VZX1dSSVRFKSkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKCWlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRoYW5kbGUgKz0gMjsKCQlhZGRfaGFuZGxlKGN1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwoJCSpyZXRrZXk9Y3VycmVudGhhbmRsZTsKICAgICAgICAgICAgICAgIFRSQUNFXyhyZWcpKCJSZXR1cm5pbmcgJXhcbiIsIGN1cnJlbnRoYW5kbGUpOwoJCWxwTmV4dEtleS0+ZmxhZ3N8PVJFR19PUFRJT05fVEFJTlRFRDsKCQlyZXR1cm4gRVJST1JfU1VDQ0VTUzsKCX0KCiAgICBpZiAobHBzelN1YktleVswXSA9PSAnXFwnKSB7CiAgICAgICAgV0FSTl8ocmVnKSgiU3Via2V5ICVzIG11c3Qgbm90IGJlZ2luIHdpdGggYmFja3NsYXNoLlxuIixkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpKTsKICAgICAgICByZXR1cm4gRVJST1JfQkFEX1BBVEhOQU1FOwogICAgfQoKCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleQk9IGxwTmV4dEtleTsKCXdoaWxlICh3cHNbaV0pIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21waVcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCQlicmVhazsKCQkJbHB4a2V5PWxweGtleS0+bmV4dDsKCQl9CgkJaWYgKCFscHhrZXkpCgkJCWJyZWFrOwoJCWkrKzsKCQlscE5leHRLZXkJPSBscHhrZXk7Cgl9CglpZiAobHB4a2V5KSB7CiAgICAgICAgICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CgkJYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKCQlscHhrZXktPmZsYWdzICB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwogICAgICAgICAgICAgICAgVFJBQ0VfKHJlZykoIlJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CgkJaWYgKGxwRGlzcG9zKQoJCQkqbHBEaXNwb3MJPSBSRUdfT1BFTkVEX0VYSVNUSU5HX0tFWTsKCQlGUkVFX0tFWV9QQVRIOwoJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJfQoKCS8qIEdvb2QuICBOb3cgdGhlIGhhcmQgcGFydCAqLwoJd2hpbGUgKHdwc1tpXSkgewoJCWxwbHBQcmV2S2V5CT0gJihscE5leHRLZXktPm5leHRzdWIpOwoJCWxweGtleQkJPSAqbHBscFByZXZLZXk7CgkJd2hpbGUgKGxweGtleSkgewoJCQlscGxwUHJldktleQk9ICYobHB4a2V5LT5uZXh0KTsKCQkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl9CgkJKmxwbHBQcmV2S2V5PW1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJaWYgKCEqbHBscFByZXZLZXkpIHsKCQkJRlJFRV9LRVlfUEFUSDsKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0VfKHJlZykoIlJldHVybmluZyBPVVRPRk1FTU9SWVxuIik7CgkJCXJldHVybiBFUlJPUl9PVVRPRk1FTU9SWTsKCQl9CgkJbWVtc2V0KCpscGxwUHJldktleSwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTsKICAgICAgICAgICAgICAgIFRSQUNFXyhyZWcpKCJBZGRpbmcgJXNcbiIsIGRlYnVnc3RyX3cod3BzW2ldKSk7CgkJKCpscGxwUHJldktleSktPmtleW5hbWUJPSBzdHJkdXBXKHdwc1tpXSk7CgkJKCpscGxwUHJldktleSktPm5leHQJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5uZXh0c3ViCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+dmFsdWVzCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+bnJvZnZhbHVlcyA9IDA7CgkJKCpscGxwUHJldktleSktPmZsYWdzIAk9IFJFR19PUFRJT05fVEFJTlRFRDsKCQlpZiAobHBzekNsYXNzKQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBzdHJkdXBXKGxwc3pDbGFzcyk7CgkJZWxzZQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBOVUxMOwoJCWxwTmV4dEtleQk9ICpscGxwUHJldktleTsKCQlpKys7Cgl9CiAgICAgICAgY3VycmVudGhhbmRsZSArPSAyOwoJYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKCgkvKkZJWE1FOiBmbGFnIGhhbmRsaW5nIGNvcnJlY3Q/ICovCglscE5leHRLZXktPmZsYWdzPSBmZHdPcHRpb25zIHxSRUdfT1BUSU9OX1RBSU5URUQ7CglpZiAobHBzekNsYXNzKQoJCWxwTmV4dEtleS0+Y2xhc3MgPSBzdHJkdXBXKGxwc3pDbGFzcyk7CgllbHNlCgkJbHBOZXh0S2V5LT5jbGFzcyA9IE5VTEw7CgkqcmV0a2V5CQk9IGN1cnJlbnRoYW5kbGU7CiAgICAgICAgVFJBQ0VfKHJlZykoIlJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CglpZiAobHBEaXNwb3MpCgkJKmxwRGlzcG9zCT0gUkVHX0NSRUFURURfTkVXX0tFWTsKCUZSRUVfS0VZX1BBVEg7CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ3JlYXRlS2V5RXgzMkEgW0FEVkFQSTMyLjEzMF0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXlFeEEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgbHBzekNsYXNzLCBEV09SRCBmZHdPcHRpb25zLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdTQU0gc2FtRGVzaXJlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIGxwU2VjQXR0cmlicywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBIS0VZIHJldGtleSwgTFBEV09SRCBscERpc3BvcyApCnsKICAgIExQV1NUUiBscHN6U3ViS2V5VywgbHBzekNsYXNzVzsKICAgIERXT1JEICByZXQ7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcywlbGQsJXMsJWx4LCVseCwlcCwlcCwlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLAogICAgICAgICAgZHdSZXNlcnZlZCxkZWJ1Z3N0cl9hKGxwc3pDbGFzcyksZmR3T3B0aW9ucyxzYW1EZXNpcmVkLGxwU2VjQXR0cmlicywKICAgICAgICAgIHJldGtleSxscERpc3Bvcyk7CgogICAgbHBzelN1YktleVcgPSBscHN6U3ViS2V5P3N0cmR1cEEyVyhscHN6U3ViS2V5KTpOVUxMOwogICAgbHBzekNsYXNzVyA9IGxwc3pDbGFzcz9zdHJkdXBBMlcobHBzekNsYXNzKTpOVUxMOwoKICAgIHJldCA9IFJlZ0NyZWF0ZUtleUV4VyggaGtleSwgbHBzelN1YktleVcsIGR3UmVzZXJ2ZWQsIGxwc3pDbGFzc1csIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkd09wdGlvbnMsIHNhbURlc2lyZWQsIGxwU2VjQXR0cmlicywgcmV0a2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscERpc3BvcyApOwoKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIGlmKGxwc3pDbGFzc1cpIGZyZWUobHBzekNsYXNzVyk7CgogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ3JlYXRlS2V5MzJXIFtBRFZBUEkzMi4xMzJdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBEV09SRCBqdW5rOwogICAgTFBLRVlTVFJVQ1QJbHBOZXh0S2V5OwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXApXG4iLCBoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkscmV0a2V5KTsKCiAgICAvKiBUaGlzIGNoZWNrIGlzIGhlcmUgYmVjYXVzZSB0aGUgcmV0dXJuIHZhbHVlIGlzIGRpZmZlcmVudCB0aGFuIHRoZQogICAgICAgb25lIGZyb20gdGhlIEV4IGZ1bmN0aW9ucyAqLwogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfQkFES0VZOwoKICAgIHJldHVybiBSZWdDcmVhdGVLZXlFeFcoIGhrZXksIGxwc3pTdWJLZXksIDAsIE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX0FMTF9BQ0NFU1MsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldGtleSwgJmp1bmspOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXkzMkEgW0FEVkFQSTMyLjEyOV0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgRFdPUkQgcmV0OwogICAgTFBXU1RSIGxwc3pTdWJLZXlXOwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgbHBzelN1YktleVcgPSBscHN6U3ViS2V5P3N0cmR1cEEyVyhscHN6U3ViS2V5KTpOVUxMOwogICAgcmV0ID0gUmVnQ3JlYXRlS2V5VyggaGtleSwgbHBzelN1YktleVcsIHJldGtleSApOwogICAgaWYobHBzelN1YktleVcpIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ3JlYXRlS2V5MTYgW1NIRUxMLjJdIFtLRVJORUwuMjE4XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5QSggaGtleSwgbHBzelN1YktleSwgcmV0a2V5ICk7Cn0KCgovKiAKICogUXVlcnkgVmFsdWUgRnVuY3Rpb25zCiAqIFdpbjMyIGRpZmZlcnMgYmV0d2VlbiBrZXluYW1lcyBhbmQgdmFsdWVuYW1lcy4gCiAqIG11bHRpcGxlIHZhbHVlcyBtYXkgYmVsb25nIHRvIG9uZSBrZXksIHRoZSBzcGVjaWFsIHZhbHVlCiAqIHdpdGggbmFtZSBOVUxMIGlzIHRoZSBkZWZhdWx0IHZhbHVlIHVzZWQgYnkgdGhlIHdpbjMxCiAqIGNvbXBhdCBmdW5jdGlvbnMuCiAqCiAqIENhbGxwYXRoOgogKiBSZWdRdWVyeVZhbHVlMTYgLT4gUmVnUXVlcnlWYWx1ZTMyQSAtPiBSZWdRdWVyeVZhbHVlRXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdRdWVyeVZhbHVlMzJXIC0+IFJlZ1F1ZXJ5VmFsdWVFeDMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWVFeDMyVyBbQURWQVBJMzIuMTU4XQogKiBSZXRyaWV2ZXMgdHlwZSBhbmQgZGF0YSBmb3IgYSBzcGVjaWZpZWQgbmFtZSBhc3NvY2lhdGVkIHdpdGggYW4gb3BlbiBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldICAgSGFuZGxlIG9mIGtleSB0byBxdWVyeQogKiAgICBscFZhbHVlTmFtZSAgIFtJXSAgIE5hbWUgb2YgdmFsdWUgdG8gcXVlcnkKICogICAgbHBkd1Jlc2VydmVkICBbSV0gICBSZXNlcnZlZCAtIG11c3QgYmUgTlVMTAogKiAgICBscGR3VHlwZSAgICAgIFtPXSAgIEFkZHJlc3Mgb2YgYnVmZmVyIGZvciB2YWx1ZSB0eXBlLiAgSWYgTlVMTCwgdGhlIHR5cGUKICogICAgICAgICAgICAgICAgICAgICAgICBpcyBub3QgcmVxdWlyZWQuCiAqICAgIGxwYkRhdGEgICAgICAgW09dICAgQWRkcmVzcyBvZiBkYXRhIGJ1ZmZlci4gIElmIE5VTEwsIHRoZSBhY3R1YWwgZGF0YSBpcwogKiAgICAgICAgICAgICAgICAgICAgICAgIG5vdCByZXF1aXJlZC4KICogICAgbHBjYkRhdGEgICAgICBbSS9PXSBBZGRyZXNzIG9mIGRhdGEgYnVmZmVyIHNpemUKICoKICogUkVUVVJOUyAKICogICAgRVJST1JfU1VDQ0VTUzogICBTdWNjZXNzCiAqICAgIEVSUk9SX01PUkVfREFUQTogISEhIGlmIHRoZSBzcGVjaWZpZWQgYnVmZmVyIGlzIG5vdCBiaWcgZW5vdWdoIHRvIGhvbGQgdGhlIGRhdGEKICogCQkgICAgICAgYnVmZmVyIGlzIGxlZnQgdW50b3VjaGVkLiBUaGUgTVMtZG9jdW1lbnRhdGlvbiBpcyB3cm9uZyAoanMpICEhIQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeFcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFZhbHVlTmFtZSwKCQkJICAgICAgIExQRFdPUkQgbHBkd1Jlc2VydmVkLCBMUERXT1JEIGxwZHdUeXBlLAoJCQkgICAgICAgTFBCWVRFIGxwYkRhdGEsIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUEtFWVNUUlVDVAlscGtleTsKCWludAkJaTsKCURXT1JECQlyZXQ7CgoJVFJBQ0VfKHJlZykoIigweCV4LCVzLCVwLCVwLCVwLCVwPSVsZClcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLCBscGR3VHlwZSwgbHBiRGF0YSwgbHBjYkRhdGEsIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwoKCWlmICghbHBrZXkpCgkgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglpZiAoKGxwYkRhdGEgJiYgISBscGNiRGF0YSkgfHwgbHBkd1Jlc2VydmVkKQoJICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgoJLyogQW4gZW1wdHkgbmFtZSBzdHJpbmcgaXMgZXF1aXZhbGVudCB0byBOVUxMICovCglpZiAobHBWYWx1ZU5hbWUgJiYgISpscFZhbHVlTmFtZSkKCSAgbHBWYWx1ZU5hbWUgPSBOVUxMOwoKCWlmIChscFZhbHVlTmFtZT09TlVMTCkgCgl7IC8qIFVzZSBrZXkncyB1bm5hbWVkIG9yIGRlZmF1bHQgdmFsdWUsIGlmIGFueSAqLwoJICBmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCSAgICBpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJICAgICAgYnJlYWs7Cgl9IAoJZWxzZSAKCXsgLyogU2VhcmNoIGZvciB0aGUga2V5IG5hbWUgKi8KCSAgZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkgICAgaWYgKCBscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYgIWxzdHJjbXBpVyhscFZhbHVlTmFtZSxscGtleS0+dmFsdWVzW2ldLm5hbWUpKQoJICAgICAgYnJlYWs7Cgl9CgoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSAKCXsgVFJBQ0VfKHJlZykoIiBLZXkgbm90IGZvdW5kXG4iKTsKCSAgaWYgKGxwVmFsdWVOYW1lPT1OVUxMKSAKCSAgeyAvKiBFbXB0eSBrZXluYW1lIG5vdCBmb3VuZCAqLwoJICAgIGlmIChscGJEYXRhKSAKCSAgICB7ICooV0NIQVIqKWxwYkRhdGEgPSAwOwoJICAgICAgKmxwY2JEYXRhCT0gMjsKCSAgICB9CgkgICAgaWYgKGxwZHdUeXBlKQoJICAgICAgKmxwZHdUeXBlCT0gUkVHX1NaOwoJICAgIFRSQUNFXyhyZWcpKCIgUmV0dXJuaW5nIGFuIGVtcHR5IHN0cmluZ1xuIik7CgkgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CgkgIH0KCSAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoJfQoKCXJldCA9IEVSUk9SX1NVQ0NFU1M7CgoJaWYgKGxwZHdUeXBlKSAJCQkJCS8qIHR5cGUgcmVxdWlyZWQgPyovCgkgICpscGR3VHlwZSA9IGxwa2V5LT52YWx1ZXNbaV0udHlwZTsKCglpZiAobHBiRGF0YSkJCQkJCS8qIGRhdGEgcmVxdWlyZWQgPyovCgl7IGlmICgqbHBjYkRhdGEgPj0gbHBrZXktPnZhbHVlc1tpXS5sZW4pCS8qIGJ1ZmZlciBsYXJnZSBlbm91Z2h0ID8qLwoJICAgIG1lbWNweShscGJEYXRhLGxwa2V5LT52YWx1ZXNbaV0uZGF0YSxscGtleS0+dmFsdWVzW2ldLmxlbik7CgkgIGVsc2UgewoJICAgICpscGNiRGF0YSA9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwoJICAgIHJldCA9IEVSUk9SX01PUkVfREFUQTsKCSAgfQoJfQoKCWlmIChscGNiRGF0YSkgCQkJCQkvKiBzaXplIHJlcXVpcmVkID8qLwoJeyAqbHBjYkRhdGEgPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKCX0KCglkZWJ1Z19wcmludF92YWx1ZSAoIGxwYkRhdGEsICZscGtleS0+dmFsdWVzW2ldKTsKCglUUkFDRV8ocmVnKSgiIChyZXQ9JWx4LCB0eXBlPSVseCwgbGVuPSVsZClcbiIsIHJldCwgbHBkd1R5cGU/KmxwZHdUeXBlOjAsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWUzMlcgW0FEVkFQSTMyLjE1OV0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQV1NUUiBscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQTE9ORyBscGNiRGF0YSApCnsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQsbHBkd1R5cGU7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxscHN6RGF0YSwKICAgICAgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICAvKiBPbmx5IG9wZW4gc3Via2V5LCBpZiB3ZSByZWFsbHkgZG8gZGVzY2VuZCAqLwogICAgaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKICAgICAgICByZXQgPSBSZWdPcGVuS2V5VyggaGtleSwgbHBzelN1YktleSwgJnhoa2V5ICk7CiAgICAgICAgaWYgKHJldCAhPSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIFdBUk5fKHJlZykoIkNvdWxkIG5vdCBvcGVuICVzXG4iLCBkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICB9IGVsc2UKICAgICAgICB4aGtleSA9IGhrZXk7CgogICAgbHBkd1R5cGUgPSBSRUdfU1o7CiAgICByZXQgPSBSZWdRdWVyeVZhbHVlRXhXKCB4aGtleSwgTlVMTCwgTlVMTCwgJmxwZHdUeXBlLCAoTFBCWVRFKWxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscGNiRGF0YSApOwogICAgaWYgKHhoa2V5ICE9IGhrZXkpCiAgICAgICAgUmVnQ2xvc2VLZXkoeGhrZXkpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZUV4MzJBIFtBRFZBUEkzMi4xNTddCiAqCiAqIE5PVEVTOgogKiB0aGUgZG9jdW1hbnRhdGlvbiBpcyB3cm9uZzogaWYgdGhlIGJ1ZmZlciBpcyB0byBzbWFsbCBpdCByZW1haW5zIHVudG91Y2hlZCAKICoKICogRklYTUU6IGNoZWNrIHJldHVybnZhbHVlIChsZW4pIGZvciBhbiBlbXB0eSBrZXkKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXhBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6VmFsdWVOYW1lLAoJCQkgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBkd1R5cGUsCgkJCSAgICAgICBMUEJZVEUgbHBiRGF0YSwgTFBEV09SRCBscGNiRGF0YSApCnsKCUxQV1NUUglscHN6VmFsdWVOYW1lVzsKCUxQQllURQlteWJ1ZiA9IE5VTEw7CglEV09SRAlyZXQsIG15dHlwZSwgbXlsZW4gPSAwOwoKCVRSQUNFXyhyZWcpKCIoJXgsJXMsJXAsJXAsJXAsJXA9JWxkKVxuIiwgaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKCWlmICghbHBjYkRhdGEgJiYgbHBiRGF0YSkJCQkvKiBidWZmZXIgd2l0aG91dCBzaXplIGlzIGlsbGVnYWwgKi8KCXsgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCX0KCglscHN6VmFsdWVOYW1lVyA9IGxwc3pWYWx1ZU5hbWUgPyBzdHJkdXBBMlcobHBzelZhbHVlTmFtZSkgOiBOVUxMOwkKCQoJLyogZ2V0IGp1c3QgdGhlIHR5cGUgZmlyc3QgKi8KCXJldCA9IFJlZ1F1ZXJ5VmFsdWVFeFcoIGhrZXksIGxwc3pWYWx1ZU5hbWVXLCBscGR3UmVzZXJ2ZWQsICZteXR5cGUsIE5VTEwsIE5VTEwgKTsKCQoJaWYgKCByZXQgIT0gRVJST1JfU1VDQ0VTUyApCQkJLyogZmFpbGVkID8/ICovCgl7IGlmKGxwc3pWYWx1ZU5hbWVXKSBmcmVlKGxwc3pWYWx1ZU5hbWVXKTsKCSAgcmV0dXJuIHJldDsKCX0KCQoJaWYgKGxwY2JEYXRhKQkJCQkJLyogYXQgbGVhc3QgbGVuZ3RoIHJlcXVlc3RlZD8gKi8KCXsgaWYgKFVOSUNPTlZNQVNLICYgKDE8PChteXR5cGUpKSkJCS8qIHN0cmluZyByZXF1ZXN0ZWQ/ICovCgkgIHsgaWYgKGxwYkRhdGEgKQkJCQkvKiB2YWx1ZSByZXF1ZXN0ZWQ/ICovCgkgICAgeyBteWxlbiA9IDIqKCAqbHBjYkRhdGEgKTsKCSAgICAgIG15YnVmID0gKExQQllURSl4bWFsbG9jKCBteWxlbiApOwoJICAgIH0KCgkgICAgcmV0ID0gUmVnUXVlcnlWYWx1ZUV4VyggaGtleSwgbHBzelZhbHVlTmFtZVcsIGxwZHdSZXNlcnZlZCwgbHBkd1R5cGUsIG15YnVmLCAmbXlsZW4gKTsKCgkgICAgaWYgKHJldCA9PSBFUlJPUl9TVUNDRVNTICkKCSAgICB7IGlmICggbHBiRGF0YSApCgkgICAgICB7IGxtZW1jcHluV3RvQShscGJEYXRhLCAoTFBXU1RSKW15YnVmLCBteWxlbi8yKTsKCSAgICAgIH0KCSAgICB9CgoJICAgICpscGNiRGF0YSA9IG15bGVuLzI7CQkJLyogc2l6ZSBpcyBpbiBieXRlISAqLwoJICB9CgkgIGVsc2UJCQkJCQkvKiBubyBzdHJpbmdzLCBjYWxsIGl0IHN0cmFpZ2h0ICovCgkgIHsgcmV0ID0gUmVnUXVlcnlWYWx1ZUV4VyggaGtleSwgbHBzelZhbHVlTmFtZVcsIGxwZHdSZXNlcnZlZCwgbHBkd1R5cGUsIGxwYkRhdGEsIGxwY2JEYXRhICk7CgkgIH0KCX0KCQoJaWYgKGxwZHdUeXBlKQkJCQkJLyogdHlwZSB3aGVuIHJlcXVlc3RlZCAqLwoJeyAqbHBkd1R5cGUgPSBteXR5cGU7Cgl9CgoJVFJBQ0VfKHJlZykoIiAocmV0PSVseCx0eXBlPSVseCwgbGVuPSVsZClcbiIsIHJldCxteXR5cGUsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoJCglpZihteWJ1ZikgZnJlZShteWJ1Zik7CglpZihscHN6VmFsdWVOYW1lVykgZnJlZShscHN6VmFsdWVOYW1lVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlRXgxNiBbS0VSTkVMLjIyNV0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXgxNiggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1Jlc2VydmVkLCBMUERXT1JEIGxwZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBscGJEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcCwlcCwlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhPypscGNiRGF0YTowKTsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlRXhBKCBoa2V5LCBscHN6VmFsdWVOYW1lLCBscGR3UmVzZXJ2ZWQsIGxwZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBiRGF0YSwgbHBjYkRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZTMyQSBbQURWQVBJMzIuMTU2XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUFNUUiBscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQTE9ORyBscGNiRGF0YSApCnsKICAgIEhLRVkgeGhrZXk7CiAgICBEV09SRCByZXQsIGR3VHlwZTsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGxwc3pEYXRhLAogICAgICAgICAgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIGlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CiAgICAgICAgcmV0ID0gUmVnT3BlbktleTE2KCBoa2V5LCBscHN6U3ViS2V5LCAmeGhrZXkgKTsKICAgICAgICBpZiggcmV0ICE9IEVSUk9SX1NVQ0NFU1MgKQogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgfSBlbHNlCiAgICAgICAgeGhrZXkgPSBoa2V5OwoKICAgIGR3VHlwZSA9IFJFR19TWjsKICAgIHJldCA9IFJlZ1F1ZXJ5VmFsdWVFeEEoIHhoa2V5LCBOVUxMLE5VTEwsICZkd1R5cGUsIChMUEJZVEUpbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwY2JEYXRhICk7CiAgICBpZiggeGhrZXkgIT0gaGtleSApCiAgICAgICAgUmVnQ2xvc2VLZXkoIHhoa2V5ICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlMTYgW1NIRUxMLjZdIFtLRVJORUwuMjI0XQogKgogKiBOT1RFUwogKiAgICBJcyB0aGlzIEhBQ0sgc3RpbGwgYXBwbGljYWJsZT8KICoKICogSEFDSwogKiAgICBUaGUgMTZiaXQgUmVnUXVlcnlWYWx1ZSBkb2Vzbid0IGhhbmRsZSBzZWxlY3RvcmJsb2NrcyBhbnl3YXksIHNvIHdlIGp1c3QKICogICAgbWFzayBvdXQgdGhlIGhpZ2ggMTYgYml0LiAgVGhpcyAobm90IHNvIG11Y2ggaW5jaWRlbnRseSkgaG9wZWZ1bGx5IGZpeGVzCiAqICAgIEFsZHVzIEZINCkKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlMTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelN1YktleSwgTFBTVFIgbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGxwc3pEYXRhLAogICAgICAgICAgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIGlmIChscGNiRGF0YSkKICAgICAgICAqbHBjYkRhdGEgJj0gMHhGRkZGOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVBKGhrZXksbHBzelN1YktleSxscHN6RGF0YSxscGNiRGF0YSk7Cn0KCgovKgogKiBTZXR0aW5nIHZhbHVlcyBvZiBSZWdpc3RyeSBrZXlzCiAqCiAqIENhbGxwYXRoOgogKiBSZWdTZXRWYWx1ZTE2IC0+IFJlZ1NldFZhbHVlMzJBIC0+IFJlZ1NldFZhbHVlRXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1NldFZhbHVlMzJXICAgLT4gUmVnU2V0VmFsdWVFeDMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgzMlcgW0FEVkFQSTMyLjE3MF0KICogU2V0cyB0aGUgZGF0YSBhbmQgdHlwZSBvZiBhIHZhbHVlIHVuZGVyIGEgcmVnaXN0ZXIga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgIFtJXSBIYW5kbGUgb2Yga2V5IHRvIHNldCB2YWx1ZSBmb3IKICogICAgbHBzelZhbHVlTmFtZSBbSV0gTmFtZSBvZiB2YWx1ZSB0byBzZXQKICogICAgZHdSZXNlcnZlZCAgICBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIHplcm8KICogICAgZHdUeXBlICAgICAgICBbSV0gRmxhZyBmb3IgdmFsdWUgdHlwZQogKiAgICBscGJEYXRhICAgICAgIFtJXSBBZGRyZXNzIG9mIHZhbHVlIGRhdGEKICogICAgY2JEYXRhICAgICAgICBbSV0gU2l6ZSBvZiB2YWx1ZSBkYXRhCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqCiAqIE5PVEVTCiAqICAgd2luOTUgZG9lcyBub3QgY2FyZSBhYm91dCBjYkRhdGEgZm9yIFJFR19TWiBhbmQgZmluZHMgb3V0IHRoZSBsZW4gYnkgaXRzZWxmIChqcykgCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeFcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6VmFsdWVOYW1lLCAKCQkJICAgICBEV09SRCBkd1Jlc2VydmVkLCBEV09SRCBkd1R5cGUsCgkJCSAgICAgQ09OU1QgQllURSAqbHBiRGF0YSwgRFdPUkQgY2JEYXRhKQp7CglMUEtFWVNUUlVDVCBscGtleTsKCWludCBpOwoKCVRSQUNFXyhyZWcpKCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgZHdSZXNlcnZlZCwgZHdUeXBlLCBscGJEYXRhLCBjYkRhdGEpOwoKCWxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKCglpZiAoIWxwa2V5KQogICAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKCWxwa2V5LT5mbGFncyB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgoJaWYgKGxwc3pWYWx1ZU5hbWU9PU5VTEwpIHsKICAgICAgICAgICAgIC8qIFNldHMgdHlwZSBhbmQgbmFtZSBmb3Iga2V5J3MgdW5uYW1lZCBvciBkZWZhdWx0IHZhbHVlICovCgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCX0gZWxzZSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmICgJbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmCgkJCQkhbHN0cmNtcGlXKGxwc3pWYWx1ZU5hbWUsbHBrZXktPnZhbHVlc1tpXS5uYW1lKQoJCQkpCgkJCQlicmVhazsKCX0KCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewoJCWxwa2V5LT52YWx1ZXMgPSAoTFBLRVlWQUxVRSl4cmVhbGxvYygKCQkJCQlscGtleS0+dmFsdWVzLAoJCQkJCShscGtleS0+bnJvZnZhbHVlcysxKSpzaXplb2YoS0VZVkFMVUUpCgkJCQkpOwoJCWxwa2V5LT5ucm9mdmFsdWVzKys7CgkJbWVtc2V0KGxwa2V5LT52YWx1ZXMraSwnXDAnLHNpemVvZihLRVlWQUxVRSkpOwoJfQoJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkgewoJCWlmIChscHN6VmFsdWVOYW1lKQoJCQlscGtleS0+dmFsdWVzW2ldLm5hbWUgPSBzdHJkdXBXKGxwc3pWYWx1ZU5hbWUpOwoJCWVsc2UKCQkJbHBrZXktPnZhbHVlc1tpXS5uYW1lID0gTlVMTDsKCX0KCglpZiAoZHdUeXBlID09IFJFR19TWikKCSAgY2JEYXRhID0gMiAqIChsc3RybGVuVyAoKExQQ1dTVFIpbHBiRGF0YSkgKyAxKTsKCSAgCglscGtleS0+dmFsdWVzW2ldLmxlbgk9IGNiRGF0YTsKCWxwa2V5LT52YWx1ZXNbaV0udHlwZQk9IGR3VHlwZTsKCWlmIChscGtleS0+dmFsdWVzW2ldLmRhdGEgIT1OVUxMKQoJCWZyZWUobHBrZXktPnZhbHVlc1tpXS5kYXRhKTsKCWxwa2V5LT52YWx1ZXNbaV0uZGF0YQk9IChMUEJZVEUpeG1hbGxvYyhjYkRhdGEpOwoJbHBrZXktPnZhbHVlc1tpXS5sYXN0bW9kaWZpZWQgPSB0aW1lKE5VTEwpOwoJbWVtY3B5KGxwa2V5LT52YWx1ZXNbaV0uZGF0YSxscGJEYXRhLGNiRGF0YSk7CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWVFeDMyQSBbQURWQVBJMzIuMTY5XQogKgogKiBOT1RFUwogKiAgIHdpbjk1IGRvZXMgbm90IGNhcmUgYWJvdXQgY2JEYXRhIGZvciBSRUdfU1ogYW5kIGZpbmRzIG91dCB0aGUgbGVuIGJ5IGl0c2VsZiAoanMpIAogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXhBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6VmFsdWVOYW1lLAoJCQkgICAgIERXT1JEIGR3UmVzZXJ2ZWQsIERXT1JEIGR3VHlwZSwKCQkJICAgICBDT05TVCBCWVRFICpscGJEYXRhLCBEV09SRCBjYkRhdGEgKQp7CglMUEJZVEUJYnVmOwoJTFBXU1RSCWxwc3pWYWx1ZU5hbWVXOwoJRFdPUkQJcmV0OwoKCWlmICghbHBiRGF0YSkKCQlyZXR1cm4gKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKCQkKCVRSQUNFXyhyZWcpKCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsZHdUeXBlLGxwYkRhdGEsY2JEYXRhKTsKCglpZiAoKDE8PGR3VHlwZSkgJiBVTklDT05WTUFTSykgCgl7IGlmIChkd1R5cGUgPT0gUkVHX1NaKQoJICAgIGNiRGF0YSA9IHN0cmxlbiAoKExQQ1NUUilscGJEYXRhKSsxOwoKCSAgYnVmID0gKExQQllURSl4bWFsbG9jKCBjYkRhdGEgKjIgKTsKCSAgbG1lbWNweW5BdG9XICgoTFBWT0lEKWJ1ZiwgbHBiRGF0YSwgY2JEYXRhICk7CgkgIGNiRGF0YT0yKmNiRGF0YTsKCX0gCgllbHNlCgkgIGJ1Zj0oTFBCWVRFKWxwYkRhdGE7CgoJaWYgKGxwc3pWYWx1ZU5hbWUpCgkgIGxwc3pWYWx1ZU5hbWVXID0gc3RyZHVwQTJXKGxwc3pWYWx1ZU5hbWUpOwoJZWxzZQoJICBscHN6VmFsdWVOYW1lVyA9IE5VTEw7CgoJcmV0PVJlZ1NldFZhbHVlRXhXKGhrZXksbHBzelZhbHVlTmFtZVcsZHdSZXNlcnZlZCxkd1R5cGUsYnVmLGNiRGF0YSk7CgoJaWYgKGxwc3pWYWx1ZU5hbWVXKQoJICBmcmVlKGxwc3pWYWx1ZU5hbWVXKTsKCglpZiAoYnVmIT1scGJEYXRhKQoJICBmcmVlKGJ1Zik7CgoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWVFeDE2IFtLRVJORUwuMjI2XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXgxNiggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWVOYW1lLCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1R5cGUsIExQQllURSBscGJEYXRhLCBEV09SRCBjYkRhdGEgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlTmFtZSksCiAgICAgICAgICBkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YSk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVFeEEoIGhrZXksIGxwc3pWYWx1ZU5hbWUsIGR3UmVzZXJ2ZWQsIGR3VHlwZSwgbHBiRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYkRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWUzMlcJW0FEVkFQSTMyLjE3MV0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBscHN6RGF0YSwgRFdPUkQgY2JEYXRhICkKewoJSEtFWQl4aGtleTsKCURXT1JECXJldDsKCglUUkFDRV8ocmVnKSgiKCV4LCVzLCVsZCwlcywlbGQpXG4iLAoJCWhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxkd1R5cGUsZGVidWdzdHJfdyhscHN6RGF0YSksY2JEYXRhCgkpOwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQ9UmVnQ3JlYXRlS2V5Vyhoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXk9aGtleTsKCWlmIChkd1R5cGUhPVJFR19TWikgewoJCVRSQUNFXyhyZWcpKCJkd1R5cGU9JWxkIC0gQ2hhbmdpbmcgdG8gUkVHX1NaXG4iLGR3VHlwZSk7CgkJZHdUeXBlPVJFR19TWjsKCX0KCWlmIChjYkRhdGEhPTIqbHN0cmxlblcobHBzekRhdGEpKzIpIHsKCQlUUkFDRV8ocmVnKSgiTGVuPSVsZCAhPSBzdHJsZW4oJXMpKzE9JWQhXG4iLAoJCQljYkRhdGEsZGVidWdzdHJfdyhscHN6RGF0YSksMipsc3RybGVuVyhscHN6RGF0YSkrMgoJCSk7CgkJY2JEYXRhPTIqbHN0cmxlblcobHBzekRhdGEpKzI7Cgl9CglyZXQ9UmVnU2V0VmFsdWVFeFcoeGhrZXksTlVMTCwwLGR3VHlwZSwoTFBCWVRFKWxwc3pEYXRhLGNiRGF0YSk7CglpZiAoaGtleSE9eGhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWUzMkEgW0FEVkFQSTMyLjE2OF0KICoKICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBzekRhdGEsIERXT1JEIGNiRGF0YSApCnsKCURXT1JECXJldDsKCUhLRVkJeGhrZXk7CgoJVFJBQ0VfKHJlZykoIigleCwlcywlbGQsJXMsJWxkKVxuIixoa2V5LGxwc3pTdWJLZXksZHdUeXBlLGxwc3pEYXRhLGNiRGF0YSk7CglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldD1SZWdDcmVhdGVLZXkxNihoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXk9aGtleTsKCglpZiAoZHdUeXBlIT1SRUdfU1opIHsKCQlUUkFDRV8ocmVnKSgiZHdUeXBlPSVsZCFcbiIsZHdUeXBlKTsKCQlkd1R5cGU9UkVHX1NaOwoJfQoJaWYgKGNiRGF0YSE9c3RybGVuKGxwc3pEYXRhKSsxKQoJCWNiRGF0YT1zdHJsZW4obHBzekRhdGEpKzE7CglyZXQ9UmVnU2V0VmFsdWVFeEEoeGhrZXksTlVMTCwwLGR3VHlwZSwoTFBCWVRFKWxwc3pEYXRhLGNiRGF0YSk7CglpZiAoeGhrZXkhPWhrZXkpCgkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWUxNiBbS0VSTkVMLjIyMV0gW1NIRUxMLjVdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgRFdPUkQJZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwc3pEYXRhLCBEV09SRCBjYkRhdGEgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzLCVsZCwlcywlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxkd1R5cGUsCiAgICAgICAgICBkZWJ1Z3N0cl9hKGxwc3pEYXRhKSxjYkRhdGEpOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlQShoa2V5LGxwc3pTdWJLZXksZHdUeXBlLGxwc3pEYXRhLGNiRGF0YSk7Cn0KCgovKiAKICogS2V5IEVudW1lcmF0aW9uCiAqCiAqIENhbGxwYXRoOgogKiBSZWdFbnVtS2V5MTYgLT4gUmVnRW51bUtleTMyQSAtPiBSZWdFbnVtS2V5RXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdFbnVtS2V5MzJXICAgLT4gUmVnRW51bUtleUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleUV4MzJXIFtBRFZBUEkzMi4xMzldCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgW0ldIEhhbmRsZSB0byBrZXkgdG8gZW51bWVyYXRlCiAqICAgIGlTdWJLZXkgICAgICBbSV0gSW5kZXggb2Ygc3Via2V5IHRvIGVudW1lcmF0ZQogKiAgICBscHN6TmFtZSAgICAgW09dIEJ1ZmZlciBmb3Igc3Via2V5IG5hbWUKICogICAgbHBjY2hOYW1lICAgIFtPXSBTaXplIG9mIHN1YmtleSBidWZmZXIKICogICAgbHBkd1Jlc2VydmVkIFtJXSBSZXNlcnZlZAogKiAgICBscHN6Q2xhc3MgICAgW09dIEJ1ZmZlciBmb3IgY2xhc3Mgc3RyaW5nCiAqICAgIGxwY2NoQ2xhc3MgICBbT10gU2l6ZSBvZiBjbGFzcyBidWZmZXIKICogICAgZnQgICAgICAgICAgIFtPXSBUaW1lIGtleSBsYXN0IHdyaXR0ZW4gdG8KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5RXhXKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQV1NUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE5hbWUsIExQRFdPUkQgbHBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgbHBzekNsYXNzLCBMUERXT1JEIGxwY2NoQ2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFVElNRSAqZnQgKQp7CglMUEtFWVNUUlVDVAlscGtleSxscHhrZXk7CgogICAgVFJBQ0VfKHJlZykoIigleCwlbGQsJXAsJWxkLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsCiAgICAgICAgICAqbHBjY2hOYW1lLGxwZHdSZXNlcnZlZCxscHN6Q2xhc3MsbHBjY2hDbGFzcyxmdCk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJaWYgKCFscGtleS0+bmV4dHN1YikKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCWxweGtleT1scGtleS0+bmV4dHN1YjsKCiAgICAvKiBUcmF2ZXJzZSB0aGUgc3Via2V5cyAqLwoJd2hpbGUgKGlTdWJrZXkgJiYgbHB4a2V5KSB7CgkJaVN1YmtleS0tOwoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9CgoJaWYgKGlTdWJrZXkgfHwgIWxweGtleSkKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCWlmIChsc3RybGVuVyhscHhrZXktPmtleW5hbWUpKzE+KmxwY2NoTmFtZSkgewoJCSpscGNjaE5hbWUgPSBsc3RybGVuVyhscHhrZXktPmtleW5hbWUpKzE7CgkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCX0KCW1lbWNweShscHN6TmFtZSxscHhrZXktPmtleW5hbWUsbHN0cmxlblcobHB4a2V5LT5rZXluYW1lKSoyKzIpOwoKICAgICAgICBpZiAoKmxwY2NoTmFtZSkKICAgICAgICAgICAgKmxwY2NoTmFtZSA9IGxzdHJsZW5XKGxwc3pOYW1lKTsKCglpZiAobHBzekNsYXNzKSB7CgkJLyogRklYTUU6IHdoYXQgc2hvdWxkIHdlIHdyaXRlIGludG8gaXQ/ICovCgkJKmxwc3pDbGFzcwk9IDA7CgkJKmxwY2NoQ2xhc3MJPSAyOwoJfQoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXkzMlcgW0FEVkFQSTMyLjE0MF0KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5VyggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFdTVFIgbHBzek5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbHBjY2hOYW1lICkKewogICAgRklMRVRJTUUJZnQ7CgogICAgVFJBQ0VfKHJlZykoIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKICAgIHJldHVybiBSZWdFbnVtS2V5RXhXKGhrZXksaVN1YmtleSxscHN6TmFtZSwmbHBjY2hOYW1lLE5VTEwsTlVMTCxOVUxMLCZmdCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXlFeDMyQSBbQURWQVBJMzIuMTM4XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlFeEEoIEhLRVkgaGtleSwgRFdPUkQgaVN1YmtleSwgTFBTVFIgbHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hOYW1lLCBMUERXT1JEIGxwZHdSZXNlcnZlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGxwc3pDbGFzcywgTFBEV09SRCBscGNjaENsYXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRVRJTUUgKmZ0ICkKewoJRFdPUkQJcmV0LGxwY2NoTmFtZVcsbHBjY2hDbGFzc1c7CglMUFdTVFIJbHBzek5hbWVXLGxwc3pDbGFzc1c7CgoKCVRSQUNFXyhyZWcpKCIoJXgsJWxkLCVwLCVsZCwlcCwlcCwlcCwlcClcbiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLCpscGNjaE5hbWUsbHBkd1Jlc2VydmVkLGxwc3pDbGFzcyxscGNjaENsYXNzLGZ0CgkpOwoJaWYgKGxwc3pOYW1lKSB7CgkJbHBzek5hbWVXCT0gKExQV1NUUil4bWFsbG9jKCpscGNjaE5hbWUqMik7CgkJbHBjY2hOYW1lVwk9ICpscGNjaE5hbWU7Cgl9IGVsc2UgewoJCWxwc3pOYW1lVwk9IE5VTEw7CgkJbHBjY2hOYW1lVyAJPSAwOwoJfQoJaWYgKGxwc3pDbGFzcykgewoJCWxwc3pDbGFzc1cJCT0gKExQV1NUUil4bWFsbG9jKCpscGNjaENsYXNzKjIpOwoJCWxwY2NoQ2xhc3NXCT0gKmxwY2NoQ2xhc3M7Cgl9IGVsc2UgewoJCWxwc3pDbGFzc1cJPTA7CgkJbHBjY2hDbGFzc1c9MDsKCX0KCXJldD1SZWdFbnVtS2V5RXhXKAoJCWhrZXksCgkJaVN1YmtleSwKCQlscHN6TmFtZVcsCgkJJmxwY2NoTmFtZVcsCgkJbHBkd1Jlc2VydmVkLAoJCWxwc3pDbGFzc1csCgkJJmxwY2NoQ2xhc3NXLAoJCWZ0CgkpOwoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCWxzdHJjcHlXdG9BKGxwc3pOYW1lLGxwc3pOYW1lVyk7CgkJKmxwY2NoTmFtZT1zdHJsZW4obHBzek5hbWUpOwoJCWlmIChscHN6Q2xhc3NXKSB7CgkJCWxzdHJjcHlXdG9BKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCQkJKmxwY2NoQ2xhc3M9c3RybGVuKGxwc3pDbGFzcyk7CgkJfQoJfQoJaWYgKGxwc3pOYW1lVykKCQlmcmVlKGxwc3pOYW1lVyk7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleTMyQSBbQURWQVBJMzIuMTM3XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlBKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbHBjY2hOYW1lICkKewogICAgRklMRVRJTUUJZnQ7CgogICAgVFJBQ0VfKHJlZykoIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKICAgIHJldHVybiBSZWdFbnVtS2V5RXhBKCBoa2V5LCBpU3Via2V5LCBscHN6TmFtZSwgJmxwY2NoTmFtZSwgTlVMTCwgTlVMTCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAmZnQgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleTE2IFtTSEVMTC43XSBbS0VSTkVMLjIxNl0KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MTYoIEhLRVkgaGtleSwgRFdPUkQgaVN1YmtleSwgTFBTVFIgbHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGxwY2NoTmFtZSApCnsKICAgIFRSQUNFXyhyZWcpKCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZSk7CiAgICByZXR1cm4gUmVnRW51bUtleUEoIGhrZXksIGlTdWJrZXksIGxwc3pOYW1lLCBscGNjaE5hbWUpOwp9CgoKLyogCiAqIEVudW1lcmF0ZSBSZWdpc3RyeSBWYWx1ZXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0VudW1WYWx1ZTE2IC0+IFJlZ0VudW1WYWx1ZTMyQSAtPiBSZWdFbnVtVmFsdWUzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUzMlcgW0FEVkFQSTMyLjE0Ml0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgIFtJXSBIYW5kbGUgdG8ga2V5IHRvIHF1ZXJ5CiAqICAgIGlWYWx1ZSAgICAgIFtJXSBJbmRleCBvZiB2YWx1ZSB0byBxdWVyeQogKiAgICBscHN6VmFsdWUgICBbT10gVmFsdWUgc3RyaW5nCiAqICAgIGxwY2NoVmFsdWUgIFtJL09dIFNpemUgb2YgdmFsdWUgYnVmZmVyIChpbiB3Y2hhcnMpCiAqICAgIGxwZFJlc2VydmVkIFtJXSBSZXNlcnZlZAogKiAgICBscGR3VHlwZSAgICBbT10gVHlwZSBjb2RlCiAqICAgIGxwYkRhdGEgICAgIFtPXSBWYWx1ZSBkYXRhCiAqICAgIGxwY2JEYXRhICAgIFtJL09dIFNpemUgb2YgZGF0YSBidWZmZXIgKGluIGJ5dGVzKQogKgogKiBOb3RlOiAgd2lkZSBjaGFyYWN0ZXIgZnVuY3Rpb25zIHRoYXQgdGFrZSBhbmQvb3IgcmV0dXJuICJjaGFyYWN0ZXIgY291bnRzIgogKiAgdXNlIFRDSEFSICh0aGF0IGlzIHVuc2lnbmVkIHNob3J0IG9yIGNoYXIpIG5vdCBieXRlIGNvdW50cy4KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWVXKCBIS0VZIGhrZXksIERXT1JEIGlWYWx1ZSwgTFBXU1RSIGxwc3pWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaFZhbHVlLCBMUERXT1JEIGxwZFJlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKCVRSQUNFXyhyZWcpKCIoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlWYWx1ZSxkZWJ1Z3N0cl93KGxwc3pWYWx1ZSksCiAgICAgICAgICBscGNjaFZhbHVlLGxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEpOwoKCWxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKCQoJaWYgKCFscGNiRGF0YSAmJiBscGJEYXRhKQoJCXJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCQkKCWlmICghbHBrZXkpCgkJcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKCWlmIChscGtleS0+bnJvZnZhbHVlcyA8PSBpVmFsdWUpCgkJcmV0dXJuIEVSUk9SX05PX01PUkVfSVRFTVM7CgoJdmFsID0gJihscGtleS0+dmFsdWVzW2lWYWx1ZV0pOwoKCWlmICh2YWwtPm5hbWUpIHsKCSAgICAgICAgaWYgKGxzdHJsZW5XKHZhbC0+bmFtZSkrMT4qbHBjY2hWYWx1ZSkgewoJCQkqbHBjY2hWYWx1ZSA9IGxzdHJsZW5XKHZhbC0+bmFtZSkrMTsKCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQl9CgkJbWVtY3B5KGxwc3pWYWx1ZSx2YWwtPm5hbWUsMiAqIChsc3RybGVuVyh2YWwtPm5hbWUpKzEpICk7CgkJKmxwY2NoVmFsdWU9bHN0cmxlblcodmFsLT5uYW1lKTsKCX0gZWxzZSB7CgkJKmxwc3pWYWx1ZQk9IDA7CgkJKmxwY2NoVmFsdWUJPSAwOwoJfQoKCS8qIENhbiBiZSBOVUxMIGlmIHRoZSB0eXBlIGNvZGUgaXMgbm90IHJlcXVpcmVkICovCglpZiAobHBkd1R5cGUpCgkJKmxwZHdUeXBlID0gdmFsLT50eXBlOwoKCWlmIChscGJEYXRhKSB7CgkJaWYgKHZhbC0+bGVuPipscGNiRGF0YSkgewoJCQkqbHBjYkRhdGEgPSB2YWwtPmxlbjsKCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQl9CgkJbWVtY3B5KGxwYkRhdGEsdmFsLT5kYXRhLHZhbC0+bGVuKTsKCQkqbHBjYkRhdGEgPSB2YWwtPmxlbjsKCX0KCglkZWJ1Z19wcmludF92YWx1ZSAoIHZhbC0+ZGF0YSwgdmFsICk7CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bVZhbHVlMzJBIFtBRFZBUEkzMi4xNDFdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlQSggSEtFWSBoa2V5LCBEV09SRCBpVmFsdWUsIExQU1RSIGxwc3pWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaFZhbHVlLCBMUERXT1JEIGxwZFJlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUFdTVFIJbHBzelZhbHVlVzsKCUxQQllURQlscGJEYXRhVzsKCURXT1JECXJldCxscGNiRGF0YVc7CglEV09SRCBkd1R5cGU7CgoJVFJBQ0VfKHJlZykoIigleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLGhrZXksaVZhbHVlLGxwc3pWYWx1ZSxscGNjaFZhbHVlLAoJCWxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEpOwoKCWxwc3pWYWx1ZVcgPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoVmFsdWUqMik7CglpZiAobHBiRGF0YSkgewoJCWxwYkRhdGFXID0gKExQQllURSl4bWFsbG9jKCpscGNiRGF0YSoyKTsKCQlscGNiRGF0YVcgPSAqbHBjYkRhdGE7Cgl9IGVsc2UKCQlscGJEYXRhVyA9IE5VTEw7CgoJcmV0ID0gUmVnRW51bVZhbHVlVyggaGtleSwgaVZhbHVlLCBscHN6VmFsdWVXLCBscGNjaFZhbHVlLCAKCQkJCWxwZFJlc2VydmVkLCAmZHdUeXBlLCBscGJEYXRhVywgJmxwY2JEYXRhVyApOwoKCWlmIChscGR3VHlwZSkKCQkqbHBkd1R5cGUgPSBkd1R5cGU7CgoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCWxzdHJjcHlXdG9BKGxwc3pWYWx1ZSxscHN6VmFsdWVXKTsKCQlpZiAobHBiRGF0YSkgewoJCQlpZiAoKDE8PGR3VHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJbHN0cmNweVd0b0EobHBiRGF0YSwoTFBXU1RSKWxwYkRhdGFXKTsKCQkJfSBlbHNlIHsKCQkJCWlmIChscGNiRGF0YVcgPiAqbHBjYkRhdGEpIHsKCQkJCQkqbHBjYkRhdGEgPSBscGNiRGF0YVc7CgkJCQkJcmV0CT0gRVJST1JfTU9SRV9EQVRBOwoJCQkJfSBlbHNlCgkJCQkJbWVtY3B5KGxwYkRhdGEsbHBiRGF0YVcsbHBjYkRhdGFXKTsKCQkJfQoJCQkqbHBjYkRhdGEgPSBscGNiRGF0YVc7CgkJfQoJfQogICAgaWYgKGxwYkRhdGFXKSBmcmVlKGxwYkRhdGFXKTsKICAgIGlmIChscHN6VmFsdWVXKSBmcmVlKGxwc3pWYWx1ZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bVZhbHVlMTYgW0tFUk5FTC4yMjNdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMTYoIEhLRVkgaGtleSwgRFdPUkQgaVZhbHVlLCBMUFNUUiBscHN6VmFsdWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hWYWx1ZSwgTFBEV09SRCBscGRSZXNlcnZlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsCiAgICAgICAgICBscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhKTsKICAgIHJldHVybiBSZWdFbnVtVmFsdWVBKCBoa2V5LCBpVmFsdWUsIGxwc3pWYWx1ZSwgbHBjY2hWYWx1ZSwgbHBkUmVzZXJ2ZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBkd1R5cGUsIGxwYkRhdGEsIGxwY2JEYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nsb3NlS2V5IFtTSEVMTC4zXSBbS0VSTkVMLjIyMF0gW0FEVkFQSTMyLjEyNl0KICogUmVsZWFzZXMgdGhlIGhhbmRsZSBvZiB0aGUgc3BlY2lmaWVkIGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byBjbG9zZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0Nsb3NlS2V5KCBIS0VZIGhrZXkgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCV4KVxuIixoa2V5KTsKCiAgICAvKiBUaGUgc3RhbmRhcmQgaGFuZGxlcyBhcmUgYWxsb3dlZCB0byBzdWNjZWVkLCBldmVuIHRob3VnaCB0aGV5IGFyZSBub3QKICAgICAgIGNsb3NlZCAqLwogICAgaWYgKGlzX3N0YW5kYXJkX2hrZXkoaGtleSkpCiAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CgogICAgcmV0dXJuIHJlbW92ZV9oYW5kbGUoaGtleSk7Cn0KCgovKiAKICogRGVsZXRlIHJlZ2lzdHJ5IGtleQogKgogKiBDYWxscGF0aDoKICogUmVnRGVsZXRlS2V5MTYgLT4gUmVnRGVsZXRlS2V5MzJBIC0+IFJlZ0RlbGV0ZUtleTMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZUtleTMyVyBbQURWQVBJMzIuMTM0XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIHRvIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIE5hbWUgb2Ygc3Via2V5IHRvIGRlbGV0ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5ICkKewoJTFBLRVlTVFJVQ1QJKmxwbHBQcmV2S2V5LGxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSk7CgogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgLyogU3Via2V5IHBhcmFtIGNhbm5vdCBiZSBOVUxMICovCiAgICBpZiAoIWxwc3pTdWJLZXkgfHwgISpscHN6U3ViS2V5KQogICAgICAgIHJldHVybiBFUlJPUl9CQURLRVk7CgogICAgLyogV2UgbmVlZCB0byBrbm93IHRoZSBwcmV2aW91cyBrZXkgaW4gdGhlIGhpZXIuICovCglzcGxpdF9rZXlwYXRoKGxwc3pTdWJLZXksJndwcywmd3BjKTsKCWkgCT0gMDsKCWxweGtleQk9IGxwTmV4dEtleTsKCXdoaWxlIChpPHdwYy0xKSB7CgkJbHB4a2V5PWxwTmV4dEtleS0+bmV4dHN1YjsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCVRSQUNFXyhyZWcpKCIgIFNjYW5uaW5nIFslc11cbiIsCgkJCQkgICAgIGRlYnVnc3RyX3cobHB4a2V5LT5rZXluYW1lKSk7CgkJCWlmICghbHN0cmNtcGlXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KSB7CgkJCUZSRUVfS0VZX1BBVEg7CgkJCVRSQUNFXyhyZWcpKCIgIE5vdCBmb3VuZC5cbiIpOwoJCQkvKiBub3QgZm91bmQgaXMgc3VjY2VzcyAqLwoJCQlyZXR1cm4gRVJST1JfU1VDQ0VTUzsKCQl9CgkJaSsrOwoJCWxwTmV4dEtleQk9IGxweGtleTsKCX0KCWxweGtleQk9IGxwTmV4dEtleS0+bmV4dHN1YjsKCWxwbHBQcmV2S2V5ID0gJihscE5leHRLZXktPm5leHRzdWIpOwoJd2hpbGUgKGxweGtleSkgewoJCVRSQUNFXyhyZWcpKCIgIFNjYW5uaW5nIFslc11cbiIsCgkJCSAgICAgZGVidWdzdHJfdyhscHhrZXktPmtleW5hbWUpKTsKCQlpZiAoIWxzdHJjbXBpVyh3cHNbaV0sbHB4a2V5LT5rZXluYW1lKSkKCQkJYnJlYWs7CgkJbHBscFByZXZLZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJbHB4a2V5CQk9IGxweGtleS0+bmV4dDsKCX0KCglpZiAoIWxweGtleSkgewoJCUZSRUVfS0VZX1BBVEg7CgkJV0FSTl8ocmVnKSgiICBOb3QgZm91bmQuXG4iKTsKCQlyZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7Cgl9CgoJaWYgKGxweGtleS0+bmV4dHN1YikgewoJCUZSRUVfS0VZX1BBVEg7CgkJV0FSTl8ocmVnKSgiICBOb3QgZW1wdHkuXG4iKTsKCQlyZXR1cm4gRVJST1JfQ0FOVFdSSVRFOwoJfQoJKmxwbHBQcmV2S2V5CT0gbHB4a2V5LT5uZXh0OwoJZnJlZShscHhrZXktPmtleW5hbWUpOwoJaWYgKGxweGtleS0+Y2xhc3MpCgkJZnJlZShscHhrZXktPmNsYXNzKTsKCWlmIChscHhrZXktPnZhbHVlcykKCQlmcmVlKGxweGtleS0+dmFsdWVzKTsKCWZyZWUobHB4a2V5KTsKCUZSRUVfS0VZX1BBVEg7CglUUkFDRV8ocmVnKSgiICBEb25lLlxuIik7CglyZXR1cm4JRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlS2V5MzJBIFtBRFZBUEkzMi4xMzNdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSApCnsKICAgIExQV1NUUiBscHN6U3ViS2V5VzsKICAgIERXT1JEICByZXQ7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpKTsKICAgIGxwc3pTdWJLZXlXID0gbHBzelN1YktleT9zdHJkdXBBMlcobHBzelN1YktleSk6TlVMTDsKICAgIHJldCA9IFJlZ0RlbGV0ZUtleVcoIGhrZXksIGxwc3pTdWJLZXlXICk7CiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVLZXkxNiBbU0hFTEwuNF0gW0tFUk5FTC4yMTldCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXkgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkpOwogICAgcmV0dXJuIFJlZ0RlbGV0ZUtleUEoIGhrZXksIGxwc3pTdWJLZXkgKTsKfQoKCi8qIAogKiBEZWxldGUgcmVnaXN0cnkgdmFsdWUKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZVZhbHVlMTYgLT4gUmVnRGVsZXRlVmFsdWUzMkEgLT4gUmVnRGVsZXRlVmFsdWUzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVWYWx1ZTMyVyBbQURWQVBJMzIuMTM2XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgIFtJXQogKiAgICBscHN6VmFsdWUgW0ldCiAqCiAqIFJFVFVSTlMKICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6VmFsdWUgKQp7CglEV09SRAkJaTsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJTFBLRVlWQUxVRQl2YWw7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pWYWx1ZSkpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKCWlmIChscHN6VmFsdWUpIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKAlscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYKCQkJCSFsc3RyY21waVcobHBrZXktPnZhbHVlc1tpXS5uYW1lLGxwc3pWYWx1ZSkKCQkJKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9CgogICAgaWYgKGkgPT0gbHBrZXktPm5yb2Z2YWx1ZXMpCiAgICAgICAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoKCXZhbAk9IGxwa2V5LT52YWx1ZXMraTsKCWlmICh2YWwtPm5hbWUpIGZyZWUodmFsLT5uYW1lKTsKCWlmICh2YWwtPmRhdGEpIGZyZWUodmFsLT5kYXRhKTsKCW1lbWNweSgJCgkJbHBrZXktPnZhbHVlcytpLAoJCWxwa2V5LT52YWx1ZXMraSsxLAoJCXNpemVvZihLRVlWQUxVRSkqKGxwa2V5LT5ucm9mdmFsdWVzLWktMSkKCSk7CglscGtleS0+dmFsdWVzCT0gKExQS0VZVkFMVUUpeHJlYWxsb2MoCgkJCQlscGtleS0+dmFsdWVzLAoJCQkJKGxwa2V5LT5ucm9mdmFsdWVzLTEpKnNpemVvZihLRVlWQUxVRSkKCQkJKTsKCWxwa2V5LT5ucm9mdmFsdWVzLS07CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlVmFsdWUzMkEgW0FEVkFQSTMyLjEzNV0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pWYWx1ZSApCnsKICAgIExQV1NUUiBscHN6VmFsdWVXOwogICAgRFdPUkQgIHJldDsKCiAgICBUUkFDRV8ocmVnKSgiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlKSk7CiAgICBscHN6VmFsdWVXID0gbHBzelZhbHVlP3N0cmR1cEEyVyhscHN6VmFsdWUpOk5VTEw7CiAgICByZXQgPSBSZWdEZWxldGVWYWx1ZVcoIGhrZXksIGxwc3pWYWx1ZVcgKTsKICAgIGlmKGxwc3pWYWx1ZVcpIGZyZWUobHBzelZhbHVlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVWYWx1ZTE2IFtLRVJORUwuMjIyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlICkKewogICAgVFJBQ0VfKHJlZykoIigleCwlcylcbiIsIGhrZXksZGVidWdzdHJfYShscHN6VmFsdWUpKTsKICAgIHJldHVybiBSZWdEZWxldGVWYWx1ZUEoIGhrZXksIGxwc3pWYWx1ZSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdGbHVzaEtleSBbS0VSTkVMLjIyN10gW0FEVkFQSTMyLjE0M10KICogSW1tZWRpYXRlbHkgd3JpdGVzIGtleSB0byByZWdpc3RyeS4KICogT25seSByZXR1cm5zIGFmdGVyIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiB0byBkaXNrLgogKgogKiBGSVhNRTogZG9lcyBpdCByZWFsbHkgd2FpdCB1bnRpbCBkYXRhIGlzIHdyaXR0ZW4gPwogKgogKiBJIGd1ZXNzIHRoYXQgd2UgY2FuIHJlbW92ZSB0aGUgUkVHX09QVElPTl9UQUlOVEVEIGZsYWcgZnJvbSBldmVyeSBrZXkKICogd3JpdHRlbiBpZiB0aGlzIGZ1bmN0aW9uIHJlYWxseSB3b3JrcyAoYW5kIG9ubHkgaWYgISkuCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdyaXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkoIEhLRVkgaGtleSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFXyhyZWcpKCIoJXgpXG4iLCBoa2V5KTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9CQURLRVk7CgoJU0hFTExfU2F2ZVJlZ2lzdHJ5QnJhbmNoKGZpbmRfcm9vdF9rZXkobHBrZXkpLCBUUlVFKTsKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qIEZJWE1FOiBscGNjaFhYWFggLi4uIGlzIHRoaXMgY291bnRpbmcgaW4gV0NIQVJTIG9yIGluIEJZVEVzID8/ICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeUluZm9LZXkzMlcgW0FEVkFQSTMyLjE1M10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICAgICAgICAgW0ldIEhhbmRsZSB0byBrZXkgdG8gcXVlcnkKICogICAgbHBzekNsYXNzICAgICAgICAgICAgICBbT10gQnVmZmVyIGZvciBjbGFzcyBzdHJpbmcKICogICAgbHBjY2hDbGFzcyAgICAgICAgICAgICBbT10gU2l6ZSBvZiBjbGFzcyBzdHJpbmcgYnVmZmVyCiAqICAgIGxwZHdSZXNlcnZlZCAgICAgICAgICAgW0ldIFJlc2VydmVkCiAqICAgIGxwY1N1YktleXMgICAgICAgICAgICAgW0ldIEJ1ZmZlciBmb3IgbnVtYmVyIG9mIHN1YmtleXMKICogICAgbHBjY2hNYXhTdWJLZXkgICAgICAgICBbT10gQnVmZmVyIGZvciBsb25nZXN0IHN1YmtleSBuYW1lIGxlbmd0aAogKiAgICBscGNjaE1heENsYXNzICAgICAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3QgY2xhc3Mgc3RyaW5nIGxlbmd0aAogKiAgICBscGNWYWx1ZXMgICAgICAgICAgICAgIFtPXSBCdWZmZXIgZm9yIG51bWJlciBvZiB2YWx1ZSBlbnRyaWVzCiAqICAgIGxwY2NoTWF4VmFsdWVOYW1lICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCB2YWx1ZSBuYW1lIGxlbmd0aAogKiAgICBscGNjYk1heFZhbHVlRGF0YSAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3QgdmFsdWUgZGF0YSBsZW5ndGgKICogICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciBbT10gQnVmZmVyIGZvciBzZWN1cml0eSBkZXNjcmlwdG9yIGxlbmd0aAogKiAgICBmdAogKiAtIHdpbjk1IGFsbG93cyBscHN6Q2xhc3MgdG8gYmUgdmFsaWQgYW5kIGxwY2NoQ2xhc3MgdG8gYmUgTlVMTCAKICogLSB3aW5udCByZXR1cm5zIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSIGlmIGxwc3pDbGFzcyBpcyB2YWxpZCBhbmQKICogICBscGNjaENsYXNzIGlzIE5VTEwKICogLSBib3RoIGFsbG93IGxwc3pDbGFzcyB0byBiZSBOVUxMIGFuZCBscGNjaENsYXNzIHRvIGJlIE5VTEwgCiAqIChpdCdzIGhhcmQgdG8gdGVzdCB2YWxpZGl0eSwgc28gdGVzdCAhTlVMTCBpbnN0ZWFkKQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5SW5mb0tleVcoIEhLRVkgaGtleSwgTFBXU1RSIGxwc3pDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hDbGFzcywgTFBEV09SRCBscGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjU3ViS2V5cywgTFBEV09SRCBscGNjaE1heFN1YmtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE1heENsYXNzLCBMUERXT1JEIGxwY1ZhbHVlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE1heFZhbHVlTmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2JNYXhWYWx1ZURhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JTZWN1cml0eURlc2NyaXB0b3IsIEZJTEVUSU1FICpmdCApCnsKCUxQS0VZU1RSVUNUCWxwa2V5LGxweGtleTsKCWludAkJbnJvZmtleXMsbWF4c3Via2V5LG1heGNsYXNzLG1heHZuYW1lLG1heHZkYXRhOwoJaW50CQlpOwoKCVRSQUNFXyhyZWcpKCIoJXgsJXAsJWxkLCVwLCVwLCVwLCVwLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LCBscHN6Q2xhc3MsIGxwY2NoQ2xhc3M/KmxwY2NoQ2xhc3M6MCxscGR3UmVzZXJ2ZWQsCgkJbHBjU3ViS2V5cyxscGNjaE1heFN1YmtleSxscGNWYWx1ZXMsbHBjY2hNYXhWYWx1ZU5hbWUsCgkJbHBjY2JNYXhWYWx1ZURhdGEsbHBjYlNlY3VyaXR5RGVzY3JpcHRvcixmdAoJKTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCWlmIChscHN6Q2xhc3MpIHsKICAgCSAgICAgICAgaWYgKFZFUlNJT05fR2V0VmVyc2lvbigpID09IE5UNDAgJiYgbHBjY2hDbGFzcyA9PSBOVUxMKSB7CgkJICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCQl9CgkJLyogZWl0aGVyIGxwY2NoQ2xhc3MgaXMgdmFsaWQgb3IgdGhpcyBpcyB3aW45NSBhbmQgbHBjY2hDbGFzcwoJCSAgIGNvdWxkIGJlIGludmFsaWQgKi8KCQlpZiAobHBrZXktPmNsYXNzKSB7CgkJICAgICAgICBEV09SRCBjbGFzc0xlbiA9IGxzdHJsZW5XKGxwa2V5LT5jbGFzcyk7CgoJCQlpZiAobHBjY2hDbGFzcyAmJiBjbGFzc0xlbisxPipscGNjaENsYXNzKSB7CgkJCQkqbHBjY2hDbGFzcz1jbGFzc0xlbisxOwoJCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQkJfQoJCQlpZiAobHBjY2hDbGFzcykKCQkJICAgICpscGNjaENsYXNzPWNsYXNzTGVuOwoJCQltZW1jcHkobHBzekNsYXNzLGxwa2V5LT5jbGFzcywgY2xhc3NMZW4qMiArIDIpOwoJCX0gZWxzZSB7CgkJCSpscHN6Q2xhc3MJPSAwOwoJCQlpZiAobHBjY2hDbGFzcykKCQkJICAgICpscGNjaENsYXNzCT0gMDsKCQl9Cgl9IGVsc2UgewoJCWlmIChscGNjaENsYXNzKQoJCQkqbHBjY2hDbGFzcwk9IGxzdHJsZW5XKGxwa2V5LT5jbGFzcyk7Cgl9CglscHhrZXk9bHBrZXktPm5leHRzdWI7Cglucm9ma2V5cz1tYXhzdWJrZXk9bWF4Y2xhc3M9bWF4dm5hbWU9bWF4dmRhdGE9MDsKCXdoaWxlIChscHhrZXkpIHsKCQlucm9ma2V5cysrOwoJCWlmIChsc3RybGVuVyhscHhrZXktPmtleW5hbWUpPm1heHN1YmtleSkKCQkJbWF4c3Via2V5PWxzdHJsZW5XKGxweGtleS0+a2V5bmFtZSk7CgkJaWYgKGxweGtleS0+Y2xhc3MgJiYgbHN0cmxlblcobHB4a2V5LT5jbGFzcyk+bWF4Y2xhc3MpCgkJCW1heGNsYXNzPWxzdHJsZW5XKGxweGtleS0+Y2xhc3MpOwoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9Cglmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykgewoJCUxQS0VZVkFMVUUJdmFsPWxwa2V5LT52YWx1ZXMraTsKCgkJaWYgKHZhbC0+bmFtZSAmJiBsc3RybGVuVyh2YWwtPm5hbWUpPm1heHZuYW1lKQoJCQltYXh2bmFtZT1sc3RybGVuVyh2YWwtPm5hbWUpOwoJCWlmICh2YWwtPmxlbj5tYXh2ZGF0YSkKCQkJbWF4dmRhdGE9dmFsLT5sZW47Cgl9CglpZiAoIW1heGNsYXNzKSBtYXhjbGFzcwk9IDE7CglpZiAoIW1heHZuYW1lKSBtYXh2bmFtZQk9IDE7CglpZiAobHBjVmFsdWVzKQoJCSpscGNWYWx1ZXMJPSBscGtleS0+bnJvZnZhbHVlczsKCWlmIChscGNTdWJLZXlzKQoJCSpscGNTdWJLZXlzCT0gbnJvZmtleXM7CglpZiAobHBjY2hNYXhTdWJrZXkpCgkJKmxwY2NoTWF4U3Via2V5CT0gbWF4c3Via2V5OwoJaWYgKGxwY2NoTWF4Q2xhc3MpCgkJKmxwY2NoTWF4Q2xhc3MJPSBtYXhjbGFzczsKCWlmIChscGNjaE1heFZhbHVlTmFtZSkKCQkqbHBjY2hNYXhWYWx1ZU5hbWU9IG1heHZuYW1lOwoJaWYgKGxwY2NiTWF4VmFsdWVEYXRhKQoJCSpscGNjYk1heFZhbHVlRGF0YT0gbWF4dmRhdGE7CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlJbmZvS2V5MzJBIFtBRFZBUEkzMi4xNTJdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlJbmZvS2V5QSggSEtFWSBoa2V5LCBMUFNUUiBscHN6Q2xhc3MsIExQRFdPUkQgbHBjY2hDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBjU3ViS2V5cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE1heFN1YmtleSwgTFBEV09SRCBscGNjaE1heENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY1ZhbHVlcywgTFBEV09SRCBscGNjaE1heFZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjYk1heFZhbHVlRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwgRklMRVRJTUUgKmZ0ICkKewoJTFBXU1RSCQlscHN6Q2xhc3NXID0gTlVMTDsKCURXT1JECQlyZXQ7CgoJVFJBQ0VfKHJlZykoIigleCwlcCwlbGQsJXAsJXAsJXAsJXAsJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksIGxwc3pDbGFzcywgbHBjY2hDbGFzcz8qbHBjY2hDbGFzczowLGxwZHdSZXNlcnZlZCwKCQlscGNTdWJLZXlzLGxwY2NoTWF4U3Via2V5LGxwY1ZhbHVlcyxscGNjaE1heFZhbHVlTmFtZSwKCQlscGNjYk1heFZhbHVlRGF0YSxscGNiU2VjdXJpdHlEZXNjcmlwdG9yLGZ0CgkpOwoJaWYgKGxwc3pDbGFzcykgewoJCWlmIChscGNjaENsYXNzKSB7CgkJICAgIGxwc3pDbGFzc1cgID0gKExQV1NUUil4bWFsbG9jKCgqbHBjY2hDbGFzcykgKiAyKTsKCQl9IGVsc2UgaWYgKFZFUlNJT05fR2V0VmVyc2lvbigpID09IFdJTjk1KSB7CgkJICAgIC8qIHdpbjk1ICBhbGxvd3MgbHBjY2hDbGFzcyB0byBiZSBudWxsICovCgkJICAgIC8qIHdlIGRvbid0IGtub3cgaG93IGJpZyBscHN6Q2xhc3MgaXMsIHdvdWxkIAoJCSAgICAgICBNQVhfUEFUSE5BTUVfTEVOIGJlIHRoZSBjb3JyZWN0IGRlZmF1bHQ/ICovCgkJICAgIGxwc3pDbGFzc1cgID0gKExQV1NUUil4bWFsbG9jKE1BWF9QQVRITkFNRV9MRU4qMik7IAoJCX0KCgl9IGVsc2UKCQlscHN6Q2xhc3NXICA9IE5VTEw7CglyZXQ9UmVnUXVlcnlJbmZvS2V5VygKCQloa2V5LAoJCWxwc3pDbGFzc1csCgkJbHBjY2hDbGFzcywKCQlscGR3UmVzZXJ2ZWQsCgkJbHBjU3ViS2V5cywKCQlscGNjaE1heFN1YmtleSwKCQlscGNjaE1heENsYXNzLAoJCWxwY1ZhbHVlcywKCQlscGNjaE1heFZhbHVlTmFtZSwKCQlscGNjYk1heFZhbHVlRGF0YSwKCQlscGNiU2VjdXJpdHlEZXNjcmlwdG9yLAoJCWZ0CgkpOwoJaWYgKHJldD09RVJST1JfU1VDQ0VTUyAmJiBscHN6Q2xhc3MpCgkJbHN0cmNweVd0b0EobHBzekNsYXNzLGxwc3pDbGFzc1cpOwoJaWYgKGxwc3pDbGFzc1cpCgkJZnJlZShscHN6Q2xhc3NXKTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyVyBbQURWQVBJMzIuMTI4XQogKgogKiBQQVJBTVMKICogICAgbHBNYWNoaW5lTmFtZSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHJlbW90ZSBjb21wdXRlcgogKiAgICBoSGV5ICAgICAgICAgIFtJXSBQcmVkZWZpbmVkIHJlZ2lzdHJ5IGhhbmRsZQogKiAgICBwaGtSZXN1bHQgICAgIFtJXSBBZGRyZXNzIG9mIGJ1ZmZlciBmb3IgcmVtb3RlIHJlZ2lzdHJ5IGhhbmRsZQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5VyggTFBDV1NUUiBscE1hY2hpbmVOYW1lLCBIS0VZIGhLZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSBwaGtSZXN1bHQgKQp7CiAgICBUUkFDRV8ocmVnKSgiKCVzLCV4LCVwKTogc3R1YlxuIixkZWJ1Z3N0cl93KGxwTWFjaGluZU5hbWUpLGhLZXkscGhrUmVzdWx0KTsKCiAgICBpZiAoIWxwTWFjaGluZU5hbWUgfHwgISpscE1hY2hpbmVOYW1lKSB7CiAgICAgICAgLyogVXNlIHRoZSBsb2NhbCBtYWNoaW5lIG5hbWUgKi8KICAgICAgICByZXR1cm4gUmVnT3BlbktleTE2KCBoS2V5LCAiIiwgcGhrUmVzdWx0ICk7CiAgICB9CgogICAgRklYTUVfKHJlZykoIkNhbm5vdCBjb25uZWN0IHRvICVzXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSkpOwogICAgcmV0dXJuIEVSUk9SX0JBRF9ORVRQQVRIOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnkzMkEgW0FEVkFQSTMyLjEyN10KICovCkxPTkcgV0lOQVBJIFJlZ0Nvbm5lY3RSZWdpc3RyeUEoIExQQ1NUUiBtYWNoaW5lLCBIS0VZIGhrZXksIExQSEtFWSByZXNrZXkgKQp7CiAgICBEV09SRCByZXQ7CiAgICBMUFdTVFIgbWFjaGluZVcgPSBzdHJkdXBBMlcobWFjaGluZSk7CiAgICByZXQgPSBSZWdDb25uZWN0UmVnaXN0cnlXKCBtYWNoaW5lVywgaGtleSwgcmVza2V5ICk7CiAgICBmcmVlKG1hY2hpbmVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0dldEtleVNlY3VyaXR5IFtBRFZBUEkzMi4xNDRdCiAqIFJldHJpZXZlcyBhIGNvcHkgb2Ygc2VjdXJpdHkgZGVzY3JpcHRvciBwcm90ZWN0aW5nIHRoZSByZWdpc3RyeSBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICAgICAgICAgW0ldICAgT3BlbiBoYW5kbGUgb2Yga2V5IHRvIHNldAogKiAgICBTZWN1cml0eUluZm9ybWF0aW9uICAgIFtJXSAgIERlc2NyaXB0b3IgY29udGVudHMKICogICAgcFNlY3VyaXR5RGVzY3JpcHRvciAgICBbT10gICBBZGRyZXNzIG9mIGRlc2NyaXB0b3IgZm9yIGtleQogKiAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yIFtJL09dIEFkZHJlc3Mgb2Ygc2l6ZSBvZiBidWZmZXIgYW5kIGRlc2NyaXB0aW9uCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpMT05HIFdJTkFQSSBSZWdHZXRLZXlTZWN1cml0eSggSEtFWSBoa2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFQ1VSSVRZX0lORk9STUFUSU9OIFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU0VDVVJJVFlfREVTQ1JJUFRPUiBwU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0VfKHJlZykoIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LFNlY3VyaXR5SW5mb3JtYXRpb24scFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgIGxwY2JTZWN1cml0eURlc2NyaXB0b3I/KmxwY2JTZWN1cml0eURlc2NyaXB0b3I6MCk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgLyogRklYTUU6IENoZWNrIGZvciB2YWxpZCBTZWN1cml0eUluZm9ybWF0aW9uIHZhbHVlcyAqLwoKICAgIGlmICgqbHBjYlNlY3VyaXR5RGVzY3JpcHRvciA8IHNpemVvZihTRUNVUklUWV9ERVNDUklQVE9SKSkKICAgICAgICByZXR1cm4gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUjsKCiAgICBGSVhNRV8ocmVnKSgiKCV4LCVsZCwlcCwlbGQpOiBzdHViXG4iLGhrZXksU2VjdXJpdHlJbmZvcm1hdGlvbiwKICAgICAgICAgIHBTZWN1cml0eURlc2NyaXB0b3IsbHBjYlNlY3VyaXR5RGVzY3JpcHRvcj8qbHBjYlNlY3VyaXR5RGVzY3JpcHRvcjowKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTG9hZEtleTMyVyBbQURWQVBJMzIuPz8/XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkKICogICAgbHBzekZpbGUgICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgcmVnaXN0cnkgaW5mb3JtYXRpb24KICovCkxPTkcgV0lOQVBJIFJlZ0xvYWRLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBDV1NUUiBscHN6RmlsZSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGRlYnVnc3RyX3cobHBzekZpbGUpKTsKCiAgICAvKiBEbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSB8fCAhbHBzekZpbGUgfHwgISpscHN6RmlsZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUVfKHJlZykoIigleCwlcywlcyk6IHN0dWJcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLAogICAgICAgICAgZGVidWdzdHJfdyhscHN6RmlsZSkpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdMb2FkS2V5MzJBIFtBRFZBUEkzMi4/Pz9dCiAqLwpMT05HIFdJTkFQSSBSZWdMb2FkS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBDU1RSIGxwc3pGaWxlICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBzelN1YktleVcgPSBzdHJkdXBBMlcobHBzelN1YktleSk7CiAgICBMUFdTVFIgbHBzekZpbGVXID0gc3RyZHVwQTJXKGxwc3pGaWxlKTsKICAgIHJldCA9IFJlZ0xvYWRLZXlXKCBoa2V5LCBscHN6U3ViS2V5VywgbHBzekZpbGVXICk7CiAgICBpZihscHN6RmlsZVcpIGZyZWUobHBzekZpbGVXKTsKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlIFtBRFZBUEkzMi4/Pz9dCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgW0ldIEhhbmRsZSBvZiBrZXkgdG8gd2F0Y2gKICogICAgZldhdGNoU3ViVHJlZSAgIFtJXSBGbGFnIGZvciBzdWJrZXkgbm90aWZpY2F0aW9uCiAqICAgIGZkd05vdGlmeUZpbHRlciBbSV0gQ2hhbmdlcyB0byBiZSByZXBvcnRlZAogKiAgICBoRXZlbnQgICAgICAgICAgW0ldIEhhbmRsZSBvZiBzaWduYWxlZCBldmVudAogKiAgICBmQXN5bmMgICAgICAgICAgW0ldIEZsYWcgZm9yIGFzeW5jaHJvbm91cyByZXBvcnRpbmcKICovCkxPTkcgV0lOQVBJIFJlZ05vdGlmeUNoYW5nZUtleVZhbHVlKCBIS0VZIGhrZXksIEJPT0wgZldhdGNoU3ViVHJlZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBmZHdOb3RpZnlGaWx0ZXIsIEhBTkRMRSBoRXZlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIGZBc3luYyApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwogICAgVFJBQ0VfKHJlZykoIigleCwlaSwlbGQsJXgsJWkpXG4iLGhrZXksZldhdGNoU3ViVHJlZSxmZHdOb3RpZnlGaWx0ZXIsCiAgICAgICAgICBoRXZlbnQsZkFzeW5jKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRV8ocmVnKSgiKCV4LCVpLCVsZCwleCwlaSk6IHN0dWJcbiIsaGtleSxmV2F0Y2hTdWJUcmVlLGZkd05vdGlmeUZpbHRlciwKICAgICAgICAgIGhFdmVudCxmQXN5bmMpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXkzMlcgW0FEVkFQSTMyLjE3M10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBTdWJLZXkgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkgdG8gdW5sb2FkCiAqLwpMT05HIFdJTkFQSSBSZWdVbkxvYWRLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBTdWJLZXkgKQp7CiAgICBGSVhNRV8ocmVnKSgiKCV4LCVzKTogc3R1YlxuIixoa2V5LCBkZWJ1Z3N0cl93KGxwU3ViS2V5KSk7CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnVW5Mb2FkS2V5MzJBIFtBRFZBUEkzMi4xNzJdCiAqLwpMT05HIFdJTkFQSSBSZWdVbkxvYWRLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwU3ViS2V5VyA9IHN0cmR1cEEyVyhscFN1YktleSk7CiAgICByZXQgPSBSZWdVbkxvYWRLZXlXKCBoa2V5LCBscFN1YktleVcgKTsKICAgIGlmKGxwU3ViS2V5VykgZnJlZShscFN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0S2V5U2VjdXJpdHkgW0FEVkFQSTMyLjE2N10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldIE9wZW4gaGFuZGxlIG9mIGtleSB0byBzZXQKICogICAgU2VjdXJpdHlJbmZvICBbSV0gRGVzY3JpcHRvciBjb250ZW50cwogKiAgICBwU2VjdXJpdHlEZXNjIFtJXSBBZGRyZXNzIG9mIGRlc2NyaXB0b3IgZm9yIGtleQogKi8KTE9ORyBXSU5BUEkgUmVnU2V0S2V5U2VjdXJpdHkoIEhLRVkgaGtleSwgU0VDVVJJVFlfSU5GT1JNQVRJT04gU2VjdXJpdHlJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzYyApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJWxkLCVwKVxuIixoa2V5LFNlY3VyaXR5SW5mbyxwU2VjdXJpdHlEZXNjKTsKCiAgICAvKiBJdCBzZWVtcyB0byBwZXJmb3JtIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoKFNlY3VyaXR5SW5mbyAmIE9XTkVSX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBHUk9VUF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgREFDTF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgU0FDTF9TRUNVUklUWV9JTkZPUk1BVElPTikpIHsKICAgICAgICAvKiBQYXJhbSBPSyAqLwogICAgfSBlbHNlCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGlmICghcFNlY3VyaXR5RGVzYykKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUVfKHJlZykoIjooJXgsJWxkLCVwKTogc3R1YlxuIixoa2V5LFNlY3VyaXR5SW5mbyxwU2VjdXJpdHlEZXNjKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2F2ZUtleTMyVyBbQURWQVBJMzIuMTY2XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgIFtJXSBIYW5kbGUgb2Yga2V5IHdoZXJlIHNhdmUgYmVnaW5zCiAqICAgIGxwRmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSB0byBzYXZlIHRvCiAqICAgIHNhICAgICBbSV0gQWRkcmVzcyBvZiBzZWN1cml0eSBzdHJ1Y3R1cmUKICovCkxPTkcgV0lOQVBJIFJlZ1NhdmVLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIHNhICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0VfKHJlZykoIigleCwlcywlcClcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBGaWxlKSwgc2EpOwoKICAgIC8qIEl0IGFwcGVhcnMgdG8gZG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBGaWxlIHx8ICEqbHBGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRV8ocmVnKSgiKCV4LCVzLCVwKTogc3R1YlxuIiwgaGtleSwgZGVidWdzdHJfdyhscEZpbGUpLCBzYSk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NhdmVLZXkzMkEgW0FEVkFQSTMyLjE2NV0KICovCkxPTkcgV0lOQVBJIFJlZ1NhdmVLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscEZpbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgc2EgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscEZpbGVXID0gc3RyZHVwQTJXKGxwRmlsZSk7CiAgICByZXQgPSBSZWdTYXZlS2V5VyggaGtleSwgbHBGaWxlVywgc2EgKTsKICAgIGZyZWUobHBGaWxlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5MzJXIFtBRFZBUEkzMi4xNjRdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgIFtJXSBIYW5kbGUgb2Yga2V5IHdoZXJlIHJlc3RvcmUgYmVnaW5zCiAqICAgIGxwRmlsZSAgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgY29udGFpbmluZyBzYXZlZCB0cmVlCiAqICAgIGR3RmxhZ3MgW0ldIE9wdGlvbmFsIGZsYWdzCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJWxkKVxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBJdCBzZWVtcyB0byBkbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscEZpbGUgfHwgISpscEZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FXyhyZWcpKCIoJXgsJXMsJWxkKTogc3R1YlxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBDaGVjayBmb3IgZmlsZSBleGlzdGVuY2UgKi8KCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleTMyQSBbQURWQVBJMzIuMTYzXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVzdG9yZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwRmlsZVcgPSBzdHJkdXBBMlcobHBGaWxlKTsKICAgIHJldCA9IFJlZ1Jlc3RvcmVLZXlXKCBoa2V5LCBscEZpbGVXLCBkd0ZsYWdzICk7CiAgICBpZihscEZpbGVXKSBmcmVlKGxwRmlsZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleTMyVyBbQURWQVBJMzIuMTYyXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBTdWJLZXkgIFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5CiAqICAgIGxwTmV3RmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgZmlsZSB3aXRoIG5ldyBkYXRhCiAqICAgIGxwT2xkRmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgYmFja3VwIGZpbGUKICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBTdWJLZXksIExQQ1dTVFIgbHBOZXdGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIGxwT2xkRmlsZSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFXyhyZWcpKCIoJXgsJXMsJXMsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscFN1YktleSksCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRV8ocmVnKSgiKCV4LCVzLCVzLCVzKTogc3R1YlxuIiwgaGtleSwgZGVidWdzdHJfdyhscFN1YktleSksIAogICAgICAgICAgZGVidWdzdHJfdyhscE5ld0ZpbGUpLGRlYnVnc3RyX3cobHBPbGRGaWxlKSk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1JlcGxhY2VLZXkzMkEgW0FEVkFQSTMyLjE2MV0KICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSwgTFBDU1RSIGxwTmV3RmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGxwT2xkRmlsZSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwU3ViS2V5VyA9IHN0cmR1cEEyVyhscFN1YktleSk7CiAgICBMUFdTVFIgbHBOZXdGaWxlVyA9IHN0cmR1cEEyVyhscE5ld0ZpbGUpOwogICAgTFBXU1RSIGxwT2xkRmlsZVcgPSBzdHJkdXBBMlcobHBPbGRGaWxlKTsKICAgIHJldCA9IFJlZ1JlcGxhY2VLZXlXKCBoa2V5LCBscFN1YktleVcsIGxwTmV3RmlsZVcsIGxwT2xkRmlsZVcgKTsKICAgIGZyZWUobHBPbGRGaWxlVyk7CiAgICBmcmVlKGxwTmV3RmlsZVcpOwogICAgZnJlZShscFN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoK