LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxwd2QuaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgInN0cmluZzMyLmgiCQojaW5jbHVkZSAic3RkZGVidWcuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJ4bWFsbG9jLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNkZWZpbmUgTUFLRV9EV09SRCh4LHkpICgoRFdPUkQpTUFLRUxPTkcoeCx5KSkKCi8qIEZJWE1FOiBmb2xsb3dpbmcgZGVmaW5lcyBzaG91bGQgYmUgY29uZmlndXJlZCBnbG9iYWwgLi4uICovCgovKiBOT1RFOiBkbyBub3QgYXBwZW5kIGEgLy4gbGludXgnIG1rZGlyKCkgV0lMTCBGQUlMIGlmIHlvdSBkbyB0aGF0ICovCiNkZWZpbmUgV0lORV9QUkVGSVgJCQkiLy53aW5lIgojZGVmaW5lIFNBVkVfVVNFUlNfREVGQVVMVAkJIi91c3IvbG9jYWwvZXRjL3dpbmUudXNlcnJlZyIKI2RlZmluZSBTQVZFX0xPQ0FMX01BQ0hJTkVfREVGQVVMVAkiL3Vzci9sb2NhbC9ldGMvd2luZS5zeXN0ZW1yZWciCgovKiByZWxhdGl2ZSBpbiB+dXNlci8ud2luZS8gOiAqLwojZGVmaW5lIFNBVkVfQ1VSUkVOVF9VU0VSCQkidXNlci5yZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FCQkic3lzdGVtLnJlZyIKCiNkZWZpbmUgS0VZX1JFR0lTVFJZCSJTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnkiCiNkZWZpbmUgVkFMX1NBVkVVUERBVEVECSJTYXZlT25seVVwZGF0ZWRLZXlzIgoKLyogb25lIHZhbHVlIG9mIGEga2V5ICovCnR5cGVkZWYgc3RydWN0IHRhZ0tFWVZBTFVFCnsKICAgIExQV1NUUiAgIG5hbWU7ICAgICAgICAgIC8qIG5hbWUgb2YgdmFsdWUgKFVOSUNPREUpIG9yIE5VTEwgZm9yIHdpbjMxICovCiAgICBEV09SRCAgICB0eXBlOyAgICAgICAgICAvKiB0eXBlIG9mIHZhbHVlICovCiAgICBEV09SRCAgICBsZW47ICAgICAgICAgICAvKiBsZW5ndGggb2YgZGF0YSAqLwogICAgRFdPUkQgICAgbGFzdG1vZGlmaWVkOyAgLyogdGltZSBvZiBzZWNvbmRzIHNpbmNlIDEuMS4xOTcwICovCiAgICBMUEJZVEUgICBkYXRhOyAgICAgICAgICAvKiBjb250ZW50LCBtYXkgYmUgc3RyaW5ncywgYmluYXJpZXMsIGV0Yy4gKi8KfSBLRVlWQUxVRSwqTFBLRVlWQUxVRTsKCi8qIGEgcmVnaXN0cnkga2V5ICovCnR5cGVkZWYgc3RydWN0IHRhZ0tFWVNUUlVDVAp7CiAgICBMUFdTVFIgICAgICAgICAgICAgICBrZXluYW1lOyAgICAgICAvKiBuYW1lIG9mIFRISVMga2V5IChVTklDT0RFKSAqLwogICAgRFdPUkQgICAgICAgICAgICAgICAgZmxhZ3M7ICAgICAgICAgLyogZmxhZ3MuICovCiAgICBMUFdTVFIgICAgICAgICAgICAgICBjbGFzczsKICAgIC8qIHZhbHVlcyAqLwogICAgRFdPUkQgICAgICAgICAgICAgICAgbnJvZnZhbHVlczsgICAgLyogbnIgb2YgdmFsdWVzIGluIFRISVMga2V5ICovCiAgICBMUEtFWVZBTFVFICAgICAgICAgICB2YWx1ZXM7ICAgICAgICAvKiB2YWx1ZXMgaW4gVEhJUyBrZXkgKi8KICAgIC8qIGtleSBtYW5hZ2VtZW50IHBvaW50ZXJzICovCiAgICBzdHJ1Y3QgdGFnS0VZU1RSVUNUCSpuZXh0OyAgICAgICAgICAvKiBuZXh0IGtleSBvbiBzYW1lIGhpZXJhcmNoeSAqLwogICAgc3RydWN0IHRhZ0tFWVNUUlVDVAkqbmV4dHN1YjsgICAgICAgLyoga2V5cyB0aGF0IGhhbmcgYmVsb3cgVEhJUyBrZXkgKi8KfSBLRVlTVFJVQ1QsICpMUEtFWVNUUlVDVDsKCgpzdGF0aWMgS0VZU1RSVUNUCSprZXlfY2xhc3Nlc19yb290PU5VTEw7CS8qIHdpbmRvd3MgMy4xIGdsb2JhbCB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X2N1cnJlbnRfdXNlcj1OVUxMOwkvKiB1c2VyIHNwZWNpZmljIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfbG9jYWxfbWFjaGluZT1OVUxMOy8qIG1hY2hpbmUgc3BlY2lmaWMgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV91c2Vycz1OVUxMOwkvKiBhbGwgdXNlcnM/ICovCgovKiBkeW5hbWljLCBub3Qgc2F2ZWQgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X3BlcmZvcm1hbmNlX2RhdGE9TlVMTDsKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2N1cnJlbnRfY29uZmlnPU5VTEw7CnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9keW5fZGF0YT1OVUxMOwoKLyogd2hhdCB2YWx1ZXR5cGVzIGRvIHdlIG5lZWQgdG8gY29udmVydD8gKi8KI2RlZmluZSBVTklDT05WTUFTSwkoKDE8PFJFR19TWil8KDE8PFJFR19NVUxUSV9TWil8KDE8PFJFR19FWFBBTkRfU1opKQoKI2RlZmluZSBzdHJkdXBBMlcoeCkJU1RSSU5HMzJfRHVwQW5zaVRvVW5pKHgpCiNkZWZpbmUgc3RyZHVwVyh4KQlTVFJJTkczMl9zdHJkdXBXKHgpCiNkZWZpbmUgc3RyY2hyVyhhLGMpCVNUUklORzMyX2xzdHJjaHJXKGEsYykKCnN0YXRpYyBzdHJ1Y3Qgb3BlbmhhbmRsZSB7CglMUEtFWVNUUlVDVAlscGtleTsKCUhLRVkJCWhrZXk7CglSRUdTQU0JCWFjY2Vzc21hc2s7Cn0gICpvcGVuaGFuZGxlcz1OVUxMOwpzdGF0aWMgaW50CW5yb2ZvcGVuaGFuZGxlcz0wOwpzdGF0aWMgaW50CWN1cnJlbnRoYW5kbGU9MTsKCnN0YXRpYyB2b2lkCmFkZF9oYW5kbGUoSEtFWSBoa2V5LExQS0VZU1RSVUNUIGxwa2V5LFJFR1NBTSBhY2Nlc3NtYXNrKSB7CglpbnQJaTsKCglmb3IgKGk9MDtpPG5yb2ZvcGVuaGFuZGxlcztpKyspIHsKCQlpZiAob3BlbmhhbmRsZXNbaV0ubHBrZXk9PWxwa2V5KSB7CgkJCWRwcmludGZfcmVnKHN0ZGRlYiwiYWRkX2hhbmRsZTpUcmllZCB0byBhZGQgJXAgdHdpY2UhXG4iLGxwa2V5KTsKCQl9CgkJaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpIHsKCQkJZHByaW50Zl9yZWcoc3RkZGViLCJhZGRfaGFuZGxlOlRyaWVkIHRvIGFkZCAlbHggdHdpY2UhXG4iLChMT05HKWhrZXkpOwoJCX0KCX0KCW9wZW5oYW5kbGVzPXhyZWFsbG9jKAlvcGVuaGFuZGxlcywKCQkJCXNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcysxKQoJCSk7CglvcGVuaGFuZGxlc1tpXS5scGtleQk9IGxwa2V5OwoJb3BlbmhhbmRsZXNbaV0uaGtleQk9IGhrZXk7CglvcGVuaGFuZGxlc1tpXS5hY2Nlc3NtYXNrPSBhY2Nlc3NtYXNrOwoJbnJvZm9wZW5oYW5kbGVzKys7Cn0KCnN0YXRpYyBMUEtFWVNUUlVDVApnZXRfaGFuZGxlKEhLRVkgaGtleSkgewoJaW50CWk7CgoJZm9yIChpPTA7aTxucm9mb3BlbmhhbmRsZXM7aSsrKQoJCWlmIChvcGVuaGFuZGxlc1tpXS5oa2V5PT1oa2V5KQoJCQlyZXR1cm4gb3BlbmhhbmRsZXNbaV0ubHBrZXk7CglkcHJpbnRmX3JlZyhzdGRkZWIsImdldF9oYW5kbGU6RGlkbid0IGZpbmQgaGFuZGxlICVseD9cbiIsKExPTkcpaGtleSk7CglyZXR1cm4gTlVMTDsKfQoKc3RhdGljIHZvaWQKcmVtb3ZlX2hhbmRsZShIS0VZIGhrZXkpIHsKCWludAlpOwoKCWZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykKCQlpZiAob3BlbmhhbmRsZXNbaV0uaGtleT09aGtleSkKCQkJYnJlYWs7CglpZiAoaT09bnJvZm9wZW5oYW5kbGVzKSB7CgkJZHByaW50Zl9yZWcoc3RkZGViLCJyZW1vdmVfaGFuZGxlOkRpZG4ndCBmaW5kIGhhbmRsZSAlMDh4P1xuIixoa2V5KTsKCQlyZXR1cm47Cgl9CgltZW1jcHkoCW9wZW5oYW5kbGVzK2ksCgkJb3BlbmhhbmRsZXMraSsxLAoJCXNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy1pLTEpCgkpOwoJb3BlbmhhbmRsZXM9eHJlYWxsb2Mob3BlbmhhbmRsZXMsc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLTEpKTsKCW5yb2ZvcGVuaGFuZGxlcy0tOwoJcmV0dXJuOwp9CgoKLyogZGVidWcgZnVuY3Rpb24sIGNvbnZlcnRzIGEgdW5pY29kZSBpbnRvIGEgc3RhdGljIG1lbW9yeSBhcmVhIAogKiAoc3ViIGZvciB1c2luZyB0d28gc3RhdGljIHN0cmluZ3MsIGluIGNhc2Ugd2UgbmVlZCB0aGVtIGluIGEgc2luZ2xlIGNhbGwpCiAqLwpMUFNUUgpXMkMoTFBDV1NUUiB4LGludCBzdWIpIHsKCXN0YXRpYwlMUFNUUgl1bmljb2RlZGVidWdbMl09e05VTEwsTlVMTH07CglpZiAoeD09TlVMTCkKCQlyZXR1cm4gIjxOVUxMPiI7CglpZiAoc3ViIT0wICYmIHN1YiE9MSkKCQlyZXR1cm4gIjxXMkM6YmFkIHN1Yj4iOwoJaWYgKHVuaWNvZGVkZWJ1Z1tzdWJdKSBIZWFwRnJlZSggU3lzdGVtSGVhcCwgMCwgdW5pY29kZWRlYnVnW3N1Yl0gKTsKCXVuaWNvZGVkZWJ1Z1tzdWJdID0gSEVBUF9zdHJkdXBXdG9BKCBTeXN0ZW1IZWFwLCAwLCB4ICk7CglyZXR1cm4gdW5pY29kZWRlYnVnW3N1Yl07Cn0KCnN0YXRpYyBMUEtFWVNUUlVDVApsb29rdXBfaGtleShIS0VZIGhrZXkpIHsKCXN3aXRjaCAoaGtleSkgewoJY2FzZSAweDAwMDAwMDAwOgoJY2FzZSAweDAwMDAwMDAxOgoJY2FzZSBIS0VZX0NMQVNTRVNfUk9PVDoKCQlyZXR1cm4ga2V5X2NsYXNzZXNfcm9vdDsKCWNhc2UgSEtFWV9DVVJSRU5UX1VTRVI6CgkJcmV0dXJuIGtleV9jdXJyZW50X3VzZXI7CgljYXNlIEhLRVlfTE9DQUxfTUFDSElORToKCQlyZXR1cm4ga2V5X2xvY2FsX21hY2hpbmU7CgljYXNlIEhLRVlfVVNFUlM6CgkJcmV0dXJuIGtleV91c2VyczsKCWNhc2UgSEtFWV9QRVJGT1JNQU5DRV9EQVRBOgoJCXJldHVybiBrZXlfcGVyZm9ybWFuY2VfZGF0YTsKCWNhc2UgSEtFWV9EWU5fREFUQToKCQlyZXR1cm4ga2V5X2R5bl9kYXRhOwoJY2FzZSBIS0VZX0NVUlJFTlRfQ09ORklHOgoJCXJldHVybiBrZXlfY3VycmVudF9jb25maWc7CglkZWZhdWx0OgoJCWRwcmludGZfcmVnKHN0ZGRlYiwibG9va3VwX2hrZXkoJWx4KSwgc3BlY2lhbCBrZXkhXG4iLAoJCQkoTE9ORyloa2V5CgkJKTsKCQlyZXR1cm4gZ2V0X2hhbmRsZShoa2V5KTsKCX0KCS8qTk9UUkVBQ0hFRCovCn0KCi8qIAogKiBzcGxpdHMgdGhlIHVuaWNvZGUgc3RyaW5nICd3cCcgaW50byBhbiBhcnJheSBvZiBzdHJpbmdzLgogKiB0aGUgYXJyYXkgaXMgYWxsb2NhdGVkIGJ5IHRoaXMgZnVuY3Rpb24uIAogKiB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgd2lsbCBiZSBzdG9yZWQgaW4gJ3dwYycKICogRnJlZSB0aGUgYXJyYXkgdXNpbmcgRlJFRV9LRVlfUEFUSAogKi8Kc3RhdGljIHZvaWQKc3BsaXRfa2V5cGF0aChMUENXU1RSIHdwLExQV1NUUiAqKndwdixpbnQgKndwYykgewoJaW50CWksaixsZW47CglMUFdTVFIJd3M7CgoJd3MJPSBIRUFQX3N0cmR1cFcoIFN5c3RlbUhlYXAsIDAsIHdwICk7Cgkqd3BjCT0gMTsKCWZvciAoaT0wO3dzW2ldO2krKykgewoJCWlmICh3c1tpXT09J1xcJykgewoJCQl3c1tpXT0wOwoJCQkoKndwYykrKzsKCQl9Cgl9CglsZW4JPSBpOwoJKndwdgk9IChMUFdTVFIqKUhlYXBBbGxvYyggU3lzdGVtSGVhcCwgMCwgc2l6ZW9mKExQV1NUUikqKCp3cGMrMikpOwoJKCp3cHYpWzBdPSB3czsKCWoJPSAxOwoJZm9yIChpPTE7aTxsZW47aSsrKQoJCWlmICh3c1tpLTFdPT0wKQoJCQkoKndwdilbaisrXT13cytpOwoJKCp3cHYpW2pdPU5VTEw7Cn0KI2RlZmluZSBGUkVFX0tFWV9QQVRIIEhlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHNbMF0pO0hlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHMpOwoKLyoKICogU2hlbGwgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBrZXlzLiAKICovCnZvaWQgU0hFTExfU3RhcnR1cFJlZ2lzdHJ5KCk7CnZvaWQKU0hFTExfSW5pdCgpIHsKCXN0cnVjdAlwYXNzd2QJKnB3ZDsKCglIS0VZCWNsX3JfaGtleSxjX3VfaGtleTsKI2RlZmluZSBBRERfUk9PVF9LRVkoeHgpIFwKCXh4ID0gKExQS0VZU1RSVUNUKXhtYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpO1wKCW1lbXNldCh4eCwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTtcCgl4eC0+a2V5bmFtZT0gc3RyZHVwQTJXKCI8c2hvdWxkX25vdF9hcHBlYXJfYW55d2hlcmU+Iik7CgoJQUREX1JPT1RfS0VZKGtleV9sb2NhbF9tYWNoaW5lKTsKCWlmIChSZWdDcmVhdGVLZXkxNihIS0VZX0xPQ0FMX01BQ0hJTkUsIlxcU09GVFdBUkVcXENsYXNzZXMiLCZjbF9yX2hrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJZnByaW50ZihzdGRlcnIsImNvdWxkbid0IGNyZWF0ZSBIS0VZX0xPQ0FMX01BQ0hJTkVcXFNPRlRXQVJFXFxDbGFzc2VzLiBUaGlzIGlzIGltcG9zc2libGUuXG4iKTsKCQlleGl0KDEpOwoJfQoJa2V5X2NsYXNzZXNfcm9vdCA9IGxvb2t1cF9oa2V5KGNsX3JfaGtleSk7CgoJQUREX1JPT1RfS0VZKGtleV91c2Vycyk7CgojaWYgMAoJLyogRklYTUU6IGxvYWQgYWxsIHVzZXJzIGFuZCB0aGVpciByZXNwLiBwd2QtPnB3X2Rpci8ud2luZS91c2VyLnJlZyAKCSAqCSAgKGxhdGVyLCB3aGVuIGEgd2luMzIgcmVnaXN0cnkgZWRpdGluZyB0b29sIGJlY29tZXMgYXZhaWwuKQoJICovCgl3aGlsZSAocHdkPWdldHB3ZW50KCkpIHsKCQlpZiAocHdkLT5wd19uYW1lID09IE5VTEwpCgkJCWNvbnRpbnVlOwoJCVJlZ0NyZWF0ZUtleTE2KEhLRVlfVVNFUlMscHdkLT5wd19uYW1lLCZjX3VfaGtleSk7CgkJUmVnQ2xvc2VLZXkoY191X2hrZXkpOwoJfQojZW5kaWYKCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CglpZiAocHdkICYmIHB3ZC0+cHdfbmFtZSkgewoJCVJlZ0NyZWF0ZUtleTE2KEhLRVlfVVNFUlMscHdkLT5wd19uYW1lLCZjX3VfaGtleSk7CgkJa2V5X2N1cnJlbnRfdXNlciA9IGxvb2t1cF9oa2V5KGNfdV9oa2V5KTsKCX0gZWxzZSB7CgkJQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X3VzZXIpOwoJfQoJQUREX1JPT1RfS0VZKGtleV9wZXJmb3JtYW5jZV9kYXRhKTsKCUFERF9ST09UX0tFWShrZXlfY3VycmVudF9jb25maWcpOwoJQUREX1JPT1RfS0VZKGtleV9keW5fZGF0YSk7CiN1bmRlZiBBRERfUk9PVF9LRVkKCVNIRUxMX1N0YXJ0dXBSZWdpc3RyeSgpOwp9CgoKdm9pZApTSEVMTF9TdGFydHVwUmVnaXN0cnkoKSB7CglIS0VZCWhrZXkseGhrZXk9MDsKCUZJTEUJKkY7CgljaGFyCWJ1ZlsyMDBdLGNwdWJ1ZlsyMDBdOwoKCVJlZ0NyZWF0ZUtleTE2KEhLRVlfRFlOX0RBVEEsIlxcUGVyZlN0YXRzXFxTdGF0RGF0YSIsJnhoa2V5KTsKCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCVJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiXFxIQVJEV0FSRVxcREVTQ1JJUFRJT05cXFN5c3RlbVxcQ2VudHJhbFByb2Nlc3NvciIsJmhrZXkpOwojaWZkZWYgbGludXgKCUY9Zm9wZW4oIi9wcm9jL2NwdWluZm8iLCJyIik7CglpZiAoRikgewoJCWludAlwcm9jbnI9LTEseDsKCQl3aGlsZSAoTlVMTCE9ZmdldHMoYnVmLDIwMCxGKSkgewoJCQlpZiAoc3NjYW5mKGJ1ZiwicHJvY2Vzc29yXHQ6ICVkIiwmeCkpIHsKCQkJCXNwcmludGYoYnVmLCIlZCIseCk7CgkJCQlpZiAoeGhrZXkpCgkJCQkJUmVnQ2xvc2VLZXkoeGhrZXkpOwoJCQkJcHJvY25yPXg7CgkJCQlSZWdDcmVhdGVLZXkxNihoa2V5LGJ1ZiwmeGhrZXkpOwoJCQl9CgkJCWlmIChzc2NhbmYoYnVmLCJjcHVcdFx0OiAlcyIsY3B1YnVmKSkgewoJCQkJc3ByaW50ZihidWYsIkNQVSAlcyIsY3B1YnVmKTsKCQkJCWlmICh4aGtleSkKCQkJCQlSZWdTZXRWYWx1ZUV4MzJBKHhoa2V5LCJJZGVudGlmaWVyIiwwLFJFR19TWixidWYsc3RybGVuKGJ1ZikpOwoJCQl9CgkJfQoJCWZjbG9zZShGKTsKCX0KCWlmICh4aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKI2Vsc2UKCS8qIEZJWE1FICovCglSZWdDcmVhdGVLZXkxNihoa2V5LCIwIiwmeGhrZXkpOwoJUmVnU2V0VmFsdWVFeDMyQSh4aGtleSwiSWRlbnRpZmllciIsMCxSRUdfU1osIkNQVSAzODYiLHN0cmxlbigiQ1BVIDM4NiIpKTsKI2VuZGlmCglSZWdPcGVuS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJcXEhBUkRXQVJFXFxERVNDUklQVElPTlxcU3lzdGVtIiwmaGtleSk7CglSZWdTZXRWYWx1ZUV4MzJBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgkvKiBcXFNPRlRXQVJFXFxNaWNyb3NvZnRcXFdpbmRvdyBOVFxcQ3VycmVudFZlcnNpb24KCSAqCQkJCQkJQ3VycmVudFZlcnNpb24KCSAqCQkJCQkJQ3VycmVudEJ1aWxkTnVtYmVyCgkgKgkJCQkJCUN1cnJlbnRUeXBlCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPd25lcgoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3JnYW5pemF0aW9uCgkgKgoJICovCgkvKiBTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxTZXJ2aWNlc1xcU05NUFxcUGFyYW1ldGVyc1xcUkZDMTE1NkFnZW50CgkgKiAJCQkJCXN0cmluZwlTeXNDb250YWN0CgkgKiAJCQkJCXN0cmluZwlTeXNMb2NhdGlvbgoJICogCQkJCQkJU3lzU2VydmljZXMKCSAqLwkJCQkJCQoJaWYgKC0xIT1nZXRob3N0bmFtZShidWYsMjAwKSkgewoJCVJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcQ29tcHV0ZXJOYW1lXFxDb21wdXRlck5hbWUiLCZ4aGtleSk7CgkJUmVnU2V0VmFsdWVFeDE2KHhoa2V5LCJDb21wdXRlck5hbWUiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSsxKTsKCQlSZWdDbG9zZUtleSh4aGtleSk7Cgl9Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKiBTQVZFIFJlZ2lzdHJ5IEZ1bmN0aW9uICoqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIFJFR0lTVFJZX1NBVkVfVkVSU0lPTgkweDAwMDAwMDAxCgovKiBSZWdpc3RyeSBzYXZlZm9ybWF0OgogKiBJZiB5b3UgY2hhbmdlIGl0LCBpbmNyZWFzZSBhYm92ZSBudW1iZXIgYnkgMSwgd2hpY2ggd2lsbCBmbHVzaAogKiBvbGQgcmVnaXN0cnkgZGF0YWJhc2UgZmlsZXMuCiAqIAogKiBHbG9iYWw6CiAqIAkiV0lORSBSRUdJU1RSWSBWZXJzaW9uICVkIgogKiAJc3Via2V5cy4uLi4KICogU3Via2V5czoKICogCWtleW5hbWUKICoJCXZhbHVlbmFtZT1sYXN0bW9kaWZpZWQsdHlwZSxkYXRhCiAqCQkuLi4KICoJCXN1YmtleXMKICoJLi4uCiAqIGtleW5hbWUsdmFsdWVuYW1lLHN0cmluZ2RhdGE6CiAqCXRoZSB1c3VhbCBhc2NpaSBjaGFyYWN0ZXJzIGZyb20gMHgwMC0weGZmICh3ZWxsLCBub3QgMHgwMCkKICoJYW5kIFx1WFhYWCBhcyBVTklDT0RFIHZhbHVlIFhYWFggd2l0aCBYWFhYPjB4ZmYKICoJKCAiPVxcXHQiIGVzY2FwZWQgaW4gXHVYWFhYIGZvcm0uKQogKiB0eXBlLGxhc3Rtb2RpZmllZDogCiAqCWludAogKiAKICogRklYTUU6IGRvZXNuJ3Qgc2F2ZSAnY2xhc3MnICh3aGF0IGRvZXMgaXQgbWVhbiBhbnl3YXk/KSwgbm9yIGZsYWdzLgogKgogKiBbSEtFWV9DVVJSRU5UX1VTRVJcXFNvZnR3YXJlXFxUaGUgV0lORSB0ZWFtXFxXSU5FXFxSZWdpc3RyeV0KICogU2F2ZU9ubHlVcGRhdGVkS2V5cz15ZXMKICovCnN0YXRpYyBpbnQKX3NhdmVfY2hlY2tfdGFpbnRlZChMUEtFWVNUUlVDVCBscGtleSkgewoJaW50CQl0YWludGVkOwoKCWlmICghbHBrZXkpCgkJcmV0dXJuIDA7CglpZiAobHBrZXktPmZsYWdzICYgUkVHX09QVElPTl9UQUlOVEVEKQoJCXRhaW50ZWQgPSAxOwoJZWxzZQoJCXRhaW50ZWQgPSAwOwoJd2hpbGUgKGxwa2V5KSB7CgkJaWYgKF9zYXZlX2NoZWNrX3RhaW50ZWQobHBrZXktPm5leHRzdWIpKSB7CgkJCWxwa2V5LT5mbGFncyB8PSBSRUdfT1BUSU9OX1RBSU5URUQ7CgkJCXRhaW50ZWQgPSAxOwoJCX0KCQlscGtleQk9IGxwa2V5LT5uZXh0OwoJfQoJcmV0dXJuIHRhaW50ZWQ7Cn0KCnN0YXRpYyB2b2lkCl9zYXZlX1VTVFJJTkcoRklMRSAqRixMUFdTVFIgd3N0cixpbnQgZXNjYXBlZXEpIHsKCUxQV1NUUglzOwoJaW50CWRvZXNjYXBlOwoKCWlmICh3c3RyPT1OVUxMKQoJCXJldHVybjsKCXM9d3N0cjsKCXdoaWxlICgqcykgewoJCWRvZXNjYXBlPTA7CgkJaWYgKCpzPjB4ZmYpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoKnM9PSdcbicpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoZXNjYXBlZXEgJiYgKnM9PSc9JykKCQkJZG9lc2NhcGUgPSAxOwoJCWlmICgqcz09J1xcJykKCQkJZnB1dGMoKnMsRik7IC8qIGlmIFxcIHRoYW4gcHV0IGl0IHR3aWNlLiAqLwoJCWlmIChkb2VzY2FwZSkKCQkJZnByaW50ZihGLCJcXHUlMDR4IiwqKCh1bnNpZ25lZCBzaG9ydCopcykpOwoJCWVsc2UKCQkJZnB1dGMoKnMsRik7CgkJcysrOwoJfQp9CgpzdGF0aWMgaW50Cl9zYXZlc3Via2V5KEZJTEUgKkYsTFBLRVlTVFJVQ1QgbHBrZXksaW50IGxldmVsLGludCBhbGwpIHsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJaSx0YWJzLGo7CgoJbHB4a2V5CT0gbHBrZXk7Cgl3aGlsZSAobHB4a2V5KSB7CgkJaWYgKAkhKGxweGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1ZPTEFUSUxFKSAmJgoJCQkoYWxsIHx8IChscHhrZXktPmZsYWdzICYgUkVHX09QVElPTl9UQUlOVEVEKSkKCQkpIHsKCQkJZm9yICh0YWJzPWxldmVsO3RhYnMtLTspCgkJCQlmcHV0YygnXHQnLEYpOwoJCQlfc2F2ZV9VU1RSSU5HKEYsbHB4a2V5LT5rZXluYW1lLDEpOwoJCQlmcHV0cygiXG4iLEYpOwoJCQlmb3IgKGk9MDtpPGxweGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQkJCUxQS0VZVkFMVUUJdmFsPWxweGtleS0+dmFsdWVzK2k7CgoJCQkJZm9yICh0YWJzPWxldmVsKzE7dGFicy0tOykKCQkJCQlmcHV0YygnXHQnLEYpOwoJCQkJX3NhdmVfVVNUUklORyhGLHZhbC0+bmFtZSwwKTsKCQkJCWZwdXRjKCc9JyxGKTsKCQkJCWZwcmludGYoRiwiJWxkLCVsZCwiLHZhbC0+dHlwZSx2YWwtPmxhc3Rtb2RpZmllZCk7CgkJCQlpZiAoKDE8PHZhbC0+dHlwZSkgJiBVTklDT05WTUFTSykKCQkJCQlfc2F2ZV9VU1RSSU5HKEYsKExQV1NUUil2YWwtPmRhdGEsMCk7CgkJCQllbHNlCgkJCQkJZm9yIChqPTA7ajx2YWwtPmxlbjtqKyspCgkJCQkJCWZwcmludGYoRiwiJTAyeCIsKigodW5zaWduZWQgY2hhciopdmFsLT5kYXRhK2opKTsKCQkJCWZwdXRzKCJcbiIsRik7CgkJCX0KCQkJLyogZGVzY2VuZCByZWN1cnNpdmVseSAqLwoJCQlpZiAoIV9zYXZlc3Via2V5KEYsbHB4a2V5LT5uZXh0c3ViLGxldmVsKzEsYWxsKSkKCQkJCXJldHVybiAwOwoJCX0KCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQKX3NhdmVzdWJyZWcoRklMRSAqRixMUEtFWVNUUlVDVCBscGtleSxpbnQgYWxsKSB7CglmcHJpbnRmKEYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZFxuIixSRUdJU1RSWV9TQVZFX1ZFUlNJT04pOwoJX3NhdmVfY2hlY2tfdGFpbnRlZChscGtleS0+bmV4dHN1Yik7CglyZXR1cm4gX3NhdmVzdWJrZXkoRixscGtleS0+bmV4dHN1YiwwLGFsbCk7Cn0KCnN0YXRpYyBCT09MMzIKX3NhdmVyZWcoTFBLRVlTVFJVQ1QgbHBrZXksY2hhciAqZm4saW50IGFsbCkgewoJRklMRQkqRjsKCglGPWZvcGVuKGZuLCJ3Iik7CglpZiAoRj09TlVMTCkgewoJCWZwcmludGYoc3RkZGViLF9fRklMRV9fIjpfc2F2ZXJlZzpDb3VsZG4ndCBvcGVuICVzIGZvciB3cml0aW5nOiAlc1xuIiwKCQkJZm4sc3RyZXJyb3IoZXJybm8pCgkJKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglpZiAoIV9zYXZlc3VicmVnKEYsbHBrZXksYWxsKSkgewoJCWZjbG9zZShGKTsKCQl1bmxpbmsoZm4pOwoJCWZwcmludGYoc3RkZGViLF9fRklMRV9fIjpfc2F2ZXJlZzpGYWlsZWQgdG8gc2F2ZSBrZXlzLCBwZXJoYXBzIG5vIG1vcmUgZGlza3NwYWNlIGZvciAlcz9cbiIsZm4pOwoJCXJldHVybiBGQUxTRTsKCX0KCWZjbG9zZShGKTsKICAgICAgICByZXR1cm4gVFJVRTsKfQoKdm9pZApTSEVMTF9TYXZlUmVnaXN0cnkoKSB7CgljaGFyCSpmbjsKCXN0cnVjdAlwYXNzd2QJKnB3ZDsKCWNoYXIJYnVmWzRdOwoJSEtFWQloa2V5OwoJaW50CWFsbDsKCglhbGw9MDsKCWlmIChSZWdPcGVuS2V5MTYoSEtFWV9DVVJSRU5UX1VTRVIsS0VZX1JFR0lTVFJZLCZoa2V5KSE9RVJST1JfU1VDQ0VTUykgewoJCXN0cmNweShidWYsInllcyIpOwoJfSBlbHNlIHsKCQlEV09SRCBsZW4sanVuayx0eXBlOwoKCQlsZW49NDsKCQlpZiAoCShFUlJPUl9TVUNDRVNTIT1SZWdRdWVyeVZhbHVlRXgzMkEoCgkJCQloa2V5LAoJCQkJVkFMX1NBVkVVUERBVEVELAoJCQkJJmp1bmssCgkJCQkmdHlwZSwKCQkJCWJ1ZiwKCQkJCSZsZW4KCQkJKSl8fCAodHlwZSE9UkVHX1NaKQoJCSkKCQkJc3RyY3B5KGJ1ZiwieWVzIik7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9CglpZiAobHN0cmNtcGkzMkEoYnVmLCJ5ZXMiKSkKCQlhbGw9MTsKCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CglpZiAocHdkIT1OVUxMICYmIHB3ZC0+cHdfZGlyIT1OVUxMKQogICAgICAgIHsKICAgICAgICAgICAgICAgIGNoYXIgKnRtcDsKCgkJZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihwd2QtPnB3X2RpcikgKyBzdHJsZW4oV0lORV9QUkVGSVgpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJsZW4oU0FWRV9DVVJSRU5UX1VTRVIpICsgMiApOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYKTsKCQkvKiBjcmVhdGUgdGhlIGRpcmVjdG9yeS4gZG9uJ3QgY2FyZSBhYm91dCBlcnJvcmNvZGVzLiAqLwoJCW1rZGlyKGZuLDA3NTUpOyAvKiBkcnd4ci14ci14ICovCgkJc3RyY2F0KGZuLCIvIlNBVkVfQ1VSUkVOVF9VU0VSKTsKCQl0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwoJCXN0cmNweSh0bXAsZm4pO3N0cmNhdCh0bXAsIi50bXAiKTsKCQlpZiAoX3NhdmVyZWcoa2V5X2N1cnJlbnRfdXNlcix0bXAsYWxsKSkgewoJCQlpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CgkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKCQkJCXVubGluayh0bXApOwoJCQl9CgkJfQoJCWZyZWUodG1wKTsKCQlmcmVlKGZuKTsKCQlmbj0oY2hhciopeG1hbGxvYyhzdHJsZW4ocHdkLT5wd19kaXIpK3N0cmxlbihXSU5FX1BSRUZJWCkrc3RybGVuKFNBVkVfTE9DQUxfTUFDSElORSkrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwoJCXRtcCA9IChjaGFyKil4bWFsbG9jKHN0cmxlbihmbikrc3RybGVuKCIudG1wIikrMSk7CgkJc3RyY3B5KHRtcCxmbik7c3RyY2F0KHRtcCwiLnRtcCIpOwoJCWlmIChfc2F2ZXJlZyhrZXlfbG9jYWxfbWFjaGluZSx0bXAsYWxsKSkgewoJCQlpZiAoLTE9PXJlbmFtZSh0bXAsZm4pKSB7CgkJCQlwZXJyb3IoInJlbmFtZSB0bXAgcmVnaXN0cnkiKTsKCQkJCXVubGluayh0bXApOwoJCQl9CgkJfQoJCWZyZWUodG1wKTsKCQlmcmVlKGZuKTsKCX0gZWxzZQoJCWZwcmludGYoc3RkZXJyLCJTSEVMTF9TYXZlUmVnaXN0cnk6ZmFpbGVkIHRvIGdldCBob21lZGlyZWN0b3J5IG9mIFVJRCAlZC5cbiIsZ2V0dWlkKCkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqIExPQUQgUmVnaXN0cnkgRnVuY3Rpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBMUEtFWVNUUlVDVApfZmluZF9vcl9hZGRfa2V5KExQS0VZU1RSVUNUIGxwa2V5LExQV1NUUiBrZXluYW1lKSB7CglMUEtFWVNUUlVDVAlscHhrZXksKmxwbHBrZXk7CgoJbHBscGtleT0gJihscGtleS0+bmV4dHN1Yik7CglscHhrZXkJPSAqbHBscGtleTsKCXdoaWxlIChscHhrZXkpIHsKCQlpZiAoIWxzdHJjbXAzMlcobHB4a2V5LT5rZXluYW1lLGtleW5hbWUpKQoJCQlicmVhazsKCQlscGxwa2V5CT0gJihscHhrZXktPm5leHQpOwoJCWxweGtleQk9ICpscGxwa2V5OwoJfQoJaWYgKGxweGtleT09TlVMTCkgewoJCSpscGxwa2V5ID0gKExQS0VZU1RSVUNUKXhtYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpOwoJCWxweGtleQk9ICpscGxwa2V5OwoJCW1lbXNldChscHhrZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5LT5rZXluYW1lCT0ga2V5bmFtZTsKCX0gZWxzZQoJCWZyZWUoa2V5bmFtZSk7CglyZXR1cm4gbHB4a2V5Owp9CgpzdGF0aWMgdm9pZApfZmluZF9vcl9hZGRfdmFsdWUoCglMUEtFWVNUUlVDVCBscGtleSxMUFdTVFIgbmFtZSxEV09SRCB0eXBlLExQQllURSBkYXRhLERXT1JEIGxlbiwKCURXT1JEIGxhc3Rtb2RpZmllZAopIHsKCUxQS0VZVkFMVUUJdmFsPU5VTEw7CglpbnQJCWk7CgoJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCWlmIChuYW1lPT1OVUxMKSB7CgkJCWlmICh2YWwtPm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCQl9IGVsc2UgewoJCQlpZiAoCXZhbC0+bmFtZSE9TlVMTCAmJiAKCQkJCSFsc3RyY21wMzJXKHZhbC0+bmFtZSxuYW1lKQoJCQkpCgkJCQlicmVhazsKCQl9Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0geHJlYWxsb2MoCgkJCWxwa2V5LT52YWx1ZXMsCgkJCSgrK2xwa2V5LT5ucm9mdmFsdWVzKSpzaXplb2YoS0VZVkFMVUUpCgkJKTsKCQl2YWw9bHBrZXktPnZhbHVlcytpOwoJCW1lbXNldCh2YWwsJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCQl2YWwtPm5hbWUgPSBuYW1lOwoJfSBlbHNlIHsKCQlpZiAobmFtZSkKCQkJZnJlZShuYW1lKTsKCX0KCWlmICh2YWwtPmxhc3Rtb2RpZmllZDxsYXN0bW9kaWZpZWQpIHsKCQl2YWwtPmxhc3Rtb2RpZmllZD1sYXN0bW9kaWZpZWQ7CgkJdmFsLT50eXBlID0gdHlwZTsKCQl2YWwtPmxlbiAgPSBsZW47CgkJaWYgKHZhbC0+ZGF0YSkgCgkJCWZyZWUodmFsLT5kYXRhKTsKCQl2YWwtPmRhdGEgPSBkYXRhOwoJfSBlbHNlCgkJZnJlZShkYXRhKTsKfQoKCi8qIHJlYWRzIGEgbGluZSBpbmNsdWRpbmcgZHluYW1pY2FsbHkgZW5sYXJnaW5nIHRoZSByZWFkYnVmZmVyIGFuZCB0aHJvd2luZwogKiBhd2F5IGNvbW1lbnRzCiAqLwpzdGF0aWMgaW50IApfd2luZV9yZWFkX2xpbmUoRklMRSAqRixjaGFyICoqYnVmLGludCAqbGVuKSB7CgljaGFyCSpzLCpjdXJyZWFkOwoJaW50CW15bGVuLGN1cm9mZjsKCgljdXJyZWFkCT0gKmJ1ZjsKCW15bGVuCT0gKmxlbjsKCSoqYnVmCT0gJ1wwJzsKCXdoaWxlICgxKSB7CgkJd2hpbGUgKDEpIHsKCQkJcz1mZ2V0cyhjdXJyZWFkLG15bGVuLEYpOwoJCQlpZiAocz09TlVMTCkKCQkJCXJldHVybiAwOyAvKiBFT0YgKi8KCQkJaWYgKE5VTEw9PShzPXN0cmNocihjdXJyZWFkLCdcbicpKSkgewoJCQkJLyogYnVmZmVyIHdhc24ndCBsYXJnZSBlbm91Z2ggKi8KCQkJCWN1cm9mZgk9IHN0cmxlbigqYnVmKTsKCQkJCSpidWYJPSB4cmVhbGxvYygqYnVmLCpsZW4qMik7CgkJCQljdXJyZWFkCT0gKmJ1ZiArIGN1cm9mZjsKCQkJCW15bGVuCT0gKmxlbjsJLyogd2UgZmlsbGVkIHVwIHRoZSBidWZmZXIgYW5kIAoJCQkJCQkgKiBnb3QgbmV3ICcqbGVuJyBieXRlcyB0byBmaWxsCgkJCQkJCSAqLwoJCQkJKmxlbgk9ICpsZW4gKiAyOwoJCQl9IGVsc2UgewoJCQkJKnM9J1wwJzsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCS8qIHRocm93IGF3YXkgY29tbWVudHMgKi8KCQlpZiAoKipidWY9PScjJyB8fCAqKmJ1Zj09JzsnKSB7CgkJCWN1cnJlYWQJPSAqYnVmOwoJCQlteWxlbgk9ICpsZW47CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAocykgCS8qIGdvdCBlbmQgb2YgbGluZSAqLwoJCQlicmVhazsKCX0KCXJldHVybiAxOwp9CgovKiBjb252ZXJ0cyBhIGNoYXIqIGludG8gYSBVTklDT0RFIHN0cmluZyAodXAgdG8gYSBzcGVjaWFsIGNoYXIpCiAqIGFuZCByZXR1cm5zIHRoZSBwb3NpdGlvbiBleGFjdGx5IGFmdGVyIHRoYXQgc3RyaW5nCiAqLwpzdGF0aWMgY2hhcioKX3dpbmVfcmVhZF9VU1RSSU5HKGNoYXIgKmJ1ZixMUFdTVFIgKnN0cikgewoJY2hhcgkqczsKCUxQV1NUUgl3czsKCgkvKiByZWFkIHVwIHRvICI9IiBvciAiXDAiIG9yICJcbiIgKi8KCXMJPSBidWY7CglpZiAoKnMgPT0gJz0nKSB7CgkJLyogZW1wdHkgc3RyaW5nIGlzIHRoZSB3aW4zLjEgZGVmYXVsdCB2YWx1ZShOVUxMKSovCgkJKnN0cgk9IE5VTEw7CgkJcmV0dXJuIHM7Cgl9Cgkqc3RyCT0gKExQV1NUUil4bWFsbG9jKDIqc3RybGVuKGJ1ZikrMik7Cgl3cwk9ICpzdHI7Cgl3aGlsZSAoKnMgJiYgKCpzIT0nXG4nKSAmJiAoKnMhPSc9JykpIHsKCQlpZiAoKnMhPSdcXCcpCgkJCSp3cysrPSooKHVuc2lnbmVkIGNoYXIqKXMrKyk7CgkJZWxzZSB7CgkJCXMrKzsKCQkJaWYgKCpzPT0nXFwnKSB7CgkJCQkqd3MrKz0nXFwnOwoJCQkJcysrOwoJCQkJY29udGludWU7CgkJCX0KCQkJaWYgKCpzIT0ndScpIHsKCQkJCWZwcmludGYoc3RkZXJyLCJfd2luZV9yZWFkX1VTVFJJTkc6Tm9uIHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlIFxcJWMgZm91bmQgaW4gfCVzfFxuIiwqcyxidWYpOwoJCQkJKndzKys9J1xcJzsKCQkJCSp3cysrPSpzKys7CgkJCX0gZWxzZSB7CgkJCQljaGFyCXhidWZbNV07CgkJCQlpbnQJd2M7CgoJCQkJcysrOwoJCQkJbWVtY3B5KHhidWYscyw0KTt4YnVmWzRdPSdcMCc7CgkJCQlpZiAoIXNzY2FuZih4YnVmLCIleCIsJndjKSkKCQkJCQlmcHJpbnRmKHN0ZGVyciwiX3dpbmVfcmVhZF9VU1RSSU5HOnN0cmFuZ2UgZXNjYXBlIHNlcXVlbmNlICVzIGZvdW5kIGluIHwlc3xcbiIseGJ1ZixidWYpOwoJCQkJcys9NDsKCQkJCSp3cysrCT0odW5zaWduZWQgc2hvcnQpd2M7CgkJCX0KCQl9Cgl9Cgkqd3MJPSAwOwoJd3MJPSAqc3RyOwoJKnN0cgk9IHN0cmR1cFcoKnN0cik7CglmcmVlKHdzKTsKCXJldHVybiBzOwp9CgpzdGF0aWMgaW50Cl93aW5lX2xvYWRzdWJrZXkoCglGSUxFICpGLExQS0VZU1RSVUNUIGxwa2V5LGludCBsZXZlbCxjaGFyICoqYnVmLGludCAqYnVmbGVuLGludCBvcHRmbGFnCikgewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlpOwoJY2hhcgkJKnM7CglMUFdTVFIJCW5hbWU7CgoJbHBrZXktPmZsYWdzIHw9IG9wdGZsYWc7CgoJLyogZ29vZC4gd2UgYWxyZWFkeSBnb3QgYSBsaW5lIGhlcmUgLi4uIHNvIHBhcnNlIGl0ICovCglscHhrZXkJPSBOVUxMOwoJd2hpbGUgKDEpIHsKCQlpPTA7cz0qYnVmOwoJCXdoaWxlICgqcz09J1x0JykgewoJCQlzKys7CgkJCWkrKzsKCQl9CgkJaWYgKGk+bGV2ZWwpIHsKCQkJaWYgKGxweGtleT09TlVMTCkgewoJCQkJZnByaW50ZihzdGRlcnIsIl9sb2FkX3N1YmtleTpHb3QgYSBzdWJoaWVyYXJjaHkgd2l0aG91dCByZXNwLiBrZXk/XG4iKTsKCQkJCXJldHVybiAwOwoJCQl9CgkJCV93aW5lX2xvYWRzdWJrZXkoRixscHhrZXksbGV2ZWwrMSxidWYsYnVmbGVuLG9wdGZsYWcpOwoJCQljb250aW51ZTsKCQl9CgkJLyogbGV0IHRoZSBjYWxsZXIgaGFuZGxlIHRoaXMgbGluZSAqLwoJCWlmIChpPGxldmVsIHx8ICoqYnVmPT0nXDAnKQoJCQlyZXR1cm4gMTsKCgkJLyogaXQgY2FuIGJlOiBhIHZhbHVlIG9yIGEga2V5bmFtZS4gUGFyc2UgdGhlIG5hbWUgZmlyc3QgKi8KCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLCZuYW1lKTsKCgkJLyogc3dpdGNoKCkgZGVmYXVsdDogaGFjayB0byBhdm9pZCBnb3RvcyAqLwoJCXN3aXRjaCAoMCkgewoJCWRlZmF1bHQ6CgkJCWlmICgqcz09J1wwJykgewoJCQkJbHB4a2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksbmFtZSk7CgkJCX0gZWxzZSB7CgkJCQlMUEJZVEUJCWRhdGE7CgkJCQlpbnQJCWxlbixsYXN0bW9kaWZpZWQsdHlwZTsKCgkJCQlpZiAoKnMhPSc9JykgewoJCQkJCWZwcmludGYoc3RkZXJyLCJfd2luZV9sb2FkX3N1YmtleTp1bmV4cGVjdGVkIGNoYXJhY3RlcjogJWNcbiIsKnMpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJcysrOwoJCQkJaWYgKDIhPXNzY2FuZihzLCIlZCwlZCwiLCZ0eXBlLCZsYXN0bW9kaWZpZWQpKSB7CgkJCQkJZnByaW50ZihzdGRlcnIsIl93aW5lX2xvYWRfc3Via2V5OiBoYXZlbid0IHVuZGVyc3Rvb2QgcG9zc2libGUgdmFsdWUgaW4gfCVzfCwgc2tpcHBpbmcuXG4iLCpidWYpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJLyogc2tpcCB0aGUgMiAsICovCgkJCQlzPXN0cmNocihzLCcsJyk7cysrOwoJCQkJcz1zdHJjaHIocywnLCcpO3MrKzsKCQkJCWlmICgoMTw8dHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsKExQV1NUUiopJmRhdGEpOwoJCQkJCWlmIChkYXRhKQoJCQkJCQlsZW4gPSBsc3RybGVuMzJXKChMUFdTVFIpZGF0YSkqMisyOwoJCQkJCWVsc2UJCgkJCQkJCWxlbiA9IDA7CgkJCQl9IGVsc2UgewoJCQkJCWxlbj1zdHJsZW4ocykvMjsKCQkJCQlkYXRhID0gKExQQllURSl4bWFsbG9jKGxlbisxKTsKCQkJCQlmb3IgKGk9MDtpPGxlbjtpKyspIHsKCQkJCQkJZGF0YVtpXT0wOwoJCQkJCQlpZiAoKnM+PScwJyAmJiAqczw9JzknKQoJCQkJCQkJZGF0YVtpXT0oKnMtJzAnKTw8NDsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV09KCpzLSdhJyk8PDQ7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldPSgqcy0nQScpPDw0OwoJCQkJCQlzKys7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldfD0qcy0nMCc7CgkJCQkJCWlmICgqcz49J2EnICYmICpzPD0nZicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nYSc7CgkJCQkJCWlmICgqcz49J0EnICYmICpzPD0nRicpCgkJCQkJCQlkYXRhW2ldfD0qcy0nQSc7CgkJCQkJCXMrKzsKCQkJCQl9CgkJCQl9CgkJCQlfZmluZF9vcl9hZGRfdmFsdWUobHBrZXksbmFtZSx0eXBlLGRhdGEsbGVuLGxhc3Rtb2RpZmllZCk7CgkJCX0KCQl9CgkJLyogcmVhZCB0aGUgbmV4dCBsaW5lICovCgkJaWYgKCFfd2luZV9yZWFkX2xpbmUoRixidWYsYnVmbGVuKSkKCQkJcmV0dXJuIDE7Cgl9CglyZXR1cm4gMTsKfQoKc3RhdGljIGludApfd2luZV9sb2Fkc3VicmVnKEZJTEUgKkYsTFBLRVlTVFJVQ1QgbHBrZXksaW50IG9wdGZsYWcpIHsKCWludAl2ZXI7CgljaGFyCSpidWY7CglpbnQJYnVmbGVuOwoKCWJ1Zj14bWFsbG9jKDEwKTtidWZsZW49MTA7CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXNzY2FuZihidWYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAodmVyIT1SRUdJU1RSWV9TQVZFX1ZFUlNJT04pIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsX19GSUxFX18iOl93aW5lX2xvYWRzdWJyZWc6T2xkIGZvcm1hdCAoJWQpIHJlZ2lzdHJ5IGZvdW5kLCBpZ25vcmluZyBpdC4gKGJ1ZiB3YXMgJXMpLlxuIix2ZXIsYnVmKTsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIV93aW5lX2xvYWRzdWJrZXkoRixscGtleSwwLCZidWYsJmJ1ZmxlbixvcHRmbGFnKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWZyZWUoYnVmKTsKCXJldHVybiAxOwp9CgpzdGF0aWMgdm9pZApfd2luZV9sb2FkcmVnKExQS0VZU1RSVUNUIGxwa2V5LGNoYXIgKmZuLGludCBvcHRmbGFnKSB7CglGSUxFCSpGOwoKCUY9Zm9wZW4oZm4sInJiIik7CglpZiAoRj09TlVMTCkgewoJCWRwcmludGZfcmVnKHN0ZGRlYixfX0ZJTEVfXyI6Q291bGRuJ3Qgb3BlbiAlcyBmb3IgcmVhZGluZzogJXNcbiIsCgkJCWZuLHN0cmVycm9yKGVycm5vKQoJCSk7CgkJcmV0dXJuOwoJfQoJaWYgKCFfd2luZV9sb2Fkc3VicmVnKEYsbHBrZXksb3B0ZmxhZykpIHsKCQlmY2xvc2UoRik7CgkJdW5saW5rKGZuKTsKCQlyZXR1cm47Cgl9CglmY2xvc2UoRik7Cn0KCnN0YXRpYyB2b2lkCl9jb3B5X3JlZ2lzdHJ5KExQS0VZU1RSVUNUIGZyb20sTFBLRVlTVFJVQ1QgdG8pIHsKCUxQS0VZU1RSVUNUCWxweGtleTsKCWludAkJajsKCUxQS0VZVkFMVUUJdmFsZnJvbTsKCglmcm9tPWZyb20tPm5leHRzdWI7Cgl3aGlsZSAoZnJvbSkgewoJCWxweGtleSA9IF9maW5kX29yX2FkZF9rZXkodG8sc3RyZHVwVyhmcm9tLT5rZXluYW1lKSk7CgoJCWZvciAoaj0wO2o8ZnJvbS0+bnJvZnZhbHVlcztqKyspIHsKCQkJTFBXU1RSCW5hbWU7CgkJCUxQQllURQlkYXRhOwoKCQkJdmFsZnJvbSA9IGZyb20tPnZhbHVlcytqOwoJCQluYW1lPXZhbGZyb20tPm5hbWU7CgkJCWlmIChuYW1lKSBuYW1lPXN0cmR1cFcobmFtZSk7CgkJCWRhdGE9KExQQllURSltYWxsb2ModmFsZnJvbS0+bGVuKTsKCQkJbWVtY3B5KGRhdGEsdmFsZnJvbS0+ZGF0YSx2YWxmcm9tLT5sZW4pOwoKCQkJX2ZpbmRfb3JfYWRkX3ZhbHVlKAoJCQkJbHB4a2V5LAoJCQkJbmFtZSwKCQkJCXZhbGZyb20tPnR5cGUsCgkJCQlkYXRhLAoJCQkJdmFsZnJvbS0+bGVuLAoJCQkJdmFsZnJvbS0+bGFzdG1vZGlmaWVkCgkJCSk7CgkJfQoJCV9jb3B5X3JlZ2lzdHJ5KGZyb20sbHB4a2V5KTsKCQlmcm9tID0gZnJvbS0+bmV4dDsKCX0KfQoKLyogV0lORE9XUyA5NSBSRUdJU1RSWSBMT0FERVIgKi8KLyogCiAqIFN0cnVjdHVyZSBvZiBhIHdpbjk1IHJlZ2lzdHJ5IGRhdGFiYXNlLgogKiBtYWluIGhlYWRlcjoKICogMCA6CSJDUkVHIgktIG1hZ2ljCiAqIDQgOglEV09SRCB2ZXJzaW9uCiAqIDggOglEV09SRCBvZmZzZXRfb2ZfUkdEQl9wYXJ0CiAqIDBDLi4xRjoJPyAoc29tZW9uZSBmaWxsIGluIHBsZWFzZSkKICoKICogMjA6IFJHS05fc2VjdGlvbjoKICogICBoZWFkZXI6CiAqIAkwIDoJCSJSR0tOIgktIG1hZ2ljCiAqIAk0Li4weDFCOiAJPyAoZmlsbCBpbikKICogICAgICAweDIwIC4uLiBvZmZzZXRfb2ZfUkdEQl9wYXJ0OiBEaXNrIEtleSBFbnRyeSBzdHJ1Y3R1cmVzCiAqCiAqICAgRGlzayBLZXkgRW50cnkgU3RydWN0dXJlOgogKgkwMDogRFdPUkQJLSB1bmtub3duCiAqCTA0OiBEV09SRAktIHVua25vd24KICoJMDg6IERXT1JECS0gdW5rbm93biwgYnV0IHVzdWFsbHkgMHhGRkZGRkZGRiBvbiB3aW45NSBzeXN0ZW1zCiAqCTBDOiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBQcmV2aW91c0xldmVsIEtleS4KICoJMTA6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIE5leHQgU3VibGV2ZWwgS2V5LgogKgkxNDogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgTmV4dCBLZXkgKG9uIHNhbWUgbGV2ZWwpLgogKiBES0VQPjE4OiBXT1JECS0gTnIsIExvdyBTaWduaWZpY2FudCBwYXJ0LgogKgkxQTogV09SRAktIE5yLCBIaWdoIFNpZ25pZmljYW50IHBhcnQuCiAqCiAqIFRoZSBkaXNrIGFkZHJlc3MgYWx3YXlzIHBvaW50cyB0byB0aGUgbnIgcGFydCBvZiB0aGUgcHJldmlvdXMga2V5IGVudHJ5IAogKiBvZiB0aGUgcmVmZXJlbmNlZCBrZXkuIERvbid0IGFzayBtZSB3aHksIG9yIGV2ZW4gaWYgSSBnb3QgdGhpcyBjb3JyZWN0CiAqIGZyb20gc3RhcmluZyBhdCAxa2cgb2YgaGV4ZHVtcHMuIChES0VQKQogKgogKiBUaGUgbnVtYmVyIG9mIHRoZSBlbnRyeSBpcyB0aGUgbG93IGJ5dGUgb2YgdGhlIExvdyBTaWduaWZpY2FudCBQYXJ0IG9yZWQKICogd2l0aCAweDEwMCAqIChsb3cgYnl0ZSBvZiB0aGUgSGlnaCBTaWduaWZpY2FudCBwYXJ0KQogKiAoQyBleHByZXNzaW9uIDogbnIgPSAobnJMUyAmIDB4RkYpIHwgKChuckhTICYweEZGKTw8OCkpCiAqCiAqIFRoZXJlIGFyZSB0d28gbWlub3IgY29ycmVjdGlvbnMgdG8gdGhlIHBvc2l0aW9uIG9mIHRoYXQgc3RydWN0dXJlLgogKiAxLiBJZiB0aGUgYWRkcmVzcyBpcyB4eHgwMTQgb3IgeHh4MDE4IGl0IHdpbGwgYmUgYWxpZ25lZCB0byB4eHgwMWMgQU5EIAogKiAgICB0aGUgREtFIHJlcmVhZCBmcm9tIHRoZXJlLgogKiAyLiBJZiB0aGUgYWRkcmVzcyBpcyB4eHhGRnggaXQgd2lsbCBiZSBhbGlnbmVkIHRvICh4eHgrMSkwMDAuCiAqIChGSVhNRTogc2xpZ2h0bHkgYmV0dGVyIGV4cGxhbmF0aW9uIG5lZWRlZCBoZXJlKQogKgogKiBSR0RCX3NlY3Rpb246CiAqIAkwMDoJCSJSR0RCIgktIG1hZ2ljCiAqCTA0OiBEV09SRAlvZmZzZXQgdG8gbmV4dCBSR0RCIHNlY3Rpb24gKHBlcmhhcHMgV09SRCkKICoJMDguLi4xRjoJPwogKgkyMC4uLi4uOglkaXNrIGtleXMKICoKICogZGlzayBrZXk6CiAqIAkwMDogCURXT1JECW5leHRrZXlvZmZzZXQJLSBvZmZzZXQgdG8gdGhlIG5leHQgZGlzayBrZXkgc3RydWN0dXJlCiAqCTA4OiAJV09SRAluckxTCQktIGxvdyBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBBOiAJV09SRAluckhTCQktIGhpZ2ggc2lnbmlmaWNhbnQgcGFydCBvZiBOUgogKgkwQzogCURXT1JECWJ5dGVzdXNlZAktIGJ5dGVzIHVzZWQgaW4gdGhpcyBzdHJ1Y3R1cmUuCiAqCTEwOiAJV09SRAluYW1lX2xlbgktIGxlbmd0aCBvZiBuYW1lIGluIGJ5dGVzLiB3aXRob3V0IFwwCiAqCTEyOiAJV09SRAlucl9vZl92YWx1ZXMJLSBudW1iZXIgb2YgdmFsdWVzLgogKgkxNDogCWNoYXIJbmFtZVtuYW1lX2xlbl0JLSBuYW1lIHN0cmluZy4gTm8gXDAuCiAqCTE0K25hbWVfbGVuOiBkaXNrIHZhbHVlcwogKgluZXh0a2V5b2Zmc2V0OiAuLi4gbmV4dCBkaXNrIGtleQogKgogKiBkaXNrIHZhbHVlOgogKgkwMDoJRFdPUkQJdHlwZQkJLSB2YWx1ZSB0eXBlIChobW0sIGNvdWxkIGJlIFdPUkQgdG9vKQogKgkwNDoJRFdPUkQJCQktIHVua25vd24sIHVzdWFsbHkgMAogKgkwODoJV09SRAluYW1lbGVuCQktIGxlbmd0aCBvZiBOYW1lLiAwIG1lYW5zIG5hbWU9TlVMTAogKgkwQzoJV09SRAlkYXRhbGVuCQktIGxlbmd0aCBvZiBEYXRhLgogKgkxMDoJY2hhcgluYW1lW25hbWVsZW5dCS0gbmFtZSwgbm8gXDAKICoJMTArbmFtZWxlbjogQllURQlkYXRhW2RhdGFsZW5dIC0gZGF0YSwgd2l0aG91dCBcMCBpZiBzdHJpbmcKICoJMTArbmFtZWxlbitkYXRhbGVuOiBuZXh0IHZhbHVlcyBvciBkaXNrIGtleQogKgogKiBEaXNrIGtleXMgYXJlIGxheWVkIG91dCBmbGF0IC4uLiBCdXQsIHNvbWV0aW1lcywgbnJMUyBhbmQgbnJIUyBhcmUgYm90aAogKiAweEZGRkYsIHdoaWNoIG1lYW5zIHNraXBwaW5nIG92ZXIgbmV4dGtleW9mZnNldCBieXRlcyAoaW5jbHVkaW5nIHRoaXMKICogc3RydWN0dXJlKSBhbmQgcmVhZGluZyBhbm90aGVyIFJHREJfc2VjdGlvbi4KICogcmVwZWF0IHVudGlsIGVuZCBvZiBmaWxlLgogKgogKiBGSVhNRTogdGhpcyBkZXNjcmlwdGlvbiBuZWVkcyBzb21lIHNlcmlvdXMgaGVscCwgeWVzLgogKi8KCnN0cnVjdAlfdzk1a2V5dmFsdWUgewoJdW5zaWduZWQgbG9uZwkJdHlwZTsKCXVuc2lnbmVkIHNob3J0CQlkYXRhbGVuOwoJY2hhcgkJCSpuYW1lOwoJdW5zaWduZWQgY2hhcgkJKmRhdGE7Cgl1bnNpZ25lZCBsb25nCQl4MTsKCWludAkJCWxhc3Rtb2RpZmllZDsKfTsKCnN0cnVjdCAJX3c5NWtleSB7CgljaGFyCQkJKm5hbWU7CglpbnQJCQlucm9mdmFsczsKCXN0cnVjdAlfdzk1a2V5dmFsdWUJKnZhbHVlczsKCXVuc2lnbmVkIGxvbmcJCWRrZWFkZHI7Cgl1bnNpZ25lZCBsb25nIAkJeDE7Cgl1bnNpZ25lZCBsb25nIAkJeDI7Cgl1bnNpZ25lZCBsb25nIAkJeDM7Cgl1bnNpZ25lZCBsb25nIAkJeHgxOwoJc3RydWN0IF93OTVrZXkJCSpwcmV2bHZsOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0c3ViOwoJc3RydWN0IF93OTVrZXkJCSpuZXh0Owp9OwoKLyogZmFzdCBsb29rdXAgdGFibGUgZGtlYWRkci0+bnIgKi8Kc3RydWN0CV93OTVucjJkYSB7Cgl1bnNpZ25lZCBsb25nCQlka2VhZGRyOwoJdW5zaWduZWQgbG9uZwkJbnI7Cn07CgoKc3RhdGljIHZvaWQKX3c5NV93YWxrX3RyZWUoTFBLRVlTVFJVQ1QgbHBrZXksc3RydWN0IF93OTVrZXkgKmtleSkgewoJaW50CQlpOwoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJTFBXU1RSCQluYW1lOwoKCXdoaWxlIChrZXkpIHsKCQlpZiAoa2V5LT5uYW1lID09IE5VTEwpIHsKCQkJZnByaW50ZihzdGRlcnIsIl93OTVfd2Fsa190cmVlOlBsZWFzZSByZXBvcnQ6IGtleSB3aXRoIGRrZWFkZHIgJWx4IG5vdCBsb2FkZWQsIHNraXBwaW5nIGhpZXJhcmNoeVxuIiwKCQkJCWtleS0+ZGtlYWRkcgoJCQkpOwoJCQlyZXR1cm47CgkJfQoJCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LHN0cmR1cEEyVyhrZXktPm5hbWUpKTsKCgkJaWYgKGtleS0+bnJvZnZhbHM8MCkgewoJCQkvKiBzaG91bGRuJ3QgaGFwcGVuICovCgkJCWZwcmludGYoc3RkZXJyLCJrZXkgJXMgYWxyZWFkeSBwcm9jZXNzZWQhXG4iLGtleS0+bmFtZSk7CgkJCWtleSA9IGtleS0+bmV4dDsKCQkJY29udGludWU7CgkJfQoJCWZvciAoaT0wO2k8a2V5LT5ucm9mdmFscztpKyspIHsKCQkJTFBCWVRFCWRhdGE7CgkJCWludAlsZW47CgoJCQluYW1lID0gc3RyZHVwQTJXKGtleS0+dmFsdWVzW2ldLm5hbWUpOwoJCQlpZiAoISpuYW1lKSBuYW1lID0gTlVMTDsKCQkJZnJlZShrZXktPnZhbHVlc1tpXS5uYW1lKTsKCgkJCWxlbgk9IGtleS0+dmFsdWVzW2ldLmRhdGFsZW47CgkJCWRhdGEJPSBrZXktPnZhbHVlc1tpXS5kYXRhOwoJCQlpZiAoKDE8PGtleS0+dmFsdWVzW2ldLnR5cGUpICYgVU5JQ09OVk1BU0spIHsKCQkJCWRhdGEgPSAoQllURSopc3RyZHVwQTJXKGRhdGEpOwoJCQkJbGVuICA9IGxzdHJsZW4zMlcoKExQV1NUUilkYXRhKSoyKzI7CgkJCQlmcmVlKGtleS0+dmFsdWVzW2ldLmRhdGEpOwoJCQl9CgkJCV9maW5kX29yX2FkZF92YWx1ZSgKCQkJCWxweGtleSwKCQkJCW5hbWUsCgkJCQlrZXktPnZhbHVlc1tpXS50eXBlLAoJCQkJZGF0YSwKCQkJCWxlbiwKCQkJCWtleS0+dmFsdWVzW2ldLmxhc3Rtb2RpZmllZAoJCQkpOwoJCX0KCQlpZiAoa2V5LT52YWx1ZXMpIHsKCQkJZnJlZShrZXktPnZhbHVlcyk7CgkJCWtleS0+dmFsdWVzID0gTlVMTDsKCQl9CgkJa2V5LT5ucm9mdmFscz0ta2V5LT5ucm9mdmFscy0xOwoJCV93OTVfd2Fsa190cmVlKGxweGtleSxrZXktPm5leHRzdWIpOwoJCWtleT1rZXktPm5leHQ7Cgl9Cn0KCi8qIHNtYWxsIGhlbHBlciBmdW5jdGlvbiB0byBhZGp1c3QgYWRkcmVzcyBvZmZzZXQgKGRrZWFkZHJzKSAqLwpzdGF0aWMgdW5zaWduZWQgbG9uZwpfdzk1X2Fkal9kYSh1bnNpZ25lZCBsb25nIGRrZWFkZHIpIHsKCWlmICgoZGtlYWRkciYweEZGRik8MHgwMTgpIHsKCQlpbnQJZGlmZjsKCgkJZGlmZj0weDFDLShka2VhZGRyJjB4RkZGKTsKCQlyZXR1cm4gZGtlYWRkcitkaWZmOwoJfQoJaWYgKCgoZGtlYWRkcisweDFDKSYweEZGRik8MHgxQykgewoJCS8qIHJlYWRqdXN0IHRvIDB4MDAwLAoJCSAqIGJ1dCBPTkxZIGlmIHdlIGFyZSA+MHgxMDAwIGFscmVhZHkKCQkgKi8KCQlpZiAoZGtlYWRkciAmIH4weEZGRikKCQkJcmV0dXJuIGRrZWFkZHIgJiB+MHhGRkY7Cgl9CglyZXR1cm4gZGtlYWRkcjsKfQoKc3RhdGljIGludApfdzk1ZGtlY29tcChzdHJ1Y3QgX3c5NW5yMmRhICphLHN0cnVjdCBfdzk1bnIyZGEgKmIpe3JldHVybiBhLT5ka2VhZGRyLWItPmRrZWFkZHI7fQoKc3RhdGljIHN0cnVjdCBfdzk1a2V5Kgpfdzk1ZGtlbG9va3VwKHVuc2lnbmVkIGxvbmcgZGtlYWRkcixpbnQgbixzdHJ1Y3QgX3c5NW5yMmRhICpucjJkYSxzdHJ1Y3QgX3c5NWtleSAqa2V5cykgewoJaW50CWksb2ZmOwoKCWlmIChka2VhZGRyID09IDB4RkZGRkZGRkYpCgkJcmV0dXJuIE5VTEw7CglpZiAoZGtlYWRkcjwweDIwKQoJCXJldHVybiBOVUxMOwoJZGtlYWRkcj1fdzk1X2Fkal9kYShka2VhZGRyKzB4MWMpOwoJb2ZmID0gKGRrZWFkZHItMHgzYykvMHgxYzsKCWZvciAoaT0wO2k8bjtpKyspCgkJaWYgKG5yMmRhWyhpK29mZiklbl0uZGtlYWRkciA9PSBka2VhZGRyKQoJCQlyZXR1cm4ga2V5cytucjJkYVsoaStvZmYpJW5dLm5yOwoJLyogMHgzQyBoYXBwZW5zIG9mdGVuLCBqdXN0IHJlcG9ydCB1bnVzdWFsIHZhbHVlcyAqLwoJaWYgKGRrZWFkZHIhPTB4M2MpCgkJZHByaW50Zl9yZWcoc3RkZGViLCJzZWFyY2ggaGFzbid0IGZvdW5kIGRrZWFkZHIgJWx4P1xuIixka2VhZGRyKTsKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgdm9pZApfdzk1X2xvYWRyZWcoY2hhciogZm4sTFBLRVlTVFJVQ1QgbHBrZXkpIHsKCS8qIERpc2sgS2V5IEVudHJ5IHN0cnVjdHVyZSAoUkdLTiBwYXJ0KSAqLwoJc3RydWN0CWRrZSB7CgkJdW5zaWduZWQgbG9uZwkJeDE7CgkJdW5zaWduZWQgbG9uZwkJeDI7CgkJdW5zaWduZWQgbG9uZwkJeDM7Lyp1c3VhbGx5IDB4RkZGRkZGRkYgKi8KCQl1bnNpZ25lZCBsb25nCQlwcmV2bHZsOwoJCXVuc2lnbmVkIGxvbmcJCW5leHRzdWI7CgkJdW5zaWduZWQgbG9uZwkJbmV4dDsKCQl1bnNpZ25lZCBzaG9ydAkJbnJMUzsKCQl1bnNpZ25lZCBzaG9ydAkJbnJNUzsKCX07CgkvKiBEaXNrIEtleSBIZWFkZXIgc3RydWN0dXJlIChSR0RCIHBhcnQpICovCglzdHJ1Y3QJZGtoIHsKCQl1bnNpZ25lZCBsb25nCQluZXh0a2V5b2ZmOyAKCQl1bnNpZ25lZCBzaG9ydAkJbnJMUzsKCQl1bnNpZ25lZCBzaG9ydAkJbnJNUzsKCQl1bnNpZ25lZCBsb25nCQlieXRlc3VzZWQ7CgkJdW5zaWduZWQgc2hvcnQJCWtleW5hbWVsZW47CgkJdW5zaWduZWQgc2hvcnQJCXZhbHVlczsKCQl1bnNpZ25lZCBsb25nCQl4eDE7CgkJLyoga2V5bmFtZSAqLwoJCS8qIGRpc2sga2V5IHZhbHVlcyBvciBub3RoaW5nICovCgl9OwoJLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlICovCglzdHJ1Y3QJZGt2IHsKCQl1bnNpZ25lZCBsb25nCQl0eXBlOwoJCXVuc2lnbmVkIGxvbmcJCXgxOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxuYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWxkYXRhbGVuOwoJCS8qIHZhbG5hbWUsIHZhbGRhdGEgKi8KCX07CglzdHJ1Y3QJX3c5NW5yMmRhIAkqbnIyZGE7CgoJSEZJTEUzMgkJaGZkOwoJaW50CQlsYXN0bW9kaWZpZWQ7CgljaGFyCQltYWdpY1s1XTsKCXVuc2lnbmVkIGxvbmcJbnIscG9zLGksd2hlcmUsdmVyc2lvbixyZ2Ric2VjdGlvbixlbmQsb2ZmX25leHRfcmdkYjsKCXN0cnVjdAlfdzk1a2V5CSprZXlzOwoJaW50CQlucm9mZGtlczsKCXVuc2lnbmVkIGNoYXIJKmRhdGEsKmN1cmRhdGEsKm5leHRyZ2RiOwoJT0ZTVFJVQ1QJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZkaW5mbzsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIkxvYWRpbmcgV2luOTUgcmVnaXN0cnkgZGF0YWJhc2UgJyVzJ1xuIixmbik7CgloZmQ9T3BlbkZpbGUzMihmbiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmZD09SEZJTEVfRVJST1IzMikKCQlyZXR1cm47CgltYWdpY1s0XT0wOwoJaWYgKDQhPV9scmVhZDMyKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJDUkVHIikpIHsKCQlmcHJpbnRmKHN0ZGRlYiwiJXMgaXMgbm90IGEgdzk1IHJlZ2lzdHJ5LlxuIixmbik7CgkJcmV0dXJuOwoJfQoJaWYgKDQhPV9scmVhZDMyKGhmZCwmdmVyc2lvbiw0KSkKCQlyZXR1cm47CglpZiAoNCE9X2xyZWFkMzIoaGZkLCZyZ2Ric2VjdGlvbiw0KSkKCQlyZXR1cm47CglpZiAoLTE9PV9sbHNlZWszMihoZmQsMHgyMCxTRUVLX1NFVCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZDMyKGhmZCxtYWdpYyw0KSkKCQlyZXR1cm47CglpZiAoc3RyY21wKG1hZ2ljLCJSR0tOIikpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJXNcbiIsbWFnaWMpOwoJCXJldHVybjsKCX0KCgkvKiBTVEVQIDE6IEtleWxpbmsgc3RydWN0dXJlcyAqLwoJaWYgKC0xPT1fbGxzZWVrMzIoaGZkLDB4NDAsU0VFS19TRVQpKQoJCXJldHVybjsKCXdoZXJlCT0gMHg0MDsKCWVuZAk9IHJnZGJzZWN0aW9uOwoKCW5yb2Zka2VzID0gKGVuZC13aGVyZSkvc2l6ZW9mKHN0cnVjdCBka2UpKzEwMDsKCWRhdGEgPSAoY2hhciopeG1hbGxvYyhlbmQtd2hlcmUpOwoJaWYgKChlbmQtd2hlcmUpIT1fbHJlYWQzMihoZmQsZGF0YSxlbmQtd2hlcmUpKQoJCXJldHVybjsKCWN1cmRhdGEgPSBkYXRhOwoKCWtleXMgPSAoc3RydWN0IF93OTVrZXkqKXhtYWxsb2MobnJvZmRrZXMgKiBzaXplb2Yoc3RydWN0IF93OTVrZXkpKTsKCW1lbXNldChrZXlzLCdcMCcsbnJvZmRrZXMqc2l6ZW9mKHN0cnVjdCBfdzk1a2V5KSk7CglucjJkYT0gKHN0cnVjdCBfdzk1bnIyZGEqKXhtYWxsb2MobnJvZmRrZXMgKiBzaXplb2Yoc3RydWN0IF93OTVucjJkYSkpOwoJbWVtc2V0KG5yMmRhLCdcMCcsbnJvZmRrZXMqc2l6ZW9mKHN0cnVjdCBfdzk1bnIyZGEpKTsKCglmb3IgKGk9MDtpPG5yb2Zka2VzO2krKykgewoJCXN0cnVjdAlka2UJZGtlOwoJCXVuc2lnbmVkIGxvbmcgCWRrZWFkZHI7CgoJCXBvcz1jdXJkYXRhLWRhdGErMHg0MDsKCQltZW1jcHkoJmRrZSxjdXJkYXRhLHNpemVvZihka2UpKTsKCQljdXJkYXRhKz1zaXplb2YoZGtlKTsKCQluciA9IGRrZS5uckxTICsgKGRrZS5uck1TPDw4KTsKCQlka2VhZGRyPXBvcy00OwoJCWlmICgoZGtlYWRkciYweEZGRik8MHgwMTgpIHsKCQkJaW50CWRpZmY7CgoJCQlkaWZmPTB4MUMtKGRrZWFkZHImMHhGRkYpOwoJCQlka2VhZGRyKz1kaWZmOwoJCQljdXJkYXRhKz1kaWZmLXNpemVvZihka2UpOwoJCQltZW1jcHkoJmRrZSxjdXJkYXRhLHNpemVvZihka2UpKTsKCQkJbnIgPSBka2UubnJMUyArIChka2UubnJNUzw8OCk7CgkJCWN1cmRhdGErPXNpemVvZihka2UpOwoJCX0KCQlpZiAoKChka2VhZGRyKzB4MUMpJjB4RkZGKTwweDFDKSB7CgkJCS8qIHJlYWRqdXN0IHRvIDB4MDAwLAoJCQkgKiBidXQgT05MWSBpZiB3ZSBhcmUgPjB4MTAwMCBhbHJlYWR5CgkJCSAqLwoJCQlpZiAoZGtlYWRkciAmIH4weEZGRikKCQkJCWRrZWFkZHIgPSBka2VhZGRyICYgfjB4RkZGOwoJCX0KCQlpZiAobnI+bnJvZmRrZXMpIHsKCQkJLyogMHhGRkZGRkZGRiBoYXBwZW5zIG9mdGVuLCBqdXN0IHJlcG9ydCB1bnVzdWFsIHZhbHVlcyAqLwoJCQlpZiAobnIhPTB4RkZGRkZGRkYpCgkJCQlkcHJpbnRmX3JlZyhzdGRkZWIsIm5yICVsZCBleGNlZWRzIG5yb2Zka2VzICVkLCBza2lwcGluZy5cbiIsbnIsbnJvZmRrZXMpOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKGtleXNbbnJdLmRrZWFkZHIpIHsKCQkJaW50CXg7CgoJCQlmb3IgKHg9c2l6ZW9mKGRrZSk7eC0tOykKCQkJCWlmICgoKGNoYXIqKSZka2UpW3hdKQoJCQkJCWJyZWFrOwoJCQlpZiAoeD09LTEpCgkJCQlicmVhazsgLyogZmluaXNoZWQgcmVhZGluZyBpZiB3ZSBnb3Qgb25seSAwICovCgkJCWlmIChucikgewoJCQkJaWYgKAkoZGtlLm5leHQhPShsb25nKWtleXNbbnJdLm5leHQpCXx8CgkJCQkJKGRrZS5uZXh0c3ViIT0obG9uZylrZXlzW25yXS5uZXh0c3ViKQl8fAoJCQkJCShka2UucHJldmx2bCE9KGxvbmcpa2V5c1tucl0ucHJldmx2bCkgCgkJCQkpCgkJCQkJZHByaW50Zl9yZWcoc3RkZGViLCJrZXkgZG91YmxlZD8gbnI9JWxkLGtleS0+ZGtlYWRkcj0lbHgsZGtlYWRkcj0lbHhcbiIsbnIsa2V5c1tucl0uZGtlYWRkcixka2VhZGRyKTsKCQkJfQoJCQljb250aW51ZTsKCQl9CgkJbnIyZGFbaV0ubnIJID0gbnI7CgkJbnIyZGFbaV0uZGtlYWRkciA9IGRrZWFkZHI7CgoJCWtleXNbbnJdLmRrZWFkZHIgPSBka2VhZGRyOwoJCWtleXNbbnJdLngxID0gZGtlLngxOwoJCWtleXNbbnJdLngyID0gZGtlLngyOwoJCWtleXNbbnJdLngzID0gZGtlLngzOwoJCWtleXNbbnJdLnByZXZsdmw9IChzdHJ1Y3QgX3c5NWtleSopZGtlLnByZXZsdmw7CgkJa2V5c1tucl0ubmV4dHN1Yj0gKHN0cnVjdCBfdzk1a2V5Kilka2UubmV4dHN1YjsKCQlrZXlzW25yXS5uZXh0IAk9IChzdHJ1Y3QgX3c5NWtleSopZGtlLm5leHQ7Cgl9CglmcmVlKGRhdGEpOwoKCXFzb3J0KG5yMmRhLG5yb2Zka2VzLHNpemVvZihucjJkYVswXSksCiAgICAgICAgICAgICAgKGludCgqKShjb25zdCB2b2lkICosY29uc3Qgdm9pZCopKV93OTVka2Vjb21wKTsKCgkvKiBTVEVQIDI6IGtleWRhdGEgJiB2YWx1ZXMgKi8KCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGZkLCZoZmRpbmZvKSkKCQlyZXR1cm47CgllbmQgPSBoZmRpbmZvLm5GaWxlU2l6ZUxvdzsKCWxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZkaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CgoJaWYgKC0xPT1fbGxzZWVrMzIoaGZkLHJnZGJzZWN0aW9uLFNFRUtfU0VUKSkKCQlyZXR1cm47CglkYXRhID0gKGNoYXIqKXhtYWxsb2MoZW5kLXJnZGJzZWN0aW9uKTsKCWlmICgoZW5kLXJnZGJzZWN0aW9uKSE9X2xyZWFkMzIoaGZkLGRhdGEsZW5kLXJnZGJzZWN0aW9uKSkKCQlyZXR1cm47CglfbGNsb3NlMzIoaGZkKTsKCWN1cmRhdGEgPSBkYXRhOwoJbWVtY3B5KG1hZ2ljLGN1cmRhdGEsNCk7CgltZW1jcHkoJm9mZl9uZXh0X3JnZGIsY3VyZGF0YSs0LDQpOwoJbmV4dHJnZGIgPSBjdXJkYXRhK29mZl9uZXh0X3JnZGI7CglpZiAoc3RyY21wKG1hZ2ljLCJSR0RCIikpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsInRoaXJkIElGRiBoZWFkZXIgbm90IFJHREIsIGJ1dCAlc1xuIixtYWdpYyk7CgkJcmV0dXJuOwoJfQoJY3VyZGF0YT1kYXRhKzB4MjA7Cgl3aGlsZSAoMSkgewoJCXN0cnVjdAlka2ggZGtoOwoJCWludAlieXRlc3JlYWQ7CgkJc3RydWN0CV93OTVrZXkJKmtleSx4a2V5OwoKCQlieXRlc3JlYWQgPSAwOwoJCWlmIChjdXJkYXRhPj1uZXh0cmdkYikgewoJCQljdXJkYXRhID0gbmV4dHJnZGI7CgkJCWlmICghc3RybmNtcChjdXJkYXRhLCJSR0RCIiw0KSkgewoJCQkJbWVtY3B5KCZvZmZfbmV4dF9yZ2RiLGN1cmRhdGErNCw0KTsKCQkJCW5leHRyZ2RiID0gY3VyZGF0YStvZmZfbmV4dF9yZ2RiOwoJCQkJY3VyZGF0YSs9MHgyMDsKCQkJfSBlbHNlIHsKCQkJCWRwcmludGZfcmVnKHN0ZGRlYiwiYXQgZW5kIG9mIFJHREIgc2VjdGlvbiwgYnV0IG5vIG5leHQgaGVhZGVyICgleCBvZiAlbHgpLiBCcmVha2luZy5cbiIsY3VyZGF0YS1kYXRhLGVuZC1yZ2Ric2VjdGlvbik7CgkJCQlicmVhazsKCQkJfQoJCX0KI2RlZmluZSBYUkVBRCh3aGVyZXRvLGxlbikgXAoJaWYgKChjdXJkYXRhLWRhdGErbGVuKTxlbmQpIHtcCgkJbWVtY3B5KHdoZXJldG8sY3VyZGF0YSxsZW4pO1wKCQljdXJkYXRhKz1sZW47XAoJCWJ5dGVzcmVhZCs9bGVuO1wKCX0KCgkJWFJFQUQoJmRraCxzaXplb2YoZGtoKSk7CgkJbnIgPSBka2gubnJMUyArIChka2gubnJNUzw8OCk7CgkJaWYgKChucj5ucm9mZGtlcykgfHwgKGRraC5uckxTID09IDB4RkZGRikpIHsKCQkJaWYgKGRraC5uckxTID09IDB4RkZGRikgewoJCQkJLyogc2tpcCBvdmVyIGtleSB1c2luZyBuZXh0a2V5b2ZmICovCiAJCQkJY3VyZGF0YSs9ZGtoLm5leHRrZXlvZmYtc2l6ZW9mKHN0cnVjdCBka2gpOwoJCQkJY29udGludWU7CgkJCX0KCQkJZHByaW50Zl9yZWcoc3RkZGViLCJoYXZlbid0IGZvdW5kIG5yICVsZC5cbiIsbnIpOwoJCQlrZXkgPSAmeGtleTsKCQkJbWVtc2V0KGtleSwnXDAnLHNpemVvZih4a2V5KSk7CgkJfSBlbHNlIHsKCQkJa2V5ID0ga2V5cytucjsKCQkJaWYgKCFrZXktPmRrZWFkZHIpCgkJCQlkcHJpbnRmX3JlZyhzdGRkZWIsImtleSB3aXRoIG5yPSVsZCBoYXMgbm8gZGtlYWRkcj9cbiIsbnIpOwoJCX0KCQlrZXktPm5yb2Z2YWxzCT0gZGtoLnZhbHVlczsKCQlrZXktPm5hbWUJPSAoY2hhciopeG1hbGxvYyhka2gua2V5bmFtZWxlbisxKTsKCQlrZXktPnh4MQk9IGRraC54eDE7CgkJWFJFQUQoa2V5LT5uYW1lLGRraC5rZXluYW1lbGVuKTsKCQlrZXktPm5hbWVbZGtoLmtleW5hbWVsZW5dPTA7CgkJaWYgKGtleS0+bnJvZnZhbHMpIHsKCQkJa2V5LT52YWx1ZXMgPSAoc3RydWN0IF93OTVrZXl2YWx1ZSopeG1hbGxvYygKCQkJCXNpemVvZihzdHJ1Y3QgX3c5NWtleXZhbHVlKSprZXktPm5yb2Z2YWxzCgkJCSk7CgkJCWZvciAoaT0wO2k8a2V5LT5ucm9mdmFscztpKyspIHsKCQkJCXN0cnVjdAlka3YJZGt2OwoKCQkJCVhSRUFEKCZka3Ysc2l6ZW9mKGRrdikpOwoJCQkJa2V5LT52YWx1ZXNbaV0udHlwZSA9IGRrdi50eXBlOwoJCQkJa2V5LT52YWx1ZXNbaV0ubmFtZSA9IChjaGFyKil4bWFsbG9jKAoJCQkJCWRrdi52YWxuYW1lbGVuKzEKCQkJCSk7CgkJCQlrZXktPnZhbHVlc1tpXS5kYXRhbGVuID0gZGt2LnZhbGRhdGFsZW47CgkJCQlrZXktPnZhbHVlc1tpXS5kYXRhID0gKHVuc2lnbmVkIGNoYXIqKXhtYWxsb2MoCgkJCQkJZGt2LnZhbGRhdGFsZW4rMQoJCQkJKTsKCQkJCWtleS0+dmFsdWVzW2ldLngxICAgPSBka3YueDE7CgkJCQlYUkVBRChrZXktPnZhbHVlc1tpXS5uYW1lLGRrdi52YWxuYW1lbGVuKTsKCQkJCVhSRUFEKGtleS0+dmFsdWVzW2ldLmRhdGEsZGt2LnZhbGRhdGFsZW4pOwoJCQkJa2V5LT52YWx1ZXNbaV0uZGF0YVtka3YudmFsZGF0YWxlbl09MDsKCQkJCWtleS0+dmFsdWVzW2ldLm5hbWVbZGt2LnZhbG5hbWVsZW5dPTA7CgkJCQlrZXktPnZhbHVlc1tpXS5sYXN0bW9kaWZpZWQ9bGFzdG1vZGlmaWVkOwoJCQl9CgkJfQoJCWlmIChieXRlc3JlYWQgIT0gZGtoLm5leHRrZXlvZmYpIHsKCQkJaWYgKGRraC5ieXRlc3VzZWQgIT0gYnl0ZXNyZWFkKQoJCQkJZHByaW50Zl9yZWcoc3RkZGViLAoJCQkJCSJyZWFkIGhhcyBkaWZmZXJlbmNlIGluIHJlYWQgYnl0ZXMgKCVkKSBhbmQgbmV4dG9mZnNldCAoJWxkKSAoYnl0ZXN1c2VkPSVsZClcbiIsYnl0ZXNyZWFkLGRraC5uZXh0a2V5b2ZmLAoJCQkJCWRraC5ieXRlc3VzZWQKCQkJCSk7CgkJCWN1cmRhdGEgKz0gZGtoLm5leHRrZXlvZmYtYnl0ZXNyZWFkOwoJCX0KCQlrZXktPnByZXZsdmwJPSBfdzk1ZGtlbG9va3VwKChsb25nKWtleS0+cHJldmx2bCxucm9mZGtlcyxucjJkYSxrZXlzKTsKCQlrZXktPm5leHRzdWIJPSBfdzk1ZGtlbG9va3VwKChsb25nKWtleS0+bmV4dHN1Yixucm9mZGtlcyxucjJkYSxrZXlzKTsKCQlrZXktPm5leHQJPSBfdzk1ZGtlbG9va3VwKChsb25nKWtleS0+bmV4dCxucm9mZGtlcyxucjJkYSxrZXlzKTsKCQlpZiAoIWJ5dGVzcmVhZCkKCQkJYnJlYWs7Cgl9CglmcmVlKGRhdGEpOwoJX3c5NV93YWxrX3RyZWUobHBrZXksa2V5cyk7CglmcmVlKGtleXMpOwp9CgovKiBXSU5ET1dTIDMxIFJFR0lTVFJZIExPQURFUiwgc3VwcGxpZWQgYnkgVG9yIFNq+HdhbGwsIHRvckBzbi5ubyAqLwoKLyoKICAgIHJlZ2hhY2sgLSB3aW5kb3dzIDMuMTEgcmVnaXN0cnkgZGF0YSBmb3JtYXQgZGVtbyBwcm9ncmFtLgoKICAgIFRoZSByZWcuZGF0IGZpbGUgaGFzIDMgcGFydHMsIGEgaGVhZGVyLCBhIHRhYmxlIG9mIDgtYnl0ZSBlbnRyaWVzIHRoYXQgaXMKICAgIGEgY29tYmluZWQgaGFzaCB0YWJsZSBhbmQgdHJlZSBkZXNjcmlwdGlvbiwgYW5kIGZpbmFsbHkgYSB0ZXh0IHRhYmxlLgoKICAgIFRoZSBoZWFkZXIgaXMgb2J2aW91cyBmcm9tIHRoZSBzdHJ1Y3QgaGVhZGVyLiBUaGUgdGFib2ZmMSBhbmQgdGFib2ZmMgogICAgZmllbGRzIGFyZSBhbHdheXMgMHgyMCwgYW5kIHRoZWlyIHVzYWdlIGlzIHVua25vd24uCgogICAgVGhlIDgtYnl0ZSBlbnRyeSB0YWJsZSBoYXMgdmFyaW91cyBlbnRyeSB0eXBlcy4KCiAgICB0YWJlbnRbMF0gaXMgYSByb290IGluZGV4LiBUaGUgc2Vjb25kIHdvcmQgaGFzIHRoZSBpbmRleCBvZiB0aGUgcm9vdCBvZgogICAgICAgICAgICB0aGUgZGlyZWN0b3J5LgogICAgdGFiZW50WzEuLmhhc2hzaXplXSBpcyBhIGhhc2ggdGFibGUuIFRoZSBmaXJzdCB3b3JkIGluIHRoZSBoYXNoIGVudHJ5IGlzCiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUga2V5L3ZhbHVlIHRoYXQgaGFzIHRoYXQgaGFzaC4gRGF0YSB3aXRoIHRoZSBzYW1lCiAgICAgICAgICAgIGhhc2ggdmFsdWUgYXJlIG9uIGEgY2lyY3VsYXIgbGlzdC4gVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZQogICAgICAgICAgICBoYXNoIGVudHJ5IGFyZSBhbHdheXMgemVyby4KICAgIHRhYmVudFtoYXNoc2l6ZS4udGFiY250XSBpcyB0aGUgdHJlZSBzdHJ1Y3R1cmUuIFRoZXJlIGFyZSB0d28ga2luZHMgb2YKICAgICAgICAgICAgZW50cnk6IGRpcmVudCBhbmQga2V5ZW50L3ZhbGVudC4gVGhleSBhcmUgaWRlbnRpZmllZCBieSBjb250ZXh0LgogICAgdGFiZW50W2ZyZWVpZHhdIGlzIHRoZSBmaXJzdCBmcmVlIGVudHJ5LiBUaGUgZmlyc3Qgd29yZCBpbiBhIGZyZWUgZW50cnkKICAgICAgICAgICAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGZyZWUgZW50cnkuIFRoZSBsYXN0IGhhcyAwIGFzIGEgbGluay4KICAgICAgICAgICAgVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZSBmcmVlIGxpc3QgYXJlIHByb2JhYmx5IGlycmVsZXZhbnQuCgogICAgRW50cmllcyBpbiB0ZXh0IHRhYmxlIGFyZSBwcmVjZWVkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewoJY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCgl1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7Cgl1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7Cgl1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCgl1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgKi8Kdm9pZApfX3czMV9kdW1wdHJlZSgJdW5zaWduZWQgc2hvcnQgaWR4LAoJCXVuc2lnbmVkIGNoYXIgKnR4dCwKCQlzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYiwKCQlzdHJ1Y3QgX3czMV9oZWFkZXIgKmhlYWQsCgkJTFBLRVlTVFJVQ1QJbHBrZXksCgkJdGltZV90CQlsYXN0bW9kaWZpZWQsCgkJaW50CQlsZXZlbAopIHsKCXN0cnVjdCBfdzMxX2RpcmVudAkqZGlyOwoJc3RydWN0IF93MzFfa2V5ZW50CSprZXk7CglzdHJ1Y3QgX3czMV92YWxlbnQJKnZhbDsKCUxQS0VZU1RSVUNUCQl4bHBrZXkgPSBOVUxMOwoJTFBXU1RSCQkJbmFtZSx2YWx1ZTsKCXN0YXRpYyBjaGFyCQl0YWlsWzQwMF07CgoJd2hpbGUgKGlkeCE9MCkgewoJCWRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgoJCWlmIChkaXItPmtleV9pZHgpIHsKCQkJa2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKCQkJbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKCQkJdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKCQkJLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZSAKCQkJICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwoJCQkgKi8KCQkJaWYgKCFsZXZlbCAmJiAhbHN0cmNtcDMyQSh0YWlsLCIuY2xhc3NlcyIpKSB7CgkJCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCQkJaWR4PWRpci0+c2libGluZ19pZHg7CgkJCQljb250aW51ZTsKCQkJfQoJCQluYW1lPVNUUklORzMyX0R1cEFuc2lUb1VuaSh0YWlsKTsKCgkJCXhscGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoKCQkJLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCgkJCWlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKCQkJCWlmIChkaXItPnZhbHVlX2lkeCkgewoJCQkJCXZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKCQkJCQltZW1jcHkodGFpbCwmdHh0W3ZhbC0+c3RyaW5nX29mZl0sdmFsLT5sZW5ndGgpOwoJCQkJCXRhaWxbdmFsLT5sZW5ndGhdPSdcMCc7CgkJCQkJdmFsdWU9U1RSSU5HMzJfRHVwQW5zaVRvVW5pKHRhaWwpOwoJCQkJCV9maW5kX29yX2FkZF92YWx1ZSh4bHBrZXksTlVMTCxSRUdfU1osKExQQllURSl2YWx1ZSxsc3RybGVuMzJXKHZhbHVlKSoyKzIsbGFzdG1vZGlmaWVkKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCWRwcmludGZfcmVnKHN0ZGRlYiwiX193MzFfZHVtcHRyZWU6c3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKCQl9CgkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHhscGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJaWR4PWRpci0+c2libGluZ19pZHg7Cgl9Cn0KCnZvaWQKX3czMV9sb2FkcmVnKCkgewoJSEZJTEUzMgkJCWhmOwoJc3RydWN0IF93MzFfaGVhZGVyCWhlYWQ7CglzdHJ1Y3QgX3czMV90YWJlbnQJKnRhYjsKCXVuc2lnbmVkIGNoYXIJCSp0eHQ7CglpbnQJCQlsZW47CglPRlNUUlVDVAkJb2ZzOwoJQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gaGZpbmZvOwoJdGltZV90CQkJbGFzdG1vZGlmaWVkOwoJSEtFWQkJCWhrZXk7CglMUEtFWVNUUlVDVAkJbHBrZXk7CgoJaGYgPSBPcGVuRmlsZTMyKCJyZWcuZGF0Iiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmPT1IRklMRV9FUlJPUjMyKQoJCXJldHVybjsKCgkvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KCWlmIChzaXplb2YoaGVhZCkhPV9scmVhZDMyKGhmLCZoZWFkLHNpemVvZihoZWFkKSkpIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsIl93MzFfbG9hZHJlZzpyZWcuZGF0IGlzIHRvbyBzaG9ydC5cbiIpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoJaWYgKG1lbWNtcChoZWFkLmNvb2tpZSwgIlNIQ0MzLjEwIiwgc2l6ZW9mKGhlYWQuY29va2llKSkhPTApIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsIl93MzFfbG9hZHJlZzpyZWcuZGF0IGhhcyBiYWQgc2lnbmF0dXJlLlxuIik7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CgoJbGVuID0gaGVhZC50YWJjbnQgKiBzaXplb2Yoc3RydWN0IF93MzFfdGFiZW50KTsKCS8qIHJlYWQgYW5kIGR1bXAgaW5kZXggdGFibGUgKi8KCXRhYiA9IHhtYWxsb2MobGVuKTsKCWlmIChsZW4hPV9scmVhZDMyKGhmLHRhYixsZW4pKSB7CgkJZHByaW50Zl9yZWcoc3RkZXJyLCJfdzMxX2xvYWRyZWc6Y291bGRuJ3QgcmVhZCAlZCBieXRlcy5cbiIsbGVuKTsgCgkJZnJlZSh0YWIpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoKCS8qIHJlYWQgdGV4dCAqLwoJdHh0ID0geG1hbGxvYyhoZWFkLnRleHRzaXplKTsKCWlmICgtMT09X2xsc2VlazMyKGhmLGhlYWQudGV4dG9mZixTRUVLX1NFVCkpIHsKCQlkcHJpbnRmX3JlZyhzdGRlcnIsIl93MzFfbG9hZHJlZzpjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoJaWYgKGhlYWQudGV4dHNpemUhPV9scmVhZDMyKGhmLHR4dCxoZWFkLnRleHRzaXplKSkgewoJCWRwcmludGZfcmVnKHN0ZGVyciwiX3czMV9sb2FkcmVnOnRleHRibG9jayB0b28gc2hvcnQgKCVkIGluc3RlYWQgb2YgJWxkKS5cbiIsbGVuLGhlYWQudGV4dHNpemUpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UzMihoZik7CgkJcmV0dXJuOwoJfQoKCWlmICghR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoaGYsJmhmaW5mbykpIHsKCQlkcHJpbnRmX3JlZyhzdGRlcnIsIl93MzFfbG9hZHJlZzpHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSBmYWlsZWQ/LlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CglsYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmaW5mby5mdExhc3RXcml0ZVRpbWUsTlVMTCk7CgoJaWYgKFJlZ0NyZWF0ZUtleTE2KEhLRVlfTE9DQUxfTUFDSElORSwiXFxTT0ZUV0FSRVxcQ2xhc3NlcyIsJmhrZXkpIT1FUlJPUl9TVUNDRVNTKQoJCXJldHVybjsKCWxwa2V5ID0gbG9va3VwX2hrZXkoaGtleSk7CglfX3czMV9kdW1wdHJlZSh0YWJbMF0udzEsdHh0LHRhYiwmaGVhZCxscGtleSxsYXN0bW9kaWZpZWQsMCk7CglmcmVlKHRhYik7CglmcmVlKHR4dCk7CglfbGNsb3NlMzIoaGYpOwoJcmV0dXJuOwp9Cgp2b2lkClNIRUxMX0xvYWRSZWdpc3RyeSgpIHsKCWNoYXIJKmZuOwoJc3RydWN0CXBhc3N3ZAkqcHdkOwoJTFBLRVlTVFJVQ1QJbHBrZXk7CglIS0VZCQloa2V5OwoKCglpZiAoa2V5X2NsYXNzZXNfcm9vdD09TlVMTCkKCQlTSEVMTF9Jbml0KCk7CgoJLyogTG9hZCB3aW5kb3dzIDMuMSBlbnRyaWVzICovCglfdzMxX2xvYWRyZWcoKTsKCS8qIExvYWQgd2luZG93cyA5NSBlbnRyaWVzICovCglfdzk1X2xvYWRyZWcoIkM6XFxzeXN0ZW0uMXN0IiwJa2V5X2xvY2FsX21hY2hpbmUpOwoJX3c5NV9sb2FkcmVnKCJzeXN0ZW0uZGF0IiwJa2V5X2xvY2FsX21hY2hpbmUpOwoJX3c5NV9sb2FkcmVnKCJ1c2VyLmRhdCIsCWtleV91c2Vycyk7CgoJLyogdGhlIGdsb2JhbCB1c2VyIGRlZmF1bHQgaXMgbG9hZGVkIHVuZGVyIEhLRVlfVVNFUlNcXC5EZWZhdWx0ICovCglSZWdDcmVhdGVLZXkxNihIS0VZX1VTRVJTLCIuRGVmYXVsdCIsJmhrZXkpOwoJbHBrZXkgPSBsb29rdXBfaGtleShoa2V5KTsKCV93aW5lX2xvYWRyZWcobHBrZXksU0FWRV9VU0VSU19ERUZBVUxULDApOwoKCS8qIEhLRVlfVVNFUlNcXC5EZWZhdWx0IGlzIGNvcGllZCB0byBIS0VZX0NVUlJFTlRfVVNFUiAqLwoJX2NvcHlfcmVnaXN0cnkobHBrZXksa2V5X2N1cnJlbnRfdXNlcik7CglSZWdDbG9zZUtleShoa2V5KTsKCgkvKiB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgKi8KCV93aW5lX2xvYWRyZWcoa2V5X2xvY2FsX21hY2hpbmUsU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQsMCk7CgoJLyogbG9hZCB0aGUgdXNlciBzYXZlZCByZWdpc3RyaWVzICovCgoJLyogRklYTUU6IHVzZSBnZXRlbnYoIkhPTUUiKSBvciBnZXRwd3VpZChnZXR1aWQoKSktPnB3X2RpciA/PyAqLwoKCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CglpZiAocHdkIT1OVUxMICYmIHB3ZC0+cHdfZGlyIT1OVUxMKSB7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0NVUlJFTlRfVVNFUik7CgkJX3dpbmVfbG9hZHJlZyhrZXlfY3VycmVudF91c2VyLGZuLFJFR19PUFRJT05fVEFJTlRFRCk7CgkJZnJlZShmbik7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9NQUNISU5FKTsKCQlfd2luZV9sb2FkcmVnKGtleV9sb2NhbF9tYWNoaW5lLGZuLFJFR19PUFRJT05fVEFJTlRFRCk7CgkJZnJlZShmbik7Cgl9IGVsc2UKCQlmcHJpbnRmKHN0ZGVyciwiU0hFTExfTG9hZFJlZ2lzdHJ5OmZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWQuXG4iLGdldHVpZCgpKTsKCWlmIChFUlJPUl9TVUNDRVNTPT1SZWdDcmVhdGVLZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpKSB7CgkJRFdPUkQJanVuayx0eXBlLGxlbjsKCQljaGFyCWRhdGFbNV07CgoJCWxlbj00OwoJCWlmICgoCVJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQkJCWhrZXksCgkJCQlWQUxfU0FWRVVQREFURUQsCgkJCQkmanVuaywKCQkJCSZ0eXBlLAoJCQkJZGF0YSwKCQkJCSZsZW4KCQkJKSE9RVJST1JfU1VDQ0VTUykgfHwKCQkJdHlwZSAhPSBSRUdfU1oKCQkpCgkJCVJlZ1NldFZhbHVlRXgzMkEoaGtleSxWQUxfU0FWRVVQREFURUQsMCxSRUdfU1osInllcyIsNCk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIEFQSSBGVU5DVElPTlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKgogKiBPcGVuIEtleXMuCiAqCiAqIEFsbCBmdW5jdGlvbnMgYXJlIHN0dWJzIHRvIFJlZ09wZW5LZXlFeDMyVyB3aGVyZSBhbGwgdGhlCiAqIG1hZ2ljIGhhcHBlbnMuIAogKgogKiBGSVhNRTogc2VjdXJpdHksb3B0aW9ucyxkZXNpcmVkYWNjZXNzLC4uLgogKgogKiBDYWxscGF0aDoKICogUmVnT3BlbktleTE2IC0+IFJlZ09wZW5LZXkzMkEgLT4gUmVnT3BlbktleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnT3BlbktleTMyVyAgIC0+IFJlZ09wZW5LZXlFeDMyVyAKICovCgovKiBSZWdPcGVuS2V5RXhXCQlbQURWQVBJMzIuMTUwXSAqLwpEV09SRCBSZWdPcGVuS2V5RXgzMlcoCglIS0VZCWhrZXksCglMUENXU1RSCWxwc3pTdWJLZXksCglEV09SRAlkd1Jlc2VydmVkLAoJUkVHU0FNCXNhbURlc2lyZWQsCglMUEhLRVkJcmV0a2V5CikgewoJTFBLRVlTVFJVQ1QJbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ09wZW5LZXlFeDMyVyglbHgsJXMsJWxkLCVseCwlcClcbiIsCgkJKExPTkcpaGtleSxXMkMobHBzelN1YktleSwwKSxkd1Jlc2VydmVkLHNhbURlc2lyZWQscmV0a2V5CgkpOwoKCWxwTmV4dEtleQk9IGxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscE5leHRLZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCWlmICghbHBzelN1YktleSB8fCAhKmxwc3pTdWJLZXkpIHsKCQlhZGRfaGFuZGxlKCsrY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgkJKnJldGtleT1jdXJyZW50aGFuZGxlOwoJCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwoJfQoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7Cgl3aGlsZSAoKGk8d3BjKSAmJiAod3BzW2ldWzBdPT0nXDAnKSkgaSsrOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKHdwc1tpXSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlpZiAoIWxzdHJjbXAzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCQlicmVhazsKCQkJbHB4a2V5PWxweGtleS0+bmV4dDsKCQl9CgkJaWYgKCFscHhrZXkpIHsKCQkJRlJFRV9LRVlfUEFUSDsKCQkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCQl9CgkJaSsrOwoJCWxwTmV4dEtleQk9IGxweGtleTsKCX0KCWFkZF9oYW5kbGUoKytjdXJyZW50aGFuZGxlLGxweGtleSxzYW1EZXNpcmVkKTsKCSpyZXRrZXkJPSBjdXJyZW50aGFuZGxlOwoJRlJFRV9LRVlfUEFUSDsKCXJldHVybglTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdPcGVuS2V5VwkJCVtBRFZBUEkzMi4xNTFdICovCkRXT1JEIFJlZ09wZW5LZXkzMlcoCglIS0VZCWhrZXksCglMUENXU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdPcGVuS2V5MzJXKCVseCwlcywlcClcbiIsCgkJKExPTkcpaGtleSxXMkMobHBzelN1YktleSwwKSxyZXRrZXkKCSk7CglyZXR1cm4gUmVnT3BlbktleUV4MzJXKGhrZXksbHBzelN1YktleSwwLEtFWV9BTExfQUNDRVNTLHJldGtleSk7Cn0KCgovKiBSZWdPcGVuS2V5RXhBCQlbQURWQVBJMzIuMTQ5XSAqLwpEV09SRCBSZWdPcGVuS2V5RXgzMkEoCglIS0VZCWhrZXksCglMUENTVFIJbHBzelN1YktleSwKCURXT1JECWR3UmVzZXJ2ZWQsCglSRUdTQU0Jc2FtRGVzaXJlZCwKCUxQSEtFWQlyZXRrZXkKKSB7CglMUFdTVFIJbHBzelN1YktleVc7CglEV09SRAlyZXQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdPcGVuS2V5RXgzMkEoJWx4LCVzLCVsZCwlbHgsJXApXG4iLAoJCShMT05HKWhrZXksbHBzelN1YktleSxkd1Jlc2VydmVkLHNhbURlc2lyZWQscmV0a2V5CgkpOwoJaWYgKGxwc3pTdWJLZXkpCgkJbHBzelN1YktleVc9c3RyZHVwQTJXKGxwc3pTdWJLZXkpOwoJZWxzZQoJCWxwc3pTdWJLZXlXPU5VTEw7CglyZXQ9UmVnT3BlbktleUV4MzJXKGhrZXksbHBzelN1YktleVcsZHdSZXNlcnZlZCxzYW1EZXNpcmVkLHJldGtleSk7CglpZiAobHBzelN1YktleVcpCgkJZnJlZShscHN6U3ViS2V5Vyk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdPcGVuS2V5QQkJCVtBRFZBUEkzMi4xNDhdICovCkRXT1JEIFJlZ09wZW5LZXkzMkEoCglIS0VZCWhrZXksCglMUENTVFIJbHBzelN1YktleSwKCUxQSEtFWQlyZXRrZXkKKSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ09wZW5LZXkzMkEoJWx4LCVzLCVwKVxuIiwKCQkoTE9ORyloa2V5LGxwc3pTdWJLZXkscmV0a2V5CgkpOwoJcmV0dXJuCVJlZ09wZW5LZXlFeDMyQShoa2V5LGxwc3pTdWJLZXksMCxLRVlfQUxMX0FDQ0VTUyxyZXRrZXkpOwp9CgovKiBSZWdPcGVuS2V5CQkJW1NIRUxMLjFdIFtLRVJORUwuMjE3XSAqLwpEV09SRCBSZWdPcGVuS2V5MTYoCglIS0VZCWhrZXksCglMUENTVFIJbHBzelN1YktleSwKCUxQSEtFWQlyZXRrZXkKKSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ09wZW5LZXkxNiglbHgsJXMsJXApXG4iLAoJCShMT05HKWhrZXksbHBzelN1YktleSxyZXRrZXkKCSk7CglyZXR1cm4gUmVnT3BlbktleTMyQShoa2V5LGxwc3pTdWJLZXkscmV0a2V5KTsKfQoKLyogCiAqIENyZWF0ZSBrZXlzCiAqIAogKiBBbGwgdGhvc2UgZnVuY3Rpb25zIGNvbnZlcnQgdGhlaXIgcmVzcGVjdGl2ZSAKICogYXJndW1lbnRzIGFuZCBjYWxsIFJlZ0NyZWF0ZUtleUV4VyBhdCB0aGUgZW5kLgogKgogKiBGSVhNRTogbm8gc2VjdXJpdHksbm8gYWNjZXNzIGF0dHJpYixubyBvcHRpb25oYW5kbGluZyB5ZXQuCiAqCiAqIENhbGxwYXRoOgogKiBSZWdDcmVhdGVLZXkxNiAtPiBSZWdDcmVhdGVLZXkzMkEgLT4gUmVnQ3JlYXRlS2V5RXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnQ3JlYXRlS2V5MzJXICAgLT4gUmVnQ3JlYXRlS2V5RXgzMlcKICovCgovKiBSZWdDcmVhdGVLZXlFeFcJCVtBRFZBUEkzMi4xMzFdICovCkRXT1JEIFJlZ0NyZWF0ZUtleUV4MzJXKAoJSEtFWQloa2V5LAoJTFBDV1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdSZXNlcnZlZCwKCUxQV1NUUglscHN6Q2xhc3MsCglEV09SRAlmZHdPcHRpb25zLAoJUkVHU0FNCXNhbURlc2lyZWQsCglMUFNFQ1VSSVRZX0FUVFJJQlVURVMgbHBTZWNBdHRyaWJzLAoJTFBIS0VZCXJldGtleSwKCUxQRFdPUkQJbHBEaXNwb3MKKSB7CglMUEtFWVNUUlVDVAkqbHBscFByZXZLZXksbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgovKkZJWE1FOiBoYW5kbGUgc2VjdXJpdHkvYWNjZXNzL3doYXRldmVyICovCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0NyZWF0ZUtleUV4MzJXKCVseCwlcywlbGQsJXMsJWx4LCVseCwlcCwlcCwlcClcbiIsCgkJKExPTkcpaGtleSwKCQlXMkMobHBzelN1YktleSwwKSwKCQlkd1Jlc2VydmVkLAoJCVcyQyhscHN6Q2xhc3MsMSksCgkJZmR3T3B0aW9ucywKCQlzYW1EZXNpcmVkLAoJCWxwU2VjQXR0cmlicywKCQlyZXRrZXksCgkJbHBEaXNwb3MKCSk7CgoJbHBOZXh0S2V5CT0gbG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwTmV4dEtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkgewoJCWFkZF9oYW5kbGUoKytjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKCQkqcmV0a2V5PWN1cnJlbnRoYW5kbGU7CgkJbHBOZXh0S2V5LT5mbGFnc3w9UkVHX09QVElPTl9UQUlOVEVEOwoJCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwoJfQoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7Cgl3aGlsZSAoKGk8d3BjKSAmJiAod3BzW2ldWzBdPT0nXDAnKSkgaSsrOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKHdwc1tpXSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlpZiAoIWxzdHJjbXAzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCQlicmVhazsKCQkJbHB4a2V5PWxweGtleS0+bmV4dDsKCQl9CgkJaWYgKCFscHhrZXkpCgkJCWJyZWFrOwoJCWkrKzsKCQlscE5leHRLZXkJPSBscHhrZXk7Cgl9CglpZiAobHB4a2V5KSB7CgkJYWRkX2hhbmRsZSgrK2N1cnJlbnRoYW5kbGUsbHB4a2V5LHNhbURlc2lyZWQpOwoJCWxweGtleS0+ZmxhZ3MgIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCQkqcmV0a2V5CQk9IGN1cnJlbnRoYW5kbGU7CgkJaWYgKGxwRGlzcG9zKQoJCQkqbHBEaXNwb3MJPSBSRUdfT1BFTkVEX0VYSVNUSU5HX0tFWTsKCQlGUkVFX0tFWV9QQVRIOwoJCXJldHVybglTSEVMTF9FUlJPUl9TVUNDRVNTOwoJfQoJLyogZ29vZC4gbm93IHRoZSBoYXJkIHBhcnQgKi8KCXdoaWxlICh3cHNbaV0pIHsKCQlscGxwUHJldktleQk9ICYobHBOZXh0S2V5LT5uZXh0c3ViKTsKCQlscHhrZXkJCT0gKmxwbHBQcmV2S2V5OwoJCXdoaWxlIChscHhrZXkpIHsKCQkJbHBscFByZXZLZXkJPSAmKGxweGtleS0+bmV4dCk7CgkJCWxweGtleQkJPSAqbHBscFByZXZLZXk7CgkJfQoJCSpscGxwUHJldktleT1tYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpOwoJCWlmICghKmxwbHBQcmV2S2V5KSB7CgkJCUZSRUVfS0VZX1BBVEg7CgkJCXJldHVybiBTSEVMTF9FUlJPUl9PVVRPRk1FTU9SWTsKCQl9CgkJbWVtc2V0KCpscGxwUHJldktleSwnXDAnLHNpemVvZihLRVlTVFJVQ1QpKTsKCQkoKmxwbHBQcmV2S2V5KS0+a2V5bmFtZQk9IHN0cmR1cFcod3BzW2ldKTsKCQkoKmxwbHBQcmV2S2V5KS0+bmV4dAk9IE5VTEw7CgkJKCpscGxwUHJldktleSktPm5leHRzdWIJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT52YWx1ZXMJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5ucm9mdmFsdWVzID0gMDsKCQkoKmxwbHBQcmV2S2V5KS0+ZmxhZ3MgCT0gUkVHX09QVElPTl9UQUlOVEVEOwoJCWlmIChscHN6Q2xhc3MpCgkJCSgqbHBscFByZXZLZXkpLT5jbGFzcyA9IHN0cmR1cFcobHBzekNsYXNzKTsKCQllbHNlCgkJCSgqbHBscFByZXZLZXkpLT5jbGFzcyA9IE5VTEw7CgkJbHBOZXh0S2V5CT0gKmxwbHBQcmV2S2V5OwoJCWkrKzsKCX0KCWFkZF9oYW5kbGUoKytjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKCgkvKkZJWE1FOiBmbGFnIGhhbmRsaW5nIGNvcnJlY3Q/ICovCglscE5leHRLZXktPmZsYWdzPSBmZHdPcHRpb25zIHxSRUdfT1BUSU9OX1RBSU5URUQ7CglpZiAobHBzekNsYXNzKQoJCWxwTmV4dEtleS0+Y2xhc3MgPSBzdHJkdXBXKGxwc3pDbGFzcyk7CgllbHNlCgkJbHBOZXh0S2V5LT5jbGFzcyA9IE5VTEw7CgkqcmV0a2V5CQk9IGN1cnJlbnRoYW5kbGU7CglpZiAobHBEaXNwb3MpCgkJKmxwRGlzcG9zCT0gUkVHX0NSRUFURURfTkVXX0tFWTsKCUZSRUVfS0VZX1BBVEg7CglyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKfQoKLyogUmVnQ3JlYXRlS2V5VwkJW0FEVkFQSTMyLjEzMl0gKi8KRFdPUkQgUmVnQ3JlYXRlS2V5MzJXKAoJSEtFWQloa2V5LAoJTFBDV1NUUglscHN6U3ViS2V5LAoJTFBIS0VZCXJldGtleQopIHsKCURXT1JECWp1bmsscmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnQ3JlYXRlS2V5MzJXKCVseCwlcywlcClcbiIsCgkJKExPTkcpaGtleSxXMkMobHBzelN1YktleSwwKSxyZXRrZXkKCSk7CglyZXQ9UmVnQ3JlYXRlS2V5RXgzMlcoCgkJaGtleSwJCS8qIGtleSBoYW5kbGUgKi8KCQlscHN6U3ViS2V5LAkvKiBzdWJrZXkgbmFtZSAqLwoJCTAsCQkvKiByZXNlcnZlZCA9IDAgKi8KCQlOVUxMLAkJLyogbHBzekNsYXNzPyBGSVhNRTogPyAqLwoJCVJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLAkvKiBvcHRpb25zICovCgkJS0VZX0FMTF9BQ0NFU1MsCS8qIGRlc2lyZWQgYWNjZXNzIGF0dHJpYnMgKi8KCQlOVUxMLAkJLyogbHBzZWN1cml0eSBhdHRyaWJ1dGVzICovCgkJcmV0a2V5LAkJLyogbHByZXRrZXkgKi8KCQkmanVuawkJLyogZGlzcG9zaXRpb24gdmFsdWUgKi8KCSk7CglyZXR1cm4JcmV0Owp9CgovKiBSZWdDcmVhdGVLZXlFeEEJCVtBRFZBUEkzMi4xMzBdICovCkRXT1JEIFJlZ0NyZWF0ZUtleUV4MzJBKAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglEV09SRAlkd1Jlc2VydmVkLAoJTFBTVFIJbHBzekNsYXNzLAoJRFdPUkQJZmR3T3B0aW9ucywKCVJFR1NBTQlzYW1EZXNpcmVkLAoJTFBTRUNVUklUWV9BVFRSSUJVVEVTIGxwU2VjQXR0cmlicywKCUxQSEtFWQlyZXRrZXksCglMUERXT1JECWxwRGlzcG9zCikgewoJTFBXU1RSCWxwc3pTdWJLZXlXLGxwc3pDbGFzc1c7CglEV09SRAlyZXQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdDcmVhdGVLZXlFeDMyQSglbHgsJXMsJWxkLCVzLCVseCwlbHgsJXAsJXAsJXApXG4iLAoJCShMT05HKWhrZXksCgkJbHBzelN1YktleSwKCQlkd1Jlc2VydmVkLAoJCWxwc3pDbGFzcywKCQlmZHdPcHRpb25zLAoJCXNhbURlc2lyZWQsCgkJbHBTZWNBdHRyaWJzLAoJCXJldGtleSwKCQlscERpc3BvcwoJKTsKCWlmIChscHN6U3ViS2V5KQoJCWxwc3pTdWJLZXlXPXN0cmR1cEEyVyhscHN6U3ViS2V5KTsKCWVsc2UKCQlscHN6U3ViS2V5Vz1OVUxMOwoJaWYgKGxwc3pDbGFzcykKCQlscHN6Q2xhc3NXPXN0cmR1cEEyVyhscHN6Q2xhc3MpOwoJZWxzZQoJCWxwc3pDbGFzc1c9TlVMTDsKCXJldD1SZWdDcmVhdGVLZXlFeDMyVygKCQloa2V5LAoJCWxwc3pTdWJLZXlXLAoJCWR3UmVzZXJ2ZWQsCgkJbHBzekNsYXNzVywKCQlmZHdPcHRpb25zLAoJCXNhbURlc2lyZWQsCgkJbHBTZWNBdHRyaWJzLAoJCXJldGtleSwKCQlscERpc3BvcwoJKTsKCWlmIChscHN6U3ViS2V5VykKCQlmcmVlKGxwc3pTdWJLZXlXKTsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdDcmVhdGVLZXlBCQlbQURWQVBJMzIuMTI5XSAqLwpEV09SRCBSZWdDcmVhdGVLZXkzMkEoCglIS0VZCWhrZXksCglMUENTVFIJbHBzelN1YktleSwKCUxQSEtFWQlyZXRrZXkKKSB7CglEV09SRAlqdW5rOwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnQ3JlYXRlS2V5MzJBKCVseCwlcywlcClcbiIsCgkJKExPTkcpaGtleSxscHN6U3ViS2V5LHJldGtleQoJKTsKCXJldHVybglSZWdDcmVhdGVLZXlFeDMyQSgKCQloa2V5LAkJLyoga2V5IGhhbmRsZSAqLwoJCWxwc3pTdWJLZXksCS8qIHN1YmtleSBuYW1lICovCgkJMCwJCS8qIHJlc2VydmVkID0gMCAqLwoJCU5VTEwsCQkvKiBscHN6Q2xhc3M/IEZJWE1FOiA/ICovCgkJUkVHX09QVElPTl9OT05fVk9MQVRJTEUsLyogb3B0aW9ucyAqLwoJCUtFWV9BTExfQUNDRVNTLAkvKiBkZXNpcmVkIGFjY2VzcyBhdHRyaWJzICovCgkJTlVMTCwJCS8qIGxwc2VjdXJpdHkgYXR0cmlidXRlcyAqLwoJCXJldGtleSwJCS8qIGxwcmV0a2V5ICovCgkJJmp1bmsJCS8qIGRpc3Bvc2l0aW9uIHZhbHVlICovCgkpOwp9CgovKiBSZWdDcmVhdGVLZXkJCQlbU0hFTEwuMl0gW0tFUk5FTC4yMThdICovCkRXT1JEIFJlZ0NyZWF0ZUtleTE2KAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglMUEhLRVkJcmV0a2V5CikgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdDcmVhdGVLZXkxNiglbHgsJXMsJXApXG4iLAoJCShMT05HKWhrZXksbHBzelN1YktleSxyZXRrZXkKCSk7CglyZXR1cm4gUmVnQ3JlYXRlS2V5MzJBKGhrZXksbHBzelN1YktleSxyZXRrZXkpOwp9CgovKiAKICogUXVlcnkgVmFsdWUgRnVuY3Rpb25zCiAqIFdpbjMyIGRpZmZlcnMgYmV0d2VlbiBrZXluYW1lcyBhbmQgdmFsdWVuYW1lcy4gCiAqIG11bHRpcGxlIHZhbHVlcyBtYXkgYmVsb25nIHRvIG9uZSBrZXksIHRoZSBzcGVjaWFsIHZhbHVlCiAqIHdpdGggbmFtZSBOVUxMIGlzIHRoZSBkZWZhdWx0IHZhbHVlIHVzZWQgYnkgdGhlIHdpbjMxCiAqIGNvbXBhdCBmdW5jdGlvbnMuCiAqCiAqIENhbGxwYXRoOgogKiBSZWdRdWVyeVZhbHVlMTYgLT4gUmVnUXVlcnlWYWx1ZTMyQSAtPiBSZWdRdWVyeVZhbHVlRXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUzMlcgLT4gUmVnUXVlcnlWYWx1ZUV4MzJXCiAqLwoKLyogUmVnUXVlcnlWYWx1ZUV4VwkJW0FEVkFQSTMyLjE1OF0gKi8KRFdPUkQgUmVnUXVlcnlWYWx1ZUV4MzJXKAoJSEtFWQloa2V5LAoJTFBXU1RSCWxwc3pWYWx1ZU5hbWUsCglMUERXT1JECWxwZHdSZXNlcnZlZCwKCUxQRFdPUkQJbHBkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglMUEtFWVNUUlVDVAlscGtleTsKCWludAkJaTsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1F1ZXJ5VmFsdWVFeDMyVygleCwlcywlcCwlcCwlcCwlbGQpXG4iLAoJCWhrZXksVzJDKGxwc3pWYWx1ZU5hbWUsMCksbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsCgkJbHBjYkRhdGE/KmxwY2JEYXRhOjAKCSk7CgoJbHBrZXkJPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCWlmIChscHN6VmFsdWVOYW1lPT1OVUxMKSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCX0gZWxzZSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmICgJbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmCgkJCQkhbHN0cmNtcDMyVyhscHN6VmFsdWVOYW1lLGxwa2V5LT52YWx1ZXNbaV0ubmFtZSkKCQkJKQoJCQkJYnJlYWs7Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlpZiAobHBzelZhbHVlTmFtZT09TlVMTCkgewoJCQlpZiAobHBiRGF0YSkgewoJCQkJKihXQ0hBUiopbHBiRGF0YSA9IDA7CgkJCQkqbHBjYkRhdGEJPSAyOwoJCQl9CgkJCWlmIChscGR3VHlwZSkKCQkJCSpscGR3VHlwZQk9IFJFR19TWjsKCQkJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7CgkJfQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7LypGSVhNRTogY29ycmVjdCByZXR1cm4/ICovCgl9CglpZiAobHBkd1R5cGUpCgkJKmxwZHdUeXBlCT0gbHBrZXktPnZhbHVlc1tpXS50eXBlOwoJaWYgKGxwYkRhdGE9PU5VTEwpIHsKCQlpZiAobHBjYkRhdGE9PU5VTEwpCgkJCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwoJCSpscGNiRGF0YQk9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwoJCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwoJfQoJaWYgKCpscGNiRGF0YTxscGtleS0+dmFsdWVzW2ldLmxlbikgewoJCSooV0NIQVIqKWxwYkRhdGEKCQkJPSAwOwoJCSpscGNiRGF0YQk9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwoJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7Cgl9CgltZW1jcHkobHBiRGF0YSxscGtleS0+dmFsdWVzW2ldLmRhdGEsbHBrZXktPnZhbHVlc1tpXS5sZW4pOwoJKmxwY2JEYXRhCT0gbHBrZXktPnZhbHVlc1tpXS5sZW47CglyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKfQoKLyogUmVnUXVlcnlWYWx1ZVcJCVtBRFZBUEkzMi4xNTldICovCkRXT1JEIFJlZ1F1ZXJ5VmFsdWUzMlcoCglIS0VZCWhrZXksCglMUFdTVFIJbHBzelN1YktleSwKCUxQV1NUUglscHN6RGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglIS0VZCXhoa2V5OwoJRFdPUkQJcmV0LGxwZHdUeXBlOwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnUXVlcnlWYWx1ZTMyVygleCwlcywlcCwlbGQpXG4tPiIsCgkJaGtleSxXMkMobHBzelN1YktleSwwKSxscHN6RGF0YSwKCQlscGNiRGF0YT8qbHBjYkRhdGE6MAoJKTsKCgkvKiBvbmx5IG9wZW4gc3Via2V5LCBpZiB3ZSByZWFsbHkgZG8gZGVzY2VuZCAqLwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQJPSBSZWdPcGVuS2V5MzJXKGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleQk9IGhrZXk7CgoJbHBkd1R5cGUJPSBSRUdfU1o7CglyZXQJPSBSZWdRdWVyeVZhbHVlRXgzMlcoCgkJeGhrZXksCgkJTlVMTCwJCS8qIHZhcm5hbWUgTlVMTCAtPiBjb21wYXQgKi8KCQlOVUxMLAkJLyogbHBkd1Jlc2VydmVkLCBtdXN0IGJlIE5VTEwgKi8KCQkmbHBkd1R5cGUsCgkJKExQQllURSlscHN6RGF0YSwKCQlscGNiRGF0YQoJKTsKCWlmICh4aGtleSE9aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdRdWVyeVZhbHVlRXhBCQlbQURWQVBJMzIuMTU3XSAqLwpEV09SRCBSZWdRdWVyeVZhbHVlRXgzMkEoCglIS0VZCWhrZXksCglMUFNUUglscHN6VmFsdWVOYW1lLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUERXT1JECWxwZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJTFBXU1RSCWxwc3pWYWx1ZU5hbWVXOwoJTFBCWVRFCWJ1ZjsKCURXT1JECXJldCxteXhsZW47CglEV09SRAkqbXlsZW47CglEV09SRAl0eXBlOwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnUXVlcnlWYWx1ZUV4MzJBKCV4LCVzLCVwLCVwLCVwLCVsZClcbi0+IiwKCQloa2V5LGxwc3pWYWx1ZU5hbWUsbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsCgkJbHBjYkRhdGE/KmxwY2JEYXRhOjAKCSk7CglpZiAobHBiRGF0YSkgewoJCS8qIGRvdWJsZSBidWZmZXIgKi8KCQlidWYJPSAoTFBCWVRFKXhtYWxsb2MoKCpscGNiRGF0YSkqMik7CgkJbXl4bGVuCT0gKmxwY2JEYXRhKjI7CgkJbXlsZW4JPSAmbXl4bGVuOwoJfSBlbHNlIHsKCQlidWY9TlVMTDsKCQlpZiAobHBjYkRhdGEpIHsKCQkJbXl4bGVuCT0gKmxwY2JEYXRhKjI7CgkJCW15bGVuCT0gJm15eGxlbjsKCQl9IGVsc2UKCQkJbXlsZW4JPSBOVUxMOwoJfQoJaWYgKGxwc3pWYWx1ZU5hbWUpCgkJbHBzelZhbHVlTmFtZVc9c3RyZHVwQTJXKGxwc3pWYWx1ZU5hbWUpOwoJZWxzZSAKCQlscHN6VmFsdWVOYW1lVz1OVUxMOwoKCWlmIChscGR3VHlwZSkKCQl0eXBlPSpscGR3VHlwZTsKCXJldD1SZWdRdWVyeVZhbHVlRXgzMlcoCgkJaGtleSwKCQlscHN6VmFsdWVOYW1lVywKCQlscGR3UmVzZXJ2ZWQsCgkJJnR5cGUsCgkJYnVmLAoJCW15bGVuCgkpOwoJaWYgKGxwZHdUeXBlKSAKCQkqbHBkd1R5cGU9dHlwZTsKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MpIHsKCQlpZiAoYnVmKSB7CgkJCWlmIChVTklDT05WTUFTSyAmICgxPDwodHlwZSkpKSB7CgkJCQkvKiBjb252ZXJ0IFVOSUNPREUgdG8gQVNDSUkgKi8KCQkJCWxzdHJjcHlXdG9BKGxwYkRhdGEsKExQV1NUUilidWYpOwoJCQkJKmxwY2JEYXRhCT0gbXl4bGVuLzI7CgkJCX0gZWxzZSB7CgkJCQlpZiAobXl4bGVuPipscGNiRGF0YSkKCQkJCQlyZXQJPSBFUlJPUl9NT1JFX0RBVEE7CgkJCQllbHNlCgkJCQkJbWVtY3B5KGxwYkRhdGEsYnVmLG15eGxlbik7CgoJCQkJKmxwY2JEYXRhCT0gbXl4bGVuOwoJCQl9CgkJfSBlbHNlIHsKCQkJaWYgKChVTklDT05WTUFTSyAmICgxPDwodHlwZSkpKSAmJiBscGNiRGF0YSkKCQkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJCX0KCX0gZWxzZSB7CgkJaWYgKChVTklDT05WTUFTSyAmICgxPDwodHlwZSkpKSAmJiBscGNiRGF0YSkKCQkJKmxwY2JEYXRhCT0gbXl4bGVuLzI7Cgl9CglpZiAoYnVmKQoJCWZyZWUoYnVmKTsKCXJldHVybiByZXQ7Cn0KCi8qIFJlZ1F1ZXJ5VmFsdWVFeAkJW0tFUk5FTC4yMjVdICovCkRXT1JEIFJlZ1F1ZXJ5VmFsdWVFeDE2KAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelZhbHVlTmFtZSwKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnUXVlcnlWYWx1ZUV4MTYoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIiwKCQloa2V5LGxwc3pWYWx1ZU5hbWUsbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsCgkJbHBjYkRhdGE/KmxwY2JEYXRhOjAKCSk7CglyZXR1cm4gUmVnUXVlcnlWYWx1ZUV4MzJBKAoJCWhrZXksCgkJbHBzelZhbHVlTmFtZSwKCQlscGR3UmVzZXJ2ZWQsCgkJbHBkd1R5cGUsCgkJbHBiRGF0YSwKCQlscGNiRGF0YQoJKTsKfQoKLyogUmVnUXVlcnlWYWx1ZUEJCVtBRFZBUEkzMi4xNTZdICovCkRXT1JEIFJlZ1F1ZXJ5VmFsdWUzMkEoCglIS0VZCWhrZXksCglMUFNUUglscHN6U3ViS2V5LAoJTFBTVFIJbHBzekRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJSEtFWQl4aGtleTsKCURXT1JECXJldCxscGR3VHlwZTsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1F1ZXJ5VmFsdWUzMkEoJXgsJXMsJXAsJWxkKVxuIiwKCQloa2V5LGxwc3pTdWJLZXksbHBzekRhdGEsCgkJbHBjYkRhdGE/KmxwY2JEYXRhOjAKCSk7CgoJLyogb25seSBvcGVuIHN1YmtleSwgaWYgd2UgcmVhbGx5IGRvIGRlc2NlbmQgKi8KCWlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CgkJcmV0CT0gUmVnT3BlbktleTE2KGhrZXksbHBzelN1YktleSwmeGhrZXkpOwoJCWlmIChyZXQhPUVSUk9SX1NVQ0NFU1MpCgkJCXJldHVybiByZXQ7Cgl9IGVsc2UKCQl4aGtleQk9IGhrZXk7CgoJbHBkd1R5cGUJPSBSRUdfU1o7CglyZXQJPSBSZWdRdWVyeVZhbHVlRXgzMkEoCgkJeGhrZXksCgkJTlVMTCwJCS8qIGxwc3pWYWx1ZU5hbWUgTlVMTCAtPiBjb21wYXQgKi8KCQlOVUxMLAkJLyogbHBkd1Jlc2VydmVkLCBtdXN0IGJlIE5VTEwgKi8KCQkmbHBkd1R5cGUsCgkJKExQQllURSlscHN6RGF0YSwKCQlscGNiRGF0YQoJKTsKCWlmICh4aGtleSE9aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdRdWVyeVZhbHVlCQlbU0hFTEwuNl0gW0tFUk5FTC4yMjRdICovCkRXT1JEIFJlZ1F1ZXJ5VmFsdWUxNigKCUhLRVkJaGtleSwKCUxQU1RSCWxwc3pTdWJLZXksCglMUFNUUglscHN6RGF0YSwKCUxQRFdPUkQJbHBjYkRhdGEKKSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1F1ZXJ5VmFsdWUxNigleCwlcywlcCwlbGQpXG4iLAoJCWhrZXksbHBzelN1YktleSxscHN6RGF0YSxscGNiRGF0YT8qbHBjYkRhdGE6MAoJKTsKCS8qIEhBQ0s6IHRoZSAxNmJpdCBSZWdRdWVyeVZhbHVlIGRvZXNuJ3QgaGFuZGxlIHNlbGVjdG9yYmxvY2tzCgkgKiAgICAgICBhbnl3YXksIHNvIHdlIGp1c3QgbWFzayBvdXQgdGhlIGhpZ2ggMTYgYml0LgoJICogICAgICAgKHRoaXMgKG5vdCBzbyBtdWNoIGluY2lkZW50bHk7KSBob3BlZnVsbHkgZml4ZXMgQWxkdXMgRkg0KQoJICovCglpZiAobHBjYkRhdGEpCgkJKmxwY2JEYXRhICY9IDB4RkZGRjsKCXJldHVybiBSZWdRdWVyeVZhbHVlMzJBKGhrZXksbHBzelN1YktleSxscHN6RGF0YSxscGNiRGF0YSk7Cn0KCi8qCiAqIFNldHRpbmcgdmFsdWVzIG9mIFJlZ2lzdHJ5IGtleXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ1NldFZhbHVlMTYgLT4gUmVnU2V0VmFsdWUzMkEgLT4gUmVnU2V0VmFsdWVFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnU2V0VmFsdWUzMlcgICAtPiBSZWdTZXRWYWx1ZUV4MzJXCiAqLwoKLyogUmVnU2V0VmFsdWVFeFcJCVtBRFZBUEkzMi4xNzBdICovCkRXT1JEIFJlZ1NldFZhbHVlRXgzMlcoCglIS0VZCWhrZXksCglMUFdTVFIJbHBzelZhbHVlTmFtZSwKCURXT1JECWR3UmVzZXJ2ZWQsCglEV09SRAlkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCURXT1JECWNiRGF0YQopIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJaW50CQlpOwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnU2V0VmFsdWVFeDMyVygleCwlcywlbGQsJWxkLCVwLCVsZClcbiIsCgkJaGtleSxXMkMobHBzelZhbHVlTmFtZSwwKSxkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YQoJKTsKCS8qIHdlIG5vIGxvbmdlciBjYXJlIGFib3V0IHRoZSBscGJEYXRhIHR5cGUgaGVyZS4uLiAqLwoJbHBrZXkJPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCglscGtleS0+ZmxhZ3MgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoKCWlmIChscHN6VmFsdWVOYW1lPT1OVUxMKSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJCQlicmVhazsKCX0gZWxzZSB7CgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmICgJbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmCgkJCQkhbHN0cmNtcDMyVyhscHN6VmFsdWVOYW1lLGxwa2V5LT52YWx1ZXNbaV0ubmFtZSkKCQkJKQoJCQkJYnJlYWs7Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0gKExQS0VZVkFMVUUpeHJlYWxsb2MoCgkJCQkJbHBrZXktPnZhbHVlcywKCQkJCQkobHBrZXktPm5yb2Z2YWx1ZXMrMSkqc2l6ZW9mKEtFWVZBTFVFKQoJCQkJKTsKCQlscGtleS0+bnJvZnZhbHVlcysrOwoJCW1lbXNldChscGtleS0+dmFsdWVzK2ksJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCX0KCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpCgkJaWYgKGxwc3pWYWx1ZU5hbWUpCgkJCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSA9IHN0cmR1cFcobHBzelZhbHVlTmFtZSk7CgkJZWxzZQoJCQlscGtleS0+dmFsdWVzW2ldLm5hbWUgPSBOVUxMOwoJbHBrZXktPnZhbHVlc1tpXS5sZW4JPSBjYkRhdGE7CglscGtleS0+dmFsdWVzW2ldLnR5cGUJPSBkd1R5cGU7CglpZiAobHBrZXktPnZhbHVlc1tpXS5kYXRhICE9TlVMTCkKCQlmcmVlKGxwa2V5LT52YWx1ZXNbaV0uZGF0YSk7CglscGtleS0+dmFsdWVzW2ldLmRhdGEJPSAoTFBCWVRFKXhtYWxsb2MoY2JEYXRhKTsKCWxwa2V5LT52YWx1ZXNbaV0ubGFzdG1vZGlmaWVkID0gdGltZShOVUxMKTsKCW1lbWNweShscGtleS0+dmFsdWVzW2ldLmRhdGEsbHBiRGF0YSxjYkRhdGEpOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ1NldFZhbHVlRXhBCQlbQURWQVBJMzIuMTY5XSAqLwpEV09SRCBSZWdTZXRWYWx1ZUV4MzJBKAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelZhbHVlTmFtZSwKCURXT1JECWR3UmVzZXJ2ZWQsCglEV09SRAlkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCURXT1JECWNiRGF0YQopIHsKCUxQQllURQlidWY7CglMUFdTVFIJbHBzelZhbHVlTmFtZVc7CglEV09SRAlyZXQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdTZXRWYWx1ZUV4MzJBKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuLT4iLAoJCWhrZXksbHBzelZhbHVlTmFtZSxkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YQoJKTsKCWlmICgoMTw8ZHdUeXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJYnVmPShMUEJZVEUpc3RyZHVwQTJXKGxwYkRhdGEpOwoJCWNiRGF0YT0yKnN0cmxlbihscGJEYXRhKSsyOwoJfSBlbHNlCgkJYnVmPWxwYkRhdGE7CglpZiAobHBzelZhbHVlTmFtZSkKCQlscHN6VmFsdWVOYW1lVyA9IHN0cmR1cEEyVyhscHN6VmFsdWVOYW1lKTsKCWVsc2UKCQlscHN6VmFsdWVOYW1lVyA9IE5VTEw7CglyZXQ9UmVnU2V0VmFsdWVFeDMyVyhoa2V5LGxwc3pWYWx1ZU5hbWVXLGR3UmVzZXJ2ZWQsZHdUeXBlLGJ1ZixjYkRhdGEpOwoJaWYgKGxwc3pWYWx1ZU5hbWVXKQoJCWZyZWUobHBzelZhbHVlTmFtZVcpOwoJaWYgKGJ1ZiE9bHBiRGF0YSkKCQlmcmVlKGJ1Zik7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdTZXRWYWx1ZUV4CQlbS0VSTkVMLjIyNl0gKi8KRFdPUkQgUmVnU2V0VmFsdWVFeDE2KAoJSEtFWQloa2V5LAoJTFBTVFIJbHBzelZhbHVlTmFtZSwKCURXT1JECWR3UmVzZXJ2ZWQsCglEV09SRAlkd1R5cGUsCglMUEJZVEUJbHBiRGF0YSwKCURXT1JECWNiRGF0YQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnU2V0VmFsdWVFeDE2KCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuLT4iLAoJCWhrZXksbHBzelZhbHVlTmFtZSxkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YQoJKTsKCXJldHVybiBSZWdTZXRWYWx1ZUV4MzJBKGhrZXksbHBzelZhbHVlTmFtZSxkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YSk7Cn0KCi8qIFJlZ1NldFZhbHVlVwkJCVtBRFZBUEkzMi4xNzFdICovCkRXT1JEIFJlZ1NldFZhbHVlMzJXKAoJSEtFWQloa2V5LAoJTFBDV1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdUeXBlLAoJTFBDV1NUUglscHN6RGF0YSwKCURXT1JECWNiRGF0YQopIHsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQ7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdTZXRWYWx1ZTMyVygleCwlcywlbGQsJXMsJWxkKVxuLT4iLAoJCWhrZXksVzJDKGxwc3pTdWJLZXksMCksZHdUeXBlLFcyQyhscHN6RGF0YSwwKSxjYkRhdGEKCSk7CglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldD1SZWdDcmVhdGVLZXkzMlcoaGtleSxscHN6U3ViS2V5LCZ4aGtleSk7CgkJaWYgKHJldCE9RVJST1JfU1VDQ0VTUykKCQkJcmV0dXJuIHJldDsKCX0gZWxzZQoJCXhoa2V5PWhrZXk7CglpZiAoZHdUeXBlIT1SRUdfU1opIHsKCQlmcHJpbnRmKHN0ZGRlYiwiUmVnU2V0VmFsdWVYIGNhbGxlZCB3aXRoIGR3VHlwZT0lbGQhXG4iLGR3VHlwZSk7CgkJZHdUeXBlPVJFR19TWjsKCX0KCWlmIChjYkRhdGEhPTIqbHN0cmxlbjMyVyhscHN6RGF0YSkrMikgewoJCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnU2V0VmFsdWVYIGNhbGxlZCB3aXRoIGxlbj0lbGQgIT0gc3RybGVuKCVzKSsxPSVkIVxuIiwKCQkJY2JEYXRhLFcyQyhscHN6RGF0YSwwKSwyKmxzdHJsZW4zMlcobHBzekRhdGEpKzIKCQkpOwoJCWNiRGF0YT0yKmxzdHJsZW4zMlcobHBzekRhdGEpKzI7Cgl9CglyZXQ9UmVnU2V0VmFsdWVFeDMyVyh4aGtleSxOVUxMLDAsZHdUeXBlLChMUEJZVEUpbHBzekRhdGEsY2JEYXRhKTsKCWlmIChoa2V5IT14aGtleSkKCQlSZWdDbG9zZUtleSh4aGtleSk7CglyZXR1cm4gcmV0OwoKfQovKiBSZWdTZXRWYWx1ZUEJCQlbQURWQVBJMzIuMTY4XSAqLwpEV09SRCBSZWdTZXRWYWx1ZTMyQSgKCUhLRVkJaGtleSwKCUxQQ1NUUglscHN6U3ViS2V5LAoJRFdPUkQJZHdUeXBlLAoJTFBDU1RSCWxwc3pEYXRhLAoJRFdPUkQJY2JEYXRhCikgewoJRFdPUkQJcmV0OwoJSEtFWQl4aGtleTsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1NldFZhbHVlMzJBKCV4LCVzLCVsZCwlcywlbGQpXG4tPiIsCgkJaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEKCSk7CglpZiAobHBzelN1YktleSAmJiAqbHBzelN1YktleSkgewoJCXJldD1SZWdDcmVhdGVLZXkxNihoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXk9aGtleTsKCglpZiAoZHdUeXBlIT1SRUdfU1opIHsKCQlkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1NldFZhbHVlQSBjYWxsZWQgd2l0aCBkd1R5cGU9JWxkIVxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT1zdHJsZW4obHBzekRhdGEpKzEpCgkJY2JEYXRhPXN0cmxlbihscHN6RGF0YSkrMTsKCXJldD1SZWdTZXRWYWx1ZUV4MzJBKHhoa2V5LE5VTEwsMCxkd1R5cGUsKExQQllURSlscHN6RGF0YSxjYkRhdGEpOwoJaWYgKHhoa2V5IT1oa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCi8qIFJlZ1NldFZhbHVlCQkJW0tFUk5FTC4yMjFdIFtTSEVMTC41XSAqLwpEV09SRCBSZWdTZXRWYWx1ZTE2KAoJSEtFWQloa2V5LAoJTFBDU1RSCWxwc3pTdWJLZXksCglEV09SRAlkd1R5cGUsCglMUENTVFIJbHBzekRhdGEsCglEV09SRAljYkRhdGEKKSB7CglEV09SRAlyZXQ7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ1NldFZhbHVlMTYoJXgsJXMsJWxkLCVzLCVsZClcbi0+IiwKCQloa2V5LGxwc3pTdWJLZXksZHdUeXBlLGxwc3pEYXRhLGNiRGF0YQoJKTsKCXJldD1SZWdTZXRWYWx1ZTMyQShoa2V5LGxwc3pTdWJLZXksZHdUeXBlLGxwc3pEYXRhLGNiRGF0YSk7CglyZXR1cm4gcmV0Owp9CgovKiAKICogS2V5IEVudW1lcmF0aW9uCiAqCiAqIENhbGxwYXRoOgogKiBSZWdFbnVtS2V5MTYgLT4gUmVnRW51bUtleTMyQSAtPiBSZWdFbnVtS2V5RXgzMkEgXAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ0VudW1LZXkzMlcgICAtPiBSZWdFbnVtS2V5RXgzMlcKICovCgovKiBSZWdFbnVtS2V5RXhXCQlbQURWQVBJMzIuMTM5XSAqLwpEV09SRCBSZWdFbnVtS2V5RXgzMlcoCglIS0VZCWhrZXksCglEV09SRAlpU3Via2V5LAoJTFBXU1RSCWxwc3pOYW1lLAoJTFBEV09SRAlscGNjaE5hbWUsCglMUERXT1JECWxwZHdSZXNlcnZlZCwKCUxQV1NUUglscHN6Q2xhc3MsCglMUERXT1JECWxwY2NoQ2xhc3MsCglGSUxFVElNRQkqZnQKKSB7CglMUEtFWVNUUlVDVAlscGtleSxscHhrZXk7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtS2V5RXgzMlcoJXgsJWxkLCVwLCVsZCwlcCwlcCwlcCwlcClcbiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLCpscGNjaE5hbWUsbHBkd1Jlc2VydmVkLGxwc3pDbGFzcyxscGNjaENsYXNzLGZ0CgkpOwoJbHBrZXk9bG9va3VwX2hrZXkoaGtleSk7CglpZiAoIWxwa2V5KQoJCXJldHVybiBTSEVMTF9FUlJPUl9CQURLRVk7CglpZiAoIWxwa2V5LT5uZXh0c3ViKQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoJbHB4a2V5PWxwa2V5LT5uZXh0c3ViOwoJd2hpbGUgKGlTdWJrZXkgJiYgbHB4a2V5KSB7CgkJaVN1YmtleS0tOwoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9CglpZiAoaVN1YmtleSB8fCAhbHB4a2V5KQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoJaWYgKDIqbHN0cmxlbjMyVyhscHhrZXktPmtleW5hbWUpKzI+KmxwY2NoTmFtZSkKCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJbWVtY3B5KGxwc3pOYW1lLGxweGtleS0+a2V5bmFtZSxsc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSkqMisyKTsKCWlmIChscHN6Q2xhc3MpIHsKCQkvKiB3aGF0IHNob3VsZCB3ZSB3cml0ZSBpbnRvIGl0PyAqLwoJCSpscHN6Q2xhc3MJCT0gMDsKCQkqbHBjY2hDbGFzcwk9IDI7Cgl9CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKCn0KCi8qIFJlZ0VudW1LZXlXCQkJW0FEVkFQSTMyLjE0MF0gKi8KRFdPUkQgUmVnRW51bUtleTMyVygKCUhLRVkJaGtleSwKCURXT1JECWlTdWJrZXksCglMUFdTVFIJbHBzek5hbWUsCglEV09SRAlscGNjaE5hbWUKKSB7CglGSUxFVElNRQlmdDsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0VudW1LZXkzMlcoJXgsJWxkLCVwLCVsZClcbi0+IiwKCQloa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lCgkpOwoJcmV0dXJuIFJlZ0VudW1LZXlFeDMyVyhoa2V5LGlTdWJrZXksbHBzek5hbWUsJmxwY2NoTmFtZSxOVUxMLE5VTEwsTlVMTCwmZnQpOwp9Ci8qIFJlZ0VudW1LZXlFeEEJCVtBRFZBUEkzMi4xMzhdICovCkRXT1JEIFJlZ0VudW1LZXlFeDMyQSgKCUhLRVkJaGtleSwKCURXT1JECWlTdWJrZXksCglMUFNUUglscHN6TmFtZSwKCUxQRFdPUkQJbHBjY2hOYW1lLAoJTFBEV09SRAlscGR3UmVzZXJ2ZWQsCglMUFNUUglscHN6Q2xhc3MsCglMUERXT1JECWxwY2NoQ2xhc3MsCglGSUxFVElNRQkqZnQKKSB7CglEV09SRAlyZXQsbHBjY2hOYW1lVyxscGNjaENsYXNzVzsKCUxQV1NUUglscHN6TmFtZVcsbHBzekNsYXNzVzsKCgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtS2V5RXgzMkEoJXgsJWxkLCVwLCVsZCwlcCwlcCwlcCwlcClcbi0+IiwKCQloa2V5LGlTdWJrZXksbHBzek5hbWUsKmxwY2NoTmFtZSxscGR3UmVzZXJ2ZWQsbHBzekNsYXNzLGxwY2NoQ2xhc3MsZnQKCSk7CglpZiAobHBzek5hbWUpIHsKCQlscHN6TmFtZVcJPSAoTFBXU1RSKXhtYWxsb2MoKmxwY2NoTmFtZSoyKTsKCQlscGNjaE5hbWVXCT0gKmxwY2NoTmFtZSoyOwoJfSBlbHNlIHsKCQlscHN6TmFtZVcJPSBOVUxMOwoJCWxwY2NoTmFtZVcgCT0gMDsKCX0KCWlmIChscHN6Q2xhc3MpIHsKCQlscHN6Q2xhc3NXCQk9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hDbGFzcyoyKTsKCQlscGNjaENsYXNzVwk9ICpscGNjaENsYXNzKjI7Cgl9IGVsc2UgewoJCWxwc3pDbGFzc1cJPTA7CgkJbHBjY2hDbGFzc1c9MDsKCX0KCXJldD1SZWdFbnVtS2V5RXgzMlcoCgkJaGtleSwKCQlpU3Via2V5LAoJCWxwc3pOYW1lVywKCQkmbHBjY2hOYW1lVywKCQlscGR3UmVzZXJ2ZWQsCgkJbHBzekNsYXNzVywKCQkmbHBjY2hDbGFzc1csCgkJZnQKCSk7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJbHN0cmNweVd0b0EobHBzek5hbWUsbHBzek5hbWVXKTsKCQkqbHBjY2hOYW1lPXN0cmxlbihscHN6TmFtZSk7CgkJaWYgKGxwc3pDbGFzc1cpIHsKCQkJbHN0cmNweVd0b0EobHBzekNsYXNzLGxwc3pDbGFzc1cpOwoJCQkqbHBjY2hDbGFzcz1zdHJsZW4obHBzekNsYXNzKTsKCQl9Cgl9CglpZiAobHBzek5hbWVXKQoJCWZyZWUobHBzek5hbWVXKTsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9CgovKiBSZWdFbnVtS2V5QQkJCVtBRFZBUEkzMi4xMzddICovCkRXT1JEIFJlZ0VudW1LZXkzMkEoCglIS0VZCWhrZXksCglEV09SRAlpU3Via2V5LAoJTFBTVFIJbHBzek5hbWUsCglEV09SRAlscGNjaE5hbWUKKSB7CglGSUxFVElNRQlmdDsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0VudW1LZXkzMkEoJXgsJWxkLCVwLCVsZClcbi0+IiwKCQloa2V5LGlTdWJrZXksbHBzek5hbWUsbHBjY2hOYW1lCgkpOwoJcmV0dXJuCVJlZ0VudW1LZXlFeDMyQSgKCQloa2V5LAoJCWlTdWJrZXksCgkJbHBzek5hbWUsCgkJJmxwY2NoTmFtZSwKCQlOVUxMLAoJCU5VTEwsCgkJTlVMTCwKCQkmZnQKCSk7Cn0KCi8qIFJlZ0VudW1LZXkJCQlbU0hFTEwuN10gW0tFUk5FTC4yMTZdICovCkRXT1JEIFJlZ0VudW1LZXkxNigKCUhLRVkJaGtleSwKCURXT1JECWlTdWJrZXksCglMUFNUUglscHN6TmFtZSwKCURXT1JECWxwY2NoTmFtZQopIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRW51bUtleTE2KCV4LCVsZCwlcCwlbGQpXG4tPiIsCgkJaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZQoJKTsKCXJldHVybiBSZWdFbnVtS2V5MzJBKGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwp9CgovKiAKICogRW51bWVyYXRlIFJlZ2lzdHJ5IFZhbHVlcwogKgogKiBDYWxscGF0aDoKICogUmVnRW51bVZhbHVlMTYgLT4gUmVnRW51bVZhbHVlMzJBIC0+IFJlZ0VudW1WYWx1ZTMyVwogKi8KCi8qIFJlZ0VudW1WYWx1ZVcJCVtBRFZBUEkzMi4xNDJdICovCkRXT1JEIFJlZ0VudW1WYWx1ZTMyVygKCUhLRVkJaGtleSwKCURXT1JECWlWYWx1ZSwKCUxQV1NUUglscHN6VmFsdWUsCglMUERXT1JECWxwY2NoVmFsdWUsCglMUERXT1JECWxwZFJlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUxQS0VZU1RSVUNUCWxwa2V5OwoJTFBLRVlWQUxVRQl2YWw7CgoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtVmFsdWUzMlcoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSxscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhCgkpOwoJbHBrZXkgPSBsb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCWlmIChscGtleS0+bnJvZnZhbHVlczw9aVZhbHVlKQoJCXJldHVybiBFUlJPUl9OT19NT1JFX0lURU1TOwoJdmFsCT0gbHBrZXktPnZhbHVlcytpVmFsdWU7CgoJaWYgKHZhbC0+bmFtZSkgewoJCWlmIChsc3RybGVuMzJXKHZhbC0+bmFtZSkqMisyPipscGNjaFZhbHVlKSB7CgkJCSpscGNjaFZhbHVlID0gbHN0cmxlbjMyVyh2YWwtPm5hbWUpKjIrMjsKCQkJcmV0dXJuIEVSUk9SX01PUkVfREFUQTsKCQl9CgkJbWVtY3B5KGxwc3pWYWx1ZSx2YWwtPm5hbWUsMipsc3RybGVuMzJXKHZhbC0+bmFtZSkrMik7CgkJKmxwY2NoVmFsdWU9bHN0cmxlbjMyVyh2YWwtPm5hbWUpKjIrMjsKCX0gZWxzZSB7CgkJLyogaG93IHRvIGhhbmRsZSBOVUxMIHZhbHVlPyAqLwoJCSpscHN6VmFsdWUJPSAwOwoJCSpscGNjaFZhbHVlCT0gMjsKCX0KCSpscGR3VHlwZT12YWwtPnR5cGU7CglpZiAobHBiRGF0YSkgewoJCWlmICh2YWwtPmxlbj4qbHBjYkRhdGEpCgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJbWVtY3B5KGxwYkRhdGEsdmFsLT5kYXRhLHZhbC0+bGVuKTsKCQkqbHBjYkRhdGEgPSB2YWwtPmxlbjsKCX0KCXJldHVybiBTSEVMTF9FUlJPUl9TVUNDRVNTOwp9CgovKiBSZWdFbnVtVmFsdWVBCQlbQURWQVBJMzIuMTQxXSAqLwpEV09SRCBSZWdFbnVtVmFsdWUzMkEoCglIS0VZCWhrZXksCglEV09SRAlpVmFsdWUsCglMUFNUUglscHN6VmFsdWUsCglMUERXT1JECWxwY2NoVmFsdWUsCglMUERXT1JECWxwZFJlc2VydmVkLAoJTFBEV09SRAlscGR3VHlwZSwKCUxQQllURQlscGJEYXRhLAoJTFBEV09SRAlscGNiRGF0YQopIHsKCUxQV1NUUglscHN6VmFsdWVXOwoJTFBCWVRFCWxwYkRhdGFXOwoJRFdPUkQJcmV0LGxwY2JEYXRhVzsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0VudW1WYWx1ZTMyQSgleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksaVZhbHVlLGxwc3pWYWx1ZSxscGNjaFZhbHVlLGxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEKCSk7CgoJbHBzelZhbHVlVyA9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hWYWx1ZSoyKTsKCWlmIChscGJEYXRhKSB7CgkJbHBiRGF0YVcgPSAoTFBCWVRFKXhtYWxsb2MoKmxwY2JEYXRhKjIpOwoJCWxwY2JEYXRhVyA9ICpscGNiRGF0YSoyOwoJfSBlbHNlCgkJbHBiRGF0YVcgPSBOVUxMOwoJcmV0PVJlZ0VudW1WYWx1ZTMyVygKCQloa2V5LAoJCWlWYWx1ZSwKCQlscHN6VmFsdWVXLAoJCWxwY2NoVmFsdWUsCgkJbHBkUmVzZXJ2ZWQsCgkJbHBkd1R5cGUsCgkJbHBiRGF0YVcsCgkJJmxwY2JEYXRhVwoJKTsKCglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKSB7CgkJbHN0cmNweVd0b0EobHBzelZhbHVlLGxwc3pWYWx1ZVcpOwoJCWlmIChscGJEYXRhKSB7CgkJCWlmICgoMTw8KmxwZHdUeXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJCQlsc3RyY3B5V3RvQShscGJEYXRhLChMUFdTVFIpbHBiRGF0YVcpOwoJCQl9IGVsc2UgewoJCQkJaWYgKGxwY2JEYXRhVyA+ICpscGNiRGF0YSkKCQkJCQlyZXQJPSBFUlJPUl9NT1JFX0RBVEE7CgkJCQllbHNlCgkJCQkJbWVtY3B5KGxwYkRhdGEsbHBiRGF0YVcsbHBjYkRhdGFXKTsKCQkJfQoJCQkqbHBjYkRhdGEgPSBscGNiRGF0YVc7CgkJfQoJfQoJaWYgKGxwYkRhdGFXKQoJCWZyZWUobHBiRGF0YVcpOwoJaWYgKGxwc3pWYWx1ZVcpCgkJZnJlZShscHN6VmFsdWVXKTsKCXJldHVybiByZXQ7Cn0KCi8qIFJlZ0VudW1WYWx1ZQkJCVtLRVJORUwuMjIzXSAqLwpEV09SRCBSZWdFbnVtVmFsdWUxNigKCUhLRVkJaGtleSwKCURXT1JECWlWYWx1ZSwKCUxQU1RSCWxwc3pWYWx1ZSwKCUxQRFdPUkQJbHBjY2hWYWx1ZSwKCUxQRFdPUkQJbHBkUmVzZXJ2ZWQsCglMUERXT1JECWxwZHdUeXBlLAoJTFBCWVRFCWxwYkRhdGEsCglMUERXT1JECWxwY2JEYXRhCikgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdFbnVtVmFsdWUoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIiwKCQloa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSxscGRSZXNlcnZlZCxscGR3VHlwZSxscGJEYXRhLGxwY2JEYXRhCgkpOwoJcmV0dXJuIFJlZ0VudW1WYWx1ZTMyQSgKCQloa2V5LAoJCWlWYWx1ZSwKCQlscHN6VmFsdWUsCgkJbHBjY2hWYWx1ZSwKCQlscGRSZXNlcnZlZCwKCQlscGR3VHlwZSwKCQlscGJEYXRhLAoJCWxwY2JEYXRhCgkpOwp9CgovKiAKICogIENsb3NlIHJlZ2lzdHJ5IGtleQogKi8KLyogUmVnQ2xvc2VLZXkJCQlbU0hFTEwuM10gW0tFUk5FTC4yMjBdIFtBRFZBUEkzMi4xMjZdICovCkRXT1JEIFJlZ0Nsb3NlS2V5KEhLRVkgaGtleSkgewoJZHByaW50Zl9yZWcoc3RkZGViLCJSZWdDbG9zZUtleSgleClcbiIsaGtleSk7CglyZW1vdmVfaGFuZGxlKGhrZXkpOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KLyogCiAqIERlbGV0ZSByZWdpc3RyeSBrZXkKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZUtleTE2IC0+IFJlZ0RlbGV0ZUtleTMyQSAtPiBSZWdEZWxldGVLZXkzMlcKICovCi8qIFJlZ0RlbGV0ZUtleVcJCVtBRFZBUEkzMi4xMzRdICovCkRXT1JEIFJlZ0RlbGV0ZUtleTMyVyhIS0VZIGhrZXksTFBXU1RSIGxwc3pTdWJLZXkpIHsKCUxQS0VZU1RSVUNUCSpscGxwUHJldktleSxscE5leHRLZXksbHB4a2V5OwoJTFBXU1RSCQkqd3BzOwoJaW50CQl3cGMsaTsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0RlbGV0ZUtleTMyVygleCwlcylcbiIsCgkJaGtleSxXMkMobHBzelN1YktleSwwKQoJKTsKCWxwTmV4dEtleQk9IGxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscE5leHRLZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCS8qIHdlIG5lZWQgdG8ga25vdyB0aGUgcHJldmlvdXMga2V5IGluIHRoZSBoaWVyLiAqLwoJaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7CglscHhrZXkJPSBscE5leHRLZXk7Cgl3aGlsZSAoaTx3cGMtMSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlpZiAoIWxzdHJjbXAzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCQlicmVhazsKCQkJbHB4a2V5PWxweGtleS0+bmV4dDsKCQl9CgkJaWYgKCFscHhrZXkpIHsKCQkJRlJFRV9LRVlfUEFUSDsKCQkJLyogbm90IGZvdW5kIGlzIHN1Y2Nlc3MgKi8KCQkJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7CgkJfQoJCWkrKzsKCQlscE5leHRLZXkJPSBscHhrZXk7Cgl9CglscHhrZXkJPSBscE5leHRLZXktPm5leHRzdWI7CglscGxwUHJldktleSA9ICYobHBOZXh0S2V5LT5uZXh0c3ViKTsKCXdoaWxlIChscHhrZXkpIHsKCQlpZiAoIWxzdHJjbXAzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCWJyZWFrOwoJCWxwbHBQcmV2S2V5CT0gJihscHhrZXktPm5leHQpOwoJCWxweGtleQkJPSBscHhrZXktPm5leHQ7Cgl9CglpZiAoIWxweGtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKCWlmIChscHhrZXktPm5leHRzdWIpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0NBTlRXUklURTsKCSpscGxwUHJldktleQk9IGxweGtleS0+bmV4dDsKCWZyZWUobHB4a2V5LT5rZXluYW1lKTsKCWlmIChscHhrZXktPmNsYXNzKQoJCWZyZWUobHB4a2V5LT5jbGFzcyk7CglpZiAobHB4a2V5LT52YWx1ZXMpCgkJZnJlZShscHhrZXktPnZhbHVlcyk7CglmcmVlKGxweGtleSk7CglGUkVFX0tFWV9QQVRIOwoJcmV0dXJuCVNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ0RlbGV0ZUtleUEJCVtBRFZBUEkzMi4xMzNdICovCkRXT1JEIFJlZ0RlbGV0ZUtleTMyQShIS0VZIGhrZXksTFBDU1RSIGxwc3pTdWJLZXkpIHsKCUxQV1NUUglscHN6U3ViS2V5VzsKCURXT1JECXJldDsKCglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0RlbGV0ZUtleTMyQSgleCwlcylcbiIsCgkJaGtleSxscHN6U3ViS2V5CgkpOwoJbHBzelN1YktleVc9SEVBUF9zdHJkdXBBdG9XKEdldFByb2Nlc3NIZWFwKCksMCxscHN6U3ViS2V5KTsKCXJldD1SZWdEZWxldGVLZXkzMlcoaGtleSxscHN6U3ViS2V5Vyk7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsbHBzelN1YktleVcpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnRGVsZXRlS2V5CQkJW1NIRUxMLjRdIFtLRVJORUwuMjE5XSAqLwpEV09SRCBSZWdEZWxldGVLZXkxNihIS0VZIGhrZXksTFBDU1RSIGxwc3pTdWJLZXkpIHsKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRGVsZXRlS2V5MTYoJXgsJXMpXG4iLAoJCWhrZXksbHBzelN1YktleQoJKTsKCXJldHVybiBSZWdEZWxldGVLZXkzMkEoaGtleSxscHN6U3ViS2V5KTsKfQoKLyogCiAqIERlbGV0ZSByZWdpc3RyeSB2YWx1ZQogKgogKiBDYWxscGF0aDoKICogUmVnRGVsZXRlVmFsdWUxNiAtPiBSZWdEZWxldGVWYWx1ZTMyQSAtPiBSZWdEZWxldGVWYWx1ZTMyVwogKi8KLyogUmVnRGVsZXRlVmFsdWVXCQlbQURWQVBJMzIuMTM2XSAqLwpEV09SRCBSZWdEZWxldGVWYWx1ZTMyVyhIS0VZIGhrZXksTFBXU1RSIGxwc3pWYWx1ZSkgewoJRFdPUkQJCWk7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnRGVsZXRlVmFsdWUzMlcoJXgsJXMpXG4iLAoJCWhrZXksVzJDKGxwc3pWYWx1ZSwwKQoJKTsKCWxwa2V5PWxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscGtleSkKCQlyZXR1cm4gU0hFTExfRVJST1JfQkFES0VZOwoJaWYgKGxwc3pWYWx1ZSkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXAzMlcobHBrZXktPnZhbHVlc1tpXS5uYW1lLGxwc3pWYWx1ZSkKCQkJKQoJCQkJYnJlYWs7Cgl9IGVsc2UgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAobHBrZXktPnZhbHVlc1tpXS5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsvKkZJWE1FOiBjb3JyZWN0IGVycm9yY29kZT8gKi8KCXZhbAk9IGxwa2V5LT52YWx1ZXMraTsKCWlmICh2YWwtPm5hbWUpIGZyZWUodmFsLT5uYW1lKTsKCWlmICh2YWwtPmRhdGEpIGZyZWUodmFsLT5kYXRhKTsKCW1lbWNweSgJCgkJbHBrZXktPnZhbHVlcytpLAoJCWxwa2V5LT52YWx1ZXMraSsxLAoJCXNpemVvZihLRVlWQUxVRSkqKGxwa2V5LT5ucm9mdmFsdWVzLWktMSkKCSk7CglscGtleS0+dmFsdWVzCT0gKExQS0VZVkFMVUUpeHJlYWxsb2MoCgkJCQlscGtleS0+dmFsdWVzLAoJCQkJKGxwa2V5LT5ucm9mdmFsdWVzLTEpKnNpemVvZihLRVlWQUxVRSkKCQkJKTsKCWxwa2V5LT5ucm9mdmFsdWVzLS07CglyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKfQoKLyogUmVnRGVsZXRlVmFsdWVBCQlbQURWQVBJMzIuMTM1XSAqLwpEV09SRCBSZWdEZWxldGVWYWx1ZTMyQShIS0VZIGhrZXksTFBTVFIgbHBzelZhbHVlKSB7CglMUFdTVFIJbHBzelZhbHVlVzsKCURXT1JECXJldDsKCglkcHJpbnRmX3JlZyggc3RkZGViLCAiUmVnRGVsZXRlVmFsdWUzMkEoJXgsJXMpXG4iLCBoa2V5LGxwc3pWYWx1ZSApOwogICAgICAgIGxwc3pWYWx1ZVc9SEVBUF9zdHJkdXBBdG9XKEdldFByb2Nlc3NIZWFwKCksMCxscHN6VmFsdWUpOwoJcmV0PVJlZ0RlbGV0ZVZhbHVlMzJXKGhrZXksbHBzelZhbHVlVyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLGxwc3pWYWx1ZVcpOwoJcmV0dXJuIHJldDsKfQoKLyogUmVnRGVsZXRlVmFsdWUJCVtLRVJORUwuMjIyXSAqLwpEV09SRCBSZWdEZWxldGVWYWx1ZTE2KEhLRVkgaGtleSxMUFNUUiBscHN6VmFsdWUpIHsKCWRwcmludGZfcmVnKCBzdGRkZWIsIlJlZ0RlbGV0ZVZhbHVlMTYoJXgsJXMpXG4iLCBoa2V5LGxwc3pWYWx1ZSApOwoJcmV0dXJuIFJlZ0RlbGV0ZVZhbHVlMzJBKGhrZXksbHBzelZhbHVlKTsKfQoKLyogUmVnRmx1c2hLZXkJCQlbQURWQVBJMzIuMTQzXSBbS0VSTkVMLjIyN10gKi8KRFdPUkQgUmVnRmx1c2hLZXkoSEtFWSBoa2V5KSB7CglkcHJpbnRmX3JlZyhzdGRkZWIsIlJlZ0ZsdXNoS2V5KCV4KSwgU1RVQi5cbiIsaGtleSk7CglyZXR1cm4gU0hFTExfRVJST1JfU1VDQ0VTUzsKfQoKLyogRklYTUU6IGxwY2NoWFhYWCAuLi4gaXMgdGhpcyBjb3VudGluZyBpbiBXQ0hBUlMgb3IgaW4gQllURXMgPz8gKi8KCi8qIFJlZ1F1ZXJ5SW5mb0tleVcJCVtBRFZBUEkzMi4xNTNdICovCkRXT1JEIFJlZ1F1ZXJ5SW5mb0tleTMyVygKCUhLRVkJaGtleSwKCUxQV1NUUglscHN6Q2xhc3MsCglMUERXT1JECWxwY2NoQ2xhc3MsCglMUERXT1JECWxwZHdSZXNlcnZlZCwKCUxQRFdPUkQJbHBjU3ViS2V5cywKCUxQRFdPUkQJbHBjY2hNYXhTdWJrZXksCglMUERXT1JECWxwY2NoTWF4Q2xhc3MsCglMUERXT1JECWxwY1ZhbHVlcywKCUxQRFdPUkQJbHBjY2hNYXhWYWx1ZU5hbWUsCglMUERXT1JECWxwY2NiTWF4VmFsdWVEYXRhLAoJTFBEV09SRAlscGNiU2VjdXJpdHlEZXNjcmlwdG9yLAoJRklMRVRJTUUJKmZ0CikgewoJTFBLRVlTVFJVQ1QJbHBrZXksbHB4a2V5OwoJaW50CQlucm9ma2V5cyxtYXhzdWJrZXksbWF4Y2xhc3MsbWF4dmFsdWVzLG1heHZuYW1lLG1heHZkYXRhOwoJaW50CQlpOwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnUXVlcnlJbmZvS2V5MzJXKCV4LC4uLi4uLilcbiIsaGtleSk7CglscGtleT1sb29rdXBfaGtleShoa2V5KTsKCWlmICghbHBrZXkpCgkJcmV0dXJuIFNIRUxMX0VSUk9SX0JBREtFWTsKCWlmIChscHN6Q2xhc3MpIHsKCQlpZiAobHBrZXktPmNsYXNzKSB7CgkJCWlmIChsc3RybGVuMzJXKGxwa2V5LT5jbGFzcykqMisyPipscGNjaENsYXNzKSB7CgkJCQkqbHBjY2hDbGFzcz1sc3RybGVuMzJXKGxwa2V5LT5jbGFzcykqMjsKCQkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJCX0KCQkJKmxwY2NoQ2xhc3M9bHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjI7CgkJCW1lbWNweShscHN6Q2xhc3MsbHBrZXktPmNsYXNzLGxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSk7CgkJfSBlbHNlIHsKCQkJKmxwc3pDbGFzcwk9IDA7CgkJCSpscGNjaENsYXNzCT0gMDsKCQl9Cgl9IGVsc2UgewoJCWlmIChscGNjaENsYXNzKQoJCQkqbHBjY2hDbGFzcwk9IGxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyOwoJfQoJbHB4a2V5PWxwa2V5LT5uZXh0c3ViOwoJbnJvZmtleXM9bWF4c3Via2V5PW1heGNsYXNzPW1heHZhbHVlcz1tYXh2bmFtZT1tYXh2ZGF0YT0wOwoJd2hpbGUgKGxweGtleSkgewoJCW5yb2ZrZXlzKys7CgkJaWYgKGxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKT5tYXhzdWJrZXkpCgkJCW1heHN1YmtleT1sc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSk7CgkJaWYgKGxweGtleS0+Y2xhc3MgJiYgbHN0cmxlbjMyVyhscHhrZXktPmNsYXNzKT5tYXhjbGFzcykKCQkJbWF4Y2xhc3M9bHN0cmxlbjMyVyhscHhrZXktPmNsYXNzKTsKCQlpZiAobHB4a2V5LT5ucm9mdmFsdWVzPm1heHZhbHVlcykKCQkJbWF4dmFsdWVzPWxweGtleS0+bnJvZnZhbHVlczsKCQlmb3IgKGk9MDtpPGxweGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQkJTFBLRVlWQUxVRQl2YWw9bHB4a2V5LT52YWx1ZXMraTsKCgkJCWlmICh2YWwtPm5hbWUgJiYgbHN0cmxlbjMyVyh2YWwtPm5hbWUpPm1heHZuYW1lKQoJCQkJbWF4dm5hbWU9bHN0cmxlbjMyVyh2YWwtPm5hbWUpOwoJCQlpZiAodmFsLT5sZW4+bWF4dmRhdGEpCgkJCQltYXh2ZGF0YT12YWwtPmxlbjsKCQl9CgkJbHB4a2V5PWxweGtleS0+bmV4dDsKCX0KCWlmICghbWF4Y2xhc3MpIG1heGNsYXNzCT0gMTsKCWlmICghbWF4dm5hbWUpIG1heHZuYW1lCT0gMTsKCWlmIChscGNTdWJLZXlzKQoJCSpscGNTdWJLZXlzCT0gbnJvZmtleXM7CglpZiAobHBjY2hNYXhTdWJrZXkpCgkJKmxwY2NoTWF4U3Via2V5CT0gbWF4c3Via2V5KjI7CglpZiAobHBjY2hNYXhDbGFzcykKCQkqbHBjY2hNYXhDbGFzcwk9IG1heGNsYXNzKjI7CglpZiAobHBjVmFsdWVzKQoJCSpscGNWYWx1ZXMJPSBtYXh2YWx1ZXM7CglpZiAobHBjY2hNYXhWYWx1ZU5hbWUpCgkJKmxwY2NoTWF4VmFsdWVOYW1lPSBtYXh2bmFtZTsKCWlmIChscGNjYk1heFZhbHVlRGF0YSkKCQkqbHBjY2JNYXhWYWx1ZURhdGE9IG1heHZkYXRhOwoJcmV0dXJuIFNIRUxMX0VSUk9SX1NVQ0NFU1M7Cn0KCi8qIFJlZ1F1ZXJ5SW5mb0tleUEJCVtBRFZBUEkzMi4xNTJdICovCkRXT1JEIFJlZ1F1ZXJ5SW5mb0tleTMyQSgKCUhLRVkJaGtleSwKCUxQU1RSCWxwc3pDbGFzcywKCUxQRFdPUkQJbHBjY2hDbGFzcywKCUxQRFdPUkQJbHBkd1Jlc2VydmVkLAoJTFBEV09SRAlscGNTdWJLZXlzLAoJTFBEV09SRAlscGNjaE1heFN1YmtleSwKCUxQRFdPUkQJbHBjY2hNYXhDbGFzcywKCUxQRFdPUkQJbHBjVmFsdWVzLAoJTFBEV09SRAlscGNjaE1heFZhbHVlTmFtZSwKCUxQRFdPUkQJbHBjY2JNYXhWYWx1ZURhdGEsCglMUERXT1JECWxwY2JTZWN1cml0eURlc2NyaXB0b3IsCglGSUxFVElNRQkqZnQKKSB7CglMUFdTVFIJCWxwc3pDbGFzc1c7CglEV09SRAkJcmV0OwoKCWRwcmludGZfcmVnKHN0ZGRlYiwiUmVnUXVlcnlJbmZvS2V5MzJBKCV4LC4uLi4uLilcbiIsaGtleSk7CglpZiAobHBzekNsYXNzKSB7CgkJKmxwY2NoQ2xhc3MqPSAyOwoJCWxwc3pDbGFzc1cgID0gKExQV1NUUil4bWFsbG9jKCpscGNjaENsYXNzKTsKCgl9IGVsc2UKCQlscHN6Q2xhc3NXICA9IE5VTEw7CglyZXQ9UmVnUXVlcnlJbmZvS2V5MzJXKAoJCWhrZXksCgkJbHBzekNsYXNzVywKCQlscGNjaENsYXNzLAoJCWxwZHdSZXNlcnZlZCwKCQlscGNTdWJLZXlzLAoJCWxwY2NoTWF4U3Via2V5LAoJCWxwY2NoTWF4Q2xhc3MsCgkJbHBjVmFsdWVzLAoJCWxwY2NoTWF4VmFsdWVOYW1lLAoJCWxwY2NiTWF4VmFsdWVEYXRhLAoJCWxwY2JTZWN1cml0eURlc2NyaXB0b3IsCgkJZnQKCSk7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTKQoJCWxzdHJjcHlXdG9BKGxwc3pDbGFzcyxscHN6Q2xhc3NXKTsKCWlmIChscGNjaENsYXNzKQoJCSpscGNjaENsYXNzLz0yOwoJaWYgKGxwY2NoTWF4U3Via2V5KQoJCSpscGNjaE1heFN1YmtleS89MjsKCWlmIChscGNjaE1heENsYXNzKQoJCSpscGNjaE1heENsYXNzLz0yOwoJaWYgKGxwY2NoTWF4VmFsdWVOYW1lKQoJCSpscGNjaE1heFZhbHVlTmFtZS89MjsKCWlmIChscHN6Q2xhc3NXKQoJCWZyZWUobHBzekNsYXNzVyk7CglyZXR1cm4gcmV0Owp9Ci8qIFJlZ0Nvbm5lY3RSZWdpc3RyeUEJCVtBRFZBUEkzMi4xMjddICovCkRXT1JEIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyQShMUENTVFIgbWFjaGluZSxIS0VZIGhrZXksTFBIS0VZIHJlc2tleSkgewoJZnByaW50ZihzdGRlcnIsIlJlZ0Nvbm5lY3RSZWdpc3RyeTMyQSglcywlMDh4LCVwKSwgU1RVQi5cbiIsCgkJbWFjaGluZSxoa2V5LHJlc2tleQoJKTsKCXJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsgLyogRklYTUUgKi8KfQo=