LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL2ZjbnRsLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8cHdkLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmUvd2luZXN0cmluZy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJ4bWFsbG9jLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbnZlcnNpb24uaCIKCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChyZWcpCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChzdHJpbmcpCgpzdGF0aWMgdm9pZCBSRUdJU1RSWV9Jbml0KHZvaWQpOwovKiBGSVhNRTogZm9sbG93aW5nIGRlZmluZXMgc2hvdWxkIGJlIGNvbmZpZ3VyZWQgZ2xvYmFsIC4uLiAqLwoKLyogTk9URTogZG8gbm90IGFwcGVuZCBhIC8uIGxpbnV4JyBta2RpcigpIFdJTEwgRkFJTCBpZiB5b3UgZG8gdGhhdCAqLwojZGVmaW5lIFdJTkVfUFJFRklYICAgICAgICAgICAgICAgICAiLy53aW5lIgojZGVmaW5lIFNBVkVfVVNFUlNfREVGQVVMVCAgICAgICAgICAiL3Vzci9sb2NhbC9ldGMvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUICAiL3Vzci9sb2NhbC9ldGMvd2luZS5zeXN0ZW1yZWciCgovKiByZWxhdGl2ZSBpbiB+dXNlci8ud2luZS8gOiAqLwojZGVmaW5lIFNBVkVfQ1VSUkVOVF9VU0VSICAgICAgICAgICAidXNlci5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUICAgICJ3aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FICAgICAgICAgICJzeXN0ZW0ucmVnIgoKI2RlZmluZSBLRVlfUkVHSVNUUlkgICAgICAgICAgICAgICAgIlNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeSIKI2RlZmluZSBWQUxfU0FWRVVQREFURUQgICAgICAgICAgICAgIlNhdmVPbmx5VXBkYXRlZEtleXMiCgovKiBvbmUgdmFsdWUgb2YgYSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZVkFMVUUKewogICAgTFBXU1RSICAgbmFtZTsgICAgICAgICAgLyogbmFtZSBvZiB2YWx1ZSAoVU5JQ09ERSkgb3IgTlVMTCBmb3Igd2luMzEgKi8KICAgIERXT1JEICAgIHR5cGU7ICAgICAgICAgIC8qIHR5cGUgb2YgdmFsdWUgKi8KICAgIERXT1JEICAgIGxlbjsgICAgICAgICAgIC8qIGxlbmd0aCBvZiBkYXRhIGluIEJZVEVzICovCiAgICBEV09SRCAgICBsYXN0bW9kaWZpZWQ7ICAvKiB0aW1lIG9mIHNlY29uZHMgc2luY2UgMS4xLjE5NzAgKi8KICAgIExQQllURSAgIGRhdGE7ICAgICAgICAgIC8qIGNvbnRlbnQsIG1heSBiZSBzdHJpbmdzLCBiaW5hcmllcywgZXRjLiAqLwp9IEtFWVZBTFVFLCpMUEtFWVZBTFVFOwoKLyogYSByZWdpc3RyeSBrZXkgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnS0VZU1RSVUNUCnsKICAgIExQV1NUUiAgICAgICAgICAgICAgIGtleW5hbWU7ICAgICAgIC8qIG5hbWUgb2YgVEhJUyBrZXkgKFVOSUNPREUpICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBmbGFnczsgICAgICAgICAvKiBmbGFncy4gKi8KICAgIExQV1NUUiAgICAgICAgICAgICAgIGNsYXNzOwogICAgLyogdmFsdWVzICovCiAgICBEV09SRCAgICAgICAgICAgICAgICBucm9mdmFsdWVzOyAgICAvKiBuciBvZiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIExQS0VZVkFMVUUgICAgICAgICAgIHZhbHVlczsgICAgICAgIC8qIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgLyoga2V5IG1hbmFnZW1lbnQgcG9pbnRlcnMgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHQ7ICAgICAgICAgIC8qIG5leHQga2V5IG9uIHNhbWUgaGllcmFyY2h5ICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0c3ViOyAgICAgICAvKiBrZXlzIHRoYXQgaGFuZyBiZWxvdyBUSElTIGtleSAqLwp9IEtFWVNUUlVDVCwgKkxQS0VZU1RSVUNUOwoKCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jbGFzc2VzX3Jvb3Q9TlVMTDsJLyogd2luZG93cyAzLjEgZ2xvYmFsIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF91c2VyPU5VTEw7CS8qIHVzZXIgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9sb2NhbF9tYWNoaW5lPU5VTEw7LyogbWFjaGluZSBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3VzZXJzPU5VTEw7CS8qIGFsbCB1c2Vycz8gKi8KCi8qIGR5bmFtaWMsIG5vdCBzYXZlZCAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfcGVyZm9ybWFuY2VfZGF0YT1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY3VycmVudF9jb25maWc9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2R5bl9kYXRhPU5VTEw7CgovKiB3aGF0IHZhbHVldHlwZXMgZG8gd2UgbmVlZCB0byBjb252ZXJ0PyAqLwojZGVmaW5lIFVOSUNPTlZNQVNLCSgoMTw8UkVHX1NaKXwoMTw8UkVHX01VTFRJX1NaKXwoMTw8UkVHX0VYUEFORF9TWikpCgoKc3RhdGljIHN0cnVjdCBvcGVuaGFuZGxlIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJSEtFWQkJaGtleTsKCVJFR1NBTQkJYWNjZXNzbWFzazsKfSAgKm9wZW5oYW5kbGVzPU5VTEw7CnN0YXRpYyBpbnQJbnJvZm9wZW5oYW5kbGVzPTA7Ci8qIFN0YXJ0cyBhZnRlciAxIGJlY2F1c2UgMCwxIGFyZSByZXNlcnZlZCBmb3IgV2luMTYgKi8KLyogTm90ZTogU2hvdWxkIGFsd2F5cyBiZSBldmVuLCBhcyBXaW45NSBBRFZBUEkzMi5ETEwgcmVzZXJ2ZXMgb2RkCiAgICAgICAgIEhLRVlzIGZvciByZW1vdGUgcmVnaXN0cnkgYWNjZXNzICovCnN0YXRpYyBpbnQJY3VycmVudGhhbmRsZT0yOwoKCi8qCiAqIFFVRVNUSU9OCiAqICAgQXJlIHRoZXNlIGRvaW5nIHRoZSBzYW1lIGFzIEhFQVBfc3RyZHVwQXRvVyBhbmQgSEVBUF9zdHJkdXBXdG9BPwogKiAgIElmIHNvLCBjYW4gd2UgcmVtb3ZlIHRoZW0/CiAqIEFOU1dFUgogKiAgIE5vLCB0aGUgbWVtb3J5IGhhbmRsaW5nIGZ1bmN0aW9ucyBhcmUgY2FsbGVkIHZlcnkgb2Z0ZW4gaW4gaGVyZSwgCiAqICAganVzdCByZXBsYWNpbmcgdGhlbSBieSBIZWFwQWxsb2MoU3lzdGVtSGVhcCwuLi4pIG1ha2VzIHJlZ2lzdHJ5CiAqICAgbG9hZGluZyAxMDAgdGltZXMgc2xvd2VyLiAtTU0KICovCnN0YXRpYyBMUFdTVFIgc3RyZHVwQTJXKExQQ1NUUiBzcmMpCnsKICAgIGlmKHNyYykgewoJTFBXU1RSIGRlc3Q9eG1hbGxvYygyKnN0cmxlbihzcmMpKzIpOwoJbHN0cmNweUF0b1coZGVzdCxzcmMpOwoJcmV0dXJuIGRlc3Q7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIExQV1NUUiBzdHJkdXBXKExQQ1dTVFIgYSkgewoJTFBXU1RSCWI7CglpbnQJbGVuOwoKICAgIGlmKGEpIHsKCWxlbj1zaXplb2YoV0NIQVIpKihsc3RybGVuVyhhKSsxKTsKCWI9KExQV1NUUil4bWFsbG9jKGxlbik7CgltZW1jcHkoYixhLGxlbik7CglyZXR1cm4gYjsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgpMUFdTVFIgc3RyY3Z0QTJXKExQQ1NUUiBzcmMsIGludCBuY2hhcnMpCgp7CiAgIExQV1NUUiBkZXN0ID0geG1hbGxvYyAoMiAqIG5jaGFycyArIDIpOwoKICAgbHN0cmNweW5BdG9XKGRlc3Qsc3JjLG5jaGFycysxKTsKICAgZGVzdFtuY2hhcnNdID0gMDsKICAgcmV0dXJuIGRlc3Q7Cn0KLyoKICogd2UgbmVlZCB0byBjb252ZXJ0IEEgdG8gVyB3aXRoICdcMCcgaW4gc3RyaW5ncyAoTVVMVElfU1opIAogKi8KCnN0YXRpYyBMUFdTVFIgIGxtZW1jcHluQXRvVyggTFBXU1RSIGRzdCwgTFBDU1RSIHNyYywgSU5UIG4gKQp7CUxQV1NUUiBwID0gZHN0OwoKCVRSQUNFKHJlZywiXCIlc1wiICVpXG4iLHNyYywgbik7CgoJd2hpbGUgKG4tLSA+IDApICpwKysgPSAoV0NIQVIpKHVuc2lnbmVkIGNoYXIpKnNyYysrOwoKCXJldHVybiBkc3Q7Cn0Kc3RhdGljIExQU1RSIGxtZW1jcHluV3RvQSggTFBTVFIgZHN0LCBMUENXU1RSIHNyYywgSU5UIG4gKQp7CUxQU1RSIHAgPSBkc3Q7CgoJVFJBQ0Uoc3RyaW5nLCJMXCIlc1wiICVpXG4iLGRlYnVnc3RyX3coc3JjKSwgbik7CgoJd2hpbGUgKG4tLSA+IDApICpwKysgPSAoQ0hBUikqc3JjKys7CgoJcmV0dXJuIGRzdDsKfQoKc3RhdGljIHZvaWQgZGVidWdfcHJpbnRfdmFsdWUgKExQQllURSBscGJEYXRhLCBMUEtFWVZBTFVFIGtleSkKewogIGlmIChUUkFDRV9PTihyZWcpICYmIGxwYkRhdGEpIAogIHsgCiAgICBzd2l0Y2goa2V5LT50eXBlKQogICAgeyAKICAgICAgY2FzZSBIRVhfUkVHX0VYUEFORF9TWjoKICAgICAgY2FzZSBIRVhfUkVHX1NaOgogICAgICBjYXNlIFJFR19TWjoKICAgICAgICBUUkFDRShyZWcsIiBWYWx1ZSAlcywgRGF0YShzeik9JXNcbiIsIAogICAgICAgICAgZGVidWdzdHJfdyhrZXktPm5hbWUpLCAKICAgICAgICAgIGRlYnVnc3RyX3coKExQQ1dTVFIpbHBiRGF0YSkpOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBIRVhfUkVHX0RXT1JEOgogICAgICBjYXNlIFJFR19EV09SRDoKICAgICAgICBUUkFDRShyZWcsIiBWYWx1ZSAlcywgRGF0YShkd29yZCk9MHglMDhseFxuIiwKICAgICAgICAgIGRlYnVnc3RyX3coa2V5LT5uYW1lKSwgCiAgICAgICAgICAoRFdPUkQpKmxwYkRhdGEpOwogICAgICAgIGJyZWFrOwogICAgCiAgICAgIGNhc2UgSEVYX1JFR19NVUxUSV9TWjoKICAgICAgY2FzZSBSRUdfTVVMVElfU1o6CiAgICAgIHsgCiAgICAgICAgaW50IGk7CiAgICAgICAgTFBDV1NUUiBwdHIgPSAoTFBDV1NUUilscGJEYXRhOwogICAgICAgIGZvciAoaT0wO3B0clswXTtpKyspCiAgICAgICAgeyAKICAgICAgICAgIFRSQUNFKHJlZywgIiBWYWx1ZSAlcywgTVVMVElfU1ooJWk9JXMpXG4iLCAKICAgICAgICAgICAgZGVidWdzdHJfdyhrZXktPm5hbWUpLCAKICAgICAgICAgICAgaSwgCiAgICAgICAgICAgIGRlYnVnc3RyX3cocHRyKSk7CgogICAgICAgICAgcHRyICs9IGxzdHJsZW5XKHB0cikrMTsKICAgICAgICB9CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgICBjYXNlIEhFWF9SRUdfTk9ORToKICAgICAgY2FzZSBIRVhfUkVHX0JJTkFSWToKICAgICAgY2FzZSBIRVhfUkVHX0xJTks6CiAgICAgIGNhc2UgSEVYX1JFR19SRVNPVVJDRV9MSVNUOgogICAgICBjYXNlIEhFWF9SRUdfRlVMTF9SRVNPVVJDRV9ERVNDUklQVE9SOgogICAgICBjYXNlIFJFR19OT05FOgogICAgICBjYXNlIFJFR19MSU5LOgogICAgICBjYXNlIFJFR19SRVNPVVJDRV9MSVNUOgogICAgICBjYXNlIFJFR19GVUxMX1JFU09VUkNFX0RFU0NSSVBUT1I6CiAgICAgIGNhc2UgUkVHX0JJTkFSWToKICAgICAgeyAKICAgICAgICBjaGFyIHN6VGVtcFsxMDBdOyAgICAgIC8qIDMqMzIgKyAzICsgMSAqLwogICAgICAgIGludCBpOwogICAgICAgIGZvciAoIGkgPSAwOyBpIDwga2V5LT5sZW4gOyBpKyspICAgICAgCiAgICAgICAgeyAKICAgICAgICAgIHNwcmludGYgKCYoc3pUZW1wW2kqM10pLCIlMDJ4ICIsIGxwYkRhdGFbaV0pOwogICAgICAgICAgaWYgKGk+PTMxKQogICAgICAgICAgeyAKICAgICAgICAgICAgc3ByaW50ZiAoJihzelRlbXBbaSozKzNdKSwiLi4uIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBUUkFDRShyZWcsIiBWYWx1ZSAlcywgRGF0YShyYXcpPSglcylcbiIsIAogICAgICAgICAgZGVidWdzdHJfdyhrZXktPm5hbWUpLCAKICAgICAgICAgIHN6VGVtcCk7ICAgICAgICAgICAgICAgICAgCiAgICAgIH0KICAgICAgYnJlYWs7CiAgICAKICAgICAgZGVmYXVsdDoKICAgICAgICBGSVhNRShyZWcsICIgVmFsdWUgJXMsIFVua25vd24gZGF0YSB0eXBlICVsZFxuIiwgCiAgICAgICAgICBkZWJ1Z3N0cl93KGtleS0+bmFtZSksIAogICAgICAgICAga2V5LT50eXBlKTsKICAgIH0gLyogc3dpdGNoICovCiAgfSAvKiBpZiAqLwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBpc19zdGFuZGFyZF9oa2V5IFtJbnRlcm5hbF0KICogRGV0ZXJtaW5lcyBpZiBhIGhrZXkgaXMgYSBzdGFuZGFyZCBrZXkKICovCnN0YXRpYyBCT09MIGlzX3N0YW5kYXJkX2hrZXkoIEhLRVkgaGtleSApCnsKICAgIHN3aXRjaChoa2V5KSB7CiAgICAgICAgY2FzZSAweDAwMDAwMDAwOgogICAgICAgIGNhc2UgMHgwMDAwMDAwMToKICAgICAgICBjYXNlIEhLRVlfQ0xBU1NFU19ST09UOgogICAgICAgIGNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKICAgICAgICBjYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgogICAgICAgIGNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgogICAgICAgIGNhc2UgSEtFWV9VU0VSUzoKICAgICAgICBjYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKICAgICAgICBjYXNlIEhLRVlfRFlOX0RBVEE6CiAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBhZGRfaGFuZGxlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIGFkZF9oYW5kbGUoIEhLRVkgaGtleSwgTFBLRVlTVFJVQ1QgbHBrZXksIFJFR1NBTSBhY2Nlc3NtYXNrICkKewogICAgaW50IGk7CgogICAgVFJBQ0UocmVnLCIoMHgleCwlcCwweCVseClcbiIsaGtleSxscGtleSxhY2Nlc3NtYXNrKTsKICAgIC8qIENoZWNrIGZvciBkdXBsaWNhdGVzICovCiAgICBmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspIHsKICAgICAgICBpZiAob3BlbmhhbmRsZXNbaV0ubHBrZXk9PWxwa2V5KSB7CiAgICAgICAgICAgIC8qIFRoaXMgaXMgbm90IHJlYWxseSBhbiBlcnJvciAtIHRoZSB1c2VyIGlzIGFsbG93ZWQgdG8gY3JlYXRlCiAgICAgICAgICAgICAgIHR3byAob3IgbW9yZSkgaGFuZGxlcyB0byB0aGUgc2FtZSBrZXkgKi8KICAgICAgICAgICAgLypXQVJOKHJlZywgIkFkZGluZyBrZXkgJXAgdHdpY2VcbiIsbHBrZXkpOyovCiAgICAgICAgfQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KSB7CiAgICAgICAgICAgIFdBUk4ocmVnLCAiQWRkaW5nIGhhbmRsZSAleCB0d2ljZVxuIixoa2V5KTsKICAgICAgICB9CiAgICB9CiAgICBvcGVuaGFuZGxlcz14cmVhbGxvYyggb3BlbmhhbmRsZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcysxKSk7CgogICAgb3BlbmhhbmRsZXNbaV0ubHBrZXkgPSBscGtleTsKICAgIG9wZW5oYW5kbGVzW2ldLmhrZXkgPSBoa2V5OwogICAgb3BlbmhhbmRsZXNbaV0uYWNjZXNzbWFzayA9IGFjY2Vzc21hc2s7CiAgICBucm9mb3BlbmhhbmRsZXMrKzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZ2V0X2hhbmRsZSBbSW50ZXJuYWxdCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogUG9pbnRlciB0byBrZXkKICogICAgRmFpbHVyZTogTlVMTAogKi8Kc3RhdGljIExQS0VZU1RSVUNUIGdldF9oYW5kbGUoIEhLRVkgaGtleSApCnsKICAgIGludCBpOwoKICAgIGZvciAoaT0wOyBpPG5yb2ZvcGVuaGFuZGxlczsgaSsrKQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5ID09IGhrZXkpCiAgICAgICAgICAgIHJldHVybiBvcGVuaGFuZGxlc1tpXS5scGtleTsKICAgIFdBUk4ocmVnLCAiQ291bGQgbm90IGZpbmQgaGFuZGxlIDB4JXhcbiIsaGtleSk7CiAgICByZXR1cm4gTlVMTDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogcmVtb3ZlX2hhbmRsZSBbSW50ZXJuYWxdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHJlbW92ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRVJST1JfSU5WQUxJRF9IQU5ETEUKICovCnN0YXRpYyBEV09SRCByZW1vdmVfaGFuZGxlKCBIS0VZIGhrZXkgKQp7CiAgICBpbnQgaTsKCiAgICBmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspCiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpCiAgICAgICAgICAgIGJyZWFrOwoKICAgIGlmIChpID09IG5yb2ZvcGVuaGFuZGxlcykgewogICAgICAgIFdBUk4ocmVnLCAiQ291bGQgbm90IGZpbmQgaGFuZGxlIDB4JXhcbiIsaGtleSk7CiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwogICAgfQoKICAgIG1lbWNweSggb3BlbmhhbmRsZXMraSwKICAgICAgICAgICAgb3BlbmhhbmRsZXMraSsxLAogICAgICAgICAgICBzaXplb2Yoc3RydWN0IG9wZW5oYW5kbGUpKihucm9mb3BlbmhhbmRsZXMtaS0xKQogICAgKTsKICAgIG9wZW5oYW5kbGVzPXhyZWFsbG9jKG9wZW5oYW5kbGVzLHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy0xKSk7CiAgICBucm9mb3BlbmhhbmRsZXMtLTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGxvb2t1cF9oa2V5IFtJbnRlcm5hbF0KICogCiAqIEp1c3QgYXMgdGhlIG5hbWUgc2F5cy4gQ3JlYXRlcyB0aGUgcm9vdCBrZXlzIG9uIGRlbWFuZCwgc28gd2UgY2FuIGNhbGwgdGhlCiAqIFJlZyogZnVuY3Rpb25zIGF0IGFueSB0aW1lLgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFBvaW50ZXIgdG8ga2V5IHN0cnVjdHVyZQogKiAgICBGYWlsdXJlOiBOVUxMCiAqLwojZGVmaW5lIEFERF9ST09UX0tFWSh4eCkgXAoJeHggPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7XAoJbWVtc2V0KHh4LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpO1wKCXh4LT5rZXluYW1lPSBzdHJkdXBBMlcoIjxzaG91bGRfbm90X2FwcGVhcl9hbnl3aGVyZT4iKTsKCnN0YXRpYyBMUEtFWVNUUlVDVCBsb29rdXBfaGtleSggSEtFWSBoa2V5ICkKewogIHN3aXRjaCAoaGtleSkgewogIC8qIDAgYW5kIDEgYXJlIHZhbGlkIHJvb3RrZXlzIGluIHdpbjE2IHNoZWxsLmRsbCBhbmQgYXJlIHVzZWQgYnkKICAgKiBzb21lIHByb2dyYW1zLiBEbyBub3QgcmVtb3ZlIHRob3NlIGNhc2VzLiAtTU0KICAgKi8KIAljYXNlIDB4MDAwMDAwMDA6CiAgY2FzZSAweDAwMDAwMDAxOgogIGNhc2UgSEtFWV9DTEFTU0VTX1JPT1Q6IAogIHsKICAgIGlmICgha2V5X2NsYXNzZXNfcm9vdCkgCiAgICB7CiAgICAgIEhLRVkJY2xfcl9oa2V5OwoKICAgICAgLyogY2FsbHMgbG9va3VwX2hrZXkgcmVjdXJzaXZlbHksIFRXSUNFICovCiAgICAgIGlmICggUmVnQ3JlYXRlS2V5MTYoCiAgICAgICAgICAgIEhLRVlfTE9DQUxfTUFDSElORSwKICAgICAgICAgICAgIlNPRlRXQVJFXFxDbGFzc2VzIiwKICAgICAgICAgICAgJmNsX3JfaGtleSkgIT0gRVJST1JfU1VDQ0VTUykgCiAgICAgIHsKICAgICAgICBFUlIoIAogICAgICAgICAgcmVnLAogICAgICAgICAgIkNvdWxkIG5vdCBjcmVhdGUgSEtMTVxcU09GVFdBUkVcXENsYXNzZXMuIFRoaXMgaXMgaW1wb3NzaWJsZS5cbiIpOwogICAgICAgIGV4aXQoMSk7CiAgICAgIH0KCiAgICAgIGtleV9jbGFzc2VzX3Jvb3QgPSBsb29rdXBfaGtleShjbF9yX2hrZXkpOwogICAgfQogICAgcmV0dXJuIGtleV9jbGFzc2VzX3Jvb3Q7CiAgfQoKICBjYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgogICAgaWYgKCFrZXlfY3VycmVudF91c2VyKSB7CiAgICAgIEFERF9ST09UX0tFWShrZXlfY3VycmVudF91c2VyKTsKICAgIH0KICAgIHJldHVybiBrZXlfY3VycmVudF91c2VyOwoKICBjYXNlIEhLRVlfTE9DQUxfTUFDSElORToKICAgIGlmICgha2V5X2xvY2FsX21hY2hpbmUpIHsKICAgICAgQUREX1JPT1RfS0VZKGtleV9sb2NhbF9tYWNoaW5lKTsKICAgICAgUkVHSVNUUllfSW5pdCgpOwogICAgfQogICAgcmV0dXJuIGtleV9sb2NhbF9tYWNoaW5lOwoKICBjYXNlIEhLRVlfVVNFUlM6CiAgICBpZiAoIWtleV91c2VycykgewogICAgICBBRERfUk9PVF9LRVkoa2V5X3VzZXJzKTsKICAgIH0KICAgIHJldHVybiBrZXlfdXNlcnM7CgogIGNhc2UgSEtFWV9QRVJGT1JNQU5DRV9EQVRBOgogICAgaWYgKCFrZXlfcGVyZm9ybWFuY2VfZGF0YSkgewogICAgICBBRERfUk9PVF9LRVkoa2V5X3BlcmZvcm1hbmNlX2RhdGEpOwogICAgfQogICAgcmV0dXJuIGtleV9wZXJmb3JtYW5jZV9kYXRhOwoKICBjYXNlIEhLRVlfRFlOX0RBVEE6CiAgICBpZiAoIWtleV9keW5fZGF0YSkgewogICAgICBBRERfUk9PVF9LRVkoa2V5X2R5bl9kYXRhKTsKICAgIH0KICAgIHJldHVybiBrZXlfZHluX2RhdGE7CgogIGNhc2UgSEtFWV9DVVJSRU5UX0NPTkZJRzoKICAgIGlmICgha2V5X2N1cnJlbnRfY29uZmlnKSB7CiAgICAgIEFERF9ST09UX0tFWShrZXlfY3VycmVudF9jb25maWcpOwogICAgfQogICAgcmV0dXJuIGtleV9jdXJyZW50X2NvbmZpZzsKCiAgZGVmYXVsdDoKICAgIHJldHVybiBnZXRfaGFuZGxlKGhrZXkpOwoKICB9CiAgLypOT1RSRUFDSEVEKi8KfQojdW5kZWYgQUREX1JPT1RfS0VZCi8qIHNvIHdlIGRvbid0IGFjY2lkZW50bHkgYWNjZXNzIHRoZW0gLi4uICovCiNkZWZpbmUga2V5X2N1cnJlbnRfY29uZmlnIE5VTEwgTlVMTAojZGVmaW5lIGtleV9jdXJyZW50X3VzZXIgTlVMTCBOVUxMCiNkZWZpbmUga2V5X3VzZXJzIE5VTEwgTlVMTAojZGVmaW5lIGtleV9sb2NhbF9tYWNoaW5lIE5VTEwgTlVMTAojZGVmaW5lIGtleV9jbGFzc2VzX3Jvb3QgTlVMTCBOVUxMCiNkZWZpbmUga2V5X2R5bl9kYXRhIE5VTEwgTlVMTAojZGVmaW5lIGtleV9wZXJmb3JtYW5jZV9kYXRhIE5VTEwgTlVMTAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBzcGxpdF9rZXlwYXRoIFtJbnRlcm5hbF0KICogc3BsaXRzIHRoZSB1bmljb2RlIHN0cmluZyAnd3AnIGludG8gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KICogdGhlIGFycmF5IGlzIGFsbG9jYXRlZCBieSB0aGlzIGZ1bmN0aW9uLiAKICogRnJlZSB0aGUgYXJyYXkgdXNpbmcgRlJFRV9LRVlfUEFUSAogKgogKiBQQVJBTVMKICogICAgd3AgIFtJXSBTdHJpbmcgdG8gc3BsaXQgdXAKICogICAgd3B2IFtPXSBBcnJheSBvZiBwb2ludGVycyB0byBzdHJpbmdzCiAqICAgIHdwYyBbT10gTnVtYmVyIG9mIGNvbXBvbmVudHMKICovCnN0YXRpYyB2b2lkIHNwbGl0X2tleXBhdGgoIExQQ1dTVFIgd3AsIExQV1NUUiAqKndwdiwgaW50ICp3cGMpCnsKICAgIGludAlpLGosbGVuOwogICAgTFBXU1RSIHdzOwoKICAgIFRSQUNFKHJlZywiKCVzLCVwLCVwKVxuIixkZWJ1Z3N0cl93KHdwKSx3cHYsd3BjKTsKCiAgICB3cwk9IEhFQVBfc3RyZHVwVyggU3lzdGVtSGVhcCwgMCwgd3AgKTsKCiAgICAvKiBXZSBrbm93IHdlIGhhdmUgYXQgbGVhc3Qgb25lIHN1YnN0cmluZyAqLwogICAgKndwYyA9IDE7CgogICAgLyogUmVwbGFjZSBlYWNoIGJhY2tzbGFzaCB3aXRoIE5VTEwsIGFuZCBpbmNyZW1lbnQgdGhlIGNvdW50ICovCiAgICBmb3IgKGk9MDt3c1tpXTtpKyspIHsKICAgICAgICBpZiAod3NbaV09PSdcXCcpIHsKICAgICAgICAgICAgd3NbaV09MDsKICAgICAgICAgICAgKCp3cGMpKys7CiAgICAgICAgfQogICAgfQoKICAgIGxlbiA9IGk7CgogICAgLyogQWxsb2NhdGUgdGhlIHNwYWNlIGZvciB0aGUgYXJyYXkgb2YgcG9pbnRlcnMsIGxlYXZpbmcgcm9vbSBmb3IgdGhlCiAgICAgICBOVUxMIGF0IHRoZSBlbmQgKi8KICAgICp3cHYgPSAoTFBXU1RSKilIZWFwQWxsb2MoIFN5c3RlbUhlYXAsIDAsIHNpemVvZihMUFdTVFIpKigqd3BjKzIpKTsKICAgICgqd3B2KVswXT0gd3M7CgogICAgLyogQXNzaWduIGVhY2ggcG9pbnRlciB0byB0aGUgYXBwcm9wcmlhdGUgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcgKi8KICAgIGogPSAxOwogICAgZm9yIChpPTE7aTxsZW47aSsrKQogICAgICAgIGlmICh3c1tpLTFdPT0wKSB7CiAgICAgICAgICAgICgqd3B2KVtqKytdPXdzK2k7CiAgICAgICAgICAgIC8qIFRSQUNFKHJlZywgIiBTdWJpdGVtICVkID0gJXNcbiIsai0xLGRlYnVnc3RyX3coKCp3cHYpW2otMV0pKTsgKi8KICAgICAgICB9CgogICAgKCp3cHYpW2pdPU5VTEw7Cn0KI2RlZmluZSBGUkVFX0tFWV9QQVRIIEhlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHNbMF0pO0hlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHMpOwoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSRUdJU1RSWV9Jbml0IFtJbnRlcm5hbF0KICogUmVnaXN0cnkgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBzb21lIGRlZmF1bHQga2V5cy4gCiAqLwpzdGF0aWMgdm9pZCBSRUdJU1RSWV9Jbml0KHZvaWQpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJVFJBQ0UocmVnLCIodm9pZClcbiIpOwoKCVJlZ0NyZWF0ZUtleTE2KEhLRVlfRFlOX0RBVEEsIlBlcmZTdGF0c1xcU3RhdERhdGEiLCZoa2V5KTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKICAgICAgICAvKiBUaGlzIHdhcyBhbiBPcGVuLCBidXQgc2luY2UgaXQgaXMgY2FsbGVkIGJlZm9yZSB0aGUgcmVhbCByZWdpc3RyaWVzCiAgICAgICAgICAgYXJlIGxvYWRlZCwgaXQgd2FzIGNoYW5nZWQgdG8gYSBDcmVhdGUgLSBNVEIgOTgwNTA3Ki8KCVJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXhBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3cgTlRcXEN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRCdWlsZE51bWJlcgoJICoJCQkJCQlDdXJyZW50VHlwZQoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3duZXIKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE9yZ2FuaXphdGlvbgoJICoKCSAqLwoJLyogU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXFNOTVBcXFBhcmFtZXRlcnNcXFJGQzExNTZBZ2VudAoJICogCQkJCQlzdHJpbmcJU3lzQ29udGFjdAoJICogCQkJCQlzdHJpbmcJU3lzTG9jYXRpb24KCSAqIAkJCQkJCVN5c1NlcnZpY2VzCgkgKi8JCQkJCQkKCWlmICgtMSE9Z2V0aG9zdG5hbWUoYnVmLDIwMCkpIHsKCQlSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXENvbnRyb2xcXENvbXB1dGVyTmFtZVxcQ29tcHV0ZXJOYW1lIiwmaGtleSk7CgkJUmVnU2V0VmFsdWVFeDE2KGhrZXksIkNvbXB1dGVyTmFtZSIsMCxSRUdfU1osYnVmLHN0cmxlbihidWYpKzEpOwoJCVJlZ0Nsb3NlS2V5KGhrZXkpOwoJfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKiBTQVZFIFJlZ2lzdHJ5IEZ1bmN0aW9uICoqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIFJFR0lTVFJZX1NBVkVfVkVSU0lPTgkweDAwMDAwMDAxCgovKiBSZWdpc3RyeSBzYXZlZm9ybWF0OgogKiBJZiB5b3UgY2hhbmdlIGl0LCBpbmNyZWFzZSBhYm92ZSBudW1iZXIgYnkgMSwgd2hpY2ggd2lsbCBmbHVzaAogKiBvbGQgcmVnaXN0cnkgZGF0YWJhc2UgZmlsZXMuCiAqIAogKiBHbG9iYWw6CiAqIAkiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIgogKiAJc3Via2V5cy4uLi4KICogU3Via2V5czoKICogCWtleW5hbWUKICoJCXZhbHVlbmFtZT1sYXN0bW9kaWZpZWQsdHlwZSxkYXRhCiAqCQkuLi4KICoJCXN1YmtleXMKICoJLi4uCiAqIGtleW5hbWUsdmFsdWVuYW1lLHN0cmluZ2RhdGE6CiAqCXRoZSB1c3VhbCBhc2NpaSBjaGFyYWN0ZXJzIGZyb20gMHgwMC0weGZmICh3ZWxsLCBub3QgMHgwMCkKICoJYW5kIFx1WFhYWCBhcyBVTklDT0RFIHZhbHVlIFhYWFggd2l0aCBYWFhYPjB4ZmYKICoJKCAiPVxcXHQiIGVzY2FwZWQgaW4gXHVYWFhYIGZvcm0uKQogKiB0eXBlLGxhc3Rtb2RpZmllZDogCiAqCWludAogKiAKICogRklYTUU6IGRvZXNuJ3Qgc2F2ZSAnY2xhc3MnICh3aGF0IGRvZXMgaXQgbWVhbiBhbnl3YXk/KSwgbm9yIGZsYWdzLgogKgogKiBbSEtFWV9DVVJSRU5UX1VTRVJcXFNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeV0KICogU2F2ZU9ubHlVcGRhdGVkS2V5cz15ZXMKICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlX2NoZWNrX3RhaW50ZWQgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfc2F2ZV9jaGVja190YWludGVkKCBMUEtFWVNUUlVDVCBscGtleSApCnsKCWludAkJdGFpbnRlZDsKCglpZiAoIWxwa2V5KQoJCXJldHVybiAwOwoJaWYgKGxwa2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkKCQl0YWludGVkID0gMTsKCWVsc2UKCQl0YWludGVkID0gMDsKCXdoaWxlIChscGtleSkgewoJCWlmIChfc2F2ZV9jaGVja190YWludGVkKGxwa2V5LT5uZXh0c3ViKSkgewoJCQlscGtleS0+ZmxhZ3MgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoJCQl0YWludGVkID0gMTsKCQl9CgkJbHBrZXkJPSBscGtleS0+bmV4dDsKCX0KCXJldHVybiB0YWludGVkOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlX1VTVFJJTkcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3NhdmVfVVNUUklORyggRklMRSAqRiwgTFBXU1RSIHdzdHIsIGludCBlc2NhcGVlcSApCnsKCUxQV1NUUglzOwoJaW50CWRvZXNjYXBlOwoKCWlmICh3c3RyPT1OVUxMKQoJCXJldHVybjsKCXM9d3N0cjsKCXdoaWxlICgqcykgewoJCWRvZXNjYXBlPTA7CgkJaWYgKCpzPjB4ZmYpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoKnM9PSdcbicpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoZXNjYXBlZXEgJiYgKnM9PSc9JykKCQkJZG9lc2NhcGUgPSAxOwoJCWlmICgqcz09J1xcJykKICAgICAgICAgICAgICAgICAgICAgICAgZnB1dGMoKnMsRik7IC8qIGlmIFxcIHRoZW4gcHV0IGl0IHR3aWNlLiAqLwoJCWlmIChkb2VzY2FwZSkKCQkJZnByaW50ZihGLCJcXHUlMDR4IiwqKCh1bnNpZ25lZCBzaG9ydCopcykpOwoJCWVsc2UKCQkJZnB1dGMoKnMsRik7CgkJcysrOwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlc3Via2V5IFtJbnRlcm5hbF0KICoKICogTk9URVMKICogIFJFR19NVUxUSV9TWiBpcyBoYW5kbGVkIGFzIGJpbmFyeSAobGlrZSBpbiB3aW45NSkgKGpzKQogKi8Kc3RhdGljIGludCBfc2F2ZXN1YmtleSggRklMRSAqRiwgTFBLRVlTVFJVQ1QgbHBrZXksIGludCBsZXZlbCwgaW50IGFsbCApCnsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJaSx0YWJzLGo7CgoJbHB4a2V5CT0gbHBrZXk7Cgl3aGlsZSAobHB4a2V5KSB7CgkJaWYgKAkhKGxweGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1ZPTEFUSUxFKSAmJgoJCQkoYWxsIHx8IChscHhrZXktPmZsYWdzICYgUkVHX09QVElPTl9UQUlOVEVEKSkKCQkpIHsKCQkJZm9yICh0YWJzPWxldmVsO3RhYnMtLTspCgkJCQlmcHV0YygnXHQnLEYpOwoJCQlfc2F2ZV9VU1RSSU5HKEYsbHB4a2V5LT5rZXluYW1lLDEpOwoJCQlmcHV0cygiXG4iLEYpOwoJCQlmb3IgKGk9MDtpPGxweGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQkJCUxQS0VZVkFMVUUJdmFsPWxweGtleS0+dmFsdWVzK2k7CgoJCQkJZm9yICh0YWJzPWxldmVsKzE7dGFicy0tOykKCQkJCQlmcHV0YygnXHQnLEYpOwoJCQkJX3NhdmVfVVNUUklORyhGLHZhbC0+bmFtZSwwKTsKCQkJCWZwdXRjKCc9JyxGKTsKCQkJCWZwcmludGYoRiwiJWxkLCVsZCwiLHZhbC0+dHlwZSx2YWwtPmxhc3Rtb2RpZmllZCk7CgkJCQlpZiAoIHZhbC0+dHlwZSA9PSBSRUdfU1ogfHwgdmFsLT50eXBlID09IFJFR19FWFBBTkRfU1ogKQoJCQkJCV9zYXZlX1VTVFJJTkcoRiwoTFBXU1RSKXZhbC0+ZGF0YSwwKTsKCQkJCWVsc2UKCQkJCQlmb3IgKGo9MDtqPHZhbC0+bGVuO2orKykKCQkJCQkJZnByaW50ZihGLCIlMDJ4IiwqKCh1bnNpZ25lZCBjaGFyKil2YWwtPmRhdGEraikpOwoJCQkJZnB1dHMoIlxuIixGKTsKCQkJfQoJCQkvKiBkZXNjZW5kIHJlY3Vyc2l2ZWx5ICovCgkJCWlmICghX3NhdmVzdWJrZXkoRixscHhrZXktPm5leHRzdWIsbGV2ZWwrMSxhbGwpKQoJCQkJcmV0dXJuIDA7CgkJfQoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9CglyZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVzdWJyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfc2F2ZXN1YnJlZyggRklMRSAqRiwgTFBLRVlTVFJVQ1QgbHBrZXksIGludCBhbGwgKQp7CglmcHJpbnRmKEYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZFxuIixSRUdJU1RSWV9TQVZFX1ZFUlNJT04pOwoJX3NhdmVfY2hlY2tfdGFpbnRlZChscGtleS0+bmV4dHN1Yik7CglyZXR1cm4gX3NhdmVzdWJrZXkoRixscGtleS0+bmV4dHN1YiwwLGFsbCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlcmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBCT09MIF9zYXZlcmVnKCBMUEtFWVNUUlVDVCBscGtleSwgY2hhciAqZm4sIGludCBhbGwgKQp7CglGSUxFCSpGOwoKCUY9Zm9wZW4oZm4sInciKTsKCWlmIChGPT1OVUxMKSB7CgkJV0FSTihyZWcsIkNvdWxkbid0IG9wZW4gJXMgZm9yIHdyaXRpbmc6ICVzXG4iLAoJCQlmbixzdHJlcnJvcihlcnJubykKCQkpOwoJCXJldHVybiBGQUxTRTsKCX0KCWlmICghX3NhdmVzdWJyZWcoRixscGtleSxhbGwpKSB7CgkJZmNsb3NlKEYpOwoJCXVubGluayhmbik7CgkJV0FSTihyZWcsIkZhaWxlZCB0byBzYXZlIGtleXMsIHBlcmhhcHMgbm8gbW9yZSBkaXNrc3BhY2UgZm9yICVzP1xuIixmbik7CgkJcmV0dXJuIEZBTFNFOwoJfQoJZmNsb3NlKEYpOwogICAgICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEVMTF9TYXZlUmVnaXN0cnkgW0ludGVybmFsXQogKi8Kdm9pZCBTSEVMTF9TYXZlUmVnaXN0cnkoIHZvaWQgKQp7CgljaGFyICAgKmZuOwoJc3RydWN0IHBhc3N3ZAkqcHdkOwoJY2hhciAgIGJ1Zls0XTsKCUhLRVkgICBoa2V5OwoJaW50ICAgIGFsbDsKCWludCAgICB1c2VkQ2ZnVXNlciA9IDA7CglpbnQgICAgdXNlZENmZ0xNICAgPSAwOwoKICBUUkFDRShyZWcsIih2b2lkKVxuIik7CgoJYWxsPTA7CglpZiAoUmVnT3BlbktleTE2KEhLRVlfQ1VSUkVOVF9VU0VSLEtFWV9SRUdJU1RSWSwmaGtleSkhPUVSUk9SX1NVQ0NFU1MpIAogIHsKCQlzdHJjcHkoYnVmLCJ5ZXMiKTsKCX0gCiAgZWxzZSAKICB7CgkJRFdPUkQgbGVuLGp1bmssdHlwZTsKCgkJbGVuPTQ7CgkJaWYgKAkoRVJST1JfU1VDQ0VTUyE9UmVnUXVlcnlWYWx1ZUV4QSgKICAgICAgICAgICAgICAgICAgICAgCQkJCWhrZXksCiAgICAgICAgICAgICAgICAgICAgIAkJCQlWQUxfU0FWRVVQREFURUQsCiAgICAgICAgICAgICAgICAgICAgIAkJCQkmanVuaywKICAgICAgICAgICAgICAgICAgICAgCQkJCSZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAJCQkJYnVmLAogICAgICAgICAgICAgICAgICAgICAJCQkJJmxlbikpIHx8ICh0eXBlIT1SRUdfU1opKQogICAgewoJCQlzdHJjcHkoYnVmLCJ5ZXMiKTsKICAgIH0KCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KCglpZiAobHN0cmNtcGlBKGJ1ZiwieWVzIikpCgkJYWxsPTE7CgoJcHdkPWdldHB3dWlkKGdldHVpZCgpKTsKCWlmICggKHB3ZCE9TlVMTCkgJiYgKHB3ZC0+cHdfZGlyIT1OVUxMKSkKICB7CiAgICBjaGFyICp0bXA7CiAgICAvKiAKICAgICAqIFNhdmUgSEtFWV9DVVJSRU5UX1VTRVIgCiAgICAgKiBUcnkgZmlyc3Qgc2F2aW5nIGFjY29yZGluZyB0byB0aGUgZGVmaW5lZCBsb2NhdGlvbiBpbiAud2luZXJjCiAgICAgKi8KICAJZm4gPSB4bWFsbG9jKCBNQVhfUEFUSE5BTUVfTEVOICk7IAogIAlpZiAoUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nICgKICAgICAgICAgICJSZWdpc3RyeSIsIAogICAgICAgICAgIlVzZXJGaWxlTmFtZSIsIAogICAgICAgICAgIiIsIAogICAgICAgICAgZm4sIAogICAgICAgICAgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKSAKICAgIHsKICAJICBfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUiksZm4sYWxsKTsKICAJICB1c2VkQ2ZnVXNlciA9IDE7CiAgCX0KICAJZnJlZSAoZm4pOwoKICAgIGlmICh1c2VkQ2ZnVXNlciAhPSAxKQogICAgewogIAkJZm49KGNoYXIqKXhtYWxsb2MoIAogICAgICAgICAgICAgICAgICBzdHJsZW4ocHdkLT5wd19kaXIpICsgCiAgICAgICAgICAgICAgICAgIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICBzdHJsZW4oU0FWRV9DVVJSRU5UX1VTRVIpICsgMiApOwoKICAJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CiAgCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgpOwogIAogIAkJLyogY3JlYXRlIHRoZSBkaXJlY3RvcnkuIGRvbid0IGNhcmUgYWJvdXQgZXJyb3Jjb2Rlcy4gKi8KICAJCW1rZGlyKGZuLDA3NTUpOyAvKiBkcnd4ci14ci14ICovCiAgCQlzdHJjYXQoZm4sIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwogIAogIAkJdG1wID0gKGNoYXIqKXhtYWxsb2Moc3RybGVuKGZuKStzdHJsZW4oIi50bXAiKSsxKTsKICAJCXN0cmNweSh0bXAsZm4pOwogICAgICBzdHJjYXQodG1wLCIudG1wIik7CiAgCiAgCQlpZiAoX3NhdmVyZWcobG9va3VwX2hrZXkoSEtFWV9DVVJSRU5UX1VTRVIpLHRtcCxhbGwpKSB7CiAgCQkJaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewogIAkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKICAJCQkJdW5saW5rKHRtcCk7CiAgCQkJfQogIAkJfQogIAkJZnJlZSh0bXApOwogIAkJZnJlZShmbik7CiAgICB9CgogICAgLyogCiAgICAgKiBTYXZlIEhLRVlfTE9DQUxfTUFDSElORQogICAgICogVHJ5IGZpcnN0IHNhdmluZyBhY2NvcmRpbmcgdG8gdGhlIGRlZmluZWQgbG9jYXRpb24gaW4gLndpbmVyYwogICAgICovCiAgICBmbiA9IHhtYWxsb2MgKCBNQVhfUEFUSE5BTUVfTEVOKTsKICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcgKAogICAgICAgICAgIlJlZ2lzdHJ5IiwgCiAgICAgICAgICAiTG9jYWxNYWNoaW5lRmlsZU5hbWUiLCAKICAgICAgICAgICIiLCAKICAgICAgICAgIGZuLCAKICAgICAgICAgIE1BWF9QQVRITkFNRV9MRU4gLSAxKSkKICAgIHsKICAgICAgX3NhdmVyZWcobG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSwgZm4sIGFsbCk7CiAgICAgIHVzZWRDZmdMTSA9IDE7CiAgICB9CiAgCWZyZWUgKGZuKTsKCiAgICBpZiAoIHVzZWRDZmdMTSAhPSAxKQogICAgewogIAkJZm49KGNoYXIqKXhtYWxsb2MoCiAgICAgICAgICAgICAgICAgIHN0cmxlbihwd2QtPnB3X2RpcikrCiAgICAgICAgICAgICAgICAgIHN0cmxlbihXSU5FX1BSRUZJWCkrCiAgICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwogIAogIAkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKICAJCXN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfTUFDSElORSk7CiAgCiAgCQl0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwogIAkJc3RyY3B5KHRtcCxmbik7CiAgICAgIHN0cmNhdCh0bXAsIi50bXAiKTsKICAKICAJCWlmIChfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpLHRtcCxhbGwpKSB7CiAgCQkJaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewogIAkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKICAJCQkJdW5saW5rKHRtcCk7CiAgCQkJfQogIAkJfQogIAkJZnJlZSh0bXApOwogIAkJZnJlZShmbik7CiAgICB9CgogICAgLyogCiAgICAgKiBTYXZlIEhLRVlfVVNFUlMKICAgICAqLwogICAgZm49KGNoYXIqKXhtYWxsb2MoCiAgICAgICAgICAgICAgICBzdHJsZW4ocHdkLT5wd19kaXIpKwogICAgICAgICAgICAgICAgc3RybGVuKFdJTkVfUFJFRklYKSsKICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpKzIpOwoKICAgIHN0cmNweShmbixwd2QtPnB3X2Rpcik7CiAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpOwoKICAgIHRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CiAgICBzdHJjcHkodG1wLGZuKTtzdHJjYXQodG1wLCIudG1wIik7CiAgICBpZiAoIF9zYXZlcmVnKGxvb2t1cF9oa2V5KEhLRVlfVVNFUlMpLHRtcCxGQUxTRSkpIHsKICAgICAgaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewogICAgICAgIHBlcnJvcigicmVuYW1lIHRtcCByZWdpc3RyeSIpOwogICAgICAgIHVubGluayh0bXApOwogICAgICB9CiAgICB9CiAgICBmcmVlKHRtcCk7CiAgICBmcmVlKGZuKTsKCX0KICBlbHNlCiAgeyAgCgkJV0FSTihyZWcsIkZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWQuXG4iLGdldHVpZCgpKTsKICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqIExPQUQgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmluZF9vcl9hZGRfa2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBMUEtFWVNUUlVDVCBfZmluZF9vcl9hZGRfa2V5KCBMUEtFWVNUUlVDVCBscGtleSwgTFBXU1RSIGtleW5hbWUgKQp7CglMUEtFWVNUUlVDVAlscHhrZXksKmxwbHBrZXk7CgoJaWYgKCgha2V5bmFtZSkgfHwgKGtleW5hbWVbMF09PTApKSB7CgkJZnJlZShrZXluYW1lKTsKCQlyZXR1cm4gbHBrZXk7Cgl9CglscGxwa2V5PSAmKGxwa2V5LT5uZXh0c3ViKTsKCWxweGtleQk9ICpscGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJKGxweGtleS0+a2V5bmFtZVswXT09a2V5bmFtZVswXSkgJiYgCgkJCSFsc3RyY21waVcobHB4a2V5LT5rZXluYW1lLGtleW5hbWUpCgkJKQoJCQlicmVhazsKCQlscGxwa2V5CT0gJihscHhrZXktPm5leHQpOwoJCWxweGtleQk9ICpscGxwa2V5OwoJfQoJaWYgKGxweGtleT09TlVMTCkgewoJCSpscGxwa2V5ID0gKExQS0VZU1RSVUNUKXhtYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpOwoJCWxweGtleQk9ICpscGxwa2V5OwoJCW1lbXNldChscHhrZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5LT5rZXluYW1lCT0ga2V5bmFtZTsKCX0gZWxzZQoJCWZyZWUoa2V5bmFtZSk7CglyZXR1cm4gbHB4a2V5Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF92YWx1ZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfZmluZF9vcl9hZGRfdmFsdWUoIExQS0VZU1RSVUNUIGxwa2V5LCBMUFdTVFIgbmFtZSwgRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgZGF0YSwgRFdPUkQgbGVuLCBEV09SRCBsYXN0bW9kaWZpZWQgKQp7CglMUEtFWVZBTFVFCXZhbD1OVUxMOwoJaW50CQlpOwoKCWlmIChuYW1lICYmICEqbmFtZSkgey8qIGVtcHR5IHN0cmluZyBlcXVhbHMgZGVmYXVsdCAoTlVMTCkgdmFsdWUgKi8KCQlmcmVlKG5hbWUpOwoJCW5hbWUgPSBOVUxMOwoJfQoKCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJdmFsPWxwa2V5LT52YWx1ZXMraTsKCQlpZiAobmFtZT09TlVMTCkgewoJCQlpZiAodmFsLT5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7CgkJfSBlbHNlIHsKCQkJaWYgKAl2YWwtPm5hbWUhPU5VTEwgJiYgCgkJCQl2YWwtPm5hbWVbMF09PW5hbWVbMF0gJiYKCQkJCSFsc3RyY21waVcodmFsLT5uYW1lLG5hbWUpCgkJCSkKCQkJCWJyZWFrOwoJCX0KCX0KCWlmIChpPT1scGtleS0+bnJvZnZhbHVlcykgewoJCWxwa2V5LT52YWx1ZXMgPSB4cmVhbGxvYygKCQkJbHBrZXktPnZhbHVlcywKCQkJKCsrbHBrZXktPm5yb2Z2YWx1ZXMpKnNpemVvZihLRVlWQUxVRSkKCQkpOwoJCXZhbD1scGtleS0+dmFsdWVzK2k7CgkJbWVtc2V0KHZhbCwnXDAnLHNpemVvZihLRVlWQUxVRSkpOwoJCXZhbC0+bmFtZSA9IG5hbWU7Cgl9IGVsc2UgewoJCWlmIChuYW1lKQoJCQlmcmVlKG5hbWUpOwoJfQoJaWYgKHZhbC0+bGFzdG1vZGlmaWVkPGxhc3Rtb2RpZmllZCkgewoJCXZhbC0+bGFzdG1vZGlmaWVkPWxhc3Rtb2RpZmllZDsKCQl2YWwtPnR5cGUgPSB0eXBlOwoKICAgICAgICAgICAgICAgIGlmICgodHlwZSA9PSBSRUdfU1ogfHwgdHlwZSA9PSBSRUdfRVhQQU5EX1NaKSAmJiAhZGF0YSl7CgogICAgICAgICAgICAgICAgICAgIGRhdGE9eG1hbGxvYyhzaXplb2YoV0NIQVIpKTsKICAgICAgICAgICAgICAgICAgICBtZW1zZXQoZGF0YSwwLHNpemVvZihXQ0hBUikpOwogICAgICAgICAgICAgICAgICAgIGxlbiA9c2l6ZW9mKFdDSEFSKTsKICAgICAgICAgICAgICAgIH0KCgkJdmFsLT5sZW4gID0gbGVuOwoJCWlmICh2YWwtPmRhdGEpIAoJCQlmcmVlKHZhbC0+ZGF0YSk7CgkJdmFsLT5kYXRhID0gZGF0YTsKCX0gZWxzZQoJCWZyZWUoZGF0YSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfbGluZSBbSW50ZXJuYWxdCiAqCiAqIHJlYWRzIGEgbGluZSBpbmNsdWRpbmcgZHluYW1pY2FsbHkgZW5sYXJnaW5nIHRoZSByZWFkYnVmZmVyIGFuZCB0aHJvd2luZwogKiBhd2F5IGNvbW1lbnRzCiAqLwpzdGF0aWMgaW50IF93aW5lX3JlYWRfbGluZSggRklMRSAqRiwgY2hhciAqKmJ1ZiwgaW50ICpsZW4gKQp7CgljaGFyCSpzLCpjdXJyZWFkOwoJaW50CW15bGVuLGN1cm9mZjsKCgljdXJyZWFkCT0gKmJ1ZjsKCW15bGVuCT0gKmxlbjsKCSoqYnVmCT0gJ1wwJzsKCXdoaWxlICgxKSB7CgkJd2hpbGUgKDEpIHsKCQkJcz1mZ2V0cyhjdXJyZWFkLG15bGVuLEYpOwoJCQlpZiAocz09TlVMTCkKCQkJCXJldHVybiAwOyAvKiBFT0YgKi8KCQkJaWYgKE5VTEw9PShzPXN0cmNocihjdXJyZWFkLCdcbicpKSkgewoJCQkJLyogYnVmZmVyIHdhc24ndCBsYXJnZSBlbm91Z2ggKi8KCQkJCWN1cm9mZgk9IHN0cmxlbigqYnVmKTsKCQkJCSpidWYJPSB4cmVhbGxvYygqYnVmLCpsZW4qMik7CgkJCQljdXJyZWFkCT0gKmJ1ZiArIGN1cm9mZjsKCQkJCW15bGVuCT0gKmxlbjsJLyogd2UgZmlsbGVkIHVwIHRoZSBidWZmZXIgYW5kIAoJCQkJCQkgKiBnb3QgbmV3ICcqbGVuJyBieXRlcyB0byBmaWxsCgkJCQkJCSAqLwoJCQkJKmxlbgk9ICpsZW4gKiAyOwoJCQl9IGVsc2UgewoJCQkJKnM9J1wwJzsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCS8qIHRocm93IGF3YXkgY29tbWVudHMgKi8KCQlpZiAoKipidWY9PScjJyB8fCAqKmJ1Zj09JzsnKSB7CgkJCWN1cnJlYWQJPSAqYnVmOwoJCQlteWxlbgk9ICpsZW47CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAocykgCS8qIGdvdCBlbmQgb2YgbGluZSAqLwoJCQlicmVhazsKCX0KCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9yZWFkX1VTVFJJTkcgW0ludGVybmFsXQogKgogKiBjb252ZXJ0cyBhIGNoYXIqIGludG8gYSBVTklDT0RFIHN0cmluZyAodXAgdG8gYSBzcGVjaWFsIGNoYXIpCiAqIGFuZCByZXR1cm5zIHRoZSBwb3NpdGlvbiBleGFjdGx5IGFmdGVyIHRoYXQgc3RyaW5nCiAqLwpzdGF0aWMgY2hhciogX3dpbmVfcmVhZF9VU1RSSU5HKCBjaGFyICpidWYsIExQV1NUUiAqc3RyICkKewoJY2hhcgkqczsKCUxQV1NUUgl3czsKCgkvKiByZWFkIHVwIHRvICI9IiBvciAiXDAiIG9yICJcbiIgKi8KCXMJPSBidWY7CglpZiAoKnMgPT0gJz0nKSB7CgkJLyogZW1wdHkgc3RyaW5nIGlzIHRoZSB3aW4zLjEgZGVmYXVsdCB2YWx1ZShOVUxMKSovCgkJKnN0cgk9IE5VTEw7CgkJcmV0dXJuIHM7Cgl9Cgkqc3RyCT0gKExQV1NUUil4bWFsbG9jKDIqc3RybGVuKGJ1ZikrMik7Cgl3cwk9ICpzdHI7Cgl3aGlsZSAoKnMgJiYgKCpzIT0nXG4nKSAmJiAoKnMhPSc9JykpIHsKCQlpZiAoKnMhPSdcXCcpCgkJCSp3cysrPSooKHVuc2lnbmVkIGNoYXIqKXMrKyk7CgkJZWxzZSB7CgkJCXMrKzsKCQkJaWYgKCEqcykgewoJCQkJLyogRGFuZ2xpbmcgXCAuLi4gbWF5IG9ubHkgaGFwcGVuIGlmIGEgcmVnaXN0cnkKCQkJCSAqIHdyaXRlIHdhcyBzaG9ydC4gRklYTUU6IFdoYXQgZG8gdG8/CgkJCQkgKi8KCQkJCSBicmVhazsKCQkJfQoJCQlpZiAoKnM9PSdcXCcpIHsKCQkJCSp3cysrPSdcXCc7CgkJCQlzKys7CgkJCQljb250aW51ZTsKCQkJfQoJCQlpZiAoKnMhPSd1JykgewoJCQkJV0FSTihyZWcsIk5vbiB1bmljb2RlIGVzY2FwZSBzZXF1ZW5jZSBcXCVjIGZvdW5kIGluIHwlc3xcbiIsKnMsYnVmKTsKCQkJCSp3cysrPSdcXCc7CgkJCQkqd3MrKz0qcysrOwoJCQl9IGVsc2UgewoJCQkJY2hhcgl4YnVmWzVdOwoJCQkJaW50CXdjOwoKCQkJCXMrKzsKCQkJCW1lbWNweSh4YnVmLHMsNCk7eGJ1Zls0XT0nXDAnOwoJCQkJaWYgKCFzc2NhbmYoeGJ1ZiwiJXgiLCZ3YykpCgkJCQkJV0FSTihyZWcsIlN0cmFuZ2UgZXNjYXBlIHNlcXVlbmNlICVzIGZvdW5kIGluIHwlc3xcbiIseGJ1ZixidWYpOwoJCQkJcys9NDsKCQkJCSp3cysrCT0odW5zaWduZWQgc2hvcnQpd2M7CgkJCX0KCQl9Cgl9Cgkqd3MJPSAwOwoJd3MJPSAqc3RyOwoJaWYgKCp3cykKCQkqc3RyCT0gc3RyZHVwVygqc3RyKTsKCWVsc2UKCQkqc3RyCT0gTlVMTDsKCWZyZWUod3MpOwoJcmV0dXJuIHM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJrZXkgW0ludGVybmFsXQogKgogKiBOT1RFUwogKiAgICBJdCBzZWVtcyBsaWtlIHRoaXMgaXMgcmV0dXJuaW5nIGEgYm9vbGVhbi4gIFNob3VsZCBpdD8KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiAxCiAqICAgIEZhaWx1cmU6IDAKICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YmtleSggRklMRSAqRiwgTFBLRVlTVFJVQ1QgbHBrZXksIGludCBsZXZlbCwgY2hhciAqKmJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKmJ1ZmxlbiwgRFdPUkQgb3B0ZmxhZyApCnsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJaTsKCWNoYXIJCSpzOwoJTFBXU1RSCQluYW1lOwoKICAgIFRSQUNFKHJlZywiKCVwLCVwLCVkLCVzLCVkLCVseClcbiIsIEYsIGxwa2V5LCBsZXZlbCwgZGVidWdzdHJfYSgqYnVmKSwKICAgICAgICAgICpidWZsZW4sIG9wdGZsYWcpOwoKICAgIGxwa2V5LT5mbGFncyB8PSBvcHRmbGFnOwoKICAgIC8qIEdvb2QuICBXZSBhbHJlYWR5IGdvdCBhIGxpbmUgaGVyZSAuLi4gc28gcGFyc2UgaXQgKi8KICAgIGxweGtleSA9IE5VTEw7CiAgICB3aGlsZSAoMSkgewogICAgICAgIGk9MDtzPSpidWY7CiAgICAgICAgd2hpbGUgKCpzPT0nXHQnKSB7CiAgICAgICAgICAgIHMrKzsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KICAgICAgICBpZiAoaT5sZXZlbCkgewogICAgICAgICAgICBpZiAobHB4a2V5PT1OVUxMKSB7CiAgICAgICAgICAgICAgICBXQVJOKHJlZywiR290IGEgc3ViaGllcmFyY2h5IHdpdGhvdXQgcmVzcC4ga2V5P1xuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBfd2luZV9sb2Fkc3Via2V5KEYsbHB4a2V5LGxldmVsKzEsYnVmLGJ1ZmxlbixvcHRmbGFnKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKCQkvKiBsZXQgdGhlIGNhbGxlciBoYW5kbGUgdGhpcyBsaW5lICovCgkJaWYgKGk8bGV2ZWwgfHwgKipidWY9PSdcMCcpCgkJCXJldHVybiAxOwoKCQkvKiBpdCBjYW4gYmU6IGEgdmFsdWUgb3IgYSBrZXluYW1lLiBQYXJzZSB0aGUgbmFtZSBmaXJzdCAqLwoJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsJm5hbWUpOwoKCQkvKiBzd2l0Y2goKSBkZWZhdWx0OiBoYWNrIHRvIGF2b2lkIGdvdG9zICovCgkJc3dpdGNoICgwKSB7CgkJZGVmYXVsdDoKCQkJaWYgKCpzPT0nXDAnKSB7CgkJCQlscHhrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxuYW1lKTsKCQkJfSBlbHNlIHsKCQkJCUxQQllURQkJZGF0YTsKCQkJCWludAkJbGVuLGxhc3Rtb2RpZmllZCx0eXBlOwoKCQkJCWlmICgqcyE9Jz0nKSB7CgkJCQkJV0FSTihyZWcsIlVuZXhwZWN0ZWQgY2hhcmFjdGVyOiAlY1xuIiwqcyk7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlzKys7CgkJCQlpZiAoMiE9c3NjYW5mKHMsIiVkLCVkLCIsJnR5cGUsJmxhc3Rtb2RpZmllZCkpIHsKCQkJCQlXQVJOKHJlZywiSGF2ZW4ndCB1bmRlcnN0b29kIHBvc3NpYmxlIHZhbHVlIGluIHwlc3wsIHNraXBwaW5nLlxuIiwqYnVmKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCS8qIHNraXAgdGhlIDIgLCAqLwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlpZiAodHlwZSA9PSBSRUdfU1ogfHwgdHlwZSA9PSBSRUdfRVhQQU5EX1NaKSB7CgkJCQkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywoTFBXU1RSKikmZGF0YSk7CgkJCQkJaWYgKGRhdGEpCgkJCQkJCWxlbiA9IGxzdHJsZW5XKChMUFdTVFIpZGF0YSkqMisyOwoJCQkJCWVsc2UJCgkJCQkJCWxlbiA9IDA7CgkJCQl9IGVsc2UgewoJCQkJCWxlbj1zdHJsZW4ocykvMjsKCQkJCQlkYXRhID0gKExQQllURSl4bWFsbG9jKGxlbisxKTsKCQkJCQlmb3IgKGk9MDtpPGxlbjtpKyspIHsKCQkJCQkJZGF0YVtpXT0wOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXT0oKnMtJzAnKTw8NDsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV09KCpzLSdhJysnXHhhJyk8PDQ7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nQScrJ1x4YScpPDw0OwoJCQkJCQlzKys7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldfD0qcy0nMCc7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nYScrJ1x4YSc7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nQScrJ1x4YSc7CgkJCQkJCXMrKzsKCQkJCQl9CgkJCQl9CgkJCQlfZmluZF9vcl9hZGRfdmFsdWUobHBrZXksbmFtZSx0eXBlLGRhdGEsbGVuLGxhc3Rtb2RpZmllZCk7CgkJCX0KCQl9CgkJLyogcmVhZCB0aGUgbmV4dCBsaW5lICovCgkJaWYgKCFfd2luZV9yZWFkX2xpbmUoRixidWYsYnVmbGVuKSkKCQkJcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHN1YnJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF93aW5lX2xvYWRzdWJyZWcoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBEV09SRCBvcHRmbGFnICkKewoJaW50CXZlcjsKCWNoYXIJKmJ1ZjsKCWludAlidWZsZW47CgoJYnVmPXhtYWxsb2MoMTApO2J1Zmxlbj0xMDsKCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghc3NjYW5mKGJ1ZiwiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIiwmdmVyKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICh2ZXIhPVJFR0lTVFJZX1NBVkVfVkVSU0lPTikgewoJCVRSQUNFKHJlZywiT2xkIGZvcm1hdCAoJWQpIHJlZ2lzdHJ5IGZvdW5kLCBpZ25vcmluZyBpdC4gKGJ1ZiB3YXMgJXMpLlxuIix2ZXIsYnVmKTsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIV93aW5lX2xvYWRzdWJrZXkoRixscGtleSwwLCZidWYsJmJ1ZmxlbixvcHRmbGFnKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWZyZWUoYnVmKTsKCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93aW5lX2xvYWRyZWcoIExQS0VZU1RSVUNUIGxwa2V5LCBjaGFyICpmbiwgRFdPUkQgb3B0ZmxhZyApCnsKICAgIEZJTEUgKkY7CgogICAgVFJBQ0UocmVnLCIoJXAsJXMsJWx4KVxuIixscGtleSxkZWJ1Z3N0cl9hKGZuKSxvcHRmbGFnKTsKCiAgICBGID0gZm9wZW4oZm4sInJiIik7CiAgICBpZiAoRj09TlVMTCkgewogICAgICAgIFdBUk4ocmVnLCJDb3VsZG4ndCBvcGVuICVzIGZvciByZWFkaW5nOiAlc1xuIixmbixzdHJlcnJvcihlcnJubykgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoIV93aW5lX2xvYWRzdWJyZWcoRixscGtleSxvcHRmbGFnKSkgewogICAgICAgIGZjbG9zZShGKTsKICAgICAgICB1bmxpbmsoZm4pOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGZjbG9zZShGKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfZmx1c2hfcmVnaXN0cnkgW0ludGVybmFsXQogKiAKICogVGhpcyBmdW5jdGlvbiBhbGxvdyB0byBmbHVzaCBzZWN0aW9uIG9mIHRoZSBpbnRlcm5hbCByZWdpc3RyeS4gIEl0IGlzIG1haW5seQogKiBpbXBsZW1lbnRzIHRvIGZpeCBhIHByb2JsZW0gd2l0aCB0aGUgZ2xvYmFsIEhLVSBhbmQgdGhlIGxvY2FsIEhLVS4KICogVGhvc2UgdHdvIGZpbGVzIGFyZSByZWFkIHRvIGJ1aWxkIHRoZSBIS1VcLkRlZmF1bHQgYnJhbmNoIHRvIGZpbmFseSBjb3B5CiAqIHRoaXMgYnJhbmNoIG9udG8gSEtDVSBoaXZlLCBvbmNlIHRoaXMgaXMgZG9uZSwgaWYgd2Uga2VlcCB0aGUgSEtVIGhpdmUgYXMgaXMsIAogKiBhbGwgdGhlIGdsb2JhbCBIS1UgYXJlIHNhdmVkIG9udG8gdGhlIHVzZXIncyBwZXJzb25hbCB2ZXJzaW9uIG9mIEhLVSBoaXZlLgogKiB3aGljaCBpcyBiYWQuLi4KICovCgogLyogRm9yd2FyZCBkZWNsYXJhdGlvbiBvZiByZWN1c2l2ZSBhZ2VudCAqLwpzdGF0aWMgdm9pZCBfZmx1c2hfcmVnKExQS0VZU1RSVUNUIGZyb20pOwoKc3RhdGljIHZvaWQgX2ZsdXNoX3JlZ2lzdHJ5KCBMUEtFWVNUUlVDVCBmcm9tICkKewogIC8qIG1ha2Ugc3VyZSB3ZSBoYXZlIHNvbWV0aGluZy4uLiAqLwogIGlmIChmcm9tID09IE5VTEwpCiAgICByZXR1cm47CgogIC8qIExhdW5jaCB0aGUgcmVjdXNpdmUgYWdlbnQgb24gc3ViIGJyYW5jaGVzICovCiAgX2ZsdXNoX3JlZyggZnJvbS0+bmV4dHN1YiApOwogIF9mbHVzaF9yZWcoIGZyb20tPm5leHQgKTsKCiAgLyogSW5pdGlhbGl6ZSBwb2ludGVycyAqLwogIGZyb20tPm5leHRzdWIgPSBOVUxMOwogIGZyb20tPm5leHQgICAgPSBOVUxMOwp9CnN0YXRpYyB2b2lkIF9mbHVzaF9yZWcoIExQS0VZU1RSVUNUIGZyb20gKQp7CglpbnQJajsKCiAgLyogbWFrZSBzdXJlIHdlIGhhdmUgc29tZXRoaW5nLi4uICovCiAgaWYgKGZyb20gPT0gTlVMTCkKICAgIHJldHVybjsKCiAgLyogCiAgICogZG8gdGhlIHNhbWUgZm9yIHRoZSBjaGlsZCBrZXlzIAogICAqLwogIGlmIChmcm9tLT5uZXh0c3ViICE9IE5VTEwpCiAgICBfZmx1c2hfcmVnKGZyb20tPm5leHRzdWIpOwoKICAvKiAKICAgKiBkbyB0aGUgc2FtZSBmb3IgdGhlIHNpYmxpbmcga2V5cyAKICAgKi8KICBpZiAoZnJvbS0+bmV4dCAhPSBOVUxMKQogICAgX2ZsdXNoX3JlZyhmcm9tLT5uZXh0KTsKCiAgLyoKICAgKiBpdGVyYXRlIHRocm91Z2ggdGhpcyBrZXkncyB2YWx1ZXMgYW5kIGRlbGV0ZSB0aGVtCiAgICovCiAgZm9yIChqPTA7ajxmcm9tLT5ucm9mdmFsdWVzO2orKykgCiAgewogICAgZnJlZSggKGZyb20tPnZhbHVlcytqKS0+bmFtZSk7CiAgICBmcmVlKCAoZnJvbS0+dmFsdWVzK2opLT5kYXRhKTsKICB9CgogIC8qCiAgICogZnJlZSB0aGUgc3RydWN0dXJlCiAgICovCiAgaWYgKCBmcm9tICE9IE5VTEwgKQogICAgZnJlZShmcm9tKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2NvcHlfcmVnaXN0cnkgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX2NvcHlfcmVnaXN0cnkoIExQS0VZU1RSVUNUIGZyb20sIExQS0VZU1RSVUNUIHRvICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlqOwoJTFBLRVlWQUxVRQl2YWxmcm9tOwoKCWZyb209ZnJvbS0+bmV4dHN1YjsKCXdoaWxlIChmcm9tKSB7CgkJbHB4a2V5ID0gX2ZpbmRfb3JfYWRkX2tleSh0byxzdHJkdXBXKGZyb20tPmtleW5hbWUpKTsKCgkJZm9yIChqPTA7ajxmcm9tLT5ucm9mdmFsdWVzO2orKykgewoJCQlMUFdTVFIJbmFtZTsKCQkJTFBCWVRFCWRhdGE7CgoJCQl2YWxmcm9tID0gZnJvbS0+dmFsdWVzK2o7CgkJCW5hbWU9dmFsZnJvbS0+bmFtZTsKCQkJaWYgKG5hbWUpIG5hbWU9c3RyZHVwVyhuYW1lKTsKCQkJZGF0YT0oTFBCWVRFKXhtYWxsb2ModmFsZnJvbS0+bGVuKTsKCQkJbWVtY3B5KGRhdGEsdmFsZnJvbS0+ZGF0YSx2YWxmcm9tLT5sZW4pOwoKCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJCQkJbHB4a2V5LAoJCQkJbmFtZSwKCQkJCXZhbGZyb20tPnR5cGUsCgkJCQlkYXRhLAoJCQkJdmFsZnJvbS0+bGVuLAoJCQkJdmFsZnJvbS0+bGFzdG1vZGlmaWVkCgkJCSk7CgkJfQoJCV9jb3B5X3JlZ2lzdHJ5KGZyb20sbHB4a2V5KTsKCQlmcm9tID0gZnJvbS0+bmV4dDsKCX0KfQoKCi8qIFdJTkRPV1MgOTUgUkVHSVNUUlkgTE9BREVSICovCi8qIAogKiBTdHJ1Y3R1cmUgb2YgYSB3aW45NSByZWdpc3RyeSBkYXRhYmFzZS4KICogbWFpbiBoZWFkZXI6CiAqIDAgOgkiQ1JFRyIJLSBtYWdpYwogKiA0IDoJRFdPUkQgdmVyc2lvbgogKiA4IDoJRFdPUkQgb2Zmc2V0X29mX1JHREJfcGFydAogKiAwQy4uMEY6CT8gKHNvbWVvbmUgZmlsbCBpbiBwbGVhc2UpCiAqIDEwOiAgV09SRAludW1iZXIgb2YgUkdEQiBibG9ja3MKICogMTI6ICBXT1JECT8KICogMTQ6ICBXT1JECWFsd2F5cyAwMDAwPwogKiAxNjogIFdPUkQJYWx3YXlzIDAwMDE/CiAqIDE4Li4xRjoJPyAoc29tZW9uZSBmaWxsIGluIHBsZWFzZSkKICoKICogMjA6IFJHS05fc2VjdGlvbjoKICogICBoZWFkZXI6CiAqIAkwIDoJCSJSR0tOIgktIG1hZ2ljCiAqICAgICAgNCA6IERXT1JECW9mZnNldCB0byBmaXJzdCBSR0RCIHNlY3Rpb24KICogICAgICA4IDogRFdPUkQJb2Zmc2V0IHRvIHRoZSByb290IHJlY29yZAogKiAJQy4uMHgxQjogCT8gKGZpbGwgaW4pCiAqICAgICAgMHgyMCAuLi4gb2Zmc2V0X29mX1JHREJfcGFydDogRGlzayBLZXkgRW50cnkgc3RydWN0dXJlcwogKgogKiAgIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZToKICoJMDA6IERXT1JECS0gRnJlZSBlbnRyeSBpbmRpY2F0b3IoPykKICoJMDQ6IERXT1JECS0gSGFzaCA9IHN1bSBvZiBieXRlcyBvZiBrZXluYW1lCiAqCTA4OiBEV09SRAktIFJvb3Qga2V5IGluZGljYXRvcj8gdW5rbm93biwgYnV0IHVzdWFsbHkgMHhGRkZGRkZGRiBvbiB3aW45NSBzeXN0ZW1zCiAqCTBDOiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBQcmV2aW91c0xldmVsIEtleS4KICoJMTA6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIE5leHQgU3VibGV2ZWwgS2V5LgogKgkxNDogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgTmV4dCBLZXkgKG9uIHNhbWUgbGV2ZWwpLgogKiBES0VQPjE4OiBXT1JECS0gTnIsIExvdyBTaWduaWZpY2FudCBwYXJ0LgogKgkxQTogV09SRAktIE5yLCBIaWdoIFNpZ25pZmljYW50IHBhcnQuCiAqCiAqIFRoZSBkaXNrIGFkZHJlc3MgYWx3YXlzIHBvaW50cyB0byB0aGUgbnIgcGFydCBvZiB0aGUgcHJldmlvdXMga2V5IGVudHJ5IAogKiBvZiB0aGUgcmVmZXJlbmNlZCBrZXkuIERvbid0IGFzayBtZSB3aHksIG9yIGV2ZW4gaWYgSSBnb3QgdGhpcyBjb3JyZWN0CiAqIGZyb20gc3RhcmluZyBhdCAxa2cgb2YgaGV4ZHVtcHMuIChES0VQKQogKgogKiBUaGUgSGlnaCBzaWduaWZpY2FudCBwYXJ0IG9mIHRoZSBzdHJ1Y3R1cmUgc2VlbXMgdG8gZXF1YWwgdGhlIG51bWJlcgogKiBvZiB0aGUgUkdEQiBzZWN0aW9uLiBUaGUgbG93IHNpZ25pZmljYW50IHBhcnQgaXMgYSB1bmlxdWUgSUQgd2l0aGluCiAqIHRoYXQgUkdEQiBzZWN0aW9uCiAqCiAqIFRoZXJlIGFyZSB0d28gbWlub3IgY29ycmVjdGlvbnMgdG8gdGhlIHBvc2l0aW9uIG9mIHRoYXQgc3RydWN0dXJlLgogKiAxLiBJZiB0aGUgYWRkcmVzcyBpcyB4eHgwMTQgb3IgeHh4MDE4IGl0IHdpbGwgYmUgYWxpZ25lZCB0byB4eHgwMWMgQU5EIAogKiAgICB0aGUgREtFIHJlcmVhZCBmcm9tIHRoZXJlLgogKiAyLiBJZiB0aGUgYWRkcmVzcyBpcyB4eHhGRnggaXQgd2lsbCBiZSBhbGlnbmVkIHRvICh4eHgrMSkwMDAuCiAqIENQUyAtIEkgaGF2ZSBub3QgZXhwZXJpZW5jZWQgdGhlIGFib3ZlIHBoZW5vbWVub24gaW4gbXkgcmVnaXN0cnkgZmlsZXMKICoKICogUkdEQl9zZWN0aW9uOgogKiAJMDA6CQkiUkdEQiIJLSBtYWdpYwogKgkwNDogRFdPUkQJb2Zmc2V0IHRvIG5leHQgUkdEQiBzZWN0aW9uCiAqCTA4OiBEV09SRAk/CiAqCTBDOiBXT1JECWFsd2F5cyAwMDBkPwogKgkwRTogV09SRAlSR0RCIGJsb2NrIG51bWJlcgogKgkxMDoJRFdPUkQJPyAoZXF1YWxzIHZhbHVlIGF0IG9mZnNldCA0IC0gdmFsdWUgYXQgb2Zmc2V0IDgpCiAqCTE0Li4xRjoJCT8KICoJMjAuLi4uLjoJZGlzayBrZXlzCiAqCiAqIGRpc2sga2V5OgogKiAJMDA6IAlEV09SRAluZXh0a2V5b2Zmc2V0CS0gb2Zmc2V0IHRvIHRoZSBuZXh0IGRpc2sga2V5IHN0cnVjdHVyZQogKgkwODogCVdPUkQJbnJMUwkJLSBsb3cgc2lnbmlmaWNhbnQgcGFydCBvZiBOUgogKgkwQTogCVdPUkQJbnJIUwkJLSBoaWdoIHNpZ25pZmljYW50IHBhcnQgb2YgTlIKICoJMEM6IAlEV09SRAlieXRlc3VzZWQJLSBieXRlcyB1c2VkIGluIHRoaXMgc3RydWN0dXJlLgogKgkxMDogCVdPUkQJbmFtZV9sZW4JLSBsZW5ndGggb2YgbmFtZSBpbiBieXRlcy4gd2l0aG91dCBcMAogKgkxMjogCVdPUkQJbnJfb2ZfdmFsdWVzCS0gbnVtYmVyIG9mIHZhbHVlcy4KICoJMTQ6IAljaGFyCW5hbWVbbmFtZV9sZW5dCS0gbmFtZSBzdHJpbmcuIE5vIFwwLgogKgkxNCtuYW1lX2xlbjogZGlzayB2YWx1ZXMKICoJbmV4dGtleW9mZnNldDogLi4uIG5leHQgZGlzayBrZXkKICoKICogZGlzayB2YWx1ZToKICoJMDA6CURXT1JECXR5cGUJCS0gdmFsdWUgdHlwZSAoaG1tLCBjb3VsZCBiZSBXT1JEIHRvbykKICoJMDQ6CURXT1JECQkJLSB1bmtub3duLCB1c3VhbGx5IDAKICoJMDg6CVdPUkQJbmFtZWxlbgkJLSBsZW5ndGggb2YgTmFtZS4gMCBtZWFucyBuYW1lPU5VTEwKICoJMEM6CVdPUkQJZGF0YWxlbgkJLSBsZW5ndGggb2YgRGF0YS4KICoJMTA6CWNoYXIJbmFtZVtuYW1lbGVuXQktIG5hbWUsIG5vIFwwCiAqCTEwK25hbWVsZW46IEJZVEUJZGF0YVtkYXRhbGVuXSAtIGRhdGEsIHdpdGhvdXQgXDAgaWYgc3RyaW5nCiAqCTEwK25hbWVsZW4rZGF0YWxlbjogbmV4dCB2YWx1ZXMgb3IgZGlzayBrZXkKICoKICogRGlzayBrZXlzIGFyZSBsYXllZCBvdXQgZmxhdCAuLi4gQnV0LCBzb21ldGltZXMsIG5yTFMgYW5kIG5ySFMgYXJlIGJvdGgKICogMHhGRkZGLCB3aGljaCBtZWFucyBza2lwcGluZyBvdmVyIG5leHRrZXlvZmZzZXQgYnl0ZXMgKGluY2x1ZGluZyB0aGlzCiAqIHN0cnVjdHVyZSkgYW5kIHJlYWRpbmcgYW5vdGhlciBSR0RCX3NlY3Rpb24uCiAqIHJlcGVhdCB1bnRpbCBlbmQgb2YgZmlsZS4KICoKICogQW4gaW50ZXJlc3RpbmcgcmVsYXRpb25zaGlwIGV4aXN0cyBpbiBSR0RCX3NlY3Rpb24uIFRoZSB2YWx1ZSBhdCBvZmZzZXQKICogMTAgZXF1YWxzIHRoZSB2YWx1ZSBhdCBvZmZzZXQgNCBtaW51cyB0aGUgdmFsdWUgYXQgb2Zmc2V0IDguIEkgaGF2ZSBubwogKiBpZGVhIGF0IHRoZSBtb21lbnQgd2hhdCB0aGlzIG1lYW5zLiAgKEtldmluIENvemVucykKICoKICogRklYTUU6IHRoaXMgZGVzY3JpcHRpb24gbmVlZHMgc29tZSBzZXJpb3VzIGhlbHAsIHllcy4KICovCgpzdHJ1Y3QJX3c5NWtleXZhbHVlIHsKCXVuc2lnbmVkIGxvbmcJCXR5cGU7Cgl1bnNpZ25lZCBzaG9ydAkJZGF0YWxlbjsKCWNoYXIJCQkqbmFtZTsKCXVuc2lnbmVkIGNoYXIJCSpkYXRhOwoJdW5zaWduZWQgbG9uZwkJeDE7CglpbnQJCQlsYXN0bW9kaWZpZWQ7Cn07CgpzdHJ1Y3QgCV93OTVrZXkgewoJY2hhcgkJCSpuYW1lOwoJaW50CQkJbnJvZnZhbHM7CglzdHJ1Y3QJX3c5NWtleXZhbHVlCSp2YWx1ZXM7CglzdHJ1Y3QgX3c5NWtleQkJKnByZXZsdmw7CglzdHJ1Y3QgX3c5NWtleQkJKm5leHRzdWI7CglzdHJ1Y3QgX3c5NWtleQkJKm5leHQ7Cn07CgoKc3RydWN0IF93OTVfaW5mbyB7CiAgY2hhciAqcmdrbmJ1ZmZlcjsKICBpbnQgIHJna25zaXplOwogIGNoYXIgKnJnZGJidWZmZXI7CiAgaW50ICByZ2Ric2l6ZTsKICBpbnQgIGRlcHRoOwogIGludCAgbGFzdG1vZGlmaWVkOwp9OwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9wcm9jZXNzS2V5IFtJbnRlcm5hbF0KICovCnN0YXRpYyBMUEtFWVNUUlVDVCBfdzk1X3Byb2Nlc3NLZXkgKCBMUEtFWVNUUlVDVCBscGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5yTFMsIGludCBuck1TLCBzdHJ1Y3QgX3c5NV9pbmZvICppbmZvICkKCnsKICAvKiBEaXNrIEtleSBIZWFkZXIgc3RydWN0dXJlIChSR0RCIHBhcnQpICovCglzdHJ1Y3QJZGtoIHsKICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcJCW5leHRrZXlvZmY7IAoJCXVuc2lnbmVkIHNob3J0CQluckxTOwoJCXVuc2lnbmVkIHNob3J0CQluck1TOwoJCXVuc2lnbmVkIGxvbmcJCWJ5dGVzdXNlZDsKCQl1bnNpZ25lZCBzaG9ydAkJa2V5bmFtZWxlbjsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsdWVzOwoJCXVuc2lnbmVkIGxvbmcJCXh4MTsKCQkvKiBrZXluYW1lICovCgkJLyogZGlzayBrZXkgdmFsdWVzIG9yIG5vdGhpbmcgKi8KCX07CgkvKiBEaXNrIEtleSBWYWx1ZSBzdHJ1Y3R1cmUgKi8KCXN0cnVjdAlka3YgewoJCXVuc2lnbmVkIGxvbmcJCXR5cGU7CgkJdW5zaWduZWQgbG9uZwkJeDE7CgkJdW5zaWduZWQgc2hvcnQJCXZhbG5hbWVsZW47CgkJdW5zaWduZWQgc2hvcnQJCXZhbGRhdGFsZW47CgkJLyogdmFsbmFtZSwgdmFsZGF0YSAqLwoJfTsKCgkKCXN0cnVjdAlka2ggZGtoOwoJaW50CWJ5dGVzcmVhZCA9IDA7CgljaGFyICAgICpyZ2RiZGF0YSA9IGluZm8tPnJnZGJidWZmZXI7CglpbnQgICAgIG5ieXRlcyA9IGluZm8tPnJnZGJzaXplOwoJY2hhciAgICAqY3VyZGF0YSA9IHJnZGJkYXRhOwoJY2hhciAgICAqZW5kID0gcmdkYmRhdGEgKyBuYnl0ZXM7CglpbnQgICAgIG9mZl9uZXh0X3JnZGI7CgljaGFyICAgICpuZXh0ID0gcmdkYmRhdGE7CglpbnQgICAgIG5yZ2RiLCBpOwoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJCglkbyB7CgkgIGN1cmRhdGEgPSBuZXh0OwoJICBpZiAoc3RybmNtcChjdXJkYXRhLCAiUkdEQiIsIDQpKSByZXR1cm4gKE5VTEwpOwoJICAgIAoJICBtZW1jcHkoJm9mZl9uZXh0X3JnZGIsY3VyZGF0YSs0LDQpOwoJICBuZXh0ID0gY3VyZGF0YSArIG9mZl9uZXh0X3JnZGI7CgkgIG5yZ2RiID0gKGludCkgKigoc2hvcnQgKiljdXJkYXRhICsgNyk7CgoJfSB3aGlsZSAobnJnZGIgIT0gbnJNUyAmJiAobmV4dCA8IGVuZCkpOwoKCS8qIGN1cmRhdGEgbm93IHBvaW50cyB0byB0aGUgc3RhcnQgb2YgdGhlIHJpZ2h0IFJHREIgc2VjdGlvbiAqLwoJY3VyZGF0YSArPSAweDIwOwoKI2RlZmluZSBYUkVBRCh3aGVyZXRvLGxlbikgXAoJaWYgKChjdXJkYXRhICsgbGVuKSA8PSBlbmQpIHtcCgkJbWVtY3B5KHdoZXJldG8sY3VyZGF0YSxsZW4pO1wKCQljdXJkYXRhKz1sZW47XAoJCWJ5dGVzcmVhZCs9bGVuO1wKCX0KCgl3aGlsZSAoY3VyZGF0YSA8IG5leHQpIHsKCSAgc3RydWN0CWRraCAqeGRraCA9IChzdHJ1Y3QgZGtoKiljdXJkYXRhOwoKCSAgYnl0ZXNyZWFkICs9IHNpemVvZihka2gpOyAvKiBGSVhNRS4uLiBuZXh0a2V5b2ZmPyAqLwoJICBpZiAoeGRraC0+bnJMUyA9PSBuckxTKSB7CgkgIAltZW1jcHkoJmRraCx4ZGtoLHNpemVvZihka2gpKTsKCSAgCWN1cmRhdGEgKz0gc2l6ZW9mKGRraCk7CgkgIAlicmVhazsKCSAgfQoJICBjdXJkYXRhICs9IHhka2gtPm5leHRrZXlvZmY7Cgl9OwoKCWlmIChka2gubnJMUyAhPSBuckxTKSByZXR1cm4gKE5VTEwpOwoKCWlmIChucmdkYiAhPSBka2gubnJNUykKCSAgcmV0dXJuIChOVUxMKTsKCiAgICAgICAgYXNzZXJ0KChka2gua2V5bmFtZWxlbjwyKSB8fCBjdXJkYXRhWzBdKTsKCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LHN0cmN2dEEyVyhjdXJkYXRhLCBka2gua2V5bmFtZWxlbikpOwoJY3VyZGF0YSArPSBka2gua2V5bmFtZWxlbjsKCglmb3IgKGk9MDtpPCBka2gudmFsdWVzOyBpKyspIHsKCSAgc3RydWN0IGRrdiBka3Y7CgkgIExQQllURSBkYXRhOwoJICBpbnQgbGVuOwoJICBMUFdTVFIgbmFtZTsKCgkgIFhSRUFEKCZka3Ysc2l6ZW9mKGRrdikpOwoKCSAgbmFtZSA9IHN0cmN2dEEyVyhjdXJkYXRhLCBka3YudmFsbmFtZWxlbik7CgkgIGN1cmRhdGEgKz0gZGt2LnZhbG5hbWVsZW47CgoJICBpZiAoKDEgPDwgZGt2LnR5cGUpICYgVU5JQ09OVk1BU0spIHsKCSAgICBkYXRhID0gKExQQllURSkgc3RyY3Z0QTJXKGN1cmRhdGEsIGRrdi52YWxkYXRhbGVuKTsKCSAgICBsZW4gPSAyKihka3YudmFsZGF0YWxlbiArIDEpOwoJICB9IGVsc2UgewoJICAgIC8qIEkgZG9uJ3QgdGhpbmsgd2Ugd2FudCB0byBOVUxMIHRlcm1pbmF0ZSBhbGwgZGF0YSAqLwoJICAgIGRhdGEgPSB4bWFsbG9jKGRrdi52YWxkYXRhbGVuKTsKCSAgICBtZW1jcHkgKGRhdGEsIGN1cmRhdGEsIGRrdi52YWxkYXRhbGVuKTsKCSAgICBsZW4gPSBka3YudmFsZGF0YWxlbjsKCSAgfQoKCSAgY3VyZGF0YSArPSBka3YudmFsZGF0YWxlbjsKCSAgCgkgIF9maW5kX29yX2FkZF92YWx1ZSgKCQkJICAgICBscHhrZXksCgkJCSAgICAgbmFtZSwKCQkJICAgICBka3YudHlwZSwKCQkJICAgICBkYXRhLAoJCQkgICAgIGxlbiwKCQkJICAgICBpbmZvLT5sYXN0bW9kaWZpZWQKCQkJICAgICApOwoJfQoJcmV0dXJuIChscHhrZXkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfd2Fsa3Jna24gW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3c5NV93YWxrcmdrbiggTFBLRVlTVFJVQ1QgcHJldmtleSwgY2hhciAqb2ZmLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IF93OTVfaW5mbyAqaW5mbyApCgp7CiAgLyogRGlzayBLZXkgRW50cnkgc3RydWN0dXJlIChSR0tOIHBhcnQpICovCiAgc3RydWN0CWRrZSB7CiAgICB1bnNpZ25lZCBsb25nCQl4MTsKICAgIHVuc2lnbmVkIGxvbmcJCXgyOwogICAgdW5zaWduZWQgbG9uZwkJeDM7Lyp1c3VhbGx5IDB4RkZGRkZGRkYgKi8KICAgIHVuc2lnbmVkIGxvbmcJCXByZXZsdmw7CiAgICB1bnNpZ25lZCBsb25nCQluZXh0c3ViOwogICAgdW5zaWduZWQgbG9uZwkJbmV4dDsKICAgIHVuc2lnbmVkIHNob3J0CQluckxTOwogICAgdW5zaWduZWQgc2hvcnQJCW5yTVM7CiAgfSAqZGtlID0gKHN0cnVjdCBka2UgKilvZmY7CiAgTFBLRVlTVFJVQ1QgIGxweGtleTsKCiAgaWYgKGRrZSA9PSBOVUxMKSB7CiAgICBka2UgPSAoc3RydWN0IGRrZSAqKSAoKGNoYXIgKilpbmZvLT5yZ2tuYnVmZmVyKTsKICB9CgogIGxweGtleSA9IF93OTVfcHJvY2Vzc0tleShwcmV2a2V5LCBka2UtPm5yTFMsIGRrZS0+bnJNUywgaW5mbyk7CiAgLyogWFhYIDwtLSBUaGlzIGlzIGEgaGFjayovCiAgaWYgKCFscHhrZXkpIHsKICAgIGxweGtleSA9IHByZXZrZXk7CiAgfQoKICBpZiAoZGtlLT5uZXh0c3ViICE9IC0xICYmIAogICAgICAoKGRrZS0+bmV4dHN1YiAtIDB4MjApIDwgaW5mby0+cmdrbnNpemUpIAogICAgICAmJiAoZGtlLT5uZXh0c3ViID4gMHgyMCkpIHsKICAgIAogICAgX3c5NV93YWxrcmdrbihscHhrZXksIAoJCSAgaW5mby0+cmdrbmJ1ZmZlciArIGRrZS0+bmV4dHN1YiAtIDB4MjAsIAoJCSAgaW5mbyk7CiAgfQogIAogIGlmIChka2UtPm5leHQgIT0gLTEgJiYgCiAgICAgICgoZGtlLT5uZXh0IC0gMHgyMCkgPCBpbmZvLT5yZ2tuc2l6ZSkgJiYgCiAgICAgIChka2UtPm5leHQgPiAweDIwKSkgewogICAgX3c5NV93YWxrcmdrbihwcmV2a2V5LCAgCgkJICBpbmZvLT5yZ2tuYnVmZmVyICsgZGtlLT5uZXh0IC0gMHgyMCwKCQkgIGluZm8pOwogIH0KCiAgcmV0dXJuOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvYWRyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3c5NV9sb2FkcmVnKCBjaGFyKiBmbiwgTFBLRVlTVFJVQ1QgbHBrZXkgKQp7CglIRklMRQkJaGZkOwoJY2hhcgkJbWFnaWNbNV07Cgl1bnNpZ25lZCBsb25nCXdoZXJlLHZlcnNpb24scmdkYnNlY3Rpb24sZW5kOwoJc3RydWN0ICAgICAgICAgIF93OTVfaW5mbyBpbmZvOwoJT0ZTVFJVQ1QJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZkaW5mbzsKCglUUkFDRShyZWcsIkxvYWRpbmcgV2luOTUgcmVnaXN0cnkgZGF0YWJhc2UgJyVzJ1xuIixmbik7CgloZmQ9T3BlbkZpbGUoZm4sJm9mcyxPRl9SRUFEKTsKCWlmIChoZmQ9PUhGSUxFX0VSUk9SKQoJCXJldHVybjsKCW1hZ2ljWzRdPTA7CglpZiAoNCE9X2xyZWFkKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJDUkVHIikpIHsKCQlXQVJOKHJlZywiJXMgaXMgbm90IGEgdzk1IHJlZ2lzdHJ5LlxuIixmbik7CgkJcmV0dXJuOwoJfQoJaWYgKDQhPV9scmVhZChoZmQsJnZlcnNpb24sNCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZChoZmQsJnJnZGJzZWN0aW9uLDQpKQoJCXJldHVybjsKCWlmICgtMT09X2xsc2VlayhoZmQsMHgyMCxTRUVLX1NFVCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZChoZmQsbWFnaWMsNCkpCgkJcmV0dXJuOwoJaWYgKHN0cmNtcChtYWdpYywiUkdLTiIpKSB7CgkJV0FSTihyZWcsICJzZWNvbmQgSUZGIGhlYWRlciBub3QgUkdLTiwgYnV0ICVzXG4iLCBtYWdpYyk7CgkJcmV0dXJuOwoJfQoKCS8qIFNURVAgMTogS2V5bGluayBzdHJ1Y3R1cmVzICovCglpZiAoLTE9PV9sbHNlZWsoaGZkLDB4NDAsU0VFS19TRVQpKQoJCXJldHVybjsKCXdoZXJlCT0gMHg0MDsKCWVuZAk9IHJnZGJzZWN0aW9uOwoKCWluZm8ucmdrbnNpemUgPSBlbmQgLSB3aGVyZTsKCWluZm8ucmdrbmJ1ZmZlciA9IChjaGFyKil4bWFsbG9jKGluZm8ucmdrbnNpemUpOwoJaWYgKGluZm8ucmdrbnNpemUgIT0gX2xyZWFkKGhmZCxpbmZvLnJna25idWZmZXIsaW5mby5yZ2tuc2l6ZSkpCgkJcmV0dXJuOwoKCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGZkLCZoZmRpbmZvKSkKCQlyZXR1cm47CgoJZW5kID0gaGZkaW5mby5uRmlsZVNpemVMb3c7CglpbmZvLmxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZkaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CgoJaWYgKC0xPT1fbGxzZWVrKGhmZCxyZ2Ric2VjdGlvbixTRUVLX1NFVCkpCgkJcmV0dXJuOwoKCWluZm8ucmdkYmJ1ZmZlciA9IChjaGFyKil4bWFsbG9jKGVuZC1yZ2Ric2VjdGlvbik7CglpbmZvLnJnZGJzaXplID0gZW5kIC0gcmdkYnNlY3Rpb247CgoJaWYgKGluZm8ucmdkYnNpemUgIT1fbHJlYWQoaGZkLGluZm8ucmdkYmJ1ZmZlcixpbmZvLnJnZGJzaXplKSkKCQlyZXR1cm47CglfbGNsb3NlKGhmZCk7CgoJX3c5NV93YWxrcmdrbihscGtleSwgTlVMTCwgJmluZm8pOwoKCWZyZWUgKGluZm8ucmdkYmJ1ZmZlcik7CglmcmVlIChpbmZvLnJna25idWZmZXIpOwp9CgoKLyogV0lORE9XUyAzMSBSRUdJU1RSWSBMT0FERVIsIHN1cHBsaWVkIGJ5IFRvciBTavh3YWxsLCB0b3JAc24ubm8gKi8KCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VlZGVkIGJ5IGEgd29yZCBhdCBvZmZzZXQtMi4gVGhpcyB3b3JkCiAgICBoYXMgdGhlIHZhbHVlICgyKmluZGV4KSsxLCB3aGVyZSBpbmRleCBpcyB0aGUgcmVmZXJyaW5nIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGluIHRoZSB0YWJsZS4gSSBoYXZlIG5vIHN1Z2dlc3Rpb24gZm9yIHRoZSAyKiBhbmQgdGhlICsxLgogICAgRm9sbG93aW5nIHRoZSB3b3JkLCB0aGVyZSBhcmUgTiBieXRlcyBvZiBkYXRhLCBhcyBwZXIgdGhlIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGxlbmd0aC4gVGhlIG9mZnNldCBvZiB0aGUga2V5ZW50L3ZhbGVudCBlbnRyeSBpcyBmcm9tIHRoZSBzdGFydAogICAgb2YgdGhlIHRleHQgdGFibGUgdG8gdGhlIGZpcnN0IGRhdGEgYnl0ZS4KCiAgICBUaGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbSBNaWNyb3NvZnQuIFRoZSBkYXRhIGZvcm1hdCBpcwogICAgZGVkdWNlZCBmcm9tIHRoZSByZWcuZGF0IGZpbGUgYnkgbWUuIE1pc3Rha2VzIG1heQogICAgaGF2ZSBiZWVuIG1hZGUuIEkgY2xhaW0gbm8gcmlnaHRzIGFuZCBnaXZlIG5vIGd1YXJhbnRlZXMgZm9yIHRoaXMgcHJvZ3JhbS4KCiAgICBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vCiovCgovKiByZWcuZGF0IGhlYWRlciBmb3JtYXQgKi8Kc3RydWN0IF93MzFfaGVhZGVyIHsKCWNoYXIJCWNvb2tpZVs4XTsJLyogJ1NIQ0MzLjEwJyAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYxOwkvKiBvZmZzZXQgb2YgaGFzaCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYyOwkvKiBvZmZzZXQgb2YgaW5kZXggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFiY250OwkJLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gaW5kZXggdGFibGUgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dG9mZjsJLyogb2Zmc2V0IG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0c2l6ZTsJLyogYnl0ZSBzaXplIG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgc2hvcnQJaGFzaHNpemU7CS8qIGhhc2ggc2l6ZSAqLwoJdW5zaWduZWQgc2hvcnQJZnJlZWlkeDsJLyogZnJlZSBpbmRleCAqLwp9OwoKLyogZ2VuZXJpYyBmb3JtYXQgb2YgdGFibGUgZW50cmllcyAqLwpzdHJ1Y3QgX3czMV90YWJlbnQgewoJdW5zaWduZWQgc2hvcnQgdzAsIHcxLCB3MiwgdzM7Cn07CgovKiBkaXJlY3RvcnkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9kaXJlbnQgewoJdW5zaWduZWQgc2hvcnQJc2libGluZ19pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHNpYmxpbmcgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAljaGlsZF9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGNoaWxkIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJa2V5X2lkeDsJLyogdGFibGUgaW5kZXggb2Yga2V5IGtleWVudCAqLwoJdW5zaWduZWQgc2hvcnQJdmFsdWVfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiB2YWx1ZSB2YWxlbnQgKi8KfTsKCi8qIGtleSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2tleWVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogdmFsdWUgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV92YWxlbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdG8gZGlzcGxheSBhIGRpcmVjdG9yeSB0cmVlICovCnZvaWQKX193MzFfZHVtcHRyZWUoCXVuc2lnbmVkIHNob3J0IGlkeCwKCQl1bnNpZ25lZCBjaGFyICp0eHQsCgkJc3RydWN0IF93MzFfdGFiZW50ICp0YWIsCgkJc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAoJCUxQS0VZU1RSVUNUCWxwa2V5LAoJCXRpbWVfdAkJbGFzdG1vZGlmaWVkLAoJCWludAkJbGV2ZWwKKSB7CglzdHJ1Y3QgX3czMV9kaXJlbnQJKmRpcjsKCXN0cnVjdCBfdzMxX2tleWVudAkqa2V5OwoJc3RydWN0IF93MzFfdmFsZW50CSp2YWw7CglMUEtFWVNUUlVDVAkJeGxwa2V5ID0gTlVMTDsKCUxQV1NUUgkJCW5hbWUsdmFsdWU7CglzdGF0aWMgY2hhcgkJdGFpbFs0MDBdOwoKCXdoaWxlIChpZHghPTApIHsKCQlkaXI9KHN0cnVjdCBfdzMxX2RpcmVudCopJnRhYltpZHhdOwoKCQlpZiAoZGlyLT5rZXlfaWR4KSB7CgkJCWtleSA9IChzdHJ1Y3QgX3czMV9rZXllbnQqKSZ0YWJbZGlyLT5rZXlfaWR4XTsKCgkJCW1lbWNweSh0YWlsLCZ0eHRba2V5LT5zdHJpbmdfb2ZmXSxrZXktPmxlbmd0aCk7CgkJCXRhaWxba2V5LT5sZW5ndGhdPSdcMCc7CgkJCS8qIGFsbCB0b3BsZXZlbCBlbnRyaWVzIEFORCB0aGUgZW50cmllcyBpbiB0aGUgCgkJCSAqIHRvcGxldmVsIHN1YmRpcmVjdG9yeSBiZWxvbmcgdG8gXFNPRlRXQVJFXENsYXNzZXMKCQkJICovCgkJCWlmICghbGV2ZWwgJiYgIWxzdHJjbXBBKHRhaWwsIi5jbGFzc2VzIikpIHsKCQkJCV9fdzMxX2R1bXB0cmVlKGRpci0+Y2hpbGRfaWR4LHR4dCx0YWIsaGVhZCxscGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJCQlpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCW5hbWU9c3RyZHVwQTJXKHRhaWwpOwoKCQkJeGxwa2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksbmFtZSk7CgoJCQkvKiBvbmx5IGFkZCBpZiBsZWFmIG5vZGUgb3IgdmFsdWVkIG5vZGUgKi8KCQkJaWYgKGRpci0+dmFsdWVfaWR4IT0wfHxkaXItPmNoaWxkX2lkeD09MCkgewoJCQkJaWYgKGRpci0+dmFsdWVfaWR4KSB7CgkJCQkJdmFsPShzdHJ1Y3QgX3czMV92YWxlbnQqKSZ0YWJbZGlyLT52YWx1ZV9pZHhdOwoJCQkJCW1lbWNweSh0YWlsLCZ0eHRbdmFsLT5zdHJpbmdfb2ZmXSx2YWwtPmxlbmd0aCk7CgkJCQkJdGFpbFt2YWwtPmxlbmd0aF09J1wwJzsKCQkJCQl2YWx1ZT1zdHJkdXBBMlcodGFpbCk7CgkJCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKHhscGtleSxOVUxMLFJFR19TWiwoTFBCWVRFKXZhbHVlLGxzdHJsZW5XKHZhbHVlKSoyKzIsbGFzdG1vZGlmaWVkKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCVRSQUNFKHJlZywic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKCQl9CgkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHhscGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJaWR4PWRpci0+c2libGluZ19pZHg7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93MzFfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwp2b2lkIF93MzFfbG9hZHJlZyh2b2lkKSB7CglIRklMRQkJCWhmOwoJc3RydWN0IF93MzFfaGVhZGVyCWhlYWQ7CglzdHJ1Y3QgX3czMV90YWJlbnQJKnRhYjsKCXVuc2lnbmVkIGNoYXIJCSp0eHQ7CglpbnQJCQlsZW47CglPRlNUUlVDVAkJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZpbmZvOwoJdGltZV90CQkJbGFzdG1vZGlmaWVkOwoJTFBLRVlTVFJVQ1QJCWxwa2V5OwoKCVRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCgloZiA9IE9wZW5GaWxlKCJyZWcuZGF0Iiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmPT1IRklMRV9FUlJPUikKCQlyZXR1cm47CgoJLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCglpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQoaGYsJmhlYWQsc2l6ZW9mKGhlYWQpKSkgewoJCUVSUihyZWcsICJyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpIT0wKSB7CgkJRVJSKHJlZywgInJlZy5kYXQgaGFzIGJhZCBzaWduYXR1cmUuXG4iKTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJbGVuID0gaGVhZC50YWJjbnQgKiBzaXplb2Yoc3RydWN0IF93MzFfdGFiZW50KTsKCS8qIHJlYWQgYW5kIGR1bXAgaW5kZXggdGFibGUgKi8KCXRhYiA9IHhtYWxsb2MobGVuKTsKCWlmIChsZW4hPV9scmVhZChoZix0YWIsbGVuKSkgewoJCUVSUihyZWcsImNvdWxkbid0IHJlYWQgJWQgYnl0ZXMuXG4iLGxlbik7IAoJCWZyZWUodGFiKTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJLyogcmVhZCB0ZXh0ICovCgl0eHQgPSB4bWFsbG9jKGhlYWQudGV4dHNpemUpOwoJaWYgKC0xPT1fbGxzZWVrKGhmLGhlYWQudGV4dG9mZixTRUVLX1NFVCkpIHsKCQlFUlIocmVnLCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWlmIChoZWFkLnRleHRzaXplIT1fbHJlYWQoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CgkJRVJSKHJlZywidGV4dGJsb2NrIHRvbyBzaG9ydCAoJWQgaW5zdGVhZCBvZiAlbGQpLlxuIixsZW4saGVhZC50ZXh0c2l6ZSk7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGYsJmhmaW5mbykpIHsKCQlFUlIocmVnLCJHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoJbGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoJbHBrZXkgPSBsb29rdXBfaGtleShIS0VZX0NMQVNTRVNfUk9PVCk7CglfX3czMV9kdW1wdHJlZSh0YWJbMF0udzEsdHh0LHRhYiwmaGVhZCxscGtleSxsYXN0bW9kaWZpZWQsMCk7CglmcmVlKHRhYik7CglmcmVlKHR4dCk7CglfbGNsb3NlKGhmKTsKCXJldHVybjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX0xvYWRSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwp2b2lkIFNIRUxMX0xvYWRSZWdpc3RyeSggdm9pZCApCnsKICBjaGFyCSAgICAgICpmbjsKICBzdHJ1Y3QJICAgIHBhc3N3ZAkqcHdkOwogIExQS0VZU1RSVUNUCWxwa2V5LCBIS0NVLCBIS1UsIEhLTE07CiAgSEtFWQkJICAgIGhrZXk7CgogIFRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCiAgSEtDVSA9IGxvb2t1cF9oa2V5KEhLRVlfQ1VSUkVOVF9VU0VSKTsKICBIS1UgID0gbG9va3VwX2hrZXkoSEtFWV9VU0VSUyk7CiAgSEtMTSA9IGxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSk7CgogIC8qIExvYWQgd2luZG93cyAzLjEgZW50cmllcyAqLwogIF93MzFfbG9hZHJlZygpOwogIC8qIExvYWQgd2luZG93cyA5NSBlbnRyaWVzICovCiAgX3c5NV9sb2FkcmVnKCJDOlxcc3lzdGVtLjFzdCIsCUhLTE0pOwogIF93OTVfbG9hZHJlZygic3lzdGVtLmRhdCIsCUhLTE0pOwogIF93OTVfbG9hZHJlZygidXNlci5kYXQiLAlIS1UpOwoKICAvKiAKICAgKiBMb2FkIHRoZSBnbG9iYWwgSEtVIGhpdmUgZGlyZWN0bHkgZnJvbSAvdXNyL2xvY2FsL2V0YwogICAqLyAKICBfd2luZV9sb2FkcmVnKCBIS1UsIFNBVkVfVVNFUlNfREVGQVVMVCwgMCk7CgogIC8qIAogICAqIExvYWQgdGhlIGdsb2JhbCBtYWNoaW5lIGRlZmF1bHRzIGRpcmVjdGx5IGZvcm0gL3Vzci9sb2NhbC9ldGMKICAgKi8KICBfd2luZV9sb2FkcmVnKCBIS0xNLCBTQVZFX0xPQ0FMX01BQ0hJTkVfREVGQVVMVCwgMCk7CgogIC8qIEdldCBjdXJyZW50IHVzZXIgaW5mbyAqLwogIHB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CgogIC8qCiAgICogTG9hZCB0aGUgdXNlciBzYXZlZCByZWdpc3RyaWVzIAogICAqLwogIGlmICggKHB3ZCAhPSBOVUxMKSAmJiAKICAgICAgIChwd2QtPnB3X2RpciAhPSBOVUxMKSApIAogIHsKICAgIC8qIAogICAgICogTG9hZCB1c2VyJ3MgcGVyc29uYWwgdmVyc2lvbnMgb2YgZ2xvYmFsIEhLVS8uRGVmYXVsdCBrZXlzCiAgICAgKi8KICAgIGZuPShjaGFyKil4bWFsbG9jKAogICAgICAgICAgICAgICAgc3RybGVuKHB3ZC0+cHdfZGlyKSsKICAgICAgICAgICAgICAgIHN0cmxlbihXSU5FX1BSRUZJWCkrCiAgICAgICAgICAgICAgICBzdHJsZW4oU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKSsyKTsKCiAgICBzdHJjcHkoZm4sIHB3ZC0+cHdfZGlyKTsKICAgIHN0cmNhdChmbiwgV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpOwogICAgX3dpbmVfbG9hZHJlZyhIS1UsIGZuLCBSRUdfT1BUSU9OX1RBSU5URUQpOyAKICAgIGZyZWUoZm4pOwoKICAgIC8qIAogICAgICogTG9hZCBIS0NVLCBhdHRlbXB0IHRvIGdldCB0aGUgcmVnaXN0cnkgbG9jYXRpb24gZnJvbSB0aGUgY29uZmlnIAogICAgICogZmlsZSBmaXJzdCwgaWYgZXhpc3QsIGxvYWQgYW5kIGtlZXAgZ29pbmcuCiAgICAgKi8gICAgICAKICAgIGZuID0geG1hbGxvYyggTUFYX1BBVEhOQU1FX0xFTiApOyAKICAgIGlmICggUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKAogICAgICAgICAgIlJlZ2lzdHJ5IiwgCiAgICAgICAgICAiVXNlckZpbGVOYW1lIiwgCiAgICAgICAgICAiIiwgCiAgICAgICAgICBmbiwgCiAgICAgICAgICBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpIAogICAgewogICAgICBfd2luZV9sb2FkcmVnKEhLQ1UsZm4sMCk7CiAgICB9CiAgCWZyZWUgKGZuKTsKCiAgICBmbj0oY2hhciopeG1hbGxvYygKICAgICAgICAgICAgICAgIHN0cmxlbihwd2QtPnB3X2RpcikrCiAgICAgICAgICAgICAgICBzdHJsZW4oV0lORV9QUkVGSVgpKwogICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfQ1VSUkVOVF9VU0VSKSsyKTsKCiAgICBzdHJjcHkoZm4sIHB3ZC0+cHdfZGlyKTsKICAgIHN0cmNhdChmbiwgV0lORV9QUkVGSVgiLyJTQVZFX0NVUlJFTlRfVVNFUik7CiAgICBfd2luZV9sb2FkcmVnKEhLQ1UsIGZuLCBSRUdfT1BUSU9OX1RBSU5URUQpOwogICAgZnJlZShmbik7CgogICAgLyogCiAgICAgKiBMb2FkIEhLTE0sIGF0dGVtcHQgdG8gZ2V0IHRoZSByZWdpc3RyeSBsb2NhdGlvbiBmcm9tIHRoZSBjb25maWcgCiAgICAgKiBmaWxlIGZpcnN0LCBpZiBleGlzdCwgbG9hZCBhbmQga2VlcCBnb2luZy4KICAgICAqLyAgICAgIAogICAgZm4gPSB4bWFsbG9jICggTUFYX1BBVEhOQU1FX0xFTik7CiAgICBpZiAoIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZygKICAgICAgICAgICJSZWdpc3RyeSIsIAogICAgICAgICAgIkxvY2FsTWFjaGluZUZpbGVOYW1lIiwgCiAgICAgICAgICAiIiwgCiAgICAgICAgICBmbiwgCiAgICAgICAgICBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpCiAgICB7CiAgCSAgX3dpbmVfbG9hZHJlZyhIS0xNLCBmbiwgMCk7CiAgCX0KICAgIGZyZWUoZm4pOwoKICAgIGZuPShjaGFyKil4bWFsbG9jKAogICAgICAgICAgICAgICAgc3RybGVuKHB3ZC0+cHdfZGlyKSsKICAgICAgICAgICAgICAgIHN0cmxlbihXSU5FX1BSRUZJWCkrCiAgICAgICAgICAgICAgICBzdHJsZW4oU0FWRV9MT0NBTF9NQUNISU5FKSsyKTsKCiAgICBzdHJjcHkoZm4scHdkLT5wd19kaXIpOwogICAgc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9NQUNISU5FKTsKICAgIF93aW5lX2xvYWRyZWcoSEtMTSwgZm4sIFJFR19PUFRJT05fVEFJTlRFRCk7CiAgICBmcmVlKGZuKTsKICB9CiAgZWxzZQogIHsKICAgIFdBUk4ocmVnLCJGYWlsZWQgdG8gZ2V0IGhvbWVkaXJlY3Rvcnkgb2YgVUlEICVkLlxuIixnZXR1aWQoKSk7CiAgfQoKICAvKiAKICAgKiBPYnRhaW4gdGhlIGhhbmRsZSBvZiB0aGUgSEtVXC5EZWZhdWx0IGtleS4KICAgKiBpbiBvcmRlciB0byBjb3B5IEhLVVwuRGVmYXVsdFwqIG9udG8gSEtFWV9DVVJSRU5UX1VTRVIgCiAgICovCiAgUmVnQ3JlYXRlS2V5MTYoSEtFWV9VU0VSUywiLkRlZmF1bHQiLCZoa2V5KTsKICBscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogIGlmKCFscGtleSkKICAgICBXQVJOKHJlZywiQ291bGQgbm90IGNyZWF0ZSBnbG9iYWwgdXNlciBkZWZhdWx0IGtleVxuIik7CiAgZWxzZQogICAgX2NvcHlfcmVnaXN0cnkobHBrZXksIEhLQ1UgKTsKCiAgUmVnQ2xvc2VLZXkoaGtleSk7CgogIC8qIAogICAqIFNpbmNlIEhLVSBpcyBidWlsdCBmcm9tIHRoZSBnbG9iYWwgSEtVIGFuZCB0aGUgbG9jYWwgdXNlciBIS1UgZmlsZSB3ZSBtdXN0CiAgICogZmx1c2ggdGhlIEhLVSB0cmVlIHdlIGhhdmUgYnVpbHQgYXQgdGhpcyBwb2ludCBvdGhlcndpc2UgdGhlIHBhcnQgYnJvdWdodAogICAqIGluIGZyb20gdGhlIGdsb2JhbCBIS1UgaXMgc2F2ZWQgaW50byB0aGUgbG9jYWwgSEtVLiAgVG8gYXZvaWQgdGhpcyAKICAgKiB1c2VsZXNzIGR1cHBsaWNhdGlvbiBvZiBIS1Uga2V5cyB3ZSByZXJlYWQgdGhlIGxvY2FsIEhLVSBrZXkuCiAgICovCgogIC8qIEFsbHdheXMgZmx1c2ggdGhlIEhLVSBoaXZlIGFuZCByZWxvYWQgaXQgb25seSB3aXRoIHVzZXIncyBwZXJzb25hbCBIS1UgKi8KICBfZmx1c2hfcmVnaXN0cnkoSEtVKTsgCgogIC8qIFJlbG9hZCB1c2VyJ3MgbG9jYWwgSEtVIGhpdmUgKi8KICBmbj0oY2hhciopeG1hbGxvYygKICAgICAgICAgICAgICBzdHJsZW4ocHdkLT5wd19kaXIpKwogICAgICAgICAgICAgIHN0cmxlbihXSU5FX1BSRUZJWCkrCiAgICAgICAgICAgICAgc3RybGVuKFNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCkrMik7CgogIHN0cmNweShmbixwd2QtPnB3X2Rpcik7CiAgc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKTsKCiAgX3dpbmVfbG9hZHJlZyggSEtVLCBmbiwgUkVHX09QVElPTl9UQUlOVEVEKTsKCiAgZnJlZShmbik7CgogIC8qIAogICAqIE1ha2Ugc3VyZSB0aGUgdXBkYXRlIG1vZGUgaXMgdGhlcmUKICAgKi8KICBpZiAoRVJST1JfU1VDQ0VTUz09UmVnQ3JlYXRlS2V5MTYoSEtFWV9DVVJSRU5UX1VTRVIsS0VZX1JFR0lTVFJZLCZoa2V5KSkgCiAgewogICAgRFdPUkQJanVuayx0eXBlLGxlbjsKICAgIGNoYXIJZGF0YVs1XTsKCiAgICBsZW49NDsKICAgIGlmICgoCVJlZ1F1ZXJ5VmFsdWVFeEEoCiAgICAgICAgICAgIGhrZXksCiAgICAgICAgICAgIFZBTF9TQVZFVVBEQVRFRCwKICAgICAgICAgICAgJmp1bmssCiAgICAgICAgICAgICZ0eXBlLAogICAgICAgICAgICBkYXRhLAogICAgICAgICAgICAmbGVuKSAhPSBFUlJPUl9TVUNDRVNTKSB8fCAodHlwZSAhPSBSRUdfU1opKQogICAgewogICAgICBSZWdTZXRWYWx1ZUV4QShoa2V5LFZBTF9TQVZFVVBEQVRFRCwwLFJFR19TWiwieWVzIiw0KTsKICAgIH0KCiAgICBSZWdDbG9zZUtleShoa2V5KTsKICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIEFQSSBGVU5DVElPTlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKgogKiBPcGVuIEtleXMuCiAqCiAqIEFsbCBmdW5jdGlvbnMgYXJlIHN0dWJzIHRvIFJlZ09wZW5LZXlFeDMyVyB3aGVyZSBhbGwgdGhlCiAqIG1hZ2ljIGhhcHBlbnMuIAogKgogKiBDYWxscGF0aDoKICogUmVnT3BlbktleTE2IC0+IFJlZ09wZW5LZXkzMkEgLT4gUmVnT3BlbktleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnT3BlbktleTMyVyAgIC0+IFJlZ09wZW5LZXlFeDMyVyAKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5RXgzMlcgW0FEVkFQSTMyLjE1MF0KICogT3BlbnMgdGhlIHNwZWNpZmllZCBrZXkKICoKICogVW5saWtlIFJlZ0NyZWF0ZUtleUV4LCB0aGlzIGRvZXMgbm90IGNyZWF0ZSB0aGUga2V5IGlmIGl0IGRvZXMgbm90IGV4aXN0LgogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIE5hbWUgb2Ygc3Via2V5IHRvIG9wZW4KICogICAgZHdSZXNlcnZlZCBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIHplcm8KICogICAgc2FtRGVzaXJlZCBbSV0gU2VjdXJpdHkgYWNjZXNzIG1hc2sKICogICAgcmV0a2V5ICAgICBbT10gQWRkcmVzcyBvZiBoYW5kbGUgb2Ygb3BlbiBrZXkKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5RXhXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHU0FNIHNhbURlc2lyZWQsIExQSEtFWSByZXRrZXkgKQp7CglMUEtFWVNUUlVDVAlscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCiAgICBUUkFDRShyZWcsIigweCV4LCVzLCVsZCwlbHgsJXApXG4iLCBoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksZHdSZXNlcnZlZCwKICAgICAgICAgIHNhbURlc2lyZWQscmV0a2V5KTsKCiAgICBscE5leHRLZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIGlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpIHsKICAgICAgICAvKiBFaXRoZXIgTlVMTCBvciBwb2ludGVyIHRvIGVtcHR5IHN0cmluZywgc28gcmV0dXJuIGEgbmV3IGhhbmRsZQogICAgICAgICAgIHRvIHRoZSBvcmlnaW5hbCBoa2V5ICovCiAgICAgICAgY3VycmVudGhhbmRsZSArPSAyOwogICAgICAgIGFkZF9oYW5kbGUoY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CiAgICAgICAgKnJldGtleT1jdXJyZW50aGFuZGxlOwogICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwogICAgfQoKICAgIGlmIChscHN6U3ViS2V5WzBdID09ICdcXCcpIHsKICAgICAgICBXQVJOKHJlZywiU3Via2V5ICVzIG11c3Qgbm90IGJlZ2luIHdpdGggYmFja3NsYXNoLlxuIixkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpKTsKICAgICAgICByZXR1cm4gRVJST1JfQkFEX1BBVEhOQU1FOwogICAgfQoKCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSA9IDA7Cgl3aGlsZSAoKGk8d3BjKSAmJiAod3BzW2ldWzBdPT0nXDAnKSkgaSsrOwoJbHB4a2V5ID0gbHBOZXh0S2V5OwoKICAgIHdoaWxlICh3cHNbaV0pIHsKICAgICAgICBscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwogICAgICAgIHdoaWxlIChscHhrZXkpIHsKICAgICAgICAgICAgaWYgKCFsc3RyY21waVcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxweGtleT1scHhrZXktPm5leHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWxweGtleSkgewogICAgICAgICAgICBUUkFDRShyZWcsIkNvdWxkIG5vdCBmaW5kIHN1YmtleSAlc1xuIixkZWJ1Z3N0cl93KHdwc1tpXSkpOwogICAgICAgICAgICBGUkVFX0tFWV9QQVRIOwogICAgICAgICAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7CiAgICAgICAgfQogICAgICAgIGkrKzsKICAgICAgICBscE5leHRLZXkgPSBscHhrZXk7CiAgICB9CgogICAgY3VycmVudGhhbmRsZSArPSAyOwogICAgYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKICAgICpyZXRrZXkgPSBjdXJyZW50aGFuZGxlOwogICAgVFJBQ0UocmVnLCIgIFJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CiAgICBGUkVFX0tFWV9QQVRIOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXlFeDMyQSBbQURWQVBJMzIuMTQ5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXlFeEEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR1NBTSBzYW1EZXNpcmVkLCBMUEhLRVkgcmV0a2V5ICkKewogICAgTFBXU1RSIGxwc3pTdWJLZXlXID0gc3RyZHVwQTJXKGxwc3pTdWJLZXkpOwogICAgRFdPUkQgcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbHgsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxkd1Jlc2VydmVkLAogICAgICAgICAgc2FtRGVzaXJlZCxyZXRrZXkpOwogICAgcmV0ID0gUmVnT3BlbktleUV4VyggaGtleSwgbHBzelN1YktleVcsIGR3UmVzZXJ2ZWQsIHNhbURlc2lyZWQsIHJldGtleSApOwogICAgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5MzJXIFtBRFZBUEkzMi4xNTFdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBzelN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleSB0byBvcGVuCiAqICAgIHJldGtleSAgICAgW09dIEFkZHJlc3Mgb2YgaGFuZGxlIG9mIG9wZW4ga2V5CiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0dXJuIFJlZ09wZW5LZXlFeFcoIGhrZXksIGxwc3pTdWJLZXksIDAsIEtFWV9BTExfQUNDRVNTLCByZXRrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleTMyQSBbQURWQVBJMzIuMTQ4XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgRFdPUkQgcmV0OwogICAgTFBXU1RSIGxwc3pTdWJLZXlXID0gc3RyZHVwQTJXKGxwc3pTdWJLZXkpOwogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0ID0gIFJlZ09wZW5LZXlXKCBoa2V5LCBscHN6U3ViS2V5VywgcmV0a2V5ICk7CiAgICBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXkxNiBbU0hFTEwuMV0gW0tFUk5FTC4yMTddCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgcmV0dXJuIFJlZ09wZW5LZXlBKCBoa2V5LCBscHN6U3ViS2V5LCByZXRrZXkgKTsKfQoKCi8qIAogKiBDcmVhdGUga2V5cwogKiAKICogQWxsIHRob3NlIGZ1bmN0aW9ucyBjb252ZXJ0IHRoZWlyIHJlc3BlY3RpdmUgCiAqIGFyZ3VtZW50cyBhbmQgY2FsbCBSZWdDcmVhdGVLZXlFeFcgYXQgdGhlIGVuZC4KICoKICogV2Ugc3RheSBhd2F5IGZyb20gdGhlIEV4IGZ1bmN0aW9ucyBhcyBsb25nIGFzIHBvc3NpYmxlIGJlY2F1c2UgdGhlcmUgYXJlCiAqIGRpZmZlcmVuY2VzIGluIHRoZSByZXR1cm4gdmFsdWVzCiAqCiAqIENhbGxwYXRoOgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnQ3JlYXRlS2V5RXgzMkEgXAogKiBSZWdDcmVhdGVLZXkxNiAtPiBSZWdDcmVhdGVLZXkzMkEgLT4gUmVnQ3JlYXRlS2V5MzJXICAgLT4gUmVnQ3JlYXRlS2V5RXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXlFeDMyVyBbQURWQVBJMzIuMTMxXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgIFtJXSBIYW5kbGUgb2YgYW4gb3BlbiBrZXkKICogICAgbHBzelN1YktleSAgIFtJXSBBZGRyZXNzIG9mIHN1YmtleSBuYW1lCiAqICAgIGR3UmVzZXJ2ZWQgICBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIDAKICogICAgbHBzekNsYXNzICAgIFtJXSBBZGRyZXNzIG9mIGNsYXNzIHN0cmluZwogKiAgICBmZHdPcHRpb25zICAgW0ldIFNwZWNpYWwgb3B0aW9ucyBmbGFnCiAqICAgIHNhbURlc2lyZWQgICBbSV0gRGVzaXJlZCBzZWN1cml0eSBhY2Nlc3MKICogICAgbHBTZWNBdHRyaWJzIFtJXSBBZGRyZXNzIG9mIGtleSBzZWN1cml0eSBzdHJ1Y3R1cmUKICogICAgcmV0a2V5ICAgICAgIFtPXSBBZGRyZXNzIG9mIGJ1ZmZlciBmb3Igb3BlbmVkIGhhbmRsZQogKiAgICBscERpc3BvcyAgICAgW09dIFJlY2VpdmVzIFJFR19DUkVBVEVEX05FV19LRVkgb3IgUkVHX09QRU5FRF9FWElTVElOR19LRVkKICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXlFeFcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1Jlc2VydmVkLCBMUFdTVFIgbHBzekNsYXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBmZHdPcHRpb25zLCBSRUdTQU0gc2FtRGVzaXJlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgbHBTZWNBdHRyaWJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEhLRVkgcmV0a2V5LCBMUERXT1JEIGxwRGlzcG9zICkKewoJTFBLRVlTVFJVQ1QJKmxwbHBQcmV2S2V5LGxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlcywlbHgsJWx4LCVwLCVwLCVwKVxuIiwgaGtleSwKCQlkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLCBkd1Jlc2VydmVkLCBkZWJ1Z3N0cl93KGxwc3pDbGFzcyksCgkJZmR3T3B0aW9ucywgc2FtRGVzaXJlZCwgbHBTZWNBdHRyaWJzLCByZXRrZXksIGxwRGlzcG9zKTsKCiAgICBscE5leHRLZXkgPSBsb29rdXBfaGtleShoa2V5KTsKICAgIGlmICghbHBOZXh0S2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICAvKiBDaGVjayBmb3IgdmFsaWQgb3B0aW9ucyAqLwogICAgc3dpdGNoKGZkd09wdGlvbnMpIHsKICAgICAgICBjYXNlIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFOgogICAgICAgIGNhc2UgUkVHX09QVElPTl9WT0xBVElMRToKICAgICAgICBjYXNlIFJFR19PUFRJT05fQkFDS1VQX1JFU1RPUkU6CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKICAgIH0KCiAgICAvKiBTYW0gaGFzIHRvIGJlIGEgY29tYmluYXRpb24gb2YgdGhlIGZvbGxvd2luZyAqLwogICAgaWYgKCEoc2FtRGVzaXJlZCAmIAogICAgICAgICAgKEtFWV9BTExfQUNDRVNTIHwgS0VZX0NSRUFURV9MSU5LIHwgS0VZX0NSRUFURV9TVUJfS0VZIHwgCiAgICAgICAgICAgS0VZX0VOVU1FUkFURV9TVUJfS0VZUyB8IEtFWV9FWEVDVVRFIHwgS0VZX05PVElGWSB8CiAgICAgICAgICAgS0VZX1FVRVJZX1ZBTFVFIHwgS0VZX1JFQUQgfCBLRVlfU0VUX1ZBTFVFIHwgS0VZX1dSSVRFKSkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKCWlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRoYW5kbGUgKz0gMjsKCQlhZGRfaGFuZGxlKGN1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwoJCSpyZXRrZXk9Y3VycmVudGhhbmRsZTsKICAgICAgICAgICAgICAgIFRSQUNFKHJlZywgIlJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CgkJbHBOZXh0S2V5LT5mbGFnc3w9UkVHX09QVElPTl9UQUlOVEVEOwoJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJfQoKICAgIGlmIChscHN6U3ViS2V5WzBdID09ICdcXCcpIHsKICAgICAgICBXQVJOKHJlZywiU3Via2V5ICVzIG11c3Qgbm90IGJlZ2luIHdpdGggYmFja3NsYXNoLlxuIixkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpKTsKICAgICAgICByZXR1cm4gRVJST1JfQkFEX1BBVEhOQU1FOwogICAgfQoKCXNwbGl0X2tleXBhdGgobHBzelN1YktleSwmd3BzLCZ3cGMpOwoJaSAJPSAwOwoJd2hpbGUgKChpPHdwYykgJiYgKHdwc1tpXVswXT09J1wwJykpIGkrKzsKCWxweGtleQk9IGxwTmV4dEtleTsKCXdoaWxlICh3cHNbaV0pIHsKCQlscHhrZXk9bHBOZXh0S2V5LT5uZXh0c3ViOwoJCXdoaWxlIChscHhrZXkpIHsKCQkJaWYgKCFsc3RyY21waVcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCQlicmVhazsKCQkJbHB4a2V5PWxweGtleS0+bmV4dDsKCQl9CgkJaWYgKCFscHhrZXkpCgkJCWJyZWFrOwoJCWkrKzsKCQlscE5leHRLZXkJPSBscHhrZXk7Cgl9CglpZiAobHB4a2V5KSB7CiAgICAgICAgICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CgkJYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKCQlscHhrZXktPmZsYWdzICB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJKnJldGtleQkJPSBjdXJyZW50aGFuZGxlOwogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCQlpZiAobHBEaXNwb3MpCgkJCSpscERpc3Bvcwk9IFJFR19PUEVORURfRVhJU1RJTkdfS0VZOwoJCUZSRUVfS0VZX1BBVEg7CgkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgl9CgoJLyogR29vZC4gIE5vdyB0aGUgaGFyZCBwYXJ0ICovCgl3aGlsZSAod3BzW2ldKSB7CgkJbHBscFByZXZLZXkJPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7CgkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl3aGlsZSAobHB4a2V5KSB7CgkJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCQlscHhrZXkJCT0gKmxwbHBQcmV2S2V5OwoJCX0KCQkqbHBscFByZXZLZXk9bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTsKCQlpZiAoISpscGxwUHJldktleSkgewoJCQlGUkVFX0tFWV9QQVRIOwogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRShyZWcsICJSZXR1cm5pbmcgT1VUT0ZNRU1PUllcbiIpOwoJCQlyZXR1cm4gRVJST1JfT1VUT0ZNRU1PUlk7CgkJfQoJCW1lbXNldCgqbHBscFByZXZLZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsIkFkZGluZyAlc1xuIiwgZGVidWdzdHJfdyh3cHNbaV0pKTsKCQkoKmxwbHBQcmV2S2V5KS0+a2V5bmFtZQk9IHN0cmR1cFcod3BzW2ldKTsKCQkoKmxwbHBQcmV2S2V5KS0+bmV4dAk9IE5VTEw7CgkJKCpscGxwUHJldktleSktPm5leHRzdWIJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT52YWx1ZXMJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5ucm9mdmFsdWVzID0gMDsKCQkoKmxwbHBQcmV2S2V5KS0+ZmxhZ3MgCT0gUkVHX09QVElPTl9UQUlOVEVEOwoJCWlmIChscHN6Q2xhc3MpCgkJCSgqbHBscFByZXZLZXkpLT5jbGFzcyA9IHN0cmR1cFcobHBzekNsYXNzKTsKCQllbHNlCgkJCSgqbHBscFByZXZLZXkpLT5jbGFzcyA9IE5VTEw7CgkJbHBOZXh0S2V5CT0gKmxwbHBQcmV2S2V5OwoJCWkrKzsKCX0KICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CglhZGRfaGFuZGxlKGN1cnJlbnRoYW5kbGUsbHBOZXh0S2V5LHNhbURlc2lyZWQpOwoKCS8qRklYTUU6IGZsYWcgaGFuZGxpbmcgY29ycmVjdD8gKi8KCWxwTmV4dEtleS0+ZmxhZ3M9IGZkd09wdGlvbnMgfFJFR19PUFRJT05fVEFJTlRFRDsKCWlmIChscHN6Q2xhc3MpCgkJbHBOZXh0S2V5LT5jbGFzcyA9IHN0cmR1cFcobHBzekNsYXNzKTsKCWVsc2UKCQlscE5leHRLZXktPmNsYXNzID0gTlVMTDsKCSpyZXRrZXkJCT0gY3VycmVudGhhbmRsZTsKICAgICAgICBUUkFDRShyZWcsICJSZXR1cm5pbmcgJXhcbiIsIGN1cnJlbnRoYW5kbGUpOwoJaWYgKGxwRGlzcG9zKQoJCSpscERpc3Bvcwk9IFJFR19DUkVBVEVEX05FV19LRVk7CglGUkVFX0tFWV9QQVRIOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleUV4MzJBIFtBRFZBUEkzMi4xMzBdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5RXhBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGxwc3pDbGFzcywgRFdPUkQgZmR3T3B0aW9ucywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHU0FNIHNhbURlc2lyZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBscFNlY0F0dHJpYnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSByZXRrZXksIExQRFdPUkQgbHBEaXNwb3MgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVcsIGxwc3pDbGFzc1c7CiAgICBEV09SRCAgcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlcywlbHgsJWx4LCVwLCVwLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSksCiAgICAgICAgICBkd1Jlc2VydmVkLGRlYnVnc3RyX2EobHBzekNsYXNzKSxmZHdPcHRpb25zLHNhbURlc2lyZWQsbHBTZWNBdHRyaWJzLAogICAgICAgICAgcmV0a2V5LGxwRGlzcG9zKTsKCiAgICBscHN6U3ViS2V5VyA9IGxwc3pTdWJLZXk/c3RyZHVwQTJXKGxwc3pTdWJLZXkpOk5VTEw7CiAgICBscHN6Q2xhc3NXID0gbHBzekNsYXNzP3N0cmR1cEEyVyhscHN6Q2xhc3MpOk5VTEw7CgogICAgcmV0ID0gUmVnQ3JlYXRlS2V5RXhXKCBoa2V5LCBscHN6U3ViS2V5VywgZHdSZXNlcnZlZCwgbHBzekNsYXNzVywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmR3T3B0aW9ucywgc2FtRGVzaXJlZCwgbHBTZWNBdHRyaWJzLCByZXRrZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwRGlzcG9zICk7CgogICAgaWYobHBzelN1YktleVcpIGZyZWUobHBzelN1YktleVcpOwogICAgaWYobHBzekNsYXNzVykgZnJlZShscHN6Q2xhc3NXKTsKCiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXkzMlcgW0FEVkFQSTMyLjEzMl0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIERXT1JEIGp1bms7CiAgICBMUEtFWVNUUlVDVAlscE5leHRLZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLCBoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkscmV0a2V5KTsKCiAgICAvKiBUaGlzIGNoZWNrIGlzIGhlcmUgYmVjYXVzZSB0aGUgcmV0dXJuIHZhbHVlIGlzIGRpZmZlcmVudCB0aGFuIHRoZQogICAgICAgb25lIGZyb20gdGhlIEV4IGZ1bmN0aW9ucyAqLwogICAgbHBOZXh0S2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfQkFES0VZOwoKICAgIHJldHVybiBSZWdDcmVhdGVLZXlFeFcoIGhrZXksIGxwc3pTdWJLZXksIDAsIE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX0FMTF9BQ0NFU1MsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldGtleSwgJmp1bmspOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXkzMkEgW0FEVkFQSTMyLjEyOV0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUEhLRVkgcmV0a2V5ICkKewogICAgRFdPUkQgcmV0OwogICAgTFBXU1RSIGxwc3pTdWJLZXlXOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIGxwc3pTdWJLZXlXID0gbHBzelN1YktleT9zdHJkdXBBMlcobHBzelN1YktleSk6TlVMTDsKICAgIHJldCA9IFJlZ0NyZWF0ZUtleVcoIGhrZXksIGxwc3pTdWJLZXlXLCByZXRrZXkgKTsKICAgIGlmKGxwc3pTdWJLZXlXKSBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleTE2IFtTSEVMTC4yXSBbS0VSTkVMLjIxOF0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdDcmVhdGVLZXlBKCBoa2V5LCBscHN6U3ViS2V5LCByZXRrZXkgKTsKfQoKCi8qIAogKiBRdWVyeSBWYWx1ZSBGdW5jdGlvbnMKICogV2luMzIgZGlmZmVycyBiZXR3ZWVuIGtleW5hbWVzIGFuZCB2YWx1ZW5hbWVzLiAKICogbXVsdGlwbGUgdmFsdWVzIG1heSBiZWxvbmcgdG8gb25lIGtleSwgdGhlIHNwZWNpYWwgdmFsdWUKICogd2l0aCBuYW1lIE5VTEwgaXMgdGhlIGRlZmF1bHQgdmFsdWUgdXNlZCBieSB0aGUgd2luMzEKICogY29tcGF0IGZ1bmN0aW9ucy4KICoKICogQ2FsbHBhdGg6CiAqIFJlZ1F1ZXJ5VmFsdWUxNiAtPiBSZWdRdWVyeVZhbHVlMzJBIC0+IFJlZ1F1ZXJ5VmFsdWVFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUzMlcgLT4gUmVnUXVlcnlWYWx1ZUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZUV4MzJXIFtBRFZBUEkzMi4xNThdCiAqIFJldHJpZXZlcyB0eXBlIGFuZCBkYXRhIGZvciBhIHNwZWNpZmllZCBuYW1lIGFzc29jaWF0ZWQgd2l0aCBhbiBvcGVuIGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICBbSV0gICBIYW5kbGUgb2Yga2V5IHRvIHF1ZXJ5CiAqICAgIGxwVmFsdWVOYW1lICAgW0ldICAgTmFtZSBvZiB2YWx1ZSB0byBxdWVyeQogKiAgICBscGR3UmVzZXJ2ZWQgIFtJXSAgIFJlc2VydmVkIC0gbXVzdCBiZSBOVUxMCiAqICAgIGxwZHdUeXBlICAgICAgW09dICAgQWRkcmVzcyBvZiBidWZmZXIgZm9yIHZhbHVlIHR5cGUuICBJZiBOVUxMLCB0aGUgdHlwZQogKiAgICAgICAgICAgICAgICAgICAgICAgIGlzIG5vdCByZXF1aXJlZC4KICogICAgbHBiRGF0YSAgICAgICBbT10gICBBZGRyZXNzIG9mIGRhdGEgYnVmZmVyLiAgSWYgTlVMTCwgdGhlIGFjdHVhbCBkYXRhIGlzCiAqICAgICAgICAgICAgICAgICAgICAgICAgbm90IHJlcXVpcmVkLgogKiAgICBscGNiRGF0YSAgICAgIFtJL09dIEFkZHJlc3Mgb2YgZGF0YSBidWZmZXIgc2l6ZQogKgogKiBSRVRVUk5TIAogKiAgICBFUlJPUl9TVUNDRVNTOiAgIFN1Y2Nlc3MKICogICAgRVJST1JfTU9SRV9EQVRBOiAhISEgaWYgdGhlIHNwZWNpZmllZCBidWZmZXIgaXMgbm90IGJpZyBlbm91Z2ggdG8gaG9sZCB0aGUgZGF0YQogKiAJCSAgICAgICBidWZmZXIgaXMgbGVmdCB1bnRvdWNoZWQuIFRoZSBNUy1kb2N1bWVudGF0aW9uIGlzIHdyb25nIChqcykgISEhCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4VyggSEtFWSBoa2V5LCBMUFdTVFIgbHBWYWx1ZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1Jlc2VydmVkLCBMUERXT1JEIGxwZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgbHBiRGF0YSwgTFBEV09SRCBscGNiRGF0YSApCnsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJaW50CQlpOwoJRFdPUkQJCXJldDsKCglUUkFDRShyZWcsIigweCV4LCVzLCVwLCVwLCVwLCVwPSVsZClcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLCBscGR3VHlwZSwgbHBiRGF0YSwgbHBjYkRhdGEsIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwoKCWlmICghbHBrZXkpCgkgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglpZiAoKGxwYkRhdGEgJiYgISBscGNiRGF0YSkgfHwgbHBkd1Jlc2VydmVkKQoJICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgoJLyogQW4gZW1wdHkgbmFtZSBzdHJpbmcgaXMgZXF1aXZhbGVudCB0byBOVUxMICovCglpZiAobHBWYWx1ZU5hbWUgJiYgISpscFZhbHVlTmFtZSkKCSAgbHBWYWx1ZU5hbWUgPSBOVUxMOwoKCWlmIChscFZhbHVlTmFtZT09TlVMTCkgCgl7IC8qIFVzZSBrZXkncyB1bm5hbWVkIG9yIGRlZmF1bHQgdmFsdWUsIGlmIGFueSAqLwoJICBmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCSAgICBpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJICAgICAgYnJlYWs7Cgl9IAoJZWxzZSAKCXsgLyogU2VhcmNoIGZvciB0aGUga2V5IG5hbWUgKi8KCSAgZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkgICAgaWYgKCBscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYgIWxzdHJjbXBpVyhscFZhbHVlTmFtZSxscGtleS0+dmFsdWVzW2ldLm5hbWUpKQoJICAgICAgYnJlYWs7Cgl9CgoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSAKCXsgVFJBQ0UocmVnLCIgS2V5IG5vdCBmb3VuZFxuIik7CgkgIGlmIChscFZhbHVlTmFtZT09TlVMTCkgCgkgIHsgLyogRW1wdHkga2V5bmFtZSBub3QgZm91bmQgKi8KCSAgICBpZiAobHBiRGF0YSkgCgkgICAgeyAqKFdDSEFSKilscGJEYXRhID0gMDsKCSAgICAgICpscGNiRGF0YQk9IDI7CgkgICAgfQoJICAgIGlmIChscGR3VHlwZSkKCSAgICAgICpscGR3VHlwZQk9IFJFR19TWjsKCSAgICBUUkFDRShyZWcsICIgUmV0dXJuaW5nIGFuIGVtcHR5IHN0cmluZ1xuIik7CgkgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CgkgIH0KCSAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoJfQoKCXJldCA9IEVSUk9SX1NVQ0NFU1M7CgoJaWYgKGxwZHdUeXBlKSAJCQkJCS8qIHR5cGUgcmVxdWlyZWQgPyovCgkgICpscGR3VHlwZSA9IGxwa2V5LT52YWx1ZXNbaV0udHlwZTsKCglpZiAobHBiRGF0YSkJCQkJCS8qIGRhdGEgcmVxdWlyZWQgPyovCgl7IGlmICgqbHBjYkRhdGEgPj0gbHBrZXktPnZhbHVlc1tpXS5sZW4pCS8qIGJ1ZmZlciBsYXJnZSBlbm91Z2h0ID8qLwoJICAgIG1lbWNweShscGJEYXRhLGxwa2V5LT52YWx1ZXNbaV0uZGF0YSxscGtleS0+dmFsdWVzW2ldLmxlbik7CgkgIGVsc2UKCSAgICByZXQgPSBFUlJPUl9NT1JFX0RBVEE7Cgl9CgoJaWYgKGxwY2JEYXRhKSAJCQkJCS8qIHNpemUgcmVxdWlyZWQgPyovCgl7ICpscGNiRGF0YSA9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwoJfQoKCWRlYnVnX3ByaW50X3ZhbHVlICggbHBiRGF0YSwgJmxwa2V5LT52YWx1ZXNbaV0pOwoKCVRSQUNFKHJlZywiIChyZXQ9JWx4LCB0eXBlPSVseCwgbGVuPSVsZClcbiIsIHJldCwgbHBkd1R5cGU/KmxwZHdUeXBlOjAsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWUzMlcgW0FEVkFQSTMyLjE1OV0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQV1NUUiBscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQTE9ORyBscGNiRGF0YSApCnsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQsbHBkd1R5cGU7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksbHBzekRhdGEsCiAgICAgICAgICBscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgogICAgLyogT25seSBvcGVuIHN1YmtleSwgaWYgd2UgcmVhbGx5IGRvIGRlc2NlbmQgKi8KICAgIGlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CiAgICAgICAgcmV0ID0gUmVnT3BlbktleVcoIGhrZXksIGxwc3pTdWJLZXksICZ4aGtleSApOwogICAgICAgIGlmIChyZXQgIT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgICAgICBXQVJOKHJlZywgIkNvdWxkIG5vdCBvcGVuICVzXG4iLCBkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICB9IGVsc2UKICAgICAgICB4aGtleSA9IGhrZXk7CgogICAgbHBkd1R5cGUgPSBSRUdfU1o7CiAgICByZXQgPSBSZWdRdWVyeVZhbHVlRXhXKCB4aGtleSwgTlVMTCwgTlVMTCwgJmxwZHdUeXBlLCAoTFBCWVRFKWxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscGNiRGF0YSApOwogICAgaWYgKHhoa2V5ICE9IGhrZXkpCiAgICAgICAgUmVnQ2xvc2VLZXkoeGhrZXkpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZUV4MzJBIFtBRFZBUEkzMi4xNTddCiAqCiAqIE5PVEVTOgogKiB0aGUgZG9jdW1hbnRhdGlvbiBpcyB3cm9uZzogaWYgdGhlIGJ1ZmZlciBpcyB0byBzbWFsbCBpdCByZW1haW5zIHVudG91Y2hlZCAKICoKICogRklYTUU6IGNoZWNrIHJldHVybnZhbHVlIChsZW4pIGZvciBhbiBlbXB0eSBrZXkKICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXhBKCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1Jlc2VydmVkLCBMUERXT1JEIGxwZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgbHBiRGF0YSwgTFBEV09SRCBscGNiRGF0YSApCnsKCUxQV1NUUglscHN6VmFsdWVOYW1lVzsKCUxQQllURQlteWJ1ZiA9IE5VTEw7CglEV09SRAlyZXQsIG15dHlwZSwgbXlsZW4gPSAwOwoKCVRSQUNFKHJlZywiKCV4LCVzLCVwLCVwLCVwLCVwPSVsZClcbiIsIGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhLGxwY2JEYXRhPypscGNiRGF0YTowKTsKCglpZiAoIWxwY2JEYXRhICYmIGxwYkRhdGEpCQkJLyogYnVmZmVyIHdpdGhvdXQgc2l6ZSBpcyBpbGxlZ2FsICovCgl7ICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7Cgl9CgoJbHBzelZhbHVlTmFtZVcgPSBscHN6VmFsdWVOYW1lID8gc3RyZHVwQTJXKGxwc3pWYWx1ZU5hbWUpIDogTlVMTDsJCgkKCS8qIGdldCBqdXN0IHRoZSB0eXBlIGZpcnN0ICovCglyZXQgPSBSZWdRdWVyeVZhbHVlRXhXKCBoa2V5LCBscHN6VmFsdWVOYW1lVywgbHBkd1Jlc2VydmVkLCAmbXl0eXBlLCBOVUxMLCBOVUxMICk7CgkKCWlmICggcmV0ICE9IEVSUk9SX1NVQ0NFU1MgKQkJCS8qIGZhaWxlZCA/PyAqLwoJeyBpZihscHN6VmFsdWVOYW1lVykgZnJlZShscHN6VmFsdWVOYW1lVyk7CgkgIHJldHVybiByZXQ7Cgl9CgkKCWlmIChscGNiRGF0YSkJCQkJCS8qIGF0IGxlYXN0IGxlbmd0aCByZXF1ZXN0ZWQ/ICovCgl7IGlmIChVTklDT05WTUFTSyAmICgxPDwobXl0eXBlKSkpCQkvKiBzdHJpbmcgcmVxdWVzdGVkPyAqLwoJICB7IGlmIChscGJEYXRhICkJCQkJLyogdmFsdWUgcmVxdWVzdGVkPyAqLwoJICAgIHsgbXlsZW4gPSAyKiggKmxwY2JEYXRhICk7CgkgICAgICBteWJ1ZiA9IChMUEJZVEUpeG1hbGxvYyggbXlsZW4gKTsKCSAgICB9CgoJICAgIHJldCA9IFJlZ1F1ZXJ5VmFsdWVFeFcoIGhrZXksIGxwc3pWYWx1ZU5hbWVXLCBscGR3UmVzZXJ2ZWQsIGxwZHdUeXBlLCBteWJ1ZiwgJm15bGVuICk7CgoJICAgIGlmIChyZXQgPT0gRVJST1JfU1VDQ0VTUyApCgkgICAgeyBpZiAoIGxwYkRhdGEgKQoJICAgICAgeyBsbWVtY3B5bld0b0EobHBiRGF0YSwgKExQV1NUUilteWJ1ZiwgbXlsZW4vMik7CgkgICAgICB9CgkgICAgfQoKCSAgICAqbHBjYkRhdGEgPSBteWxlbi8yOwkJCS8qIHNpemUgaXMgaW4gYnl0ZSEgKi8KCSAgfQoJICBlbHNlCQkJCQkJLyogbm8gc3RyaW5ncywgY2FsbCBpdCBzdHJhaWdodCAqLwoJICB7IHJldCA9IFJlZ1F1ZXJ5VmFsdWVFeFcoIGhrZXksIGxwc3pWYWx1ZU5hbWVXLCBscGR3UmVzZXJ2ZWQsIGxwZHdUeXBlLCBscGJEYXRhLCBscGNiRGF0YSApOwoJICB9Cgl9CgkKCWlmIChscGR3VHlwZSkJCQkJCS8qIHR5cGUgd2hlbiByZXF1ZXN0ZWQgKi8KCXsgKmxwZHdUeXBlID0gbXl0eXBlOwoJfQoKCVRSQUNFKHJlZywiIChyZXQ9JWx4LHR5cGU9JWx4LCBsZW49JWxkKVxuIiwgcmV0LG15dHlwZSxscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgkKCWlmKG15YnVmKSBmcmVlKG15YnVmKTsKCWlmKGxwc3pWYWx1ZU5hbWVXKSBmcmVlKGxwc3pWYWx1ZU5hbWVXKTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWVFeDE2IFtLRVJORUwuMjI1XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQU1RSIGxwc3pWYWx1ZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGxwYkRhdGEsIExQRFdPUkQgbHBjYkRhdGEgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlcCwlcCwlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGxwZHdSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhPypscGNiRGF0YTowKTsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlRXhBKCBoa2V5LCBscHN6VmFsdWVOYW1lLCBscGR3UmVzZXJ2ZWQsIGxwZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBiRGF0YSwgbHBjYkRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZTMyQSBbQURWQVBJMzIuMTU2XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUFNUUiBscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQTE9ORyBscGNiRGF0YSApCnsKICAgIEhLRVkgeGhrZXk7CiAgICBEV09SRCByZXQsIGR3VHlwZTsKCiAgICBUUkFDRShyZWcsIigleCwlcywlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxscHN6RGF0YSwKICAgICAgICAgIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewogICAgICAgIHJldCA9IFJlZ09wZW5LZXkxNiggaGtleSwgbHBzelN1YktleSwgJnhoa2V5ICk7CiAgICAgICAgaWYoIHJldCAhPSBFUlJPUl9TVUNDRVNTICkKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgIH0gZWxzZQogICAgICAgIHhoa2V5ID0gaGtleTsKCiAgICBkd1R5cGUgPSBSRUdfU1o7CiAgICByZXQgPSBSZWdRdWVyeVZhbHVlRXhBKCB4aGtleSwgTlVMTCxOVUxMLCAmZHdUeXBlLCAoTFBCWVRFKWxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscGNiRGF0YSApOwogICAgaWYoIHhoa2V5ICE9IGhrZXkgKQogICAgICAgIFJlZ0Nsb3NlS2V5KCB4aGtleSApOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZTE2IFtTSEVMTC42XSBbS0VSTkVMLjIyNF0KICoKICogTk9URVMKICogICAgSXMgdGhpcyBIQUNLIHN0aWxsIGFwcGxpY2FibGU/CiAqCiAqIEhBQ0sKICogICAgVGhlIDE2Yml0IFJlZ1F1ZXJ5VmFsdWUgZG9lc24ndCBoYW5kbGUgc2VsZWN0b3JibG9ja3MgYW55d2F5LCBzbyB3ZSBqdXN0CiAqICAgIG1hc2sgb3V0IHRoZSBoaWdoIDE2IGJpdC4gIFRoaXMgKG5vdCBzbyBtdWNoIGluY2lkZW50bHkpIGhvcGVmdWxseSBmaXhlcwogKiAgICBBbGR1cyBGSDQpCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZTE2KCBIS0VZIGhrZXksIExQU1RSIGxwc3pTdWJLZXksIExQU1RSIGxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSksbHBzekRhdGEsCiAgICAgICAgICBscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgogICAgaWYgKGxwY2JEYXRhKQogICAgICAgICpscGNiRGF0YSAmPSAweEZGRkY7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUEoaGtleSxscHN6U3ViS2V5LGxwc3pEYXRhLGxwY2JEYXRhKTsKfQoKCi8qCiAqIFNldHRpbmcgdmFsdWVzIG9mIFJlZ2lzdHJ5IGtleXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ1NldFZhbHVlMTYgLT4gUmVnU2V0VmFsdWUzMkEgLT4gUmVnU2V0VmFsdWVFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnU2V0VmFsdWUzMlcgICAtPiBSZWdTZXRWYWx1ZUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWVFeDMyVyBbQURWQVBJMzIuMTcwXQogKiBTZXRzIHRoZSBkYXRhIGFuZCB0eXBlIG9mIGEgdmFsdWUgdW5kZXIgYSByZWdpc3RlciBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldIEhhbmRsZSBvZiBrZXkgdG8gc2V0IHZhbHVlIGZvcgogKiAgICBscHN6VmFsdWVOYW1lIFtJXSBOYW1lIG9mIHZhbHVlIHRvIHNldAogKiAgICBkd1Jlc2VydmVkICAgIFtJXSBSZXNlcnZlZCAtIG11c3QgYmUgemVybwogKiAgICBkd1R5cGUgICAgICAgIFtJXSBGbGFnIGZvciB2YWx1ZSB0eXBlCiAqICAgIGxwYkRhdGEgICAgICAgW0ldIEFkZHJlc3Mgb2YgdmFsdWUgZGF0YQogKiAgICBjYkRhdGEgICAgICAgIFtJXSBTaXplIG9mIHZhbHVlIGRhdGEKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICoKICogTk9URVMKICogICB3aW45NSBkb2VzIG5vdCBjYXJlIGFib3V0IGNiRGF0YSBmb3IgUkVHX1NaIGFuZCBmaW5kcyBvdXQgdGhlIGxlbiBieSBpdHNlbGYgKGpzKSAKICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4VyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzelZhbHVlTmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1Jlc2VydmVkLCBEV09SRCBkd1R5cGUsIExQQllURSBscGJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgY2JEYXRhKQp7CglMUEtFWVNUUlVDVCBscGtleTsKCWludCBpOwoKCVRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuIiwgaGtleSwgZGVidWdzdHJfdyhscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsIGR3VHlwZSwgbHBiRGF0YSwgY2JEYXRhKTsKCglscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CgoJaWYgKCFscGtleSkKICAgICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglscGtleS0+ZmxhZ3MgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoKCWlmIChscHN6VmFsdWVOYW1lPT1OVUxMKSB7CiAgICAgICAgICAgICAvKiBTZXRzIHR5cGUgYW5kIG5hbWUgZm9yIGtleSdzIHVubmFtZWQgb3IgZGVmYXVsdCB2YWx1ZSAqLwoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXBpVyhscHN6VmFsdWVOYW1lLGxwa2V5LT52YWx1ZXNbaV0ubmFtZSkKCQkJKQoJCQkJYnJlYWs7Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0gKExQS0VZVkFMVUUpeHJlYWxsb2MoCgkJCQkJbHBrZXktPnZhbHVlcywKCQkJCQkobHBrZXktPm5yb2Z2YWx1ZXMrMSkqc2l6ZW9mKEtFWVZBTFVFKQoJCQkJKTsKCQlscGtleS0+bnJvZnZhbHVlcysrOwoJCW1lbXNldChscGtleS0+dmFsdWVzK2ksJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCX0KCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpIHsKCQlpZiAobHBzelZhbHVlTmFtZSkKCQkJbHBrZXktPnZhbHVlc1tpXS5uYW1lID0gc3RyZHVwVyhscHN6VmFsdWVOYW1lKTsKCQllbHNlCgkJCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSA9IE5VTEw7Cgl9CgoJaWYgKGR3VHlwZSA9PSBSRUdfU1opCgkgIGNiRGF0YSA9IDIgKiAobHN0cmxlblcgKChMUENXU1RSKWxwYkRhdGEpICsgMSk7CgkgIAoJbHBrZXktPnZhbHVlc1tpXS5sZW4JPSBjYkRhdGE7CglscGtleS0+dmFsdWVzW2ldLnR5cGUJPSBkd1R5cGU7CglpZiAobHBrZXktPnZhbHVlc1tpXS5kYXRhICE9TlVMTCkKCQlmcmVlKGxwa2V5LT52YWx1ZXNbaV0uZGF0YSk7CglscGtleS0+dmFsdWVzW2ldLmRhdGEJPSAoTFBCWVRFKXhtYWxsb2MoY2JEYXRhKTsKCWxwa2V5LT52YWx1ZXNbaV0ubGFzdG1vZGlmaWVkID0gdGltZShOVUxMKTsKCW1lbWNweShscGtleS0+dmFsdWVzW2ldLmRhdGEsbHBiRGF0YSxjYkRhdGEpOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgzMkEgW0FEVkFQSTMyLjE2OV0KICoKICogTk9URVMKICogICB3aW45NSBkb2VzIG5vdCBjYXJlIGFib3V0IGNiRGF0YSBmb3IgUkVHX1NaIGFuZCBmaW5kcyBvdXQgdGhlIGxlbiBieSBpdHNlbGYgKGpzKSAKICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4QSggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdSZXNlcnZlZCwgRFdPUkQgZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGNiRGF0YSApCnsKCUxQQllURQlidWY7CglMUFdTVFIJbHBzelZhbHVlTmFtZVc7CglEV09SRAlyZXQ7CgoJaWYgKCFscGJEYXRhKQoJCXJldHVybiAoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwoJCQoJVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsZHdUeXBlLGxwYkRhdGEsY2JEYXRhKTsKCglpZiAoKDE8PGR3VHlwZSkgJiBVTklDT05WTUFTSykgCgl7IGlmIChkd1R5cGUgPT0gUkVHX1NaKQoJICAgIGNiRGF0YSA9IHN0cmxlbiAoKExQQ1NUUilscGJEYXRhKSsxOwoKCSAgYnVmID0gKExQQllURSl4bWFsbG9jKCBjYkRhdGEgKjIgKTsKCSAgbG1lbWNweW5BdG9XICgoTFBWT0lEKWJ1ZiwgbHBiRGF0YSwgY2JEYXRhICk7CgkgIGNiRGF0YT0yKmNiRGF0YTsKCX0gCgllbHNlCgkgIGJ1Zj1scGJEYXRhOwoKCWlmIChscHN6VmFsdWVOYW1lKQoJICBscHN6VmFsdWVOYW1lVyA9IHN0cmR1cEEyVyhscHN6VmFsdWVOYW1lKTsKCWVsc2UKCSAgbHBzelZhbHVlTmFtZVcgPSBOVUxMOwoKCXJldD1SZWdTZXRWYWx1ZUV4Vyhoa2V5LGxwc3pWYWx1ZU5hbWVXLGR3UmVzZXJ2ZWQsZHdUeXBlLGJ1ZixjYkRhdGEpOwoKCWlmIChscHN6VmFsdWVOYW1lVykKCSAgZnJlZShscHN6VmFsdWVOYW1lVyk7CgoJaWYgKGJ1ZiE9bHBiRGF0YSkKCSAgZnJlZShidWYpOwoKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgxNiBbS0VSTkVMLjIyNl0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgRFdPUkQgY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsZHdUeXBlLGxwYkRhdGEsY2JEYXRhKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUV4QSggaGtleSwgbHBzelZhbHVlTmFtZSwgZHdSZXNlcnZlZCwgZHdUeXBlLCBscGJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNiRGF0YSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZTMyVwlbQURWQVBJMzIuMTcxXQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIGxwc3pEYXRhLCBEV09SRCBjYkRhdGEgKQp7CglIS0VZCXhoa2V5OwoJRFdPUkQJcmV0OwoKCVRSQUNFKHJlZywiKCV4LCVzLCVsZCwlcywlbGQpXG4iLAoJCWhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxkd1R5cGUsZGVidWdzdHJfdyhscHN6RGF0YSksY2JEYXRhCgkpOwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQ9UmVnQ3JlYXRlS2V5Vyhoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXk9aGtleTsKCWlmIChkd1R5cGUhPVJFR19TWikgewoJCVRSQUNFKHJlZywiZHdUeXBlPSVsZCAtIENoYW5naW5nIHRvIFJFR19TWlxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT0yKmxzdHJsZW5XKGxwc3pEYXRhKSsyKSB7CgkJVFJBQ0UocmVnLCJMZW49JWxkICE9IHN0cmxlbiglcykrMT0lZCFcbiIsCgkJCWNiRGF0YSxkZWJ1Z3N0cl93KGxwc3pEYXRhKSwyKmxzdHJsZW5XKGxwc3pEYXRhKSsyCgkJKTsKCQljYkRhdGE9Mipsc3RybGVuVyhscHN6RGF0YSkrMjsKCX0KCXJldD1SZWdTZXRWYWx1ZUV4Vyh4aGtleSxOVUxMLDAsZHdUeXBlLChMUEJZVEUpbHBzekRhdGEsY2JEYXRhKTsKCWlmIChoa2V5IT14aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRWYWx1ZTMyQSBbQURWQVBJMzIuMTY4XQogKgogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgRFdPUkQgZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscHN6RGF0YSwgRFdPUkQgY2JEYXRhICkKewoJRFdPUkQJcmV0OwoJSEtFWQl4aGtleTsKCglUUkFDRShyZWcsIigleCwlcywlbGQsJXMsJWxkKVxuIixoa2V5LGxwc3pTdWJLZXksZHdUeXBlLGxwc3pEYXRhLGNiRGF0YSk7CglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldD1SZWdDcmVhdGVLZXkxNihoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXk9aGtleTsKCglpZiAoZHdUeXBlIT1SRUdfU1opIHsKCQlUUkFDRShyZWcsImR3VHlwZT0lbGQhXG4iLGR3VHlwZSk7CgkJZHdUeXBlPVJFR19TWjsKCX0KCWlmIChjYkRhdGEhPXN0cmxlbihscHN6RGF0YSkrMSkKCQljYkRhdGE9c3RybGVuKGxwc3pEYXRhKSsxOwoJcmV0PVJlZ1NldFZhbHVlRXhBKHhoa2V5LE5VTEwsMCxkd1R5cGUsKExQQllURSlscHN6RGF0YSxjYkRhdGEpOwoJaWYgKHhoa2V5IT1oa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMTYgW0tFUk5FTC4yMjFdIFtTSEVMTC41XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JECWR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscHN6RGF0YSwgRFdPUkQgY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGR3VHlwZSwKICAgICAgICAgIGRlYnVnc3RyX2EobHBzekRhdGEpLGNiRGF0YSk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWVBKGhrZXksbHBzelN1YktleSxkd1R5cGUsbHBzekRhdGEsY2JEYXRhKTsKfQoKCi8qIAogKiBLZXkgRW51bWVyYXRpb24KICoKICogQ2FsbHBhdGg6CiAqIFJlZ0VudW1LZXkxNiAtPiBSZWdFbnVtS2V5MzJBIC0+IFJlZ0VudW1LZXlFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ0VudW1LZXkzMlcgICAtPiBSZWdFbnVtS2V5RXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5RXgzMlcgW0FEVkFQSTMyLjEzOV0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICBbSV0gSGFuZGxlIHRvIGtleSB0byBlbnVtZXJhdGUKICogICAgaVN1YktleSAgICAgIFtJXSBJbmRleCBvZiBzdWJrZXkgdG8gZW51bWVyYXRlCiAqICAgIGxwc3pOYW1lICAgICBbT10gQnVmZmVyIGZvciBzdWJrZXkgbmFtZQogKiAgICBscGNjaE5hbWUgICAgW09dIFNpemUgb2Ygc3Via2V5IGJ1ZmZlcgogKiAgICBscGR3UmVzZXJ2ZWQgW0ldIFJlc2VydmVkCiAqICAgIGxwc3pDbGFzcyAgICBbT10gQnVmZmVyIGZvciBjbGFzcyBzdHJpbmcKICogICAgbHBjY2hDbGFzcyAgIFtPXSBTaXplIG9mIGNsYXNzIGJ1ZmZlcgogKiAgICBmdCAgICAgICAgICAgW09dIFRpbWUga2V5IGxhc3Qgd3JpdHRlbiB0bwogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlFeFcoIEhLRVkgaGtleSwgRFdPUkQgaVN1YmtleSwgTFBXU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTmFtZSwgTFBEV09SRCBscGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBscHN6Q2xhc3MsIExQRFdPUkQgbHBjY2hDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVUSU1FICpmdCApCnsKCUxQS0VZU1RSVUNUCWxwa2V5LGxweGtleTsKCiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsCiAgICAgICAgICAqbHBjY2hOYW1lLGxwZHdSZXNlcnZlZCxscHN6Q2xhc3MsbHBjY2hDbGFzcyxmdCk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJaWYgKCFscGtleS0+bmV4dHN1YikKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCWxweGtleT1scGtleS0+bmV4dHN1YjsKCiAgICAvKiBUcmF2ZXJzZSB0aGUgc3Via2V5cyAqLwoJd2hpbGUgKGlTdWJrZXkgJiYgbHB4a2V5KSB7CgkJaVN1YmtleS0tOwoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9CgoJaWYgKGlTdWJrZXkgfHwgIWxweGtleSkKCQlyZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCWlmIChsc3RybGVuVyhscHhrZXktPmtleW5hbWUpKzE+KmxwY2NoTmFtZSkKCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJbWVtY3B5KGxwc3pOYW1lLGxweGtleS0+a2V5bmFtZSxsc3RybGVuVyhscHhrZXktPmtleW5hbWUpKjIrMik7CgogICAgICAgIGlmICgqbHBjY2hOYW1lKQogICAgICAgICAgICAqbHBjY2hOYW1lID0gbHN0cmxlblcobHBzek5hbWUpOwoKCWlmIChscHN6Q2xhc3MpIHsKCQkvKiBGSVhNRTogd2hhdCBzaG91bGQgd2Ugd3JpdGUgaW50byBpdD8gKi8KCQkqbHBzekNsYXNzCT0gMDsKCQkqbHBjY2hDbGFzcwk9IDI7Cgl9CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleTMyVyBbQURWQVBJMzIuMTQwXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlXKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQV1NUUiBscHN6TmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBscGNjaE5hbWUgKQp7CiAgICBGSUxFVElNRQlmdDsKCiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lKTsKICAgIHJldHVybiBSZWdFbnVtS2V5RXhXKGhrZXksaVN1YmtleSxscHN6TmFtZSwmbHBjY2hOYW1lLE5VTEwsTlVMTCxOVUxMLCZmdCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXlFeDMyQSBbQURWQVBJMzIuMTM4XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXlFeEEoIEhLRVkgaGtleSwgRFdPUkQgaVN1YmtleSwgTFBTVFIgbHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hOYW1lLCBMUERXT1JEIGxwZHdSZXNlcnZlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGxwc3pDbGFzcywgTFBEV09SRCBscGNjaENsYXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRVRJTUUgKmZ0ICkKewoJRFdPUkQJcmV0LGxwY2NoTmFtZVcsbHBjY2hDbGFzc1c7CglMUFdTVFIJbHBzek5hbWVXLGxwc3pDbGFzc1c7CgoKCVRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQsJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksaVN1YmtleSxscHN6TmFtZSwqbHBjY2hOYW1lLGxwZHdSZXNlcnZlZCxscHN6Q2xhc3MsbHBjY2hDbGFzcyxmdAoJKTsKCWlmIChscHN6TmFtZSkgewoJCWxwc3pOYW1lVwk9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hOYW1lKjIpOwoJCWxwY2NoTmFtZVcJPSAqbHBjY2hOYW1lOwoJfSBlbHNlIHsKCQlscHN6TmFtZVcJPSBOVUxMOwoJCWxwY2NoTmFtZVcgCT0gMDsKCX0KCWlmIChscHN6Q2xhc3MpIHsKCQlscHN6Q2xhc3NXCQk9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hDbGFzcyoyKTsKCQlscGNjaENsYXNzVwk9ICpscGNjaENsYXNzOwoJfSBlbHNlIHsKCQlscHN6Q2xhc3NXCT0wOwoJCWxwY2NoQ2xhc3NXPTA7Cgl9CglyZXQ9UmVnRW51bUtleUV4VygKCQloa2V5LAoJCWlTdWJrZXksCgkJbHBzek5hbWVXLAoJCSZscGNjaE5hbWVXLAoJCWxwZHdSZXNlcnZlZCwKCQlscHN6Q2xhc3NXLAoJCSZscGNjaENsYXNzVywKCQlmdAoJKTsKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MpIHsKCQlsc3RyY3B5V3RvQShscHN6TmFtZSxscHN6TmFtZVcpOwoJCSpscGNjaE5hbWU9c3RybGVuKGxwc3pOYW1lKTsKCQlpZiAobHBzekNsYXNzVykgewoJCQlsc3RyY3B5V3RvQShscHN6Q2xhc3MsbHBzekNsYXNzVyk7CgkJCSpscGNjaENsYXNzPXN0cmxlbihscHN6Q2xhc3MpOwoJCX0KCX0KCWlmIChscHN6TmFtZVcpCgkJZnJlZShscHN6TmFtZVcpOwoJaWYgKGxwc3pDbGFzc1cpCgkJZnJlZShscHN6Q2xhc3NXKTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXkzMkEgW0FEVkFQSTMyLjEzN10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5QSggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGxwY2NoTmFtZSApCnsKICAgIEZJTEVUSU1FCWZ0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwogICAgcmV0dXJuIFJlZ0VudW1LZXlFeEEoIGhrZXksIGlTdWJrZXksIGxwc3pOYW1lLCAmbHBjY2hOYW1lLCBOVUxMLCBOVUxMLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICZmdCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5MTYgW1NIRUxMLjddIFtLRVJORUwuMjE2XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXkxNiggSEtFWSBoa2V5LCBEV09SRCBpU3Via2V5LCBMUFNUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbHBjY2hOYW1lICkKewogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZSk7CiAgICByZXR1cm4gUmVnRW51bUtleUEoIGhrZXksIGlTdWJrZXksIGxwc3pOYW1lLCBscGNjaE5hbWUpOwp9CgoKLyogCiAqIEVudW1lcmF0ZSBSZWdpc3RyeSBWYWx1ZXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0VudW1WYWx1ZTE2IC0+IFJlZ0VudW1WYWx1ZTMyQSAtPiBSZWdFbnVtVmFsdWUzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUzMlcgW0FEVkFQSTMyLjE0Ml0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgIFtJXSBIYW5kbGUgdG8ga2V5IHRvIHF1ZXJ5CiAqICAgIGlWYWx1ZSAgICAgIFtJXSBJbmRleCBvZiB2YWx1ZSB0byBxdWVyeQogKiAgICBscHN6VmFsdWUgICBbT10gVmFsdWUgc3RyaW5nCiAqICAgIGxwY2NoVmFsdWUgIFtJL09dIFNpemUgb2YgdmFsdWUgYnVmZmVyIChpbiB3Y2hhcnMpCiAqICAgIGxwZFJlc2VydmVkIFtJXSBSZXNlcnZlZAogKiAgICBscGR3VHlwZSAgICBbT10gVHlwZSBjb2RlCiAqICAgIGxwYkRhdGEgICAgIFtPXSBWYWx1ZSBkYXRhCiAqICAgIGxwY2JEYXRhICAgIFtJL09dIFNpemUgb2YgZGF0YSBidWZmZXIgKGluIGJ5dGVzKQogKgogKiBOb3RlOiAgd2lkZSBjaGFyYWN0ZXIgZnVuY3Rpb25zIHRoYXQgdGFrZSBhbmQvb3IgcmV0dXJuICJjaGFyYWN0ZXIgY291bnRzIgogKiAgdXNlIFRDSEFSICh0aGF0IGlzIHVuc2lnbmVkIHNob3J0IG9yIGNoYXIpIG5vdCBieXRlIGNvdW50cy4KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWVXKCBIS0VZIGhrZXksIERXT1JEIGlWYWx1ZSwgTFBXU1RSIGxwc3pWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaFZhbHVlLCBMUERXT1JEIGxwZFJlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKCVRSQUNFKHJlZywiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsZGVidWdzdHJfdyhscHN6VmFsdWUpLAogICAgICAgICAgbHBjY2hWYWx1ZSxscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhKTsKCglscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CgkKCWlmICghbHBjYkRhdGEgJiYgbHBiRGF0YSkKCQlyZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgkJCglpZiAoIWxwa2V5KQoJCXJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCglpZiAobHBrZXktPm5yb2Z2YWx1ZXMgPD0gaVZhbHVlKQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoKCXZhbCA9ICYobHBrZXktPnZhbHVlc1tpVmFsdWVdKTsKCglpZiAodmFsLT5uYW1lKSB7CgkgICAgICAgIGlmIChsc3RybGVuVyh2YWwtPm5hbWUpKzE+KmxwY2NoVmFsdWUpIHsKCQkJKmxwY2NoVmFsdWUgPSBsc3RybGVuVyh2YWwtPm5hbWUpKzE7CgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJfQoJCW1lbWNweShscHN6VmFsdWUsdmFsLT5uYW1lLDIgKiAobHN0cmxlblcodmFsLT5uYW1lKSsxKSApOwoJCSpscGNjaFZhbHVlPWxzdHJsZW5XKHZhbC0+bmFtZSk7Cgl9IGVsc2UgewoJCSpscHN6VmFsdWUJPSAwOwoJCSpscGNjaFZhbHVlCT0gMDsKCX0KCgkvKiBDYW4gYmUgTlVMTCBpZiB0aGUgdHlwZSBjb2RlIGlzIG5vdCByZXF1aXJlZCAqLwoJaWYgKGxwZHdUeXBlKQoJCSpscGR3VHlwZSA9IHZhbC0+dHlwZTsKCglpZiAobHBiRGF0YSkgewoJCWlmICh2YWwtPmxlbj4qbHBjYkRhdGEpCgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJbWVtY3B5KGxwYkRhdGEsdmFsLT5kYXRhLHZhbC0+bGVuKTsKCQkqbHBjYkRhdGEgPSB2YWwtPmxlbjsKCX0KCglkZWJ1Z19wcmludF92YWx1ZSAoIHZhbC0+ZGF0YSwgdmFsICk7CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bVZhbHVlMzJBIFtBRFZBUEkzMi4xNDFdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlQSggSEtFWSBoa2V5LCBEV09SRCBpVmFsdWUsIExQU1RSIGxwc3pWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaFZhbHVlLCBMUERXT1JEIGxwZFJlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUFdTVFIJbHBzelZhbHVlVzsKCUxQQllURQlscGJEYXRhVzsKCURXT1JECXJldCxscGNiRGF0YVc7CglEV09SRCBkd1R5cGU7CgoJVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSwKCQlscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhKTsKCglscHN6VmFsdWVXID0gKExQV1NUUil4bWFsbG9jKCpscGNjaFZhbHVlKjIpOwoJaWYgKGxwYkRhdGEpIHsKCQlscGJEYXRhVyA9IChMUEJZVEUpeG1hbGxvYygqbHBjYkRhdGEqMik7CgkJbHBjYkRhdGFXID0gKmxwY2JEYXRhOwoJfSBlbHNlCgkJbHBiRGF0YVcgPSBOVUxMOwoKCXJldCA9IFJlZ0VudW1WYWx1ZVcoIGhrZXksIGlWYWx1ZSwgbHBzelZhbHVlVywgbHBjY2hWYWx1ZSwgCgkJCQlscGRSZXNlcnZlZCwgJmR3VHlwZSwgbHBiRGF0YVcsICZscGNiRGF0YVcgKTsKCglpZiAobHBkd1R5cGUpCgkJKmxwZHdUeXBlID0gZHdUeXBlOwoKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MpIHsKCQlsc3RyY3B5V3RvQShscHN6VmFsdWUsbHBzelZhbHVlVyk7CgkJaWYgKGxwYkRhdGEpIHsKCQkJaWYgKCgxPDxkd1R5cGUpICYgVU5JQ09OVk1BU0spIHsKCQkJCWxzdHJjcHlXdG9BKGxwYkRhdGEsKExQV1NUUilscGJEYXRhVyk7CgkJCX0gZWxzZSB7CgkJCQlpZiAobHBjYkRhdGFXID4gKmxwY2JEYXRhKQoJCQkJCXJldAk9IEVSUk9SX01PUkVfREFUQTsKCQkJCWVsc2UKCQkJCQltZW1jcHkobHBiRGF0YSxscGJEYXRhVyxscGNiRGF0YVcpOwoJCQl9CgkJCSpscGNiRGF0YSA9IGxwY2JEYXRhVzsKCQl9Cgl9CiAgICBpZiAobHBiRGF0YVcpIGZyZWUobHBiRGF0YVcpOwogICAgaWYgKGxwc3pWYWx1ZVcpIGZyZWUobHBzelZhbHVlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUxNiBbS0VSTkVMLjIyM10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUxNiggSEtFWSBoa2V5LCBEV09SRCBpVmFsdWUsIExQU1RSIGxwc3pWYWx1ZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaFZhbHVlLCBMUERXT1JEIGxwZFJlc2VydmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsCiAgICAgICAgICBscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhKTsKICAgIHJldHVybiBSZWdFbnVtVmFsdWVBKCBoa2V5LCBpVmFsdWUsIGxwc3pWYWx1ZSwgbHBjY2hWYWx1ZSwgbHBkUmVzZXJ2ZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBkd1R5cGUsIGxwYkRhdGEsIGxwY2JEYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nsb3NlS2V5IFtTSEVMTC4zXSBbS0VSTkVMLjIyMF0gW0FEVkFQSTMyLjEyNl0KICogUmVsZWFzZXMgdGhlIGhhbmRsZSBvZiB0aGUgc3BlY2lmaWVkIGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byBjbG9zZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0Nsb3NlS2V5KCBIS0VZIGhrZXkgKQp7CiAgICBUUkFDRShyZWcsIigleClcbiIsaGtleSk7CgogICAgLyogVGhlIHN0YW5kYXJkIGhhbmRsZXMgYXJlIGFsbG93ZWQgdG8gc3VjY2VlZCwgZXZlbiB0aG91Z2ggdGhleSBhcmUgbm90CiAgICAgICBjbG9zZWQgKi8KICAgIGlmIChpc19zdGFuZGFyZF9oa2V5KGhrZXkpKQogICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwoKICAgIHJldHVybiByZW1vdmVfaGFuZGxlKGhrZXkpOwp9CgoKLyogCiAqIERlbGV0ZSByZWdpc3RyeSBrZXkKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZUtleTE2IC0+IFJlZ0RlbGV0ZUtleTMyQSAtPiBSZWdEZWxldGVLZXkzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVLZXkzMlcgW0FEVkFQSTMyLjEzNF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldIEhhbmRsZSB0byBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5IFtJXSBOYW1lIG9mIHN1YmtleSB0byBkZWxldGUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXlXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6U3ViS2V5ICkKewoJTFBLRVlTVFJVQ1QJKmxwbHBQcmV2S2V5LGxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIFN1YmtleSBwYXJhbSBjYW5ub3QgYmUgTlVMTCAqLwogICAgaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkKICAgICAgICByZXR1cm4gRVJST1JfQkFES0VZOwoKICAgIC8qIFdlIG5lZWQgdG8ga25vdyB0aGUgcHJldmlvdXMga2V5IGluIHRoZSBoaWVyLiAqLwoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7CglscHhrZXkJPSBscE5leHRLZXk7Cgl3aGlsZSAoaTx3cGMtMSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlUUkFDRShyZWcsICIgIFNjYW5uaW5nIFslc11cbiIsCgkJCQkgICAgIGRlYnVnc3RyX3cobHB4a2V5LT5rZXluYW1lKSk7CgkJCWlmICghbHN0cmNtcGlXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KSB7CgkJCUZSRUVfS0VZX1BBVEg7CgkJCVRSQUNFKHJlZywgIiAgTm90IGZvdW5kLlxuIik7CgkJCS8qIG5vdCBmb3VuZCBpcyBzdWNjZXNzICovCgkJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJCX0KCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJbHB4a2V5CT0gbHBOZXh0S2V5LT5uZXh0c3ViOwoJbHBscFByZXZLZXkgPSAmKGxwTmV4dEtleS0+bmV4dHN1Yik7Cgl3aGlsZSAobHB4a2V5KSB7CgkJVFJBQ0UocmVnLCAiICBTY2FubmluZyBbJXNdXG4iLAoJCQkgICAgIGRlYnVnc3RyX3cobHB4a2V5LT5rZXluYW1lKSk7CgkJaWYgKCFsc3RyY21waVcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCWJyZWFrOwoJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCWxweGtleQkJPSBscHhrZXktPm5leHQ7Cgl9CgoJaWYgKCFscHhrZXkpIHsKCQlGUkVFX0tFWV9QQVRIOwoJCVdBUk4ocmVnICwgIiAgTm90IGZvdW5kLlxuIik7CgkJcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoJfQoKCWlmIChscHhrZXktPm5leHRzdWIpIHsKCQlGUkVFX0tFWV9QQVRIOwoJCVdBUk4ocmVnICwgIiAgTm90IGVtcHR5LlxuIik7CgkJcmV0dXJuIEVSUk9SX0NBTlRXUklURTsKCX0KCSpscGxwUHJldktleQk9IGxweGtleS0+bmV4dDsKCWZyZWUobHB4a2V5LT5rZXluYW1lKTsKCWlmIChscHhrZXktPmNsYXNzKQoJCWZyZWUobHB4a2V5LT5jbGFzcyk7CglpZiAobHB4a2V5LT52YWx1ZXMpCgkJZnJlZShscHhrZXktPnZhbHVlcyk7CglmcmVlKGxweGtleSk7CglGUkVFX0tFWV9QQVRIOwoJVFJBQ0UocmVnLCAiICBEb25lLlxuIik7CglyZXR1cm4JRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlS2V5MzJBIFtBRFZBUEkzMi4xMzNdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSApCnsKICAgIExQV1NUUiBscHN6U3ViS2V5VzsKICAgIERXT1JEICByZXQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSk7CiAgICBscHN6U3ViS2V5VyA9IGxwc3pTdWJLZXk/c3RyZHVwQTJXKGxwc3pTdWJLZXkpOk5VTEw7CiAgICByZXQgPSBSZWdEZWxldGVLZXlXKCBoa2V5LCBscHN6U3ViS2V5VyApOwogICAgaWYobHBzelN1YktleVcpIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlS2V5MTYgW1NIRUxMLjRdIFtLRVJORUwuMjE5XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSk7CiAgICByZXR1cm4gUmVnRGVsZXRlS2V5QSggaGtleSwgbHBzelN1YktleSApOwp9CgoKLyogCiAqIERlbGV0ZSByZWdpc3RyeSB2YWx1ZQogKgogKiBDYWxscGF0aDoKICogUmVnRGVsZXRlVmFsdWUxNiAtPiBSZWdEZWxldGVWYWx1ZTMyQSAtPiBSZWdEZWxldGVWYWx1ZTMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZVZhbHVlMzJXIFtBRFZBUEkzMi4xMzZdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgW0ldCiAqICAgIGxwc3pWYWx1ZSBbSV0KICoKICogUkVUVVJOUwogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzelZhbHVlICkKewoJRFdPUkQJCWk7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelZhbHVlKSk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJaWYgKGxwc3pWYWx1ZSkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXBpVyhscGtleS0+dmFsdWVzW2ldLm5hbWUsbHBzelZhbHVlKQoJCQkpCgkJCQlicmVhazsKCX0gZWxzZSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCX0KCiAgICBpZiAoaSA9PSBscGtleS0+bnJvZnZhbHVlcykKICAgICAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7CgoJdmFsCT0gbHBrZXktPnZhbHVlcytpOwoJaWYgKHZhbC0+bmFtZSkgZnJlZSh2YWwtPm5hbWUpOwoJaWYgKHZhbC0+ZGF0YSkgZnJlZSh2YWwtPmRhdGEpOwoJbWVtY3B5KAkKCQlscGtleS0+dmFsdWVzK2ksCgkJbHBrZXktPnZhbHVlcytpKzEsCgkJc2l6ZW9mKEtFWVZBTFVFKSoobHBrZXktPm5yb2Z2YWx1ZXMtaS0xKQoJKTsKCWxwa2V5LT52YWx1ZXMJPSAoTFBLRVlWQUxVRSl4cmVhbGxvYygKCQkJCWxwa2V5LT52YWx1ZXMsCgkJCQkobHBrZXktPm5yb2Z2YWx1ZXMtMSkqc2l6ZW9mKEtFWVZBTFVFKQoJCQkpOwoJbHBrZXktPm5yb2Z2YWx1ZXMtLTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVWYWx1ZTMyQSBbQURWQVBJMzIuMTM1XQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlQSggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWUgKQp7CiAgICBMUFdTVFIgbHBzelZhbHVlVzsKICAgIERXT1JEICByZXQ7CgogICAgVFJBQ0UocmVnLCAiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlKSk7CiAgICBscHN6VmFsdWVXID0gbHBzelZhbHVlP3N0cmR1cEEyVyhscHN6VmFsdWUpOk5VTEw7CiAgICByZXQgPSBSZWdEZWxldGVWYWx1ZVcoIGhrZXksIGxwc3pWYWx1ZVcgKTsKICAgIGlmKGxwc3pWYWx1ZVcpIGZyZWUobHBzelZhbHVlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVWYWx1ZTE2IFtLRVJORUwuMjIyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLCBoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlKSk7CiAgICByZXR1cm4gUmVnRGVsZXRlVmFsdWVBKCBoa2V5LCBscHN6VmFsdWUgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRmx1c2hLZXkgW0tFUk5FTC4yMjddIFtBRFZBUEkzMi4xNDNdCiAqIFdyaXRlcyBrZXkgdG8gcmVnaXN0cnkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgW0ldIEhhbmRsZSBvZiBrZXkgdG8gd3JpdGUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdGbHVzaEtleSggSEtFWSBoa2V5ICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CiAgICBCT09MIHJldDsKCiAgICBUUkFDRShyZWcsICIoJXgpXG4iLCBoa2V5KTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9CQURLRVk7CgogICAgRVJSKHJlZywgIldoYXQgaXMgdGhlIGNvcnJlY3QgZmlsZW5hbWU/XG4iKTsKCiAgICByZXQgPSBfc2F2ZXJlZyggbHBrZXksICJmb28uYmFyIiwgVFJVRSk7CgogICAgaWYoIHJldCApIHsKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKICAgIH0gZWxzZQogICAgICAgIHJldHVybiBFUlJPUl9VTktOT1dOOyAgLyogRklYTUUgKi8KfQoKCi8qIEZJWE1FOiBscGNjaFhYWFggLi4uIGlzIHRoaXMgY291bnRpbmcgaW4gV0NIQVJTIG9yIGluIEJZVEVzID8/ICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeUluZm9LZXkzMlcgW0FEVkFQSTMyLjE1M10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICAgICAgICAgW0ldIEhhbmRsZSB0byBrZXkgdG8gcXVlcnkKICogICAgbHBzekNsYXNzICAgICAgICAgICAgICBbT10gQnVmZmVyIGZvciBjbGFzcyBzdHJpbmcKICogICAgbHBjY2hDbGFzcyAgICAgICAgICAgICBbT10gU2l6ZSBvZiBjbGFzcyBzdHJpbmcgYnVmZmVyCiAqICAgIGxwZHdSZXNlcnZlZCAgICAgICAgICAgW0ldIFJlc2VydmVkCiAqICAgIGxwY1N1YktleXMgICAgICAgICAgICAgW0ldIEJ1ZmZlciBmb3IgbnVtYmVyIG9mIHN1YmtleXMKICogICAgbHBjY2hNYXhTdWJLZXkgICAgICAgICBbT10gQnVmZmVyIGZvciBsb25nZXN0IHN1YmtleSBuYW1lIGxlbmd0aAogKiAgICBscGNjaE1heENsYXNzICAgICAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3QgY2xhc3Mgc3RyaW5nIGxlbmd0aAogKiAgICBscGNWYWx1ZXMgICAgICAgICAgICAgIFtPXSBCdWZmZXIgZm9yIG51bWJlciBvZiB2YWx1ZSBlbnRyaWVzCiAqICAgIGxwY2NoTWF4VmFsdWVOYW1lICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCB2YWx1ZSBuYW1lIGxlbmd0aAogKiAgICBscGNjYk1heFZhbHVlRGF0YSAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3QgdmFsdWUgZGF0YSBsZW5ndGgKICogICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciBbT10gQnVmZmVyIGZvciBzZWN1cml0eSBkZXNjcmlwdG9yIGxlbmd0aAogKiAgICBmdAogKiAtIHdpbjk1IGFsbG93cyBscHN6Q2xhc3MgdG8gYmUgdmFsaWQgYW5kIGxwY2NoQ2xhc3MgdG8gYmUgTlVMTCAKICogLSB3aW5udCByZXR1cm5zIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSIGlmIGxwc3pDbGFzcyBpcyB2YWxpZCBhbmQKICogICBscGNjaENsYXNzIGlzIE5VTEwKICogLSBib3RoIGFsbG93IGxwc3pDbGFzcyB0byBiZSBOVUxMIGFuZCBscGNjaENsYXNzIHRvIGJlIE5VTEwgCiAqIChpdCdzIGhhcmQgdG8gdGVzdCB2YWxpZGl0eSwgc28gdGVzdCAhTlVMTCBpbnN0ZWFkKQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5SW5mb0tleVcoIEhLRVkgaGtleSwgTFBXU1RSIGxwc3pDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hDbGFzcywgTFBEV09SRCBscGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjU3ViS2V5cywgTFBEV09SRCBscGNjaE1heFN1YmtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE1heENsYXNzLCBMUERXT1JEIGxwY1ZhbHVlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE1heFZhbHVlTmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2JNYXhWYWx1ZURhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JTZWN1cml0eURlc2NyaXB0b3IsIEZJTEVUSU1FICpmdCApCnsKCUxQS0VZU1RSVUNUCWxwa2V5LGxweGtleTsKCWludAkJbnJvZmtleXMsbWF4c3Via2V5LG1heGNsYXNzLG1heHZuYW1lLG1heHZkYXRhOwoJaW50CQlpOwoKCVRSQUNFKHJlZywiKCV4LCVwLC4uLilcbiIsaGtleSxscHN6Q2xhc3MpOwoJbHBrZXkgPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoJaWYgKGxwc3pDbGFzcykgewogICAJICAgICAgICBpZiAoVkVSU0lPTl9HZXRWZXJzaW9uKCkgPT0gTlQ0MCAmJiBscGNjaENsYXNzID09IE5VTEwpIHsKCQkgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoJCX0KCQkvKiBlaXRoZXIgbHBjY2hDbGFzcyBpcyB2YWxpZCBvciB0aGlzIGlzIHdpbjk1IGFuZCBscGNjaENsYXNzCgkJICAgY291bGQgYmUgaW52YWxpZCAqLwoJCWlmIChscGtleS0+Y2xhc3MpIHsKCQkgICAgICAgIERXT1JEIGNsYXNzTGVuID0gbHN0cmxlblcobHBrZXktPmNsYXNzKTsKCgkJCWlmIChscGNjaENsYXNzICYmIGNsYXNzTGVuKzE+KmxwY2NoQ2xhc3MpIHsKCQkJCSpscGNjaENsYXNzPWNsYXNzTGVuKzE7CgkJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCQl9CgkJCWlmIChscGNjaENsYXNzKQoJCQkgICAgKmxwY2NoQ2xhc3M9Y2xhc3NMZW47CgkJCW1lbWNweShscHN6Q2xhc3MsbHBrZXktPmNsYXNzLCBjbGFzc0xlbioyICsgMik7CgkJfSBlbHNlIHsKCQkJKmxwc3pDbGFzcwk9IDA7CgkJCWlmIChscGNjaENsYXNzKQoJCQkgICAgKmxwY2NoQ2xhc3MJPSAwOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGxwY2NoQ2xhc3MpCgkJCSpscGNjaENsYXNzCT0gbHN0cmxlblcobHBrZXktPmNsYXNzKTsKCX0KCWxweGtleT1scGtleS0+bmV4dHN1YjsKCW5yb2ZrZXlzPW1heHN1YmtleT1tYXhjbGFzcz1tYXh2bmFtZT1tYXh2ZGF0YT0wOwoJd2hpbGUgKGxweGtleSkgewoJCW5yb2ZrZXlzKys7CgkJaWYgKGxzdHJsZW5XKGxweGtleS0+a2V5bmFtZSk+bWF4c3Via2V5KQoJCQltYXhzdWJrZXk9bHN0cmxlblcobHB4a2V5LT5rZXluYW1lKTsKCQlpZiAobHB4a2V5LT5jbGFzcyAmJiBsc3RybGVuVyhscHhrZXktPmNsYXNzKT5tYXhjbGFzcykKCQkJbWF4Y2xhc3M9bHN0cmxlblcobHB4a2V5LT5jbGFzcyk7CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJTFBLRVlWQUxVRQl2YWw9bHBrZXktPnZhbHVlcytpOwoKCQlpZiAodmFsLT5uYW1lICYmIGxzdHJsZW5XKHZhbC0+bmFtZSk+bWF4dm5hbWUpCgkJCW1heHZuYW1lPWxzdHJsZW5XKHZhbC0+bmFtZSk7CgkJaWYgKHZhbC0+bGVuPm1heHZkYXRhKQoJCQltYXh2ZGF0YT12YWwtPmxlbjsKCX0KCWlmICghbWF4Y2xhc3MpIG1heGNsYXNzCT0gMTsKCWlmICghbWF4dm5hbWUpIG1heHZuYW1lCT0gMTsKCWlmIChscGNWYWx1ZXMpCgkJKmxwY1ZhbHVlcwk9IGxwa2V5LT5ucm9mdmFsdWVzOwoJaWYgKGxwY1N1YktleXMpCgkJKmxwY1N1YktleXMJPSBucm9ma2V5czsKCWlmIChscGNjaE1heFN1YmtleSkKCQkqbHBjY2hNYXhTdWJrZXkJPSBtYXhzdWJrZXk7CglpZiAobHBjY2hNYXhDbGFzcykKCQkqbHBjY2hNYXhDbGFzcwk9IG1heGNsYXNzOwoJaWYgKGxwY2NoTWF4VmFsdWVOYW1lKQoJCSpscGNjaE1heFZhbHVlTmFtZT0gbWF4dm5hbWU7CglpZiAobHBjY2JNYXhWYWx1ZURhdGEpCgkJKmxwY2NiTWF4VmFsdWVEYXRhPSBtYXh2ZGF0YTsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeUluZm9LZXkzMkEgW0FEVkFQSTMyLjE1Ml0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeUluZm9LZXlBKCBIS0VZIGhrZXksIExQU1RSIGxwc3pDbGFzcywgTFBEV09SRCBscGNjaENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGNTdWJLZXlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTWF4U3Via2V5LCBMUERXT1JEIGxwY2NoTWF4Q2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjVmFsdWVzLCBMUERXT1JEIGxwY2NoTWF4VmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NiTWF4VmFsdWVEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yLCBGSUxFVElNRSAqZnQgKQp7CglMUFdTVFIJCWxwc3pDbGFzc1cgPSBOVUxMOwoJRFdPUkQJCXJldDsKCglUUkFDRShyZWcsIigleCwlcCwlcC4uLi4uLilcbiIsaGtleSwgbHBzekNsYXNzLCBscGNjaENsYXNzKTsKCWlmIChscHN6Q2xhc3MpIHsKCQlpZiAobHBjY2hDbGFzcykgewoJCSAgICBscHN6Q2xhc3NXICA9IChMUFdTVFIpeG1hbGxvYygoKmxwY2NoQ2xhc3MpICogMik7CgkJfSBlbHNlIGlmIChWRVJTSU9OX0dldFZlcnNpb24oKSA9PSBXSU45NSkgewoJCSAgICAvKiB3aW45NSAgYWxsb3dzIGxwY2NoQ2xhc3MgdG8gYmUgbnVsbCAqLwoJCSAgICAvKiB3ZSBkb24ndCBrbm93IGhvdyBiaWcgbHBzekNsYXNzIGlzLCB3b3VsZCAKCQkgICAgICAgTUFYX1BBVEhOQU1FX0xFTiBiZSB0aGUgY29ycmVjdCBkZWZhdWx0PyAqLwoJCSAgICBscHN6Q2xhc3NXICA9IChMUFdTVFIpeG1hbGxvYyhNQVhfUEFUSE5BTUVfTEVOKjIpOyAKCQl9CgoJfSBlbHNlCgkJbHBzekNsYXNzVyAgPSBOVUxMOwoJcmV0PVJlZ1F1ZXJ5SW5mb0tleVcoCgkJaGtleSwKCQlscHN6Q2xhc3NXLAoJCWxwY2NoQ2xhc3MsCgkJbHBkd1Jlc2VydmVkLAoJCWxwY1N1YktleXMsCgkJbHBjY2hNYXhTdWJrZXksCgkJbHBjY2hNYXhDbGFzcywKCQlscGNWYWx1ZXMsCgkJbHBjY2hNYXhWYWx1ZU5hbWUsCgkJbHBjY2JNYXhWYWx1ZURhdGEsCgkJbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwKCQlmdAoJKTsKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MgJiYgbHBzekNsYXNzKQoJCWxzdHJjcHlXdG9BKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnkzMlcgW0FEVkFQSTMyLjEyOF0KICoKICogUEFSQU1TCiAqICAgIGxwTWFjaGluZU5hbWUgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiByZW1vdGUgY29tcHV0ZXIKICogICAgaEhleSAgICAgICAgICBbSV0gUHJlZGVmaW5lZCByZWdpc3RyeSBoYW5kbGUKICogICAgcGhrUmVzdWx0ICAgICBbSV0gQWRkcmVzcyBvZiBidWZmZXIgZm9yIHJlbW90ZSByZWdpc3RyeSBoYW5kbGUKICovCkxPTkcgV0lOQVBJIFJlZ0Nvbm5lY3RSZWdpc3RyeVcoIExQQ1dTVFIgbHBNYWNoaW5lTmFtZSwgSEtFWSBoS2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEhLRVkgcGhrUmVzdWx0ICkKewogICAgVFJBQ0UocmVnLCIoJXMsJXgsJXApOiBzdHViXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSksaEtleSxwaGtSZXN1bHQpOwoKICAgIGlmICghbHBNYWNoaW5lTmFtZSB8fCAhKmxwTWFjaGluZU5hbWUpIHsKICAgICAgICAvKiBVc2UgdGhlIGxvY2FsIG1hY2hpbmUgbmFtZSAqLwogICAgICAgIHJldHVybiBSZWdPcGVuS2V5MTYoIGhLZXksICIiLCBwaGtSZXN1bHQgKTsKICAgIH0KCiAgICBGSVhNRShyZWcsIkNhbm5vdCBjb25uZWN0IHRvICVzXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSkpOwogICAgcmV0dXJuIEVSUk9SX0JBRF9ORVRQQVRIOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnkzMkEgW0FEVkFQSTMyLjEyN10KICovCkxPTkcgV0lOQVBJIFJlZ0Nvbm5lY3RSZWdpc3RyeUEoIExQQ1NUUiBtYWNoaW5lLCBIS0VZIGhrZXksIExQSEtFWSByZXNrZXkgKQp7CiAgICBEV09SRCByZXQ7CiAgICBMUFdTVFIgbWFjaGluZVcgPSBzdHJkdXBBMlcobWFjaGluZSk7CiAgICByZXQgPSBSZWdDb25uZWN0UmVnaXN0cnlXKCBtYWNoaW5lVywgaGtleSwgcmVza2V5ICk7CiAgICBmcmVlKG1hY2hpbmVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0dldEtleVNlY3VyaXR5IFtBRFZBUEkzMi4xNDRdCiAqIFJldHJpZXZlcyBhIGNvcHkgb2Ygc2VjdXJpdHkgZGVzY3JpcHRvciBwcm90ZWN0aW5nIHRoZSByZWdpc3RyeSBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICAgICAgICAgW0ldICAgT3BlbiBoYW5kbGUgb2Yga2V5IHRvIHNldAogKiAgICBTZWN1cml0eUluZm9ybWF0aW9uICAgIFtJXSAgIERlc2NyaXB0b3IgY29udGVudHMKICogICAgcFNlY3VyaXR5RGVzY3JpcHRvciAgICBbT10gICBBZGRyZXNzIG9mIGRlc2NyaXB0b3IgZm9yIGtleQogKiAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yIFtJL09dIEFkZHJlc3Mgb2Ygc2l6ZSBvZiBidWZmZXIgYW5kIGRlc2NyaXB0aW9uCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpMT05HIFdJTkFQSSBSZWdHZXRLZXlTZWN1cml0eSggSEtFWSBoa2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFQ1VSSVRZX0lORk9STUFUSU9OIFNlY3VyaXR5SW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU0VDVVJJVFlfREVTQ1JJUFRPUiBwU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxTZWN1cml0eUluZm9ybWF0aW9uLHBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICBscGNiU2VjdXJpdHlEZXNjcmlwdG9yPypscGNiU2VjdXJpdHlEZXNjcmlwdG9yOjApOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIEZJWE1FOiBDaGVjayBmb3IgdmFsaWQgU2VjdXJpdHlJbmZvcm1hdGlvbiB2YWx1ZXMgKi8KCiAgICBpZiAoKmxwY2JTZWN1cml0eURlc2NyaXB0b3IgPCBzaXplb2YoU0VDVVJJVFlfREVTQ1JJUFRPUikpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVI7CgogICAgRklYTUUocmVnLCAiKCV4LCVsZCwlcCwlbGQpOiBzdHViXG4iLGhrZXksU2VjdXJpdHlJbmZvcm1hdGlvbiwKICAgICAgICAgIHBTZWN1cml0eURlc2NyaXB0b3IsbHBjYlNlY3VyaXR5RGVzY3JpcHRvcj8qbHBjYlNlY3VyaXR5RGVzY3JpcHRvcjowKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTG9hZEtleTMyVyBbQURWQVBJMzIuPz8/XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkKICogICAgbHBzekZpbGUgICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgcmVnaXN0cnkgaW5mb3JtYXRpb24KICovCkxPTkcgV0lOQVBJIFJlZ0xvYWRLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBDV1NUUiBscHN6RmlsZSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxkZWJ1Z3N0cl93KGxwc3pGaWxlKSk7CgogICAgLyogRG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkgfHwgIWxwc3pGaWxlIHx8ICEqbHBzekZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywiKCV4LCVzLCVzKTogc3R1YlxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwc3pGaWxlKSk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0xvYWRLZXkzMkEgW0FEVkFQSTMyLj8/P10KICovCkxPTkcgV0lOQVBJIFJlZ0xvYWRLZXlBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBMUENTVFIgbHBzekZpbGUgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscHN6U3ViS2V5VyA9IHN0cmR1cEEyVyhscHN6U3ViS2V5KTsKICAgIExQV1NUUiBscHN6RmlsZVcgPSBzdHJkdXBBMlcobHBzekZpbGUpOwogICAgcmV0ID0gUmVnTG9hZEtleVcoIGhrZXksIGxwc3pTdWJLZXlXLCBscHN6RmlsZVcgKTsKICAgIGlmKGxwc3pGaWxlVykgZnJlZShscHN6RmlsZVcpOwogICAgaWYobHBzelN1YktleVcpIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTm90aWZ5Q2hhbmdlS2V5VmFsdWUgW0FEVkFQSTMyLj8/P10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICBbSV0gSGFuZGxlIG9mIGtleSB0byB3YXRjaAogKiAgICBmV2F0Y2hTdWJUcmVlICAgW0ldIEZsYWcgZm9yIHN1YmtleSBub3RpZmljYXRpb24KICogICAgZmR3Tm90aWZ5RmlsdGVyIFtJXSBDaGFuZ2VzIHRvIGJlIHJlcG9ydGVkCiAqICAgIGhFdmVudCAgICAgICAgICBbSV0gSGFuZGxlIG9mIHNpZ25hbGVkIGV2ZW50CiAqICAgIGZBc3luYyAgICAgICAgICBbSV0gRmxhZyBmb3IgYXN5bmNocm9ub3VzIHJlcG9ydGluZwogKi8KTE9ORyBXSU5BUEkgUmVnTm90aWZ5Q2hhbmdlS2V5VmFsdWUoIEhLRVkgaGtleSwgQk9PTCBmV2F0Y2hTdWJUcmVlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGZkd05vdGlmeUZpbHRlciwgSEFORExFIGhFdmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgZkFzeW5jICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CiAgICBUUkFDRShyZWcsIigleCwlaSwlbGQsJXgsJWkpXG4iLGhrZXksZldhdGNoU3ViVHJlZSxmZHdOb3RpZnlGaWx0ZXIsCiAgICAgICAgICBoRXZlbnQsZkFzeW5jKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsIigleCwlaSwlbGQsJXgsJWkpOiBzdHViXG4iLGhrZXksZldhdGNoU3ViVHJlZSxmZHdOb3RpZnlGaWx0ZXIsCiAgICAgICAgICBoRXZlbnQsZkFzeW5jKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnVW5Mb2FkS2V5MzJXIFtBRFZBUEkzMi4xNzNdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwU3ViS2V5IFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5IHRvIHVubG9hZAogKi8KTE9ORyBXSU5BUEkgUmVnVW5Mb2FkS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwU3ViS2V5ICkKewogICAgRklYTUUocmVnLCIoJXgsJXMpOiBzdHViXG4iLGhrZXksIGRlYnVnc3RyX3cobHBTdWJLZXkpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXkzMkEgW0FEVkFQSTMyLjE3Ml0KICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5ICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBTdWJLZXlXID0gc3RyZHVwQTJXKGxwU3ViS2V5KTsKICAgIHJldCA9IFJlZ1VuTG9hZEtleVcoIGhrZXksIGxwU3ViS2V5VyApOwogICAgaWYobHBTdWJLZXlXKSBmcmVlKGxwU3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTY3XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICBbSV0gT3BlbiBoYW5kbGUgb2Yga2V5IHRvIHNldAogKiAgICBTZWN1cml0eUluZm8gIFtJXSBEZXNjcmlwdG9yIGNvbnRlbnRzCiAqICAgIHBTZWN1cml0eURlc2MgW0ldIEFkZHJlc3Mgb2YgZGVzY3JpcHRvciBmb3Iga2V5CiAqLwpMT05HIFdJTkFQSSBSZWdTZXRLZXlTZWN1cml0eSggSEtFWSBoa2V5LCBTRUNVUklUWV9JTkZPUk1BVElPTiBTZWN1cml0eUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU0VDVVJJVFlfREVTQ1JJUFRPUiBwU2VjdXJpdHlEZXNjICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwKVxuIixoa2V5LFNlY3VyaXR5SW5mbyxwU2VjdXJpdHlEZXNjKTsKCiAgICAvKiBJdCBzZWVtcyB0byBwZXJmb3JtIHRoaXMgY2hlY2sgYmVmb3JlIHRoZSBoa2V5IGNoZWNrICovCiAgICBpZiAoKFNlY3VyaXR5SW5mbyAmIE9XTkVSX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBHUk9VUF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgREFDTF9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgU0FDTF9TRUNVUklUWV9JTkZPUk1BVElPTikpIHsKICAgICAgICAvKiBQYXJhbSBPSyAqLwogICAgfSBlbHNlCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGlmICghcFNlY3VyaXR5RGVzYykKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUUocmVnLCI6KCV4LCVsZCwlcCk6IHN0dWJcbiIsaGtleSxTZWN1cml0eUluZm8scFNlY3VyaXR5RGVzYyk7CgogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NhdmVLZXkzMlcgW0FEVkFQSTMyLjE2Nl0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICBbSV0gSGFuZGxlIG9mIGtleSB3aGVyZSBzYXZlIGJlZ2lucwogKiAgICBscEZpbGUgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgdG8gc2F2ZSB0bwogKiAgICBzYSAgICAgW0ldIEFkZHJlc3Mgb2Ygc2VjdXJpdHkgc3RydWN0dXJlCiAqLwpMT05HIFdJTkFQSSBSZWdTYXZlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwRmlsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBzYSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFKHJlZywgIigleCwlcywlcClcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBGaWxlKSwgc2EpOwoKICAgIC8qIEl0IGFwcGVhcnMgdG8gZG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBGaWxlIHx8ICEqbHBGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsICIoJXgsJXMsJXApOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwRmlsZSksIHNhKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2F2ZUtleTMyQSBbQURWQVBJMzIuMTY1XQogKi8KTE9ORyBXSU5BUEkgUmVnU2F2ZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwRmlsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBzYSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwRmlsZVcgPSBzdHJkdXBBMlcobHBGaWxlKTsKICAgIHJldCA9IFJlZ1NhdmVLZXlXKCBoa2V5LCBscEZpbGVXLCBzYSApOwogICAgZnJlZShscEZpbGVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1Jlc3RvcmVLZXkzMlcgW0FEVkFQSTMyLjE2NF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgcmVzdG9yZSBiZWdpbnMKICogICAgbHBGaWxlICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBjb250YWluaW5nIHNhdmVkIHRyZWUKICogICAgZHdGbGFncyBbSV0gT3B0aW9uYWwgZmxhZ3MKICovCkxPTkcgV0lOQVBJIFJlZ1Jlc3RvcmVLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCAiKCV4LCVzLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl93KGxwRmlsZSksZHdGbGFncyk7CgogICAgLyogSXQgc2VlbXMgdG8gZG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBGaWxlIHx8ICEqbHBGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsIigleCwlcywlbGQpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIENoZWNrIGZvciBmaWxlIGV4aXN0ZW5jZSAqLwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5MzJBIFtBRFZBUEkzMi4xNjNdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBGaWxlVyA9IHN0cmR1cEEyVyhscEZpbGUpOwogICAgcmV0ID0gUmVnUmVzdG9yZUtleVcoIGhrZXksIGxwRmlsZVcsIGR3RmxhZ3MgKTsKICAgIGlmKGxwRmlsZVcpIGZyZWUobHBGaWxlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5MzJXIFtBRFZBUEkzMi4xNjJdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscFN1YktleSAgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkKICogICAgbHBOZXdGaWxlIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGZvciBmaWxlIHdpdGggbmV3IGRhdGEKICogICAgbHBPbGRGaWxlIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIGZvciBiYWNrdXAgZmlsZQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSwgTFBDV1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbHBPbGRGaWxlICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXMsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscFN1YktleSksCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsICIoJXgsJXMsJXMsJXMpOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwU3ViS2V5KSwgCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleTMyQSBbQURWQVBJMzIuMTYxXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5LCBMUENTVFIgbHBOZXdGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBPbGRGaWxlICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBTdWJLZXlXID0gc3RyZHVwQTJXKGxwU3ViS2V5KTsKICAgIExQV1NUUiBscE5ld0ZpbGVXID0gc3RyZHVwQTJXKGxwTmV3RmlsZSk7CiAgICBMUFdTVFIgbHBPbGRGaWxlVyA9IHN0cmR1cEEyVyhscE9sZEZpbGUpOwogICAgcmV0ID0gUmVnUmVwbGFjZUtleVcoIGhrZXksIGxwU3ViS2V5VywgbHBOZXdGaWxlVywgbHBPbGRGaWxlVyApOwogICAgZnJlZShscE9sZEZpbGVXKTsKICAgIGZyZWUobHBOZXdGaWxlVyk7CiAgICBmcmVlKGxwU3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9Cgo=