LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL2ZjbnRsLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDx0aW1lLmg+CiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5lL3dpbmVzdHJpbmcuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW52ZXJzaW9uLmgiCgpERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVnKQpERUNMQVJFX0RFQlVHX0NIQU5ORUwoc3RyaW5nKQoKc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCh2b2lkKTsKLyogRklYTUU6IGZvbGxvd2luZyBkZWZpbmVzIHNob3VsZCBiZSBjb25maWd1cmVkIGdsb2JhbCAuLi4gKi8KCi8qIE5PVEU6IGRvIG5vdCBhcHBlbmQgYSAvLiBsaW51eCcgbWtkaXIoKSBXSUxMIEZBSUwgaWYgeW91IGRvIHRoYXQgKi8KI2RlZmluZSBXSU5FX1BSRUZJWCAgICAgICAgICAgICAgICAgIi8ud2luZSIKI2RlZmluZSBTQVZFX1VTRVJTX0RFRkFVTFQgICAgICAgICAgIi91c3IvbG9jYWwvZXRjL3dpbmUudXNlcnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX01BQ0hJTkVfREVGQVVMVCAgIi91c3IvbG9jYWwvZXRjL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0NVUlJFTlRfVVNFUiAgICAgICAgICAgInVzZXIucmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCAgICAid2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORSAgICAgICAgICAic3lzdGVtLnJlZyIKCiNkZWZpbmUgS0VZX1JFR0lTVFJZICAgICAgICAgICAgICAgICJTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnkiCiNkZWZpbmUgVkFMX1NBVkVVUERBVEVEICAgICAgICAgICAgICJTYXZlT25seVVwZGF0ZWRLZXlzIgoKLyogb25lIHZhbHVlIG9mIGEga2V5ICovCnR5cGVkZWYgc3RydWN0IHRhZ0tFWVZBTFVFCnsKICAgIExQV1NUUiAgIG5hbWU7ICAgICAgICAgIC8qIG5hbWUgb2YgdmFsdWUgKFVOSUNPREUpIG9yIE5VTEwgZm9yIHdpbjMxICovCiAgICBEV09SRCAgICB0eXBlOyAgICAgICAgICAvKiB0eXBlIG9mIHZhbHVlICovCiAgICBEV09SRCAgICBsZW47ICAgICAgICAgICAvKiBsZW5ndGggb2YgZGF0YSBpbiBCWVRFcyAqLwogICAgRFdPUkQgICAgbGFzdG1vZGlmaWVkOyAgLyogdGltZSBvZiBzZWNvbmRzIHNpbmNlIDEuMS4xOTcwICovCiAgICBMUEJZVEUgICBkYXRhOyAgICAgICAgICAvKiBjb250ZW50LCBtYXkgYmUgc3RyaW5ncywgYmluYXJpZXMsIGV0Yy4gKi8KfSBLRVlWQUxVRSwqTFBLRVlWQUxVRTsKCi8qIGEgcmVnaXN0cnkga2V5ICovCnR5cGVkZWYgc3RydWN0IHRhZ0tFWVNUUlVDVAp7CiAgICBMUFdTVFIgICAgICAgICAgICAgICBrZXluYW1lOyAgICAgICAvKiBuYW1lIG9mIFRISVMga2V5IChVTklDT0RFKSAqLwogICAgRFdPUkQgICAgICAgICAgICAgICAgZmxhZ3M7ICAgICAgICAgLyogZmxhZ3MuICovCiAgICBMUFdTVFIgICAgICAgICAgICAgICBjbGFzczsKICAgIC8qIHZhbHVlcyAqLwogICAgRFdPUkQgICAgICAgICAgICAgICAgbnJvZnZhbHVlczsgICAgLyogbnIgb2YgdmFsdWVzIGluIFRISVMga2V5ICovCiAgICBMUEtFWVZBTFVFICAgICAgICAgICB2YWx1ZXM7ICAgICAgICAvKiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIC8qIGtleSBtYW5hZ2VtZW50IHBvaW50ZXJzICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0OyAgICAgICAgICAvKiBuZXh0IGtleSBvbiBzYW1lIGhpZXJhcmNoeSAqLwogICAgc3RydWN0IHRhZ0tFWVNUUlVDVAkqbmV4dHN1YjsgICAgICAgLyoga2V5cyB0aGF0IGhhbmcgYmVsb3cgVEhJUyBrZXkgKi8KfSBLRVlTVFJVQ1QsICpMUEtFWVNUUlVDVDsKCgpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY2xhc3Nlc19yb290PU5VTEw7CS8qIHdpbmRvd3MgMy4xIGdsb2JhbCB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X2N1cnJlbnRfdXNlcj1OVUxMOwkvKiB1c2VyIHNwZWNpZmljIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfbG9jYWxfbWFjaGluZT1OVUxMOy8qIG1hY2hpbmUgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV91c2Vycz1OVUxMOwkvKiBhbGwgdXNlcnM/ICovCgovKiBkeW5hbWljLCBub3Qgc2F2ZWQgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3BlcmZvcm1hbmNlX2RhdGE9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2N1cnJlbnRfY29uZmlnPU5VTEw7CnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9keW5fZGF0YT1OVUxMOwoKLyogd2hhdCB2YWx1ZXR5cGVzIGRvIHdlIG5lZWQgdG8gY29udmVydD8gKi8KI2RlZmluZSBVTklDT05WTUFTSwkoKDE8PFJFR19TWil8KDE8PFJFR19NVUxUSV9TWil8KDE8PFJFR19FWFBBTkRfU1opKQoKCnN0YXRpYyBzdHJ1Y3Qgb3BlbmhhbmRsZSB7CglMUEtFWVNUUlVDVAlscGtleTsKCUhLRVkJCWhrZXk7CglSRUdTQU0JCWFjY2Vzc21hc2s7Cn0gICpvcGVuaGFuZGxlcz1OVUxMOwpzdGF0aWMgaW50CW5yb2ZvcGVuaGFuZGxlcz0wOwovKiBTdGFydHMgYWZ0ZXIgMSBiZWNhdXNlIDAsMSBhcmUgcmVzZXJ2ZWQgZm9yIFdpbjE2ICovCi8qIE5vdGU6IFNob3VsZCBhbHdheXMgYmUgZXZlbiwgYXMgV2luOTUgQURWQVBJMzIuRExMIHJlc2VydmVzIG9kZAogICAgICAgICBIS0VZcyBmb3IgcmVtb3RlIHJlZ2lzdHJ5IGFjY2VzcyAqLwpzdGF0aWMgaW50CWN1cnJlbnRoYW5kbGU9MjsKCgovKgogKiBRVUVTVElPTgogKiAgIEFyZSB0aGVzZSBkb2luZyB0aGUgc2FtZSBhcyBIRUFQX3N0cmR1cEF0b1cgYW5kIEhFQVBfc3RyZHVwV3RvQT8KICogICBJZiBzbywgY2FuIHdlIHJlbW92ZSB0aGVtPwogKiBBTlNXRVIKICogICBObywgdGhlIG1lbW9yeSBoYW5kbGluZyBmdW5jdGlvbnMgYXJlIGNhbGxlZCB2ZXJ5IG9mdGVuIGluIGhlcmUsIAogKiAgIGp1c3QgcmVwbGFjaW5nIHRoZW0gYnkgSGVhcEFsbG9jKFN5c3RlbUhlYXAsLi4uKSBtYWtlcyByZWdpc3RyeQogKiAgIGxvYWRpbmcgMTAwIHRpbWVzIHNsb3dlci4gLU1NCiAqLwpzdGF0aWMgTFBXU1RSIHN0cmR1cEEyVyhMUENTVFIgc3JjKQp7CiAgICBpZihzcmMpIHsKCUxQV1NUUiBkZXN0PXhtYWxsb2MoMipzdHJsZW4oc3JjKSsyKTsKCWxzdHJjcHlBdG9XKGRlc3Qsc3JjKTsKCXJldHVybiBkZXN0OwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBMUFdTVFIgc3RyZHVwVyhMUENXU1RSIGEpIHsKCUxQV1NUUgliOwoJaW50CWxlbjsKCiAgICBpZihhKSB7CglsZW49c2l6ZW9mKFdDSEFSKSoobHN0cmxlblcoYSkrMSk7CgliPShMUFdTVFIpeG1hbGxvYyhsZW4pOwoJbWVtY3B5KGIsYSxsZW4pOwoJcmV0dXJuIGI7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKTFBXU1RSIHN0cmN2dEEyVyhMUENTVFIgc3JjLCBpbnQgbmNoYXJzKQoKewogICBMUFdTVFIgZGVzdCA9IHhtYWxsb2MgKDIgKiBuY2hhcnMgKyAyKTsKCiAgIGxzdHJjcHluQXRvVyhkZXN0LHNyYyxuY2hhcnMrMSk7CiAgIGRlc3RbbmNoYXJzXSA9IDA7CiAgIHJldHVybiBkZXN0Owp9Ci8qCiAqIHdlIG5lZWQgdG8gY29udmVydCBBIHRvIFcgd2l0aCAnXDAnIGluIHN0cmluZ3MgKE1VTFRJX1NaKSAKICovCgpzdGF0aWMgTFBXU1RSICBsbWVtY3B5bkF0b1coIExQV1NUUiBkc3QsIExQQ1NUUiBzcmMsIElOVCBuICkKewlMUFdTVFIgcCA9IGRzdDsKCglUUkFDRShyZWcsIlwiJXNcIiAlaVxuIixzcmMsIG4pOwoKCXdoaWxlIChuLS0gPiAwKSAqcCsrID0gKFdDSEFSKSh1bnNpZ25lZCBjaGFyKSpzcmMrKzsKCglyZXR1cm4gZHN0Owp9CnN0YXRpYyBMUFNUUiBsbWVtY3B5bld0b0EoIExQU1RSIGRzdCwgTFBDV1NUUiBzcmMsIElOVCBuICkKewlMUFNUUiBwID0gZHN0OwoKCVRSQUNFKHN0cmluZywiTFwiJXNcIiAlaVxuIixkZWJ1Z3N0cl93KHNyYyksIG4pOwoKCXdoaWxlIChuLS0gPiAwKSAqcCsrID0gKENIQVIpKnNyYysrOwoKCXJldHVybiBkc3Q7Cn0KCnN0YXRpYyB2b2lkIGRlYnVnX3ByaW50X3ZhbHVlIChMUEJZVEUgbHBiRGF0YSwgTFBLRVlWQUxVRSBrZXkpCnsKICBpZiAoVFJBQ0VfT04ocmVnKSAmJiBscGJEYXRhKSAKICB7IAogICAgc3dpdGNoKGtleS0+dHlwZSkKICAgIHsgCiAgICAgIGNhc2UgSEVYX1JFR19FWFBBTkRfU1o6CiAgICAgIGNhc2UgSEVYX1JFR19TWjoKICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgVFJBQ0UocmVnLCIgVmFsdWUgJXMsIERhdGEoc3opPSVzXG4iLCAKICAgICAgICAgIGRlYnVnc3RyX3coa2V5LT5uYW1lKSwgCiAgICAgICAgICBkZWJ1Z3N0cl93KChMUENXU1RSKWxwYkRhdGEpKTsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgSEVYX1JFR19EV09SRDoKICAgICAgY2FzZSBSRUdfRFdPUkQ6CiAgICAgICAgVFJBQ0UocmVnLCIgVmFsdWUgJXMsIERhdGEoZHdvcmQpPTB4JTA4bHhcbiIsCiAgICAgICAgICBkZWJ1Z3N0cl93KGtleS0+bmFtZSksIAogICAgICAgICAgKERXT1JEKSpscGJEYXRhKTsKICAgICAgICBicmVhazsKICAgIAogICAgICBjYXNlIEhFWF9SRUdfTVVMVElfU1o6CiAgICAgIGNhc2UgUkVHX01VTFRJX1NaOgogICAgICB7IAogICAgICAgIGludCBpOwogICAgICAgIExQQ1dTVFIgcHRyID0gKExQQ1dTVFIpbHBiRGF0YTsKICAgICAgICBmb3IgKGk9MDtwdHJbMF07aSsrKQogICAgICAgIHsgCiAgICAgICAgICBUUkFDRShyZWcsICIgVmFsdWUgJXMsIE1VTFRJX1NaKCVpPSVzKVxuIiwgCiAgICAgICAgICAgIGRlYnVnc3RyX3coa2V5LT5uYW1lKSwgCiAgICAgICAgICAgIGksIAogICAgICAgICAgICBkZWJ1Z3N0cl93KHB0cikpOwoKICAgICAgICAgIHB0ciArPSBsc3RybGVuVyhwdHIpKzE7CiAgICAgICAgfQogICAgICB9CiAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBIRVhfUkVHX05PTkU6CiAgICAgIGNhc2UgSEVYX1JFR19CSU5BUlk6CiAgICAgIGNhc2UgSEVYX1JFR19MSU5LOgogICAgICBjYXNlIEhFWF9SRUdfUkVTT1VSQ0VfTElTVDoKICAgICAgY2FzZSBIRVhfUkVHX0ZVTExfUkVTT1VSQ0VfREVTQ1JJUFRPUjoKICAgICAgY2FzZSBSRUdfTk9ORToKICAgICAgY2FzZSBSRUdfTElOSzoKICAgICAgY2FzZSBSRUdfUkVTT1VSQ0VfTElTVDoKICAgICAgY2FzZSBSRUdfRlVMTF9SRVNPVVJDRV9ERVNDUklQVE9SOgogICAgICBjYXNlIFJFR19CSU5BUlk6CiAgICAgIHsgCiAgICAgICAgY2hhciBzelRlbXBbMTAwXTsgICAgICAvKiAzKjMyICsgMyArIDEgKi8KICAgICAgICBpbnQgaTsKICAgICAgICBmb3IgKCBpID0gMDsgaSA8IGtleS0+bGVuIDsgaSsrKSAgICAgIAogICAgICAgIHsgCiAgICAgICAgICBzcHJpbnRmICgmKHN6VGVtcFtpKjNdKSwiJTAyeCAiLCBscGJEYXRhW2ldKTsKICAgICAgICAgIGlmIChpPj0zMSkKICAgICAgICAgIHsgCiAgICAgICAgICAgIHNwcmludGYgKCYoc3pUZW1wW2kqMyszXSksIi4uLiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgVFJBQ0UocmVnLCIgVmFsdWUgJXMsIERhdGEocmF3KT0oJXMpXG4iLCAKICAgICAgICAgIGRlYnVnc3RyX3coa2V5LT5uYW1lKSwgCiAgICAgICAgICBzelRlbXApOyAgICAgICAgICAgICAgICAgIAogICAgICB9CiAgICAgIGJyZWFrOwogICAgCiAgICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUocmVnLCAiIFZhbHVlICVzLCBVbmtub3duIGRhdGEgdHlwZSAlbGRcbiIsIAogICAgICAgICAgZGVidWdzdHJfdyhrZXktPm5hbWUpLCAKICAgICAgICAgIGtleS0+dHlwZSk7CiAgICB9IC8qIHN3aXRjaCAqLwogIH0gLyogaWYgKi8KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogaXNfc3RhbmRhcmRfaGtleSBbSW50ZXJuYWxdCiAqIERldGVybWluZXMgaWYgYSBoa2V5IGlzIGEgc3RhbmRhcmQga2V5CiAqLwpzdGF0aWMgQk9PTCBpc19zdGFuZGFyZF9oa2V5KCBIS0VZIGhrZXkgKQp7CiAgICBzd2l0Y2goaGtleSkgewogICAgICAgIGNhc2UgMHgwMDAwMDAwMDoKICAgICAgICBjYXNlIDB4MDAwMDAwMDE6CiAgICAgICAgY2FzZSBIS0VZX0NMQVNTRVNfUk9PVDoKICAgICAgICBjYXNlIEhLRVlfQ1VSUkVOVF9DT05GSUc6CiAgICAgICAgY2FzZSBIS0VZX0NVUlJFTlRfVVNFUjoKICAgICAgICBjYXNlIEhLRVlfTE9DQUxfTUFDSElORToKICAgICAgICBjYXNlIEhLRVlfVVNFUlM6CiAgICAgICAgY2FzZSBIS0VZX1BFUkZPUk1BTkNFX0RBVEE6CiAgICAgICAgY2FzZSBIS0VZX0RZTl9EQVRBOgogICAgICAgICAgICByZXR1cm4gVFJVRTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogYWRkX2hhbmRsZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBhZGRfaGFuZGxlKCBIS0VZIGhrZXksIExQS0VZU1RSVUNUIGxwa2V5LCBSRUdTQU0gYWNjZXNzbWFzayApCnsKICAgIGludCBpOwoKICAgIFRSQUNFKHJlZywiKDB4JXgsJXAsMHglbHgpXG4iLGhrZXksbHBrZXksYWNjZXNzbWFzayk7CiAgICAvKiBDaGVjayBmb3IgZHVwbGljYXRlcyAqLwogICAgZm9yIChpPTA7aTxucm9mb3BlbmhhbmRsZXM7aSsrKSB7CiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmxwa2V5PT1scGtleSkgewogICAgICAgICAgICAvKiBUaGlzIGlzIG5vdCByZWFsbHkgYW4gZXJyb3IgLSB0aGUgdXNlciBpcyBhbGxvd2VkIHRvIGNyZWF0ZQogICAgICAgICAgICAgICB0d28gKG9yIG1vcmUpIGhhbmRsZXMgdG8gdGhlIHNhbWUga2V5ICovCiAgICAgICAgICAgIC8qV0FSTihyZWcsICJBZGRpbmcga2V5ICVwIHR3aWNlXG4iLGxwa2V5KTsqLwogICAgICAgIH0KICAgICAgICBpZiAob3BlbmhhbmRsZXNbaV0uaGtleT09aGtleSkgewogICAgICAgICAgICBXQVJOKHJlZywgIkFkZGluZyBoYW5kbGUgJXggdHdpY2VcbiIsaGtleSk7CiAgICAgICAgfQogICAgfQogICAgb3BlbmhhbmRsZXM9eHJlYWxsb2MoIG9wZW5oYW5kbGVzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3RydWN0IG9wZW5oYW5kbGUpKihucm9mb3BlbmhhbmRsZXMrMSkpOwoKICAgIG9wZW5oYW5kbGVzW2ldLmxwa2V5ID0gbHBrZXk7CiAgICBvcGVuaGFuZGxlc1tpXS5oa2V5ID0gaGtleTsKICAgIG9wZW5oYW5kbGVzW2ldLmFjY2Vzc21hc2sgPSBhY2Nlc3NtYXNrOwogICAgbnJvZm9wZW5oYW5kbGVzKys7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGdldF9oYW5kbGUgW0ludGVybmFsXQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFBvaW50ZXIgdG8ga2V5CiAqICAgIEZhaWx1cmU6IE5VTEwKICovCnN0YXRpYyBMUEtFWVNUUlVDVCBnZXRfaGFuZGxlKCBIS0VZIGhrZXkgKQp7CiAgICBpbnQgaTsKCiAgICBmb3IgKGk9MDsgaTxucm9mb3BlbmhhbmRsZXM7IGkrKykKICAgICAgICBpZiAob3BlbmhhbmRsZXNbaV0uaGtleSA9PSBoa2V5KQogICAgICAgICAgICByZXR1cm4gb3BlbmhhbmRsZXNbaV0ubHBrZXk7CiAgICBXQVJOKHJlZywgIkNvdWxkIG5vdCBmaW5kIGhhbmRsZSAweCV4XG4iLGhrZXkpOwogICAgcmV0dXJuIE5VTEw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIHJlbW92ZV9oYW5kbGUgW0ludGVybmFsXQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byByZW1vdmUKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVSUk9SX0lOVkFMSURfSEFORExFCiAqLwpzdGF0aWMgRFdPUkQgcmVtb3ZlX2hhbmRsZSggSEtFWSBoa2V5ICkKewogICAgaW50IGk7CgogICAgZm9yIChpPTA7aTxucm9mb3BlbmhhbmRsZXM7aSsrKQogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KQogICAgICAgICAgICBicmVhazsKCiAgICBpZiAoaSA9PSBucm9mb3BlbmhhbmRsZXMpIHsKICAgICAgICBXQVJOKHJlZywgIkNvdWxkIG5vdCBmaW5kIGhhbmRsZSAweCV4XG4iLGhrZXkpOwogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKICAgIH0KCiAgICBtZW1jcHkoIG9wZW5oYW5kbGVzK2ksCiAgICAgICAgICAgIG9wZW5oYW5kbGVzK2krMSwKICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLWktMSkKICAgICk7CiAgICBvcGVuaGFuZGxlcz14cmVhbGxvYyhvcGVuaGFuZGxlcyxzaXplb2Yoc3RydWN0IG9wZW5oYW5kbGUpKihucm9mb3BlbmhhbmRsZXMtMSkpOwogICAgbnJvZm9wZW5oYW5kbGVzLS07CiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBsb29rdXBfaGtleSBbSW50ZXJuYWxdCiAqIAogKiBKdXN0IGFzIHRoZSBuYW1lIHNheXMuIENyZWF0ZXMgdGhlIHJvb3Qga2V5cyBvbiBkZW1hbmQsIHNvIHdlIGNhbiBjYWxsIHRoZQogKiBSZWcqIGZ1bmN0aW9ucyBhdCBhbnkgdGltZS4KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBQb2ludGVyIHRvIGtleSBzdHJ1Y3R1cmUKICogICAgRmFpbHVyZTogTlVMTAogKi8KI2RlZmluZSBBRERfUk9PVF9LRVkoeHgpIFwKCXh4ID0gKExQS0VZU1RSVUNUKXhtYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpO1wKCW1lbXNldCh4eCwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTtcCgl4eC0+a2V5bmFtZT0gc3RyZHVwQTJXKCI8c2hvdWxkX25vdF9hcHBlYXJfYW55d2hlcmU+Iik7CgpzdGF0aWMgTFBLRVlTVFJVQ1QgbG9va3VwX2hrZXkoIEhLRVkgaGtleSApCnsKICBzd2l0Y2ggKGhrZXkpIHsKICAvKiAwIGFuZCAxIGFyZSB2YWxpZCByb290a2V5cyBpbiB3aW4xNiBzaGVsbC5kbGwgYW5kIGFyZSB1c2VkIGJ5CiAgICogc29tZSBwcm9ncmFtcy4gRG8gbm90IHJlbW92ZSB0aG9zZSBjYXNlcy4gLU1NCiAgICovCiAJY2FzZSAweDAwMDAwMDAwOgogIGNhc2UgMHgwMDAwMDAwMToKICBjYXNlIEhLRVlfQ0xBU1NFU19ST09UOiAKICB7CiAgICBpZiAoIWtleV9jbGFzc2VzX3Jvb3QpIAogICAgewogICAgICBIS0VZCWNsX3JfaGtleTsKCiAgICAgIC8qIGNhbGxzIGxvb2t1cF9oa2V5IHJlY3Vyc2l2ZWx5LCBUV0lDRSAqLwogICAgICBpZiAoIFJlZ0NyZWF0ZUtleTE2KAogICAgICAgICAgICBIS0VZX0xPQ0FMX01BQ0hJTkUsCiAgICAgICAgICAgICJTT0ZUV0FSRVxcQ2xhc3NlcyIsCiAgICAgICAgICAgICZjbF9yX2hrZXkpICE9IEVSUk9SX1NVQ0NFU1MpIAogICAgICB7CiAgICAgICAgRVJSKCAKICAgICAgICAgIHJlZywKICAgICAgICAgICJDb3VsZCBub3QgY3JlYXRlIEhLTE1cXFNPRlRXQVJFXFxDbGFzc2VzLiBUaGlzIGlzIGltcG9zc2libGUuXG4iKTsKICAgICAgICBleGl0KDEpOwogICAgICB9CgogICAgICBrZXlfY2xhc3Nlc19yb290ID0gbG9va3VwX2hrZXkoY2xfcl9oa2V5KTsKICAgIH0KICAgIHJldHVybiBrZXlfY2xhc3Nlc19yb290OwogIH0KCiAgY2FzZSBIS0VZX0NVUlJFTlRfVVNFUjoKICAgIGlmICgha2V5X2N1cnJlbnRfdXNlcikgewogICAgICBBRERfUk9PVF9LRVkoa2V5X2N1cnJlbnRfdXNlcik7CiAgICB9CiAgICByZXR1cm4ga2V5X2N1cnJlbnRfdXNlcjsKCiAgY2FzZSBIS0VZX0xPQ0FMX01BQ0hJTkU6CiAgICBpZiAoIWtleV9sb2NhbF9tYWNoaW5lKSB7CiAgICAgIEFERF9ST09UX0tFWShrZXlfbG9jYWxfbWFjaGluZSk7CiAgICAgIFJFR0lTVFJZX0luaXQoKTsKICAgIH0KICAgIHJldHVybiBrZXlfbG9jYWxfbWFjaGluZTsKCiAgY2FzZSBIS0VZX1VTRVJTOgogICAgaWYgKCFrZXlfdXNlcnMpIHsKICAgICAgQUREX1JPT1RfS0VZKGtleV91c2Vycyk7CiAgICB9CiAgICByZXR1cm4ga2V5X3VzZXJzOwoKICBjYXNlIEhLRVlfUEVSRk9STUFOQ0VfREFUQToKICAgIGlmICgha2V5X3BlcmZvcm1hbmNlX2RhdGEpIHsKICAgICAgQUREX1JPT1RfS0VZKGtleV9wZXJmb3JtYW5jZV9kYXRhKTsKICAgIH0KICAgIHJldHVybiBrZXlfcGVyZm9ybWFuY2VfZGF0YTsKCiAgY2FzZSBIS0VZX0RZTl9EQVRBOgogICAgaWYgKCFrZXlfZHluX2RhdGEpIHsKICAgICAgQUREX1JPT1RfS0VZKGtleV9keW5fZGF0YSk7CiAgICB9CiAgICByZXR1cm4ga2V5X2R5bl9kYXRhOwoKICBjYXNlIEhLRVlfQ1VSUkVOVF9DT05GSUc6CiAgICBpZiAoIWtleV9jdXJyZW50X2NvbmZpZykgewogICAgICBBRERfUk9PVF9LRVkoa2V5X2N1cnJlbnRfY29uZmlnKTsKICAgIH0KICAgIHJldHVybiBrZXlfY3VycmVudF9jb25maWc7CgogIGRlZmF1bHQ6CiAgICByZXR1cm4gZ2V0X2hhbmRsZShoa2V5KTsKCiAgfQogIC8qTk9UUkVBQ0hFRCovCn0KI3VuZGVmIEFERF9ST09UX0tFWQovKiBzbyB3ZSBkb24ndCBhY2NpZGVudGx5IGFjY2VzcyB0aGVtIC4uLiAqLwojZGVmaW5lIGtleV9jdXJyZW50X2NvbmZpZyBOVUxMIE5VTEwKI2RlZmluZSBrZXlfY3VycmVudF91c2VyIE5VTEwgTlVMTAojZGVmaW5lIGtleV91c2VycyBOVUxMIE5VTEwKI2RlZmluZSBrZXlfbG9jYWxfbWFjaGluZSBOVUxMIE5VTEwKI2RlZmluZSBrZXlfY2xhc3Nlc19yb290IE5VTEwgTlVMTAojZGVmaW5lIGtleV9keW5fZGF0YSBOVUxMIE5VTEwKI2RlZmluZSBrZXlfcGVyZm9ybWFuY2VfZGF0YSBOVUxMIE5VTEwKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogc3BsaXRfa2V5cGF0aCBbSW50ZXJuYWxdCiAqIHNwbGl0cyB0aGUgdW5pY29kZSBzdHJpbmcgJ3dwJyBpbnRvIGFuIGFycmF5IG9mIHN0cmluZ3MuCiAqIHRoZSBhcnJheSBpcyBhbGxvY2F0ZWQgYnkgdGhpcyBmdW5jdGlvbi4gCiAqIEZyZWUgdGhlIGFycmF5IHVzaW5nIEZSRUVfS0VZX1BBVEgKICoKICogUEFSQU1TCiAqICAgIHdwICBbSV0gU3RyaW5nIHRvIHNwbGl0IHVwCiAqICAgIHdwdiBbT10gQXJyYXkgb2YgcG9pbnRlcnMgdG8gc3RyaW5ncwogKiAgICB3cGMgW09dIE51bWJlciBvZiBjb21wb25lbnRzCiAqLwpzdGF0aWMgdm9pZCBzcGxpdF9rZXlwYXRoKCBMUENXU1RSIHdwLCBMUFdTVFIgKip3cHYsIGludCAqd3BjKQp7CiAgICBpbnQJaSxqLGxlbjsKICAgIExQV1NUUiB3czsKCiAgICBUUkFDRShyZWcsIiglcywlcCwlcClcbiIsZGVidWdzdHJfdyh3cCksd3B2LHdwYyk7CgogICAgd3MJPSBIRUFQX3N0cmR1cFcoIFN5c3RlbUhlYXAsIDAsIHdwICk7CgogICAgLyogV2Uga25vdyB3ZSBoYXZlIGF0IGxlYXN0IG9uZSBzdWJzdHJpbmcgKi8KICAgICp3cGMgPSAxOwoKICAgIC8qIFJlcGxhY2UgZWFjaCBiYWNrc2xhc2ggd2l0aCBOVUxMLCBhbmQgaW5jcmVtZW50IHRoZSBjb3VudCAqLwogICAgZm9yIChpPTA7d3NbaV07aSsrKSB7CiAgICAgICAgaWYgKHdzW2ldPT0nXFwnKSB7CiAgICAgICAgICAgIHdzW2ldPTA7CiAgICAgICAgICAgICgqd3BjKSsrOwogICAgICAgIH0KICAgIH0KCiAgICBsZW4gPSBpOwoKICAgIC8qIEFsbG9jYXRlIHRoZSBzcGFjZSBmb3IgdGhlIGFycmF5IG9mIHBvaW50ZXJzLCBsZWF2aW5nIHJvb20gZm9yIHRoZQogICAgICAgTlVMTCBhdCB0aGUgZW5kICovCiAgICAqd3B2ID0gKExQV1NUUiopSGVhcEFsbG9jKCBTeXN0ZW1IZWFwLCAwLCBzaXplb2YoTFBXU1RSKSooKndwYysyKSk7CiAgICAoKndwdilbMF09IHdzOwoKICAgIC8qIEFzc2lnbiBlYWNoIHBvaW50ZXIgdG8gdGhlIGFwcHJvcHJpYXRlIGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nICovCiAgICBqID0gMTsKICAgIGZvciAoaT0xO2k8bGVuO2krKykKICAgICAgICBpZiAod3NbaS0xXT09MCkgewogICAgICAgICAgICAoKndwdilbaisrXT13cytpOwogICAgICAgICAgICAvKiBUUkFDRShyZWcsICIgU3ViaXRlbSAlZCA9ICVzXG4iLGotMSxkZWJ1Z3N0cl93KCgqd3B2KVtqLTFdKSk7ICovCiAgICAgICAgfQoKICAgICgqd3B2KVtqXT1OVUxMOwp9CiNkZWZpbmUgRlJFRV9LRVlfUEFUSCBIZWFwRnJlZShTeXN0ZW1IZWFwLDAsd3BzWzBdKTtIZWFwRnJlZShTeXN0ZW1IZWFwLDAsd3BzKTsKCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUkVHSVNUUllfSW5pdCBbSW50ZXJuYWxdCiAqIFJlZ2lzdHJ5IGluaXRpYWxpc2F0aW9uLCBhbGxvY2F0ZXMgc29tZSBkZWZhdWx0IGtleXMuIAogKi8Kc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCh2b2lkKSB7CglIS0VZCWhrZXk7CgljaGFyCWJ1ZlsyMDBdOwoKCVRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCglSZWdDcmVhdGVLZXkxNihIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIkhBUkRXQVJFXFxERVNDUklQVElPTlxcU3lzdGVtIiwmaGtleSk7CglSZWdTZXRWYWx1ZUV4QShoa2V5LCJJZGVudGlmaWVyIiwwLFJFR19TWiwiU3lzdGVtVHlwZSBXSU5FIixzdHJsZW4oIlN5c3RlbVR5cGUgV0lORSIpKTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKCS8qIFxcU09GVFdBUkVcXE1pY3Jvc29mdFxcV2luZG93IE5UXFxDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50QnVpbGROdW1iZXIKCSAqCQkJCQkJQ3VycmVudFR5cGUKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE93bmVyCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPcmdhbml6YXRpb24KCSAqCgkgKi8KCS8qIFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTTk1QXFxQYXJhbWV0ZXJzXFxSRkMxMTU2QWdlbnQKCSAqIAkJCQkJc3RyaW5nCVN5c0NvbnRhY3QKCSAqIAkJCQkJc3RyaW5nCVN5c0xvY2F0aW9uCgkgKiAJCQkJCQlTeXNTZXJ2aWNlcwoJICovCQkJCQkJCglpZiAoLTEhPWdldGhvc3RuYW1lKGJ1ZiwyMDApKSB7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxDb250cm9sXFxDb21wdXRlck5hbWVcXENvbXB1dGVyTmFtZSIsJmhrZXkpOwoJCVJlZ1NldFZhbHVlRXgxNihoa2V5LCJDb21wdXRlck5hbWUiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSsxKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKiogU0FWRSBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBSRUdJU1RSWV9TQVZFX1ZFUlNJT04JMHgwMDAwMDAwMQoKLyogUmVnaXN0cnkgc2F2ZWZvcm1hdDoKICogSWYgeW91IGNoYW5nZSBpdCwgaW5jcmVhc2UgYWJvdmUgbnVtYmVyIGJ5IDEsIHdoaWNoIHdpbGwgZmx1c2gKICogb2xkIHJlZ2lzdHJ5IGRhdGFiYXNlIGZpbGVzLgogKiAKICogR2xvYmFsOgogKiAJIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIKICogCXN1YmtleXMuLi4uCiAqIFN1YmtleXM6CiAqIAlrZXluYW1lCiAqCQl2YWx1ZW5hbWU9bGFzdG1vZGlmaWVkLHR5cGUsZGF0YQogKgkJLi4uCiAqCQlzdWJrZXlzCiAqCS4uLgogKiBrZXluYW1lLHZhbHVlbmFtZSxzdHJpbmdkYXRhOgogKgl0aGUgdXN1YWwgYXNjaWkgY2hhcmFjdGVycyBmcm9tIDB4MDAtMHhmZiAod2VsbCwgbm90IDB4MDApCiAqCWFuZCBcdVhYWFggYXMgVU5JQ09ERSB2YWx1ZSBYWFhYIHdpdGggWFhYWD4weGZmCiAqCSggIj1cXFx0IiBlc2NhcGVkIGluIFx1WFhYWCBmb3JtLikKICogdHlwZSxsYXN0bW9kaWZpZWQ6IAogKglpbnQKICogCiAqIEZJWE1FOiBkb2Vzbid0IHNhdmUgJ2NsYXNzJyAod2hhdCBkb2VzIGl0IG1lYW4gYW55d2F5PyksIG5vciBmbGFncy4KICoKICogW0hLRVlfQ1VSUkVOVF9VU0VSXFxTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnldCiAqIFNhdmVPbmx5VXBkYXRlZEtleXM9eWVzCiAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZV9jaGVja190YWludGVkIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3NhdmVfY2hlY2tfdGFpbnRlZCggTFBLRVlTVFJVQ1QgbHBrZXkgKQp7CglpbnQJCXRhaW50ZWQ7CgoJaWYgKCFscGtleSkKCQlyZXR1cm4gMDsKCWlmIChscGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1RBSU5URUQpCgkJdGFpbnRlZCA9IDE7CgllbHNlCgkJdGFpbnRlZCA9IDA7Cgl3aGlsZSAobHBrZXkpIHsKCQlpZiAoX3NhdmVfY2hlY2tfdGFpbnRlZChscGtleS0+bmV4dHN1YikpIHsKCQkJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCQkJdGFpbnRlZCA9IDE7CgkJfQoJCWxwa2V5CT0gbHBrZXktPm5leHQ7Cgl9CglyZXR1cm4gdGFpbnRlZDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZV9VU1RSSU5HIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9zYXZlX1VTVFJJTkcoIEZJTEUgKkYsIExQV1NUUiB3c3RyLCBpbnQgZXNjYXBlZXEgKQp7CglMUFdTVFIJczsKCWludAlkb2VzY2FwZTsKCglpZiAod3N0cj09TlVMTCkKCQlyZXR1cm47CglzPXdzdHI7Cgl3aGlsZSAoKnMpIHsKCQlkb2VzY2FwZT0wOwoJCWlmICgqcz4weGZmKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKCpzPT0nXG4nKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKGVzY2FwZWVxICYmICpzPT0nPScpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoKnM9PSdcXCcpCiAgICAgICAgICAgICAgICAgICAgICAgIGZwdXRjKCpzLEYpOyAvKiBpZiBcXCB0aGVuIHB1dCBpdCB0d2ljZS4gKi8KCQlpZiAoZG9lc2NhcGUpCgkJCWZwcmludGYoRiwiXFx1JTA0eCIsKigodW5zaWduZWQgc2hvcnQqKXMpKTsKCQllbHNlCgkJCWZwdXRjKCpzLEYpOwoJCXMrKzsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXN1YmtleSBbSW50ZXJuYWxdCiAqCiAqIE5PVEVTCiAqICBSRUdfTVVMVElfU1ogaXMgaGFuZGxlZCBhcyBiaW5hcnkgKGxpa2UgaW4gd2luOTUpIChqcykKICovCnN0YXRpYyBpbnQgX3NhdmVzdWJrZXkoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgbGV2ZWwsIGludCBhbGwgKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWksdGFicyxqOwoKCWxweGtleQk9IGxwa2V5OwoJd2hpbGUgKGxweGtleSkgewoJCWlmICgJIShscHhrZXktPmZsYWdzICYgUkVHX09QVElPTl9WT0xBVElMRSkgJiYKCQkJKGFsbCB8fCAobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVEFJTlRFRCkpCgkJKSB7CgkJCWZvciAodGFicz1sZXZlbDt0YWJzLS07KQoJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJX3NhdmVfVVNUUklORyhGLGxweGtleS0+a2V5bmFtZSwxKTsKCQkJZnB1dHMoIlxuIixGKTsKCQkJZm9yIChpPTA7aTxscHhrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJCQlMUEtFWVZBTFVFCXZhbD1scHhrZXktPnZhbHVlcytpOwoKCQkJCWZvciAodGFicz1sZXZlbCsxO3RhYnMtLTspCgkJCQkJZnB1dGMoJ1x0JyxGKTsKCQkJCV9zYXZlX1VTVFJJTkcoRix2YWwtPm5hbWUsMCk7CgkJCQlmcHV0YygnPScsRik7CgkJCQlmcHJpbnRmKEYsIiVsZCwlbGQsIix2YWwtPnR5cGUsdmFsLT5sYXN0bW9kaWZpZWQpOwoJCQkJaWYgKCB2YWwtPnR5cGUgPT0gUkVHX1NaIHx8IHZhbC0+dHlwZSA9PSBSRUdfRVhQQU5EX1NaICkKCQkJCQlfc2F2ZV9VU1RSSU5HKEYsKExQV1NUUil2YWwtPmRhdGEsMCk7CgkJCQllbHNlCgkJCQkJZm9yIChqPTA7ajx2YWwtPmxlbjtqKyspCgkJCQkJCWZwcmludGYoRiwiJTAyeCIsKigodW5zaWduZWQgY2hhciopdmFsLT5kYXRhK2opKTsKCQkJCWZwdXRzKCJcbiIsRik7CgkJCX0KCQkJLyogZGVzY2VuZCByZWN1cnNpdmVseSAqLwoJCQlpZiAoIV9zYXZlc3Via2V5KEYsbHB4a2V5LT5uZXh0c3ViLGxldmVsKzEsYWxsKSkKCQkJCXJldHVybiAwOwoJCX0KCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlc3VicmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3NhdmVzdWJyZWcoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgYWxsICkKewoJZnByaW50ZihGLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWRcbiIsUkVHSVNUUllfU0FWRV9WRVJTSU9OKTsKCV9zYXZlX2NoZWNrX3RhaW50ZWQobHBrZXktPm5leHRzdWIpOwoJcmV0dXJuIF9zYXZlc3Via2V5KEYsbHBrZXktPm5leHRzdWIsMCxhbGwpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgQk9PTCBfc2F2ZXJlZyggTFBLRVlTVFJVQ1QgbHBrZXksIGNoYXIgKmZuLCBpbnQgYWxsICkKewoJRklMRQkqRjsKCglGPWZvcGVuKGZuLCJ3Iik7CglpZiAoRj09TlVMTCkgewoJCVdBUk4ocmVnLCJDb3VsZG4ndCBvcGVuICVzIGZvciB3cml0aW5nOiAlc1xuIiwKCQkJZm4sc3RyZXJyb3IoZXJybm8pCgkJKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglpZiAoIV9zYXZlc3VicmVnKEYsbHBrZXksYWxsKSkgewoJCWZjbG9zZShGKTsKCQl1bmxpbmsoZm4pOwoJCVdBUk4ocmVnLCJGYWlsZWQgdG8gc2F2ZSBrZXlzLCBwZXJoYXBzIG5vIG1vcmUgZGlza3NwYWNlIGZvciAlcz9cbiIsZm4pOwoJCXJldHVybiBGQUxTRTsKCX0KCWZjbG9zZShGKTsKICAgICAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfU2F2ZVJlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnZvaWQgU0hFTExfU2F2ZVJlZ2lzdHJ5KCB2b2lkICkKewogICAgY2hhciAgICpmbiwgKmhvbWUsICp0bXA7CiAgICBjaGFyICAgYnVmWzRdOwogICAgSEtFWSAgIGhrZXk7CiAgICBpbnQgICAgYWxsOwogICAgaW50ICAgIHVzZWRDZmdVc2VyID0gMDsKICAgIGludCAgICB1c2VkQ2ZnTE0gICA9IDA7CgogICAgVFJBQ0UocmVnLCIodm9pZClcbiIpOwoKICAgIGFsbD0wOwogICAgaWYgKFJlZ09wZW5LZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpIT1FUlJPUl9TVUNDRVNTKSAKICAgIHsKICAgICAgICBzdHJjcHkoYnVmLCJ5ZXMiKTsKICAgIH0gCiAgICBlbHNlIAogICAgewogICAgICAgIERXT1JEIGxlbixqdW5rLHR5cGU7CgogICAgICAgIGxlbj00OwogICAgICAgIGlmICgoRVJST1JfU1VDQ0VTUyE9UmVnUXVlcnlWYWx1ZUV4QSggaGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBTF9TQVZFVVBEQVRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZqdW5rLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbGVuKSkgfHwgKHR5cGUhPVJFR19TWikpCiAgICAgICAgewogICAgICAgICAgICBzdHJjcHkoYnVmLCJ5ZXMiKTsKICAgICAgICB9CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICB9CgogICAgaWYgKGxzdHJjbXBpQShidWYsInllcyIpKSBhbGw9MTsKCiAgICBpZiAoIShob21lID0gZ2V0ZW52KCAiSE9NRSIgKSkpCiAgICB7CiAgICAgICAgV0FSTihyZWcsIkZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWQuXG4iLGdldHVpZCgpKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAvKiAKICAgICAqIFNhdmUgSEtFWV9DVVJSRU5UX1VTRVIgCiAgICAgKiBUcnkgZmlyc3Qgc2F2aW5nIGFjY29yZGluZyB0byB0aGUgZGVmaW5lZCBsb2NhdGlvbiBpbiAud2luZXJjCiAgICAgKi8KICAgIGZuID0geG1hbGxvYyggTUFYX1BBVEhOQU1FX0xFTiApOyAKICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcgKCAiUmVnaXN0cnkiLCAiVXNlckZpbGVOYW1lIiwgIiIsIGZuLCBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpIAogICAgewogICAgICAgIF9zYXZlcmVnKGxvb2t1cF9oa2V5KEhLRVlfQ1VSUkVOVF9VU0VSKSxmbixhbGwpOwogICAgICAgIHVzZWRDZmdVc2VyID0gMTsKICAgIH0KICAgIGZyZWUgKGZuKTsKCiAgICBpZiAodXNlZENmZ1VzZXIgIT0gMSkKICAgIHsKICAgICAgICBmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKGhvbWUpICsgc3RybGVuKFdJTkVfUFJFRklYKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikgKyAyICk7CiAgICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICAgIHN0cmNhdChmbixXSU5FX1BSRUZJWCk7CiAgCiAgICAgICAgLyogY3JlYXRlIHRoZSBkaXJlY3RvcnkuIGRvbid0IGNhcmUgYWJvdXQgZXJyb3Jjb2Rlcy4gKi8KICAgICAgICBta2RpcihmbiwwNzU1KTsgLyogZHJ3eHIteHIteCAqLwogICAgICAgIHN0cmNhdChmbiwiLyJTQVZFX0NVUlJFTlRfVVNFUik7CgogICAgICAgIHRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CiAgICAgICAgc3RyY3B5KHRtcCxmbik7CiAgICAgICAgc3RyY2F0KHRtcCwiLnRtcCIpOwogIAogICAgICAgIGlmIChfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUiksdG1wLGFsbCkpIHsKICAgICAgICAgICAgaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewogICAgICAgICAgICAgICAgcGVycm9yKCJyZW5hbWUgdG1wIHJlZ2lzdHJ5Iik7CiAgICAgICAgICAgICAgICB1bmxpbmsodG1wKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmcmVlKHRtcCk7CiAgICAgICAgZnJlZShmbik7CiAgICB9CgogICAgLyogCiAgICAgKiBTYXZlIEhLRVlfTE9DQUxfTUFDSElORQogICAgICogVHJ5IGZpcnN0IHNhdmluZyBhY2NvcmRpbmcgdG8gdGhlIGRlZmluZWQgbG9jYXRpb24gaW4gLndpbmVyYwogICAgICovCiAgICBmbiA9IHhtYWxsb2MgKCBNQVhfUEFUSE5BTUVfTEVOKTsKICAgIGlmIChQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcgKCAiUmVnaXN0cnkiLCAiTG9jYWxNYWNoaW5lRmlsZU5hbWUiLCAiIiwgZm4sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BWF9QQVRITkFNRV9MRU4gLSAxKSkKICAgIHsKICAgICAgICBfc2F2ZXJlZyhsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpLCBmbiwgYWxsKTsKICAgICAgICB1c2VkQ2ZnTE0gPSAxOwogICAgfQogICAgZnJlZSAoZm4pOwoKICAgIGlmICggdXNlZENmZ0xNICE9IDEpCiAgICB7CiAgICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSsgc3RybGVuKFdJTkVfUFJFRklYKSsgc3RybGVuKFNBVkVfTE9DQUxfTUFDSElORSkrMik7CiAgICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICAgIHN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfTUFDSElORSk7CgogICAgICAgIHRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CiAgICAgICAgc3RyY3B5KHRtcCxmbik7CiAgICAgICAgc3RyY2F0KHRtcCwiLnRtcCIpOwoKICAgICAgICBpZiAoX3NhdmVyZWcobG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSx0bXAsYWxsKSkgewogICAgICAgICAgICBpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CiAgICAgICAgICAgICAgICBwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKICAgICAgICAgICAgICAgIHVubGluayh0bXApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZyZWUodG1wKTsKICAgICAgICBmcmVlKGZuKTsKICAgIH0KCiAgICAvKiAKICAgICAqIFNhdmUgSEtFWV9VU0VSUwogICAgICovCiAgICBmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKGhvbWUpKyBzdHJsZW4oV0lORV9QUkVGSVgpKyBzdHJsZW4oU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKSsyKTsKCiAgICBzdHJjcHkoZm4saG9tZSk7CiAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpOwoKICAgIHRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CiAgICBzdHJjcHkodG1wLGZuKTtzdHJjYXQodG1wLCIudG1wIik7CiAgICBpZiAoIF9zYXZlcmVnKGxvb2t1cF9oa2V5KEhLRVlfVVNFUlMpLHRtcCxGQUxTRSkpIHsKICAgICAgICBpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CiAgICAgICAgICAgIHBlcnJvcigicmVuYW1lIHRtcCByZWdpc3RyeSIpOwogICAgICAgICAgICB1bmxpbmsodG1wKTsKICAgICAgICB9CiAgICB9CiAgICBmcmVlKHRtcCk7CiAgICBmcmVlKGZuKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKiogTE9BRCBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF9rZXkgW0ludGVybmFsXQogKi8Kc3RhdGljIExQS0VZU1RSVUNUIF9maW5kX29yX2FkZF9rZXkoIExQS0VZU1RSVUNUIGxwa2V5LCBMUFdTVFIga2V5bmFtZSApCnsKCUxQS0VZU1RSVUNUCWxweGtleSwqbHBscGtleTsKCglpZiAoKCFrZXluYW1lKSB8fCAoa2V5bmFtZVswXT09MCkpIHsKCQlmcmVlKGtleW5hbWUpOwoJCXJldHVybiBscGtleTsKCX0KCWxwbHBrZXk9ICYobHBrZXktPm5leHRzdWIpOwoJbHB4a2V5CT0gKmxwbHBrZXk7Cgl3aGlsZSAobHB4a2V5KSB7CgkJaWYgKAkobHB4a2V5LT5rZXluYW1lWzBdPT1rZXluYW1lWzBdKSAmJiAKCQkJIWxzdHJjbXBpVyhscHhrZXktPmtleW5hbWUsa2V5bmFtZSkKCQkpCgkJCWJyZWFrOwoJCWxwbHBrZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7Cgl9CglpZiAobHB4a2V5PT1OVUxMKSB7CgkJKmxwbHBrZXkgPSAoTFBLRVlTVFJVQ1QpeG1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5CT0gKmxwbHBrZXk7CgkJbWVtc2V0KGxweGtleSwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTsKCQlscHhrZXktPmtleW5hbWUJPSBrZXluYW1lOwoJfSBlbHNlCgkJZnJlZShrZXluYW1lKTsKCXJldHVybiBscHhrZXk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2ZpbmRfb3JfYWRkX3ZhbHVlIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9maW5kX29yX2FkZF92YWx1ZSggTFBLRVlTVFJVQ1QgbHBrZXksIExQV1NUUiBuYW1lLCBEV09SRCB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBkYXRhLCBEV09SRCBsZW4sIERXT1JEIGxhc3Rtb2RpZmllZCApCnsKCUxQS0VZVkFMVUUJdmFsPU5VTEw7CglpbnQJCWk7CgoJaWYgKG5hbWUgJiYgISpuYW1lKSB7LyogZW1wdHkgc3RyaW5nIGVxdWFscyBkZWZhdWx0IChOVUxMKSB2YWx1ZSAqLwoJCWZyZWUobmFtZSk7CgkJbmFtZSA9IE5VTEw7Cgl9CgoJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCWlmIChuYW1lPT1OVUxMKSB7CgkJCWlmICh2YWwtPm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCQl9IGVsc2UgewoJCQlpZiAoCXZhbC0+bmFtZSE9TlVMTCAmJiAKCQkJCXZhbC0+bmFtZVswXT09bmFtZVswXSAmJgoJCQkJIWxzdHJjbXBpVyh2YWwtPm5hbWUsbmFtZSkKCQkJKQoJCQkJYnJlYWs7CgkJfQoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CgkJbHBrZXktPnZhbHVlcyA9IHhyZWFsbG9jKAoJCQlscGtleS0+dmFsdWVzLAoJCQkoKytscGtleS0+bnJvZnZhbHVlcykqc2l6ZW9mKEtFWVZBTFVFKQoJCSk7CgkJdmFsPWxwa2V5LT52YWx1ZXMraTsKCQltZW1zZXQodmFsLCdcMCcsc2l6ZW9mKEtFWVZBTFVFKSk7CgkJdmFsLT5uYW1lID0gbmFtZTsKCX0gZWxzZSB7CgkJaWYgKG5hbWUpCgkJCWZyZWUobmFtZSk7Cgl9CglpZiAodmFsLT5sYXN0bW9kaWZpZWQ8bGFzdG1vZGlmaWVkKSB7CgkJdmFsLT5sYXN0bW9kaWZpZWQ9bGFzdG1vZGlmaWVkOwoJCXZhbC0+dHlwZSA9IHR5cGU7CgogICAgICAgICAgICAgICAgaWYgKCh0eXBlID09IFJFR19TWiB8fCB0eXBlID09IFJFR19FWFBBTkRfU1opICYmICFkYXRhKXsKCiAgICAgICAgICAgICAgICAgICAgZGF0YT14bWFsbG9jKHNpemVvZihXQ0hBUikpOwogICAgICAgICAgICAgICAgICAgIG1lbXNldChkYXRhLDAsc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgICAgICAgICAgICAgbGVuID1zaXplb2YoV0NIQVIpOwogICAgICAgICAgICAgICAgfQoKCQl2YWwtPmxlbiAgPSBsZW47CgkJaWYgKHZhbC0+ZGF0YSkgCgkJCWZyZWUodmFsLT5kYXRhKTsKCQl2YWwtPmRhdGEgPSBkYXRhOwoJfSBlbHNlCgkJZnJlZShkYXRhKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9saW5lIFtJbnRlcm5hbF0KICoKICogcmVhZHMgYSBsaW5lIGluY2x1ZGluZyBkeW5hbWljYWxseSBlbmxhcmdpbmcgdGhlIHJlYWRidWZmZXIgYW5kIHRocm93aW5nCiAqIGF3YXkgY29tbWVudHMKICovCnN0YXRpYyBpbnQgX3dpbmVfcmVhZF9saW5lKCBGSUxFICpGLCBjaGFyICoqYnVmLCBpbnQgKmxlbiApCnsKCWNoYXIJKnMsKmN1cnJlYWQ7CglpbnQJbXlsZW4sY3Vyb2ZmOwoKCWN1cnJlYWQJPSAqYnVmOwoJbXlsZW4JPSAqbGVuOwoJKipidWYJPSAnXDAnOwoJd2hpbGUgKDEpIHsKCQl3aGlsZSAoMSkgewoJCQlzPWZnZXRzKGN1cnJlYWQsbXlsZW4sRik7CgkJCWlmIChzPT1OVUxMKQoJCQkJcmV0dXJuIDA7IC8qIEVPRiAqLwoJCQlpZiAoTlVMTD09KHM9c3RyY2hyKGN1cnJlYWQsJ1xuJykpKSB7CgkJCQkvKiBidWZmZXIgd2Fzbid0IGxhcmdlIGVub3VnaCAqLwoJCQkJY3Vyb2ZmCT0gc3RybGVuKCpidWYpOwoJCQkJKmJ1Zgk9IHhyZWFsbG9jKCpidWYsKmxlbioyKTsKCQkJCWN1cnJlYWQJPSAqYnVmICsgY3Vyb2ZmOwoJCQkJbXlsZW4JPSAqbGVuOwkvKiB3ZSBmaWxsZWQgdXAgdGhlIGJ1ZmZlciBhbmQgCgkJCQkJCSAqIGdvdCBuZXcgJypsZW4nIGJ5dGVzIHRvIGZpbGwKCQkJCQkJICovCgkJCQkqbGVuCT0gKmxlbiAqIDI7CgkJCX0gZWxzZSB7CgkJCQkqcz0nXDAnOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLyogdGhyb3cgYXdheSBjb21tZW50cyAqLwoJCWlmICgqKmJ1Zj09JyMnIHx8ICoqYnVmPT0nOycpIHsKCQkJY3VycmVhZAk9ICpidWY7CgkJCW15bGVuCT0gKmxlbjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzKSAJLyogZ290IGVuZCBvZiBsaW5lICovCgkJCWJyZWFrOwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfVVNUUklORyBbSW50ZXJuYWxdCiAqCiAqIGNvbnZlcnRzIGEgY2hhciogaW50byBhIFVOSUNPREUgc3RyaW5nICh1cCB0byBhIHNwZWNpYWwgY2hhcikKICogYW5kIHJldHVybnMgdGhlIHBvc2l0aW9uIGV4YWN0bHkgYWZ0ZXIgdGhhdCBzdHJpbmcKICovCnN0YXRpYyBjaGFyKiBfd2luZV9yZWFkX1VTVFJJTkcoIGNoYXIgKmJ1ZiwgTFBXU1RSICpzdHIgKQp7CgljaGFyCSpzOwoJTFBXU1RSCXdzOwoKCS8qIHJlYWQgdXAgdG8gIj0iIG9yICJcMCIgb3IgIlxuIiAqLwoJcwk9IGJ1ZjsKCWlmICgqcyA9PSAnPScpIHsKCQkvKiBlbXB0eSBzdHJpbmcgaXMgdGhlIHdpbjMuMSBkZWZhdWx0IHZhbHVlKE5VTEwpKi8KCQkqc3RyCT0gTlVMTDsKCQlyZXR1cm4gczsKCX0KCSpzdHIJPSAoTFBXU1RSKXhtYWxsb2MoMipzdHJsZW4oYnVmKSsyKTsKCXdzCT0gKnN0cjsKCXdoaWxlICgqcyAmJiAoKnMhPSdcbicpICYmICgqcyE9Jz0nKSkgewoJCWlmICgqcyE9J1xcJykKCQkJKndzKys9KigodW5zaWduZWQgY2hhciopcysrKTsKCQllbHNlIHsKCQkJcysrOwoJCQlpZiAoISpzKSB7CgkJCQkvKiBEYW5nbGluZyBcIC4uLiBtYXkgb25seSBoYXBwZW4gaWYgYSByZWdpc3RyeQoJCQkJICogd3JpdGUgd2FzIHNob3J0LiBGSVhNRTogV2hhdCBkbyB0bz8KCQkJCSAqLwoJCQkJIGJyZWFrOwoJCQl9CgkJCWlmICgqcz09J1xcJykgewoJCQkJKndzKys9J1xcJzsKCQkJCXMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWlmICgqcyE9J3UnKSB7CgkJCQlXQVJOKHJlZywiTm9uIHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlIFxcJWMgZm91bmQgaW4gfCVzfFxuIiwqcyxidWYpOwoJCQkJKndzKys9J1xcJzsKCQkJCSp3cysrPSpzKys7CgkJCX0gZWxzZSB7CgkJCQljaGFyCXhidWZbNV07CgkJCQlpbnQJd2M7CgoJCQkJcysrOwoJCQkJbWVtY3B5KHhidWYscyw0KTt4YnVmWzRdPSdcMCc7CgkJCQlpZiAoIXNzY2FuZih4YnVmLCIleCIsJndjKSkKCQkJCQlXQVJOKHJlZywiU3RyYW5nZSBlc2NhcGUgc2VxdWVuY2UgJXMgZm91bmQgaW4gfCVzfFxuIix4YnVmLGJ1Zik7CgkJCQlzKz00OwoJCQkJKndzKysJPSh1bnNpZ25lZCBzaG9ydCl3YzsKCQkJfQoJCX0KCX0KCSp3cwk9IDA7Cgl3cwk9ICpzdHI7CglpZiAoKndzKQoJCSpzdHIJPSBzdHJkdXBXKCpzdHIpOwoJZWxzZQoJCSpzdHIJPSBOVUxMOwoJZnJlZSh3cyk7CglyZXR1cm4gczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfbG9hZHN1YmtleSBbSW50ZXJuYWxdCiAqCiAqIE5PVEVTCiAqICAgIEl0IHNlZW1zIGxpa2UgdGhpcyBpcyByZXR1cm5pbmcgYSBib29sZWFuLiAgU2hvdWxkIGl0PwogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IDEKICogICAgRmFpbHVyZTogMAogKi8Kc3RhdGljIGludCBfd2luZV9sb2Fkc3Via2V5KCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGxldmVsLCBjaGFyICoqYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqYnVmbGVuLCBEV09SRCBvcHRmbGFnICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlpOwoJY2hhcgkJKnM7CglMUFdTVFIJCW5hbWU7CgogICAgVFJBQ0UocmVnLCIoJXAsJXAsJWQsJXMsJWQsJWx4KVxuIiwgRiwgbHBrZXksIGxldmVsLCBkZWJ1Z3N0cl9hKCpidWYpLAogICAgICAgICAgKmJ1Zmxlbiwgb3B0ZmxhZyk7CgogICAgbHBrZXktPmZsYWdzIHw9IG9wdGZsYWc7CgogICAgLyogR29vZC4gIFdlIGFscmVhZHkgZ290IGEgbGluZSBoZXJlIC4uLiBzbyBwYXJzZSBpdCAqLwogICAgbHB4a2V5ID0gTlVMTDsKICAgIHdoaWxlICgxKSB7CiAgICAgICAgaT0wO3M9KmJ1ZjsKICAgICAgICB3aGlsZSAoKnM9PSdcdCcpIHsKICAgICAgICAgICAgcysrOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQogICAgICAgIGlmIChpPmxldmVsKSB7CiAgICAgICAgICAgIGlmIChscHhrZXk9PU5VTEwpIHsKICAgICAgICAgICAgICAgIFdBUk4ocmVnLCJHb3QgYSBzdWJoaWVyYXJjaHkgd2l0aG91dCByZXNwLiBrZXk/XG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF93aW5lX2xvYWRzdWJrZXkoRixscHhrZXksbGV2ZWwrMSxidWYsYnVmbGVuLG9wdGZsYWcpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoJCS8qIGxldCB0aGUgY2FsbGVyIGhhbmRsZSB0aGlzIGxpbmUgKi8KCQlpZiAoaTxsZXZlbCB8fCAqKmJ1Zj09J1wwJykKCQkJcmV0dXJuIDE7CgoJCS8qIGl0IGNhbiBiZTogYSB2YWx1ZSBvciBhIGtleW5hbWUuIFBhcnNlIHRoZSBuYW1lIGZpcnN0ICovCgkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywmbmFtZSk7CgoJCS8qIHN3aXRjaCgpIGRlZmF1bHQ6IGhhY2sgdG8gYXZvaWQgZ290b3MgKi8KCQlzd2l0Y2ggKDApIHsKCQlkZWZhdWx0OgoJCQlpZiAoKnM9PSdcMCcpIHsKCQkJCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoJCQl9IGVsc2UgewoJCQkJTFBCWVRFCQlkYXRhOwoJCQkJaW50CQlsZW4sbGFzdG1vZGlmaWVkLHR5cGU7CgoJCQkJaWYgKCpzIT0nPScpIHsKCQkJCQlXQVJOKHJlZywiVW5leHBlY3RlZCBjaGFyYWN0ZXI6ICVjXG4iLCpzKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCXMrKzsKCQkJCWlmICgyIT1zc2NhbmYocywiJWQsJWQsIiwmdHlwZSwmbGFzdG1vZGlmaWVkKSkgewoJCQkJCVdBUk4ocmVnLCJIYXZlbid0IHVuZGVyc3Rvb2QgcG9zc2libGUgdmFsdWUgaW4gfCVzfCwgc2tpcHBpbmcuXG4iLCpidWYpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJLyogc2tpcCB0aGUgMiAsICovCgkJCQlzPXN0cmNocihzLCcsJyk7cysrOwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCWlmICh0eXBlID09IFJFR19TWiB8fCB0eXBlID09IFJFR19FWFBBTkRfU1opIHsKCQkJCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLChMUFdTVFIqKSZkYXRhKTsKCQkJCQlpZiAoZGF0YSkKCQkJCQkJbGVuID0gbHN0cmxlblcoKExQV1NUUilkYXRhKSoyKzI7CgkJCQkJZWxzZQkKCQkJCQkJbGVuID0gMDsKCQkJCX0gZWxzZSB7CgkJCQkJbGVuPXN0cmxlbihzKS8yOwoJCQkJCWRhdGEgPSAoTFBCWVRFKXhtYWxsb2MobGVuKzEpOwoJCQkJCWZvciAoaT0wO2k8bGVuO2krKykgewoJCQkJCQlkYXRhW2ldPTA7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldPSgqcy0nMCcpPDw0OwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ2EnKydceGEnKTw8NDsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV09KCpzLSdBJysnXHhhJyk8PDQ7CgkJCQkJCXMrKzsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV18PSpzLScwJzsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV18PSpzLSdhJysnXHhhJzsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV18PSpzLSdBJysnXHhhJzsKCQkJCQkJcysrOwoJCQkJCX0KCQkJCX0KCQkJCV9maW5kX29yX2FkZF92YWx1ZShscGtleSxuYW1lLHR5cGUsZGF0YSxsZW4sbGFzdG1vZGlmaWVkKTsKCQkJfQoJCX0KCQkvKiByZWFkIHRoZSBuZXh0IGxpbmUgKi8KCQlpZiAoIV93aW5lX3JlYWRfbGluZShGLGJ1ZixidWZsZW4pKQoJCQlyZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2Fkc3VicmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YnJlZyggRklMRSAqRiwgTFBLRVlTVFJVQ1QgbHBrZXksIERXT1JEIG9wdGZsYWcgKQp7CglpbnQJdmVyOwoJY2hhcgkqYnVmOwoJaW50CWJ1ZmxlbjsKCglidWY9eG1hbGxvYygxMCk7YnVmbGVuPTEwOwoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFzc2NhbmYoYnVmLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWQiLCZ2ZXIpKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKHZlciE9UkVHSVNUUllfU0FWRV9WRVJTSU9OKSB7CgkJVFJBQ0UocmVnLCJPbGQgZm9ybWF0ICglZCkgcmVnaXN0cnkgZm91bmQsIGlnbm9yaW5nIGl0LiAoYnVmIHdhcyAlcykuXG4iLHZlcixidWYpOwoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfbG9hZHN1YmtleShGLGxwa2V5LDAsJmJ1ZiwmYnVmbGVuLG9wdGZsYWcpKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJZnJlZShidWYpOwoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3dpbmVfbG9hZHJlZyggTFBLRVlTVFJVQ1QgbHBrZXksIGNoYXIgKmZuLCBEV09SRCBvcHRmbGFnICkKewogICAgRklMRSAqRjsKCiAgICBUUkFDRShyZWcsIiglcCwlcywlbHgpXG4iLGxwa2V5LGRlYnVnc3RyX2EoZm4pLG9wdGZsYWcpOwoKICAgIEYgPSBmb3BlbihmbiwicmIiKTsKICAgIGlmIChGPT1OVUxMKSB7CiAgICAgICAgV0FSTihyZWcsIkNvdWxkbid0IG9wZW4gJXMgZm9yIHJlYWRpbmc6ICVzXG4iLGZuLHN0cmVycm9yKGVycm5vKSApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmICghX3dpbmVfbG9hZHN1YnJlZyhGLGxwa2V5LG9wdGZsYWcpKSB7CiAgICAgICAgZmNsb3NlKEYpOwogICAgICAgIHVubGluayhmbik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgZmNsb3NlKEYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9mbHVzaF9yZWdpc3RyeSBbSW50ZXJuYWxdCiAqIAogKiBUaGlzIGZ1bmN0aW9uIGFsbG93IHRvIGZsdXNoIHNlY3Rpb24gb2YgdGhlIGludGVybmFsIHJlZ2lzdHJ5LiAgSXQgaXMgbWFpbmx5CiAqIGltcGxlbWVudHMgdG8gZml4IGEgcHJvYmxlbSB3aXRoIHRoZSBnbG9iYWwgSEtVIGFuZCB0aGUgbG9jYWwgSEtVLgogKiBUaG9zZSB0d28gZmlsZXMgYXJlIHJlYWQgdG8gYnVpbGQgdGhlIEhLVVwuRGVmYXVsdCBicmFuY2ggdG8gZmluYWx5IGNvcHkKICogdGhpcyBicmFuY2ggb250byBIS0NVIGhpdmUsIG9uY2UgdGhpcyBpcyBkb25lLCBpZiB3ZSBrZWVwIHRoZSBIS1UgaGl2ZSBhcyBpcywgCiAqIGFsbCB0aGUgZ2xvYmFsIEhLVSBhcmUgc2F2ZWQgb250byB0aGUgdXNlcidzIHBlcnNvbmFsIHZlcnNpb24gb2YgSEtVIGhpdmUuCiAqIHdoaWNoIGlzIGJhZC4uLgogKi8KCiAvKiBGb3J3YXJkIGRlY2xhcmF0aW9uIG9mIHJlY3VzaXZlIGFnZW50ICovCnN0YXRpYyB2b2lkIF9mbHVzaF9yZWcoTFBLRVlTVFJVQ1QgZnJvbSk7CgpzdGF0aWMgdm9pZCBfZmx1c2hfcmVnaXN0cnkoIExQS0VZU1RSVUNUIGZyb20gKQp7CiAgLyogbWFrZSBzdXJlIHdlIGhhdmUgc29tZXRoaW5nLi4uICovCiAgaWYgKGZyb20gPT0gTlVMTCkKICAgIHJldHVybjsKCiAgLyogTGF1bmNoIHRoZSByZWN1c2l2ZSBhZ2VudCBvbiBzdWIgYnJhbmNoZXMgKi8KICBfZmx1c2hfcmVnKCBmcm9tLT5uZXh0c3ViICk7CiAgX2ZsdXNoX3JlZyggZnJvbS0+bmV4dCApOwoKICAvKiBJbml0aWFsaXplIHBvaW50ZXJzICovCiAgZnJvbS0+bmV4dHN1YiA9IE5VTEw7CiAgZnJvbS0+bmV4dCAgICA9IE5VTEw7Cn0Kc3RhdGljIHZvaWQgX2ZsdXNoX3JlZyggTFBLRVlTVFJVQ1QgZnJvbSApCnsKCWludAlqOwoKICAvKiBtYWtlIHN1cmUgd2UgaGF2ZSBzb21ldGhpbmcuLi4gKi8KICBpZiAoZnJvbSA9PSBOVUxMKQogICAgcmV0dXJuOwoKICAvKiAKICAgKiBkbyB0aGUgc2FtZSBmb3IgdGhlIGNoaWxkIGtleXMgCiAgICovCiAgaWYgKGZyb20tPm5leHRzdWIgIT0gTlVMTCkKICAgIF9mbHVzaF9yZWcoZnJvbS0+bmV4dHN1Yik7CgogIC8qIAogICAqIGRvIHRoZSBzYW1lIGZvciB0aGUgc2libGluZyBrZXlzIAogICAqLwogIGlmIChmcm9tLT5uZXh0ICE9IE5VTEwpCiAgICBfZmx1c2hfcmVnKGZyb20tPm5leHQpOwoKICAvKgogICAqIGl0ZXJhdGUgdGhyb3VnaCB0aGlzIGtleSdzIHZhbHVlcyBhbmQgZGVsZXRlIHRoZW0KICAgKi8KICBmb3IgKGo9MDtqPGZyb20tPm5yb2Z2YWx1ZXM7aisrKSAKICB7CiAgICBmcmVlKCAoZnJvbS0+dmFsdWVzK2opLT5uYW1lKTsKICAgIGZyZWUoIChmcm9tLT52YWx1ZXMraiktPmRhdGEpOwogIH0KCiAgLyoKICAgKiBmcmVlIHRoZSBzdHJ1Y3R1cmUKICAgKi8KICBpZiAoIGZyb20gIT0gTlVMTCApCiAgICBmcmVlKGZyb20pOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfY29weV9yZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfY29weV9yZWdpc3RyeSggTFBLRVlTVFJVQ1QgZnJvbSwgTFBLRVlTVFJVQ1QgdG8gKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWo7CglMUEtFWVZBTFVFCXZhbGZyb207CgoJZnJvbT1mcm9tLT5uZXh0c3ViOwoJd2hpbGUgKGZyb20pIHsKCQlscHhrZXkgPSBfZmluZF9vcl9hZGRfa2V5KHRvLHN0cmR1cFcoZnJvbS0+a2V5bmFtZSkpOwoKCQlmb3IgKGo9MDtqPGZyb20tPm5yb2Z2YWx1ZXM7aisrKSB7CgkJCUxQV1NUUgluYW1lOwoJCQlMUEJZVEUJZGF0YTsKCgkJCXZhbGZyb20gPSBmcm9tLT52YWx1ZXMrajsKCQkJbmFtZT12YWxmcm9tLT5uYW1lOwoJCQlpZiAobmFtZSkgbmFtZT1zdHJkdXBXKG5hbWUpOwoJCQlkYXRhPShMUEJZVEUpeG1hbGxvYyh2YWxmcm9tLT5sZW4pOwoJCQltZW1jcHkoZGF0YSx2YWxmcm9tLT5kYXRhLHZhbGZyb20tPmxlbik7CgoJCQlfZmluZF9vcl9hZGRfdmFsdWUoCgkJCQlscHhrZXksCgkJCQluYW1lLAoJCQkJdmFsZnJvbS0+dHlwZSwKCQkJCWRhdGEsCgkJCQl2YWxmcm9tLT5sZW4sCgkJCQl2YWxmcm9tLT5sYXN0bW9kaWZpZWQKCQkJKTsKCQl9CgkJX2NvcHlfcmVnaXN0cnkoZnJvbSxscHhrZXkpOwoJCWZyb20gPSBmcm9tLT5uZXh0OwoJfQp9CgoKLyogV0lORE9XUyA5NSBSRUdJU1RSWSBMT0FERVIgKi8KLyogCiAqIFN0cnVjdHVyZSBvZiBhIHdpbjk1IHJlZ2lzdHJ5IGRhdGFiYXNlLgogKiBtYWluIGhlYWRlcjoKICogMCA6CSJDUkVHIgktIG1hZ2ljCiAqIDQgOglEV09SRCB2ZXJzaW9uCiAqIDggOglEV09SRCBvZmZzZXRfb2ZfUkdEQl9wYXJ0CiAqIDBDLi4wRjoJPyAoc29tZW9uZSBmaWxsIGluIHBsZWFzZSkKICogMTA6ICBXT1JECW51bWJlciBvZiBSR0RCIGJsb2NrcwogKiAxMjogIFdPUkQJPwogKiAxNDogIFdPUkQJYWx3YXlzIDAwMDA/CiAqIDE2OiAgV09SRAlhbHdheXMgMDAwMT8KICogMTguLjFGOgk/IChzb21lb25lIGZpbGwgaW4gcGxlYXNlKQogKgogKiAyMDogUkdLTl9zZWN0aW9uOgogKiAgIGhlYWRlcjoKICogCTAgOgkJIlJHS04iCS0gbWFnaWMKICogICAgICA0IDogRFdPUkQJb2Zmc2V0IHRvIGZpcnN0IFJHREIgc2VjdGlvbgogKiAgICAgIDggOiBEV09SRAlvZmZzZXQgdG8gdGhlIHJvb3QgcmVjb3JkCiAqIAlDLi4weDFCOiAJPyAoZmlsbCBpbikKICogICAgICAweDIwIC4uLiBvZmZzZXRfb2ZfUkdEQl9wYXJ0OiBEaXNrIEtleSBFbnRyeSBzdHJ1Y3R1cmVzCiAqCiAqICAgRGlzayBLZXkgRW50cnkgU3RydWN0dXJlOgogKgkwMDogRFdPUkQJLSBGcmVlIGVudHJ5IGluZGljYXRvcig/KQogKgkwNDogRFdPUkQJLSBIYXNoID0gc3VtIG9mIGJ5dGVzIG9mIGtleW5hbWUKICoJMDg6IERXT1JECS0gUm9vdCBrZXkgaW5kaWNhdG9yPyB1bmtub3duLCBidXQgdXN1YWxseSAweEZGRkZGRkZGIG9uIHdpbjk1IHN5c3RlbXMKICoJMEM6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIFByZXZpb3VzTGV2ZWwgS2V5LgogKgkxMDogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgTmV4dCBTdWJsZXZlbCBLZXkuCiAqCTE0OiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBOZXh0IEtleSAob24gc2FtZSBsZXZlbCkuCiAqIERLRVA+MTg6IFdPUkQJLSBOciwgTG93IFNpZ25pZmljYW50IHBhcnQuCiAqCTFBOiBXT1JECS0gTnIsIEhpZ2ggU2lnbmlmaWNhbnQgcGFydC4KICoKICogVGhlIGRpc2sgYWRkcmVzcyBhbHdheXMgcG9pbnRzIHRvIHRoZSBuciBwYXJ0IG9mIHRoZSBwcmV2aW91cyBrZXkgZW50cnkgCiAqIG9mIHRoZSByZWZlcmVuY2VkIGtleS4gRG9uJ3QgYXNrIG1lIHdoeSwgb3IgZXZlbiBpZiBJIGdvdCB0aGlzIGNvcnJlY3QKICogZnJvbSBzdGFyaW5nIGF0IDFrZyBvZiBoZXhkdW1wcy4gKERLRVApCiAqCiAqIFRoZSBIaWdoIHNpZ25pZmljYW50IHBhcnQgb2YgdGhlIHN0cnVjdHVyZSBzZWVtcyB0byBlcXVhbCB0aGUgbnVtYmVyCiAqIG9mIHRoZSBSR0RCIHNlY3Rpb24uIFRoZSBsb3cgc2lnbmlmaWNhbnQgcGFydCBpcyBhIHVuaXF1ZSBJRCB3aXRoaW4KICogdGhhdCBSR0RCIHNlY3Rpb24KICoKICogVGhlcmUgYXJlIHR3byBtaW5vciBjb3JyZWN0aW9ucyB0byB0aGUgcG9zaXRpb24gb2YgdGhhdCBzdHJ1Y3R1cmUuCiAqIDEuIElmIHRoZSBhZGRyZXNzIGlzIHh4eDAxNCBvciB4eHgwMTggaXQgd2lsbCBiZSBhbGlnbmVkIHRvIHh4eDAxYyBBTkQgCiAqICAgIHRoZSBES0UgcmVyZWFkIGZyb20gdGhlcmUuCiAqIDIuIElmIHRoZSBhZGRyZXNzIGlzIHh4eEZGeCBpdCB3aWxsIGJlIGFsaWduZWQgdG8gKHh4eCsxKTAwMC4KICogQ1BTIC0gSSBoYXZlIG5vdCBleHBlcmllbmNlZCB0aGUgYWJvdmUgcGhlbm9tZW5vbiBpbiBteSByZWdpc3RyeSBmaWxlcwogKgogKiBSR0RCX3NlY3Rpb246CiAqIAkwMDoJCSJSR0RCIgktIG1hZ2ljCiAqCTA0OiBEV09SRAlvZmZzZXQgdG8gbmV4dCBSR0RCIHNlY3Rpb24KICoJMDg6IERXT1JECT8KICoJMEM6IFdPUkQJYWx3YXlzIDAwMGQ/CiAqCTBFOiBXT1JECVJHREIgYmxvY2sgbnVtYmVyCiAqCTEwOglEV09SRAk/IChlcXVhbHMgdmFsdWUgYXQgb2Zmc2V0IDQgLSB2YWx1ZSBhdCBvZmZzZXQgOCkKICoJMTQuLjFGOgkJPwogKgkyMC4uLi4uOglkaXNrIGtleXMKICoKICogZGlzayBrZXk6CiAqIAkwMDogCURXT1JECW5leHRrZXlvZmZzZXQJLSBvZmZzZXQgdG8gdGhlIG5leHQgZGlzayBrZXkgc3RydWN0dXJlCiAqCTA4OiAJV09SRAluckxTCQktIGxvdyBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBBOiAJV09SRAluckhTCQktIGhpZ2ggc2lnbmlmaWNhbnQgcGFydCBvZiBOUgogKgkwQzogCURXT1JECWJ5dGVzdXNlZAktIGJ5dGVzIHVzZWQgaW4gdGhpcyBzdHJ1Y3R1cmUuCiAqCTEwOiAJV09SRAluYW1lX2xlbgktIGxlbmd0aCBvZiBuYW1lIGluIGJ5dGVzLiB3aXRob3V0IFwwCiAqCTEyOiAJV09SRAlucl9vZl92YWx1ZXMJLSBudW1iZXIgb2YgdmFsdWVzLgogKgkxNDogCWNoYXIJbmFtZVtuYW1lX2xlbl0JLSBuYW1lIHN0cmluZy4gTm8gXDAuCiAqCTE0K25hbWVfbGVuOiBkaXNrIHZhbHVlcwogKgluZXh0a2V5b2Zmc2V0OiAuLi4gbmV4dCBkaXNrIGtleQogKgogKiBkaXNrIHZhbHVlOgogKgkwMDoJRFdPUkQJdHlwZQkJLSB2YWx1ZSB0eXBlIChobW0sIGNvdWxkIGJlIFdPUkQgdG9vKQogKgkwNDoJRFdPUkQJCQktIHVua25vd24sIHVzdWFsbHkgMAogKgkwODoJV09SRAluYW1lbGVuCQktIGxlbmd0aCBvZiBOYW1lLiAwIG1lYW5zIG5hbWU9TlVMTAogKgkwQzoJV09SRAlkYXRhbGVuCQktIGxlbmd0aCBvZiBEYXRhLgogKgkxMDoJY2hhcgluYW1lW25hbWVsZW5dCS0gbmFtZSwgbm8gXDAKICoJMTArbmFtZWxlbjogQllURQlkYXRhW2RhdGFsZW5dIC0gZGF0YSwgd2l0aG91dCBcMCBpZiBzdHJpbmcKICoJMTArbmFtZWxlbitkYXRhbGVuOiBuZXh0IHZhbHVlcyBvciBkaXNrIGtleQogKgogKiBEaXNrIGtleXMgYXJlIGxheWVkIG91dCBmbGF0IC4uLiBCdXQsIHNvbWV0aW1lcywgbnJMUyBhbmQgbnJIUyBhcmUgYm90aAogKiAweEZGRkYsIHdoaWNoIG1lYW5zIHNraXBwaW5nIG92ZXIgbmV4dGtleW9mZnNldCBieXRlcyAoaW5jbHVkaW5nIHRoaXMKICogc3RydWN0dXJlKSBhbmQgcmVhZGluZyBhbm90aGVyIFJHREJfc2VjdGlvbi4KICogcmVwZWF0IHVudGlsIGVuZCBvZiBmaWxlLgogKgogKiBBbiBpbnRlcmVzdGluZyByZWxhdGlvbnNoaXAgZXhpc3RzIGluIFJHREJfc2VjdGlvbi4gVGhlIHZhbHVlIGF0IG9mZnNldAogKiAxMCBlcXVhbHMgdGhlIHZhbHVlIGF0IG9mZnNldCA0IG1pbnVzIHRoZSB2YWx1ZSBhdCBvZmZzZXQgOC4gSSBoYXZlIG5vCiAqIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKgogKiBGSVhNRTogdGhpcyBkZXNjcmlwdGlvbiBuZWVkcyBzb21lIHNlcmlvdXMgaGVscCwgeWVzLgogKi8KCnN0cnVjdAlfdzk1a2V5dmFsdWUgewoJdW5zaWduZWQgbG9uZwkJdHlwZTsKCXVuc2lnbmVkIHNob3J0CQlkYXRhbGVuOwoJY2hhcgkJCSpuYW1lOwoJdW5zaWduZWQgY2hhcgkJKmRhdGE7Cgl1bnNpZ25lZCBsb25nCQl4MTsKCWludAkJCWxhc3Rtb2RpZmllZDsKfTsKCnN0cnVjdCAJX3c5NWtleSB7CgljaGFyCQkJKm5hbWU7CglpbnQJCQlucm9mdmFsczsKCXN0cnVjdAlfdzk1a2V5dmFsdWUJKnZhbHVlczsKCXN0cnVjdCBfdzk1a2V5CQkqcHJldmx2bDsKCXN0cnVjdCBfdzk1a2V5CQkqbmV4dHN1YjsKCXN0cnVjdCBfdzk1a2V5CQkqbmV4dDsKfTsKCgpzdHJ1Y3QgX3c5NV9pbmZvIHsKICBjaGFyICpyZ2tuYnVmZmVyOwogIGludCAgcmdrbnNpemU7CiAgY2hhciAqcmdkYmJ1ZmZlcjsKICBpbnQgIHJnZGJzaXplOwogIGludCAgZGVwdGg7CiAgaW50ICBsYXN0bW9kaWZpZWQ7Cn07CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X3Byb2Nlc3NLZXkgW0ludGVybmFsXQogKi8Kc3RhdGljIExQS0VZU1RSVUNUIF93OTVfcHJvY2Vzc0tleSAoIExQS0VZU1RSVUNUIGxwa2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnJMUywgaW50IG5yTVMsIHN0cnVjdCBfdzk1X2luZm8gKmluZm8gKQoKewogIC8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCkgKi8KCXN0cnVjdAlka2ggewogICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZwkJbmV4dGtleW9mZjsgCgkJdW5zaWduZWQgc2hvcnQJCW5yTFM7CgkJdW5zaWduZWQgc2hvcnQJCW5yTVM7CgkJdW5zaWduZWQgbG9uZwkJYnl0ZXN1c2VkOwoJCXVuc2lnbmVkIHNob3J0CQlrZXluYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWx1ZXM7CgkJdW5zaWduZWQgbG9uZwkJeHgxOwoJCS8qIGtleW5hbWUgKi8KCQkvKiBkaXNrIGtleSB2YWx1ZXMgb3Igbm90aGluZyAqLwoJfTsKCS8qIERpc2sgS2V5IFZhbHVlIHN0cnVjdHVyZSAqLwoJc3RydWN0CWRrdiB7CgkJdW5zaWduZWQgbG9uZwkJdHlwZTsKCQl1bnNpZ25lZCBsb25nCQl4MTsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsbmFtZWxlbjsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsZGF0YWxlbjsKCQkvKiB2YWxuYW1lLCB2YWxkYXRhICovCgl9OwoKCQoJc3RydWN0CWRraCBka2g7CglpbnQJYnl0ZXNyZWFkID0gMDsKCWNoYXIgICAgKnJnZGJkYXRhID0gaW5mby0+cmdkYmJ1ZmZlcjsKCWludCAgICAgbmJ5dGVzID0gaW5mby0+cmdkYnNpemU7CgljaGFyICAgICpjdXJkYXRhID0gcmdkYmRhdGE7CgljaGFyICAgICplbmQgPSByZ2RiZGF0YSArIG5ieXRlczsKCWludCAgICAgb2ZmX25leHRfcmdkYjsKCWNoYXIgICAgKm5leHQgPSByZ2RiZGF0YTsKCWludCAgICAgbnJnZGIsIGk7CglMUEtFWVNUUlVDVAlscHhrZXk7CgkKCWRvIHsKCSAgY3VyZGF0YSA9IG5leHQ7CgkgIGlmIChzdHJuY21wKGN1cmRhdGEsICJSR0RCIiwgNCkpIHJldHVybiAoTlVMTCk7CgkgICAgCgkgIG1lbWNweSgmb2ZmX25leHRfcmdkYixjdXJkYXRhKzQsNCk7CgkgIG5leHQgPSBjdXJkYXRhICsgb2ZmX25leHRfcmdkYjsKCSAgbnJnZGIgPSAoaW50KSAqKChzaG9ydCAqKWN1cmRhdGEgKyA3KTsKCgl9IHdoaWxlIChucmdkYiAhPSBuck1TICYmIChuZXh0IDwgZW5kKSk7CgoJLyogY3VyZGF0YSBub3cgcG9pbnRzIHRvIHRoZSBzdGFydCBvZiB0aGUgcmlnaHQgUkdEQiBzZWN0aW9uICovCgljdXJkYXRhICs9IDB4MjA7CgojZGVmaW5lIFhSRUFEKHdoZXJldG8sbGVuKSBcCglpZiAoKGN1cmRhdGEgKyBsZW4pIDw9IGVuZCkge1wKCQltZW1jcHkod2hlcmV0byxjdXJkYXRhLGxlbik7XAoJCWN1cmRhdGErPWxlbjtcCgkJYnl0ZXNyZWFkKz1sZW47XAoJfQoKCXdoaWxlIChjdXJkYXRhIDwgbmV4dCkgewoJICBzdHJ1Y3QJZGtoICp4ZGtoID0gKHN0cnVjdCBka2gqKWN1cmRhdGE7CgoJICBieXRlc3JlYWQgKz0gc2l6ZW9mKGRraCk7IC8qIEZJWE1FLi4uIG5leHRrZXlvZmY/ICovCgkgIGlmICh4ZGtoLT5uckxTID09IG5yTFMpIHsKCSAgCW1lbWNweSgmZGtoLHhka2gsc2l6ZW9mKGRraCkpOwoJICAJY3VyZGF0YSArPSBzaXplb2YoZGtoKTsKCSAgCWJyZWFrOwoJICB9CgkgIGN1cmRhdGEgKz0geGRraC0+bmV4dGtleW9mZjsKCX07CgoJaWYgKGRraC5uckxTICE9IG5yTFMpIHJldHVybiAoTlVMTCk7CgoJaWYgKG5yZ2RiICE9IGRraC5uck1TKQoJICByZXR1cm4gKE5VTEwpOwoKICAgICAgICBhc3NlcnQoKGRraC5rZXluYW1lbGVuPDIpIHx8IGN1cmRhdGFbMF0pOwoJbHB4a2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksc3RyY3Z0QTJXKGN1cmRhdGEsIGRraC5rZXluYW1lbGVuKSk7CgljdXJkYXRhICs9IGRraC5rZXluYW1lbGVuOwoKCWZvciAoaT0wO2k8IGRraC52YWx1ZXM7IGkrKykgewoJICBzdHJ1Y3QgZGt2IGRrdjsKCSAgTFBCWVRFIGRhdGE7CgkgIGludCBsZW47CgkgIExQV1NUUiBuYW1lOwoKCSAgWFJFQUQoJmRrdixzaXplb2YoZGt2KSk7CgoJICBuYW1lID0gc3RyY3Z0QTJXKGN1cmRhdGEsIGRrdi52YWxuYW1lbGVuKTsKCSAgY3VyZGF0YSArPSBka3YudmFsbmFtZWxlbjsKCgkgIGlmICgoMSA8PCBka3YudHlwZSkgJiBVTklDT05WTUFTSykgewoJICAgIGRhdGEgPSAoTFBCWVRFKSBzdHJjdnRBMlcoY3VyZGF0YSwgZGt2LnZhbGRhdGFsZW4pOwoJICAgIGxlbiA9IDIqKGRrdi52YWxkYXRhbGVuICsgMSk7CgkgIH0gZWxzZSB7CgkgICAgLyogSSBkb24ndCB0aGluayB3ZSB3YW50IHRvIE5VTEwgdGVybWluYXRlIGFsbCBkYXRhICovCgkgICAgZGF0YSA9IHhtYWxsb2MoZGt2LnZhbGRhdGFsZW4pOwoJICAgIG1lbWNweSAoZGF0YSwgY3VyZGF0YSwgZGt2LnZhbGRhdGFsZW4pOwoJICAgIGxlbiA9IGRrdi52YWxkYXRhbGVuOwoJICB9CgoJICBjdXJkYXRhICs9IGRrdi52YWxkYXRhbGVuOwoJICAKCSAgX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJCQkgICAgIGxweGtleSwKCQkJICAgICBuYW1lLAoJCQkgICAgIGRrdi50eXBlLAoJCQkgICAgIGRhdGEsCgkJCSAgICAgbGVuLAoJCQkgICAgIGluZm8tPmxhc3Rtb2RpZmllZAoJCQkgICAgICk7Cgl9CglyZXR1cm4gKGxweGtleSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV93YWxrcmdrbiBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfdzk1X3dhbGtyZ2tuKCBMUEtFWVNUUlVDVCBwcmV2a2V5LCBjaGFyICpvZmYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgX3c5NV9pbmZvICppbmZvICkKCnsKICAvKiBEaXNrIEtleSBFbnRyeSBzdHJ1Y3R1cmUgKFJHS04gcGFydCkgKi8KICBzdHJ1Y3QJZGtlIHsKICAgIHVuc2lnbmVkIGxvbmcJCXgxOwogICAgdW5zaWduZWQgbG9uZwkJeDI7CiAgICB1bnNpZ25lZCBsb25nCQl4MzsvKnVzdWFsbHkgMHhGRkZGRkZGRiAqLwogICAgdW5zaWduZWQgbG9uZwkJcHJldmx2bDsKICAgIHVuc2lnbmVkIGxvbmcJCW5leHRzdWI7CiAgICB1bnNpZ25lZCBsb25nCQluZXh0OwogICAgdW5zaWduZWQgc2hvcnQJCW5yTFM7CiAgICB1bnNpZ25lZCBzaG9ydAkJbnJNUzsKICB9ICpka2UgPSAoc3RydWN0IGRrZSAqKW9mZjsKICBMUEtFWVNUUlVDVCAgbHB4a2V5OwoKICBpZiAoZGtlID09IE5VTEwpIHsKICAgIGRrZSA9IChzdHJ1Y3QgZGtlICopICgoY2hhciAqKWluZm8tPnJna25idWZmZXIpOwogIH0KCiAgbHB4a2V5ID0gX3c5NV9wcm9jZXNzS2V5KHByZXZrZXksIGRrZS0+bnJMUywgZGtlLT5uck1TLCBpbmZvKTsKICAvKiBYWFggPC0tIFRoaXMgaXMgYSBoYWNrKi8KICBpZiAoIWxweGtleSkgewogICAgbHB4a2V5ID0gcHJldmtleTsKICB9CgogIGlmIChka2UtPm5leHRzdWIgIT0gLTEgJiYgCiAgICAgICgoZGtlLT5uZXh0c3ViIC0gMHgyMCkgPCBpbmZvLT5yZ2tuc2l6ZSkgCiAgICAgICYmIChka2UtPm5leHRzdWIgPiAweDIwKSkgewogICAgCiAgICBfdzk1X3dhbGtyZ2tuKGxweGtleSwgCgkJICBpbmZvLT5yZ2tuYnVmZmVyICsgZGtlLT5uZXh0c3ViIC0gMHgyMCwgCgkJICBpbmZvKTsKICB9CiAgCiAgaWYgKGRrZS0+bmV4dCAhPSAtMSAmJiAKICAgICAgKChka2UtPm5leHQgLSAweDIwKSA8IGluZm8tPnJna25zaXplKSAmJiAKICAgICAgKGRrZS0+bmV4dCA+IDB4MjApKSB7CiAgICBfdzk1X3dhbGtyZ2tuKHByZXZrZXksICAKCQkgIGluZm8tPnJna25idWZmZXIgKyBka2UtPm5leHQgLSAweDIwLAoJCSAgaW5mbyk7CiAgfQoKICByZXR1cm47Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfdzk1X2xvYWRyZWcoIGNoYXIqIGZuLCBMUEtFWVNUUlVDVCBscGtleSApCnsKCUhGSUxFCQloZmQ7CgljaGFyCQltYWdpY1s1XTsKCXVuc2lnbmVkIGxvbmcJd2hlcmUsdmVyc2lvbixyZ2Ric2VjdGlvbixlbmQ7CglzdHJ1Y3QgICAgICAgICAgX3c5NV9pbmZvIGluZm87CglPRlNUUlVDVAlvZnM7CglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmRpbmZvOwoKCVRSQUNFKHJlZywiTG9hZGluZyBXaW45NSByZWdpc3RyeSBkYXRhYmFzZSAnJXMnXG4iLGZuKTsKCWhmZD1PcGVuRmlsZShmbiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmZD09SEZJTEVfRVJST1IpCgkJcmV0dXJuOwoJbWFnaWNbNF09MDsKCWlmICg0IT1fbHJlYWQoaGZkLG1hZ2ljLDQpKQoJCXJldHVybjsKCWlmIChzdHJjbXAobWFnaWMsIkNSRUciKSkgewoJCVdBUk4ocmVnLCIlcyBpcyBub3QgYSB3OTUgcmVnaXN0cnkuXG4iLGZuKTsKCQlyZXR1cm47Cgl9CglpZiAoNCE9X2xyZWFkKGhmZCwmdmVyc2lvbiw0KSkKCQlyZXR1cm47CglpZiAoNCE9X2xyZWFkKGhmZCwmcmdkYnNlY3Rpb24sNCkpCgkJcmV0dXJuOwoJaWYgKC0xPT1fbGxzZWVrKGhmZCwweDIwLFNFRUtfU0VUKSkKCQlyZXR1cm47CglpZiAoNCE9X2xyZWFkKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJSR0tOIikpIHsKCQlXQVJOKHJlZywgInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJXNcbiIsIG1hZ2ljKTsKCQlyZXR1cm47Cgl9CgoJLyogU1RFUCAxOiBLZXlsaW5rIHN0cnVjdHVyZXMgKi8KCWlmICgtMT09X2xsc2VlayhoZmQsMHg0MCxTRUVLX1NFVCkpCgkJcmV0dXJuOwoJd2hlcmUJPSAweDQwOwoJZW5kCT0gcmdkYnNlY3Rpb247CgoJaW5mby5yZ2tuc2l6ZSA9IGVuZCAtIHdoZXJlOwoJaW5mby5yZ2tuYnVmZmVyID0gKGNoYXIqKXhtYWxsb2MoaW5mby5yZ2tuc2l6ZSk7CglpZiAoaW5mby5yZ2tuc2l6ZSAhPSBfbHJlYWQoaGZkLGluZm8ucmdrbmJ1ZmZlcixpbmZvLnJna25zaXplKSkKCQlyZXR1cm47CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZmQsJmhmZGluZm8pKQoJCXJldHVybjsKCgllbmQgPSBoZmRpbmZvLm5GaWxlU2l6ZUxvdzsKCWluZm8ubGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmRpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCglpZiAoLTE9PV9sbHNlZWsoaGZkLHJnZGJzZWN0aW9uLFNFRUtfU0VUKSkKCQlyZXR1cm47CgoJaW5mby5yZ2RiYnVmZmVyID0gKGNoYXIqKXhtYWxsb2MoZW5kLXJnZGJzZWN0aW9uKTsKCWluZm8ucmdkYnNpemUgPSBlbmQgLSByZ2Ric2VjdGlvbjsKCglpZiAoaW5mby5yZ2Ric2l6ZSAhPV9scmVhZChoZmQsaW5mby5yZ2RiYnVmZmVyLGluZm8ucmdkYnNpemUpKQoJCXJldHVybjsKCV9sY2xvc2UoaGZkKTsKCglfdzk1X3dhbGtyZ2tuKGxwa2V5LCBOVUxMLCAmaW5mbyk7CgoJZnJlZSAoaW5mby5yZ2RiYnVmZmVyKTsKCWZyZWUgKGluZm8ucmdrbmJ1ZmZlcik7Cn0KCgovKiBXSU5ET1dTIDMxIFJFR0lTVFJZIExPQURFUiwgc3VwcGxpZWQgYnkgVG9yIFNq+HdhbGwsIHRvckBzbi5ubyAqLwoKLyoKICAgIHJlZ2hhY2sgLSB3aW5kb3dzIDMuMTEgcmVnaXN0cnkgZGF0YSBmb3JtYXQgZGVtbyBwcm9ncmFtLgoKICAgIFRoZSByZWcuZGF0IGZpbGUgaGFzIDMgcGFydHMsIGEgaGVhZGVyLCBhIHRhYmxlIG9mIDgtYnl0ZSBlbnRyaWVzIHRoYXQgaXMKICAgIGEgY29tYmluZWQgaGFzaCB0YWJsZSBhbmQgdHJlZSBkZXNjcmlwdGlvbiwgYW5kIGZpbmFsbHkgYSB0ZXh0IHRhYmxlLgoKICAgIFRoZSBoZWFkZXIgaXMgb2J2aW91cyBmcm9tIHRoZSBzdHJ1Y3QgaGVhZGVyLiBUaGUgdGFib2ZmMSBhbmQgdGFib2ZmMgogICAgZmllbGRzIGFyZSBhbHdheXMgMHgyMCwgYW5kIHRoZWlyIHVzYWdlIGlzIHVua25vd24uCgogICAgVGhlIDgtYnl0ZSBlbnRyeSB0YWJsZSBoYXMgdmFyaW91cyBlbnRyeSB0eXBlcy4KCiAgICB0YWJlbnRbMF0gaXMgYSByb290IGluZGV4LiBUaGUgc2Vjb25kIHdvcmQgaGFzIHRoZSBpbmRleCBvZiB0aGUgcm9vdCBvZgogICAgICAgICAgICB0aGUgZGlyZWN0b3J5LgogICAgdGFiZW50WzEuLmhhc2hzaXplXSBpcyBhIGhhc2ggdGFibGUuIFRoZSBmaXJzdCB3b3JkIGluIHRoZSBoYXNoIGVudHJ5IGlzCiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUga2V5L3ZhbHVlIHRoYXQgaGFzIHRoYXQgaGFzaC4gRGF0YSB3aXRoIHRoZSBzYW1lCiAgICAgICAgICAgIGhhc2ggdmFsdWUgYXJlIG9uIGEgY2lyY3VsYXIgbGlzdC4gVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZQogICAgICAgICAgICBoYXNoIGVudHJ5IGFyZSBhbHdheXMgemVyby4KICAgIHRhYmVudFtoYXNoc2l6ZS4udGFiY250XSBpcyB0aGUgdHJlZSBzdHJ1Y3R1cmUuIFRoZXJlIGFyZSB0d28ga2luZHMgb2YKICAgICAgICAgICAgZW50cnk6IGRpcmVudCBhbmQga2V5ZW50L3ZhbGVudC4gVGhleSBhcmUgaWRlbnRpZmllZCBieSBjb250ZXh0LgogICAgdGFiZW50W2ZyZWVpZHhdIGlzIHRoZSBmaXJzdCBmcmVlIGVudHJ5LiBUaGUgZmlyc3Qgd29yZCBpbiBhIGZyZWUgZW50cnkKICAgICAgICAgICAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGZyZWUgZW50cnkuIFRoZSBsYXN0IGhhcyAwIGFzIGEgbGluay4KICAgICAgICAgICAgVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZSBmcmVlIGxpc3QgYXJlIHByb2JhYmx5IGlycmVsZXZhbnQuCgogICAgRW50cmllcyBpbiB0ZXh0IHRhYmxlIGFyZSBwcmVjZWVkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewoJY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCgl1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7Cgl1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7Cgl1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCgl1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgKi8Kdm9pZApfX3czMV9kdW1wdHJlZSgJdW5zaWduZWQgc2hvcnQgaWR4LAoJCXVuc2lnbmVkIGNoYXIgKnR4dCwKCQlzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYiwKCQlzdHJ1Y3QgX3czMV9oZWFkZXIgKmhlYWQsCgkJTFBLRVlTVFJVQ1QJbHBrZXksCgkJdGltZV90CQlsYXN0bW9kaWZpZWQsCgkJaW50CQlsZXZlbAopIHsKCXN0cnVjdCBfdzMxX2RpcmVudAkqZGlyOwoJc3RydWN0IF93MzFfa2V5ZW50CSprZXk7CglzdHJ1Y3QgX3czMV92YWxlbnQJKnZhbDsKCUxQS0VZU1RSVUNUCQl4bHBrZXkgPSBOVUxMOwoJTFBXU1RSCQkJbmFtZSx2YWx1ZTsKCXN0YXRpYyBjaGFyCQl0YWlsWzQwMF07CgoJd2hpbGUgKGlkeCE9MCkgewoJCWRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgoJCWlmIChkaXItPmtleV9pZHgpIHsKCQkJa2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKCQkJbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKCQkJdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKCQkJLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZSAKCQkJICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwoJCQkgKi8KCQkJaWYgKCFsZXZlbCAmJiAhbHN0cmNtcEEodGFpbCwiLmNsYXNzZXMiKSkgewoJCQkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLGxwa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQkJCWlkeD1kaXItPnNpYmxpbmdfaWR4OwoJCQkJY29udGludWU7CgkJCX0KCQkJbmFtZT1zdHJkdXBBMlcodGFpbCk7CgoJCQl4bHBrZXk9X2ZpbmRfb3JfYWRkX2tleShscGtleSxuYW1lKTsKCgkJCS8qIG9ubHkgYWRkIGlmIGxlYWYgbm9kZSBvciB2YWx1ZWQgbm9kZSAqLwoJCQlpZiAoZGlyLT52YWx1ZV9pZHghPTB8fGRpci0+Y2hpbGRfaWR4PT0wKSB7CgkJCQlpZiAoZGlyLT52YWx1ZV9pZHgpIHsKCQkJCQl2YWw9KHN0cnVjdCBfdzMxX3ZhbGVudCopJnRhYltkaXItPnZhbHVlX2lkeF07CgkJCQkJbWVtY3B5KHRhaWwsJnR4dFt2YWwtPnN0cmluZ19vZmZdLHZhbC0+bGVuZ3RoKTsKCQkJCQl0YWlsW3ZhbC0+bGVuZ3RoXT0nXDAnOwoJCQkJCXZhbHVlPXN0cmR1cEEyVyh0YWlsKTsKCQkJCQlfZmluZF9vcl9hZGRfdmFsdWUoeGxwa2V5LE5VTEwsUkVHX1NaLChMUEJZVEUpdmFsdWUsbHN0cmxlblcodmFsdWUpKjIrMixsYXN0bW9kaWZpZWQpOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJVFJBQ0UocmVnLCJzdHJhbmdlOiBubyBkaXJlY3Rvcnkga2V5IG5hbWUsIGlkeD0lMDR4XG4iLCBpZHgpOwoJCX0KCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQseGxwa2V5LGxhc3Rtb2RpZmllZCxsZXZlbCsxKTsKCQlpZHg9ZGlyLT5zaWJsaW5nX2lkeDsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3czMV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnZvaWQgX3czMV9sb2FkcmVnKHZvaWQpIHsKCUhGSUxFCQkJaGY7CglzdHJ1Y3QgX3czMV9oZWFkZXIJaGVhZDsKCXN0cnVjdCBfdzMxX3RhYmVudAkqdGFiOwoJdW5zaWduZWQgY2hhcgkJKnR4dDsKCWludAkJCWxlbjsKCU9GU1RSVUNUCQlvZnM7CglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmluZm87Cgl0aW1lX3QJCQlsYXN0bW9kaWZpZWQ7CglMUEtFWVNUUlVDVAkJbHBrZXk7CgoJVFJBQ0UocmVnLCIodm9pZClcbiIpOwoKCWhmID0gT3BlbkZpbGUoInJlZy5kYXQiLCZvZnMsT0ZfUkVBRCk7CglpZiAoaGY9PUhGSUxFX0VSUk9SKQoJCXJldHVybjsKCgkvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KCWlmIChzaXplb2YoaGVhZCkhPV9scmVhZChoZiwmaGVhZCxzaXplb2YoaGVhZCkpKSB7CgkJRVJSKHJlZywgInJlZy5kYXQgaXMgdG9vIHNob3J0LlxuIik7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoJaWYgKG1lbWNtcChoZWFkLmNvb2tpZSwgIlNIQ0MzLjEwIiwgc2l6ZW9mKGhlYWQuY29va2llKSkhPTApIHsKCQlFUlIocmVnLCAicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCglsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwoJLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwoJdGFiID0geG1hbGxvYyhsZW4pOwoJaWYgKGxlbiE9X2xyZWFkKGhmLHRhYixsZW4pKSB7CgkJRVJSKHJlZywiY291bGRuJ3QgcmVhZCAlZCBieXRlcy5cbiIsbGVuKTsgCgkJZnJlZSh0YWIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCgkvKiByZWFkIHRleHQgKi8KCXR4dCA9IHhtYWxsb2MoaGVhZC50ZXh0c2l6ZSk7CglpZiAoLTE9PV9sbHNlZWsoaGYsaGVhZC50ZXh0b2ZmLFNFRUtfU0VUKSkgewoJCUVSUihyZWcsImNvdWxkbid0IHNlZWsgdG8gdGV4dGJsb2NrLlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoJaWYgKGhlYWQudGV4dHNpemUhPV9scmVhZChoZix0eHQsaGVhZC50ZXh0c2l6ZSkpIHsKCQlFUlIocmVnLCJ0ZXh0YmxvY2sgdG9vIHNob3J0ICglZCBpbnN0ZWFkIG9mICVsZCkuXG4iLGxlbixoZWFkLnRleHRzaXplKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZiwmaGZpbmZvKSkgewoJCUVSUihyZWcsIkdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlIGZhaWxlZD8uXG4iKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CglsYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CglscGtleSA9IGxvb2t1cF9oa2V5KEhLRVlfQ0xBU1NFU19ST09UKTsKCV9fdzMxX2R1bXB0cmVlKHRhYlswXS53MSx0eHQsdGFiLCZoZWFkLGxwa2V5LGxhc3Rtb2RpZmllZCwwKTsKCWZyZWUodGFiKTsKCWZyZWUodHh0KTsKCV9sY2xvc2UoaGYpOwoJcmV0dXJuOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfTG9hZFJlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnZvaWQgU0hFTExfTG9hZFJlZ2lzdHJ5KCB2b2lkICkKewogIGNoYXIJICAgICAgKmZuLCAqaG9tZTsKICBMUEtFWVNUUlVDVAlscGtleSwgSEtDVSwgSEtVLCBIS0xNOwogIEhLRVkJCSAgICBoa2V5OwoKICBUUkFDRShyZWcsIih2b2lkKVxuIik7CgogIEhLQ1UgPSBsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUik7CiAgSEtVICA9IGxvb2t1cF9oa2V5KEhLRVlfVVNFUlMpOwogIEhLTE0gPSBsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpOwoKICAvKiBMb2FkIHdpbmRvd3MgMy4xIGVudHJpZXMgKi8KICBfdzMxX2xvYWRyZWcoKTsKICAvKiBMb2FkIHdpbmRvd3MgOTUgZW50cmllcyAqLwogIF93OTVfbG9hZHJlZygiQzpcXHN5c3RlbS4xc3QiLAlIS0xNKTsKICBfdzk1X2xvYWRyZWcoInN5c3RlbS5kYXQiLAlIS0xNKTsKICBfdzk1X2xvYWRyZWcoInVzZXIuZGF0IiwJSEtVKTsKCiAgLyogCiAgICogTG9hZCB0aGUgZ2xvYmFsIEhLVSBoaXZlIGRpcmVjdGx5IGZyb20gL3Vzci9sb2NhbC9ldGMKICAgKi8gCiAgX3dpbmVfbG9hZHJlZyggSEtVLCBTQVZFX1VTRVJTX0RFRkFVTFQsIDApOwoKICAvKiAKICAgKiBMb2FkIHRoZSBnbG9iYWwgbWFjaGluZSBkZWZhdWx0cyBkaXJlY3RseSBmb3JtIC91c3IvbG9jYWwvZXRjCiAgICovCiAgX3dpbmVfbG9hZHJlZyggSEtMTSwgU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQsIDApOwoKICAvKgogICAqIExvYWQgdGhlIHVzZXIgc2F2ZWQgcmVnaXN0cmllcyAKICAgKi8KICBpZiAoKGhvbWUgPSBnZXRlbnYoICJIT01FIiApKSkKICB7CiAgICAvKiAKICAgICAqIExvYWQgdXNlcidzIHBlcnNvbmFsIHZlcnNpb25zIG9mIGdsb2JhbCBIS1UvLkRlZmF1bHQga2V5cwogICAgICovCiAgICBmbj0oY2hhciopeG1hbGxvYygKICAgICAgICAgICAgICAgIHN0cmxlbihob21lKSsKICAgICAgICAgICAgICAgIHN0cmxlbihXSU5FX1BSRUZJWCkrCiAgICAgICAgICAgICAgICBzdHJsZW4oU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKSsyKTsKCiAgICBzdHJjcHkoZm4sIGhvbWUpOwogICAgc3RyY2F0KGZuLCBXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCk7CiAgICBfd2luZV9sb2FkcmVnKEhLVSwgZm4sIFJFR19PUFRJT05fVEFJTlRFRCk7IAogICAgZnJlZShmbik7CgogICAgLyogCiAgICAgKiBMb2FkIEhLQ1UsIGF0dGVtcHQgdG8gZ2V0IHRoZSByZWdpc3RyeSBsb2NhdGlvbiBmcm9tIHRoZSBjb25maWcgCiAgICAgKiBmaWxlIGZpcnN0LCBpZiBleGlzdCwgbG9hZCBhbmQga2VlcCBnb2luZy4KICAgICAqLyAgICAgIAogICAgZm4gPSB4bWFsbG9jKCBNQVhfUEFUSE5BTUVfTEVOICk7IAogICAgaWYgKCBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoCiAgICAgICAgICAiUmVnaXN0cnkiLCAKICAgICAgICAgICJVc2VyRmlsZU5hbWUiLCAKICAgICAgICAgICIiLCAKICAgICAgICAgIGZuLCAKICAgICAgICAgIE1BWF9QQVRITkFNRV9MRU4gLSAxKSkgCiAgICB7CiAgICAgIF93aW5lX2xvYWRyZWcoSEtDVSxmbiwwKTsKICAgIH0KICAJZnJlZSAoZm4pOwoKICAgIGZuPShjaGFyKil4bWFsbG9jKAogICAgICAgICAgICAgICAgc3RybGVuKGhvbWUpKwogICAgICAgICAgICAgICAgc3RybGVuKFdJTkVfUFJFRklYKSsKICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikrMik7CgogICAgc3RyY3B5KGZuLCBob21lKTsKICAgIHN0cmNhdChmbiwgV0lORV9QUkVGSVgiLyJTQVZFX0NVUlJFTlRfVVNFUik7CiAgICBfd2luZV9sb2FkcmVnKEhLQ1UsIGZuLCBSRUdfT1BUSU9OX1RBSU5URUQpOwogICAgZnJlZShmbik7CgogICAgLyogCiAgICAgKiBMb2FkIEhLTE0sIGF0dGVtcHQgdG8gZ2V0IHRoZSByZWdpc3RyeSBsb2NhdGlvbiBmcm9tIHRoZSBjb25maWcgCiAgICAgKiBmaWxlIGZpcnN0LCBpZiBleGlzdCwgbG9hZCBhbmQga2VlcCBnb2luZy4KICAgICAqLyAgICAgIAogICAgZm4gPSB4bWFsbG9jICggTUFYX1BBVEhOQU1FX0xFTik7CiAgICBpZiAoIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZygKICAgICAgICAgICJSZWdpc3RyeSIsIAogICAgICAgICAgIkxvY2FsTWFjaGluZUZpbGVOYW1lIiwgCiAgICAgICAgICAiIiwgCiAgICAgICAgICBmbiwgCiAgICAgICAgICBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpCiAgICB7CiAgICAgICAgX3dpbmVfbG9hZHJlZyhIS0xNLCBmbiwgMCk7CiAgICB9CiAgICBmcmVlKGZuKTsKCiAgICBmbj0oY2hhciopeG1hbGxvYygKICAgICAgICAgICAgICAgIHN0cmxlbihob21lKSsKICAgICAgICAgICAgICAgIHN0cmxlbihXSU5FX1BSRUZJWCkrCiAgICAgICAgICAgICAgICBzdHJsZW4oU0FWRV9MT0NBTF9NQUNISU5FKSsyKTsKCiAgICBzdHJjcHkoZm4saG9tZSk7CiAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwogICAgX3dpbmVfbG9hZHJlZyhIS0xNLCBmbiwgUkVHX09QVElPTl9UQUlOVEVEKTsKICAgIGZyZWUoZm4pOwogIH0KICBlbHNlCiAgewogICAgV0FSTihyZWcsIkZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWQuXG4iLGdldHVpZCgpKTsKICB9CgogIC8qIAogICAqIE9idGFpbiB0aGUgaGFuZGxlIG9mIHRoZSBIS1VcLkRlZmF1bHQga2V5LgogICAqIGluIG9yZGVyIHRvIGNvcHkgSEtVXC5EZWZhdWx0XCogb250byBIS0VZX0NVUlJFTlRfVVNFUiAKICAgKi8KICBSZWdDcmVhdGVLZXkxNihIS0VZX1VTRVJTLCIuRGVmYXVsdCIsJmhrZXkpOwogIGxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CiAgaWYoIWxwa2V5KQogICAgIFdBUk4ocmVnLCJDb3VsZCBub3QgY3JlYXRlIGdsb2JhbCB1c2VyIGRlZmF1bHQga2V5XG4iKTsKICBlbHNlCiAgICBfY29weV9yZWdpc3RyeShscGtleSwgSEtDVSApOwoKICBSZWdDbG9zZUtleShoa2V5KTsKCiAgLyogCiAgICogU2luY2UgSEtVIGlzIGJ1aWx0IGZyb20gdGhlIGdsb2JhbCBIS1UgYW5kIHRoZSBsb2NhbCB1c2VyIEhLVSBmaWxlIHdlIG11c3QKICAgKiBmbHVzaCB0aGUgSEtVIHRyZWUgd2UgaGF2ZSBidWlsdCBhdCB0aGlzIHBvaW50IG90aGVyd2lzZSB0aGUgcGFydCBicm91Z2h0CiAgICogaW4gZnJvbSB0aGUgZ2xvYmFsIEhLVSBpcyBzYXZlZCBpbnRvIHRoZSBsb2NhbCBIS1UuICBUbyBhdm9pZCB0aGlzIAogICAqIHVzZWxlc3MgZHVwcGxpY2F0aW9uIG9mIEhLVSBrZXlzIHdlIHJlcmVhZCB0aGUgbG9jYWwgSEtVIGtleS4KICAgKi8KCiAgLyogQWxsd2F5cyBmbHVzaCB0aGUgSEtVIGhpdmUgYW5kIHJlbG9hZCBpdCBvbmx5IHdpdGggdXNlcidzIHBlcnNvbmFsIEhLVSAqLwogIF9mbHVzaF9yZWdpc3RyeShIS1UpOyAKCiAgLyogUmVsb2FkIHVzZXIncyBsb2NhbCBIS1UgaGl2ZSAqLwogIGlmIChob21lKQogIHsKICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkKICAgICAgICAgICAgICAgICAgICAgICAgICsgc3RybGVuKFNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCkgKyAyKTsKICAgICAgCiAgICAgIHN0cmNweShmbixob21lKTsKICAgICAgc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKTsKCiAgICAgIF93aW5lX2xvYWRyZWcoIEhLVSwgZm4sIFJFR19PUFRJT05fVEFJTlRFRCk7CgogICAgICBmcmVlKGZuKTsKICB9CgogIC8qIAogICAqIE1ha2Ugc3VyZSB0aGUgdXBkYXRlIG1vZGUgaXMgdGhlcmUKICAgKi8KICBpZiAoRVJST1JfU1VDQ0VTUz09UmVnQ3JlYXRlS2V5MTYoSEtFWV9DVVJSRU5UX1VTRVIsS0VZX1JFR0lTVFJZLCZoa2V5KSkgCiAgewogICAgRFdPUkQJanVuayx0eXBlLGxlbjsKICAgIGNoYXIJZGF0YVs1XTsKCiAgICBsZW49NDsKICAgIGlmICgoCVJlZ1F1ZXJ5VmFsdWVFeEEoCiAgICAgICAgICAgIGhrZXksCiAgICAgICAgICAgIFZBTF9TQVZFVVBEQVRFRCwKICAgICAgICAgICAgJmp1bmssCiAgICAgICAgICAgICZ0eXBlLAogICAgICAgICAgICBkYXRhLAogICAgICAgICAgICAmbGVuKSAhPSBFUlJPUl9TVUNDRVNTKSB8fCAodHlwZSAhPSBSRUdfU1opKQogICAgewogICAgICBSZWdTZXRWYWx1ZUV4QShoa2V5LFZBTF9TQVZFVVBEQVRFRCwwLFJFR19TWiwieWVzIiw0KTsKICAgIH0KCiAgICBSZWdDbG9zZUtleShoa2V5KTsKICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIEFQSSBGVU5DVElPTlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKgogKiBPcGVuIEtleXMuCiAqCiAqIEFsbCBmdW5jdGlvbnMgYXJlIHN0dWJzIHRvIFJlZ09wZW5LZXlFeDMyVyB3aGVyZSBhbGwgdGhlCiAqIG1hZ2ljIGhhcHBlbnMuIAogKgogKiBDYWxscGF0aDoKICogUmVnT3BlbktleTE2IC0+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=