LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpZmRlZiBIQVZFX1NZU19FUlJOT19ICiNpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmUvd2luZXN0cmluZy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgImRlYnVndG9vbHMuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIm9wdGlvbnMuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAic2VydmVyLmgiCiNpbmNsdWRlICJzZXJ2aWNlcy5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKHJlZykKCnN0YXRpYyB2b2lkIFJFR0lTVFJZX0luaXQodm9pZCk7Ci8qIEZJWE1FOiBmb2xsb3dpbmcgZGVmaW5lcyBzaG91bGQgYmUgY29uZmlndXJlZCBnbG9iYWwgLi4uICovCgovKiBOT1RFOiBkbyBub3QgYXBwZW5kIGEgLy4gbGludXgnIG1rZGlyKCkgV0lMTCBGQUlMIGlmIHlvdSBkbyB0aGF0ICovCiNkZWZpbmUgV0lORV9QUkVGSVggICAgICAgICAgICAgICAgICIvLndpbmUiCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUICAgICAgICAgIEVUQ0RJUiIvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUICBFVENESVIiL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0NVUlJFTlRfVVNFUiAgICAgICAgICAgInVzZXIucmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCAgICAid2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORSAgICAgICAgICAic3lzdGVtLnJlZyIKCiNkZWZpbmUgS0VZX1JFR0lTVFJZICAgICAgICAgICAgICAgICJTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnkiCiNkZWZpbmUgVkFMX1NBVkVVUERBVEVEICAgICAgICAgICAgICJTYXZlT25seVVwZGF0ZWRLZXlzIgoKCi8qIHdoYXQgdmFsdWV0eXBlcyBkbyB3ZSBuZWVkIHRvIGNvbnZlcnQ/ICovCiNkZWZpbmUgVU5JQ09OVk1BU0sJKCgxPDxSRUdfU1opfCgxPDxSRUdfTVVMVElfU1opfCgxPDxSRUdfRVhQQU5EX1NaKSkKCgoKLyoKICogUVVFU1RJT04KICogICBBcmUgdGhlc2UgZG9pbmcgdGhlIHNhbWUgYXMgSEVBUF9zdHJkdXBBdG9XIGFuZCBIRUFQX3N0cmR1cFd0b0E/CiAqICAgSWYgc28sIGNhbiB3ZSByZW1vdmUgdGhlbT8KICogQU5TV0VSCiAqICAgTm8sIHRoZSBtZW1vcnkgaGFuZGxpbmcgZnVuY3Rpb25zIGFyZSBjYWxsZWQgdmVyeSBvZnRlbiBpbiBoZXJlLCAKICogICBqdXN0IHJlcGxhY2luZyB0aGVtIGJ5IEhlYXBBbGxvYyhTeXN0ZW1IZWFwLC4uLikgbWFrZXMgcmVnaXN0cnkKICogICBsb2FkaW5nIDEwMCB0aW1lcyBzbG93ZXIuIC1NTQogKi8Kc3RhdGljIExQV1NUUiBzdHJkdXBBMlcoTFBDU1RSIHNyYykKewogICAgaWYoc3JjKSB7CglMUFdTVFIgZGVzdD14bWFsbG9jKDIqc3RybGVuKHNyYykrMik7Cglsc3RyY3B5QXRvVyhkZXN0LHNyYyk7CglyZXR1cm4gZGVzdDsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgpMUFdTVFIgc3RyY3Z0QTJXKExQQ1NUUiBzcmMsIGludCBuY2hhcnMpCgp7CiAgIExQV1NUUiBkZXN0ID0geG1hbGxvYyAoMiAqIG5jaGFycyArIDIpOwoKICAgbHN0cmNweW5BdG9XKGRlc3Qsc3JjLG5jaGFycysxKTsKICAgcmV0dXJuIGRlc3Q7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSRUdJU1RSWV9Jbml0IFtJbnRlcm5hbF0KICogUmVnaXN0cnkgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBzb21lIGRlZmF1bHQga2V5cy4gCiAqLwpzdGF0aWMgdm9pZCBSRUdJU1RSWV9Jbml0KHZvaWQpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJVFJBQ0UoIih2b2lkKVxuIik7CgoJUmVnQ3JlYXRlS2V5QShIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXhBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3cgTlRcXEN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRCdWlsZE51bWJlcgoJICoJCQkJCQlDdXJyZW50VHlwZQoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3duZXIKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE9yZ2FuaXphdGlvbgoJICoKCSAqLwoJLyogU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXFNOTVBcXFBhcmFtZXRlcnNcXFJGQzExNTZBZ2VudAoJICogCQkJCQlzdHJpbmcJU3lzQ29udGFjdAoJICogCQkJCQlzdHJpbmcJU3lzTG9jYXRpb24KCSAqIAkJCQkJCVN5c1NlcnZpY2VzCgkgKi8KCWlmICgtMSE9Z2V0aG9zdG5hbWUoYnVmLDIwMCkpIHsKCQlSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcQ29tcHV0ZXJOYW1lXFxDb21wdXRlck5hbWUiLCZoa2V5KTsKCQlSZWdTZXRWYWx1ZUV4QShoa2V5LCJDb21wdXRlck5hbWUiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSsxKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKiogU0FWRSBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBSRUdJU1RSWV9TQVZFX1ZFUlNJT04JMHgwMDAwMDAwMQoKLyogUmVnaXN0cnkgc2F2ZWZvcm1hdDoKICogSWYgeW91IGNoYW5nZSBpdCwgaW5jcmVhc2UgYWJvdmUgbnVtYmVyIGJ5IDEsIHdoaWNoIHdpbGwgZmx1c2gKICogb2xkIHJlZ2lzdHJ5IGRhdGFiYXNlIGZpbGVzLgogKiAKICogR2xvYmFsOgogKiAJIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIKICogCXN1YmtleXMuLi4uCiAqIFN1YmtleXM6CiAqIAlrZXluYW1lCiAqCQl2YWx1ZW5hbWU9bGFzdG1vZGlmaWVkLHR5cGUsZGF0YQogKgkJLi4uCiAqCQlzdWJrZXlzCiAqCS4uLgogKiBrZXluYW1lLHZhbHVlbmFtZSxzdHJpbmdkYXRhOgogKgl0aGUgdXN1YWwgYXNjaWkgY2hhcmFjdGVycyBmcm9tIDB4MDAtMHhmZiAod2VsbCwgbm90IDB4MDApCiAqCWFuZCBcdVhYWFggYXMgVU5JQ09ERSB2YWx1ZSBYWFhYIHdpdGggWFhYWD4weGZmCiAqCSggIj1cXFx0IiBlc2NhcGVkIGluIFx1WFhYWCBmb3JtLikKICogdHlwZSxsYXN0bW9kaWZpZWQ6IAogKglpbnQKICogCiAqIEZJWE1FOiBkb2Vzbid0IHNhdmUgJ2NsYXNzJyAod2hhdCBkb2VzIGl0IG1lYW4gYW55d2F5PyksIG5vciBmbGFncy4KICoKICogW0hLRVlfQ1VSUkVOVF9VU0VSXFxTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnldCiAqIFNhdmVPbmx5VXBkYXRlZEtleXM9eWVzCiAqLwoKLyogU2FtZSBhcyBSZWdTYXZlS2V5IGJ1dCB3aXRoIFVuaXggcGF0aG5hbWVzICovCnN0YXRpYyB2b2lkIHNhdmVfa2V5KCBIS0VZIGhrZXksIGNvbnN0IGNoYXIgKmZpbGVuYW1lICkKewogICAgc3RydWN0IHNhdmVfcmVnaXN0cnlfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKICAgIGludCBjb3VudCA9IDA7CiAgICBEV09SRCByZXQ7CiAgICBIQU5ETEUgaGFuZGxlOwogICAgY2hhciAqcDsKICAgIGNoYXIgKm5hbWUgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihmaWxlbmFtZSkgKyAyMCApOwoKICAgIGlmICghbmFtZSkgcmV0dXJuOwogICAgc3RyY3B5KCBuYW1lLCBmaWxlbmFtZSApOwogICAgaWYgKChwID0gc3RycmNociggbmFtZSwgJy8nICkpKSBwKys7CiAgICBlbHNlIHAgPSBuYW1lOwoKICAgIGZvciAoOzspCiAgICB7CiAgICAgICAgc3ByaW50ZiggcCwgInJlZyUwNHgudG1wIiwgY291bnQrKyApOwogICAgICAgIGhhbmRsZSA9IEZJTEVfQ3JlYXRlRmlsZSggbmFtZSwgR0VORVJJQ19XUklURSwgMCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENSRUFURV9ORVcsIEZJTEVfQVRUUklCVVRFX05PUk1BTCwgLTEgKTsKICAgICAgICBpZiAoaGFuZGxlICE9IElOVkFMSURfSEFORExFX1ZBTFVFKSBicmVhazsKICAgICAgICBpZiAoKHJldCA9IEdldExhc3RFcnJvcigpKSAhPSBFUlJPUl9GSUxFX0VYSVNUUykgYnJlYWs7CiAgICB9CgogICAgaWYgKGhhbmRsZSAhPSBJTlZBTElEX0hBTkRMRV9WQUxVRSkKICAgIHsKICAgICAgICByZXEtPmhrZXkgPSBoa2V5OwogICAgICAgIHJlcS0+ZmlsZSA9IGhhbmRsZTsKICAgICAgICByZXQgPSBzZXJ2ZXJfY2FsbF9ub2VyciggUkVRX1NBVkVfUkVHSVNUUlkgKTsKICAgICAgICBDbG9zZUhhbmRsZSggaGFuZGxlICk7CiAgICAgICAgaWYgKHJldCkgdW5saW5rKCBuYW1lICk7CiAgICAgICAgZWxzZSBpZiAocmVuYW1lKCBuYW1lLCBmaWxlbmFtZSApID09IC0xKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCAiRmFpbGVkIHRvIG1vdmUgJXMgdG8gJXM6ICIsIG5hbWUsIGZpbGVuYW1lICk7CiAgICAgICAgICAgIHBlcnJvciggInJlbmFtZSIgKTsKICAgICAgICAgICAgdW5saW5rKCBuYW1lICk7CiAgICAgICAgfQogICAgfQogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIG5hbWUgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfU2F2ZVJlZ2lzdHJ5QnJhbmNoIFtJbnRlcm5hbF0KICoKICogU2F2ZXMgbWFpbiByZWdpc3RyeSBicmFuY2ggc3BlY2lmaWVkIGJ5IGhrZXkuCiAqLwpzdGF0aWMgdm9pZCBTSEVMTF9TYXZlUmVnaXN0cnlCcmFuY2goSEtFWSBoa2V5KQp7CiAgICBjaGFyICAgKmZuLCAqaG9tZTsKCiAgICAvKiBGaW5kIG91dCB3aGF0IHRvIHNhdmUgdG8sIGdldCBmcm9tIGNvbmZpZyBmaWxlICovCiAgICBCT09MIHdyaXRlVG9Ib21lID0gUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgicmVnaXN0cnkiLCJXcml0ZXRvSG9tZVJlZ2lzdHJpZXMiLDEpOwogICAgQk9PTCB3cml0ZVRvQWx0ID0gUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgicmVnaXN0cnkiLCJXcml0ZXRvQWx0UmVnaXN0cmllcyIsMSk7CgogICAgLyogRklYTUU6IGRvZXMgdGhpcyBjaGVjayBhcHBseSB0byBhbGwga2V5cyB3cml0dGVuIGJlbG93ID8gKi8KICAgIGlmICghKGhvbWUgPSBnZXRlbnYoICJIT01FIiApKSkKICAgICAgICBFUlIoIkZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWxkLlxuIiwobG9uZykgZ2V0dWlkKCkpOwoKICAgIC8qIEhLRVlfTE9DQUxfTUFDSElORSBjb250YWlucyB0aGUgSEtFWV9DTEFTU0VTX1JPT1QgYnJhbmNoICovCiAgICBpZiAoaGtleSA9PSBIS0VZX0NMQVNTRVNfUk9PVCkgaGtleSA9IEhLRVlfTE9DQUxfTUFDSElORTsKCiAgICBzd2l0Y2ggKGhrZXkpCiAgICB7CiAgICBjYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgogICAgICAgIGZuID0geG1hbGxvYyggTUFYX1BBVEhOQU1FX0xFTiApOyAKICAgICAgICBpZiAod3JpdGVUb0FsdCAmJiBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJyZWdpc3RyeSIsICJBbHRDdXJyZW50VXNlckZpbGUiLCAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZuLCBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpCiAgICAgICAgICAgIHNhdmVfa2V5KCBIS0VZX0NVUlJFTlRfVVNFUiwgZm4gKTsKICAgICAgICBmcmVlIChmbik7CgogICAgICAgIGlmIChob21lICYmIHdyaXRlVG9Ib21lKQogICAgICAgIHsKICAgICAgICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfQ1VSUkVOVF9VU0VSKSArIDIgKTsKICAgICAgICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICAgICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgpOwogIAogICAgICAgICAgICAvKiBjcmVhdGUgdGhlIGRpcmVjdG9yeS4gZG9uJ3QgY2FyZSBhYm91dCBlcnJvcmNvZGVzLiAqLwogICAgICAgICAgICBta2RpcihmbiwwNzU1KTsgLyogZHJ3eHIteHIteCAqLwogICAgICAgICAgICBzdHJjYXQoZm4sIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwogICAgICAgICAgICBzYXZlX2tleSggSEtFWV9DVVJSRU5UX1VTRVIsIGZuICk7CiAgICAgICAgICAgIGZyZWUoZm4pOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgogICAgICAgIC8qIFRyeSBmaXJzdCBzYXZpbmcgYWNjb3JkaW5nIHRvIHRoZSBkZWZpbmVkIGxvY2F0aW9uIGluIC53aW5lcmMgKi8KICAgICAgICBmbiA9IHhtYWxsb2MgKCBNQVhfUEFUSE5BTUVfTEVOKTsKICAgICAgICBpZiAod3JpdGVUb0FsdCAmJiBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJSZWdpc3RyeSIsICJBbHRMb2NhbE1hY2hpbmVGaWxlIiwgIiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm4sIE1BWF9QQVRITkFNRV9MRU4gLSAxKSkKICAgICAgICAgICAgc2F2ZV9rZXkoIEhLRVlfTE9DQUxfTUFDSElORSwgZm4gKTsKICAgICAgICBmcmVlIChmbik7CgogICAgICAgIGlmIChob21lICYmIHdyaXRlVG9Ib21lKQogICAgICAgIHsKICAgICAgICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfTE9DQUxfTUFDSElORSkgKyAyKTsKICAgICAgICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICAgICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwogICAgICAgICAgICBzYXZlX2tleSggSEtFWV9MT0NBTF9NQUNISU5FLCBmbiApOwogICAgICAgICAgICBmcmVlKGZuKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEhLRVlfVVNFUlM6CiAgICAgICAgZm4gPSB4bWFsbG9jKCBNQVhfUEFUSE5BTUVfTEVOICk7CiAgICAgICAgaWYgKHdyaXRlVG9BbHQgJiYgUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiUmVnaXN0cnkiLCAiQWx0VXNlckZpbGUiLCAiIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiwgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKQogICAgICAgICAgICBzYXZlX2tleSggSEtFWV9VU0VSUywgZm4gKTsKICAgICAgICBmcmVlIChmbik7CgogICAgICAgIGlmIChob21lICYmIHdyaXRlVG9Ib21lKQogICAgICAgIHsKICAgICAgICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCkgKyAyKTsKICAgICAgICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICAgICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpOwogICAgICAgICAgICBzYXZlX2tleSggSEtFWV9VU0VSUywgZm4gKTsKICAgICAgICAgICAgZnJlZShmbik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBFUlIoInVua25vd24vaW52YWxpZCBrZXkgaGFuZGxlICFcbiIpOwogICAgICAgIGJyZWFrOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEVMTF9TYXZlUmVnaXN0cnkgW0ludGVybmFsXQogKi8Kdm9pZCBTSEVMTF9TYXZlUmVnaXN0cnkoIHZvaWQgKQp7CiAgICBzdHJ1Y3Qgc2V0X3JlZ2lzdHJ5X2xldmVsc19yZXF1ZXN0ICpyZXEgPSBnZXRfcmVxX2J1ZmZlcigpOwogICAgY2hhciAgIGJ1Zls0XTsKICAgIEhLRVkgICBoa2V5OwogICAgaW50ICAgIGFsbDsKCiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICBhbGw9MDsKICAgIGlmIChSZWdPcGVuS2V5QShIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpIT1FUlJPUl9TVUNDRVNTKSAKICAgIHsKICAgICAgICBzdHJjcHkoYnVmLCJ5ZXMiKTsKICAgIH0gCiAgICBlbHNlIAogICAgewogICAgICAgIERXT1JEIGxlbixqdW5rLHR5cGU7CgogICAgICAgIGxlbj00OwogICAgICAgIGlmICgoRVJST1JfU1VDQ0VTUyE9UmVnUXVlcnlWYWx1ZUV4QSggaGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBTF9TQVZFVVBEQVRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZqdW5rLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbGVuKSkgfHwgKHR5cGUhPVJFR19TWikpCiAgICAgICAgewogICAgICAgICAgICBzdHJjcHkoYnVmLCJ5ZXMiKTsKICAgICAgICB9CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICB9CgogICAgaWYgKGxzdHJjbXBpQShidWYsInllcyIpKSBhbGwgPSAxOwoKICAgIC8qIHNldCBzYXZpbmcgbGV2ZWwgKDAgZm9yIHNhdmluZyBldmVyeXRoaW5nLCAxIGZvciBzYXZpbmcgb25seSBtb2RpZmllZCBrZXlzKSAqLwogICAgcmVxLT5jdXJyZW50ID0gMTsKICAgIHJlcS0+c2F2aW5nICA9ICFhbGw7CiAgICByZXEtPnZlcnNpb24gPSBQUk9GSUxFX0dldFdpbmVJbmlCb29sKCAicmVnaXN0cnkiLCAiVXNlTmV3Rm9ybWF0IiwgMCApID8gMiA6IDE7CiAgICBzZXJ2ZXJfY2FsbCggUkVRX1NFVF9SRUdJU1RSWV9MRVZFTFMgKTsKCiAgICBTSEVMTF9TYXZlUmVnaXN0cnlCcmFuY2goSEtFWV9DVVJSRU5UX1VTRVIpOwogICAgU0hFTExfU2F2ZVJlZ2lzdHJ5QnJhbmNoKEhLRVlfTE9DQUxfTUFDSElORSk7CiAgICBTSEVMTF9TYXZlUmVnaXN0cnlCcmFuY2goSEtFWV9VU0VSUyk7Cn0KCi8qIFBlcmlvZGljIHNhdmUgY2FsbGJhY2sgKi8Kc3RhdGljIHZvaWQgQ0FMTEJBQ0sgcGVyaW9kaWNfc2F2ZSggVUxPTkdfUFRSIGR1bW15ICkKewogICAgU0hFTExfU2F2ZVJlZ2lzdHJ5KCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKiogTE9BRCBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF9rZXkgW0ludGVybmFsXQogKi8Kc3RhdGljIGlubGluZSBIS0VZIF9maW5kX29yX2FkZF9rZXkoIEhLRVkgaGtleSwgTFBXU1RSIGtleW5hbWUgKQp7CiAgICBIS0VZIHN1YmtleTsKICAgIGlmIChSZWdDcmVhdGVLZXlXKCBoa2V5LCBrZXluYW1lLCAmc3Via2V5ICkgIT0gRVJST1JfU1VDQ0VTUykgc3Via2V5ID0gMDsKICAgIGlmIChrZXluYW1lKSBmcmVlKCBrZXluYW1lICk7CiAgICByZXR1cm4gc3Via2V5Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF92YWx1ZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfZmluZF9vcl9hZGRfdmFsdWUoIEhLRVkgaGtleSwgTFBXU1RSIG5hbWUsIERXT1JEIHR5cGUsIExQQllURSBkYXRhLCBEV09SRCBsZW4gKQp7CiAgICBSZWdTZXRWYWx1ZUV4VyggaGtleSwgbmFtZSwgMCwgdHlwZSwgZGF0YSwgbGVuICk7CiAgICBpZiAobmFtZSkgZnJlZSggbmFtZSApOwogICAgaWYgKGRhdGEpIGZyZWUoIGRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9saW5lIFtJbnRlcm5hbF0KICoKICogcmVhZHMgYSBsaW5lIGluY2x1ZGluZyBkeW5hbWljYWxseSBlbmxhcmdpbmcgdGhlIHJlYWRidWZmZXIgYW5kIHRocm93aW5nCiAqIGF3YXkgY29tbWVudHMKICovCnN0YXRpYyBpbnQgX3dpbmVfcmVhZF9saW5lKCBGSUxFICpGLCBjaGFyICoqYnVmLCBpbnQgKmxlbiApCnsKCWNoYXIJKnMsKmN1cnJlYWQ7CglpbnQJbXlsZW4sY3Vyb2ZmOwoKCWN1cnJlYWQJPSAqYnVmOwoJbXlsZW4JPSAqbGVuOwoJKipidWYJPSAnXDAnOwoJd2hpbGUgKDEpIHsKCQl3aGlsZSAoMSkgewoJCQlzPWZnZXRzKGN1cnJlYWQsbXlsZW4sRik7CgkJCWlmIChzPT1OVUxMKQoJCQkJcmV0dXJuIDA7IC8qIEVPRiAqLwoJCQlpZiAoTlVMTD09KHM9c3RyY2hyKGN1cnJlYWQsJ1xuJykpKSB7CgkJCQkvKiBidWZmZXIgd2Fzbid0IGxhcmdlIGVub3VnaCAqLwoJCQkJY3Vyb2ZmCT0gc3RybGVuKCpidWYpOwoJCQkJKmJ1Zgk9IHhyZWFsbG9jKCpidWYsKmxlbioyKTsKCQkJCWN1cnJlYWQJPSAqYnVmICsgY3Vyb2ZmOwoJCQkJbXlsZW4JPSAqbGVuOwkvKiB3ZSBmaWxsZWQgdXAgdGhlIGJ1ZmZlciBhbmQgCgkJCQkJCSAqIGdvdCBuZXcgJypsZW4nIGJ5dGVzIHRvIGZpbGwKCQkJCQkJICovCgkJCQkqbGVuCT0gKmxlbiAqIDI7CgkJCX0gZWxzZSB7CgkJCQkqcz0nXDAnOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLyogdGhyb3cgYXdheSBjb21tZW50cyAqLwoJCWlmICgqKmJ1Zj09JyMnIHx8ICoqYnVmPT0nOycpIHsKCQkJY3VycmVhZAk9ICpidWY7CgkJCW15bGVuCT0gKmxlbjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzKSAJLyogZ290IGVuZCBvZiBsaW5lICovCgkJCWJyZWFrOwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfVVNUUklORyBbSW50ZXJuYWxdCiAqCiAqIGNvbnZlcnRzIGEgY2hhciogaW50byBhIFVOSUNPREUgc3RyaW5nICh1cCB0byBhIHNwZWNpYWwgY2hhcikKICogYW5kIHJldHVybnMgdGhlIHBvc2l0aW9uIGV4YWN0bHkgYWZ0ZXIgdGhhdCBzdHJpbmcKICovCnN0YXRpYyBjaGFyKiBfd2luZV9yZWFkX1VTVFJJTkcoIGNoYXIgKmJ1ZiwgTFBXU1RSICpzdHIgKQp7CgljaGFyCSpzOwoJTFBXU1RSCXdzOwoKCS8qIHJlYWQgdXAgdG8gIj0iIG9yICJcMCIgb3IgIlxuIiAqLwoJcwk9IGJ1ZjsKCSpzdHIJPSAoTFBXU1RSKXhtYWxsb2MoMipzdHJsZW4oYnVmKSsyKTsKCXdzCT0gKnN0cjsKCXdoaWxlICgqcyAmJiAoKnMhPSdcbicpICYmICgqcyE9Jz0nKSkgewoJCWlmICgqcyE9J1xcJykKCQkJKndzKys9KigodW5zaWduZWQgY2hhciopcysrKTsKCQllbHNlIHsKCQkJcysrOwoJCQlpZiAoISpzKSB7CgkJCQkvKiBEYW5nbGluZyBcIC4uLiBtYXkgb25seSBoYXBwZW4gaWYgYSByZWdpc3RyeQoJCQkJICogd3JpdGUgd2FzIHNob3J0LiBGSVhNRTogV2hhdCBkbyB0bz8KCQkJCSAqLwoJCQkJIGJyZWFrOwoJCQl9CgkJCWlmICgqcz09J1xcJykgewoJCQkJKndzKys9J1xcJzsKCQkJCXMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWlmICgqcyE9J3UnKSB7CgkJCQlXQVJOKCJOb24gdW5pY29kZSBlc2NhcGUgc2VxdWVuY2UgXFwlYyBmb3VuZCBpbiB8JXN8XG4iLCpzLGJ1Zik7CgkJCQkqd3MrKz0nXFwnOwoJCQkJKndzKys9KnMrKzsKCQkJfSBlbHNlIHsKCQkJCWNoYXIJeGJ1Zls1XTsKCQkJCWludAl3YzsKCgkJCQlzKys7CgkJCQltZW1jcHkoeGJ1ZixzLDQpO3hidWZbNF09J1wwJzsKCQkJCWlmICghc3NjYW5mKHhidWYsIiV4Iiwmd2MpKQoJCQkJCVdBUk4oIlN0cmFuZ2UgZXNjYXBlIHNlcXVlbmNlICVzIGZvdW5kIGluIHwlc3xcbiIseGJ1ZixidWYpOwoJCQkJcys9NDsKCQkJCSp3cysrCT0odW5zaWduZWQgc2hvcnQpd2M7CgkJCX0KCQl9Cgl9Cgkqd3MJPSAwOwoJcmV0dXJuIHM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJrZXkgW0ludGVybmFsXQogKgogKiBOT1RFUwogKiAgICBJdCBzZWVtcyBsaWtlIHRoaXMgaXMgcmV0dXJuaW5nIGEgYm9vbGVhbi4gIFNob3VsZCBpdD8KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiAxCiAqICAgIEZhaWx1cmU6IDAKICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YmtleSggRklMRSAqRiwgSEtFWSBoa2V5LCBpbnQgbGV2ZWwsIGNoYXIgKipidWYsIGludCAqYnVmbGVuICkKewogICAgCUhLRVkgc3Via2V5OwoJaW50CQlpOwoJY2hhcgkJKnM7CglMUFdTVFIJCW5hbWU7CgogICAgVFJBQ0UoIiglcCwleCwlZCwlcywlZClcbiIsIEYsIGhrZXksIGxldmVsLCBkZWJ1Z3N0cl9hKCpidWYpLCAqYnVmbGVuKTsKCiAgICAvKiBHb29kLiAgV2UgYWxyZWFkeSBnb3QgYSBsaW5lIGhlcmUgLi4uIHNvIHBhcnNlIGl0ICovCiAgICBzdWJrZXkgPSAwOwogICAgd2hpbGUgKDEpIHsKICAgICAgICBpPTA7cz0qYnVmOwogICAgICAgIHdoaWxlICgqcz09J1x0JykgewogICAgICAgICAgICBzKys7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9CiAgICAgICAgaWYgKGk+bGV2ZWwpIHsKICAgICAgICAgICAgaWYgKCFzdWJrZXkpIHsKICAgICAgICAgICAgICAgIFdBUk4oIkdvdCBhIHN1YmhpZXJhcmNoeSB3aXRob3V0IHJlc3AuIGtleT9cbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCSAgICBpZiAoIV93aW5lX2xvYWRzdWJrZXkoRixzdWJrZXksbGV2ZWwrMSxidWYsYnVmbGVuKSkKCSAgICAgICBpZiAoIV93aW5lX3JlYWRfbGluZShGLGJ1ZixidWZsZW4pKQoJCSAgZ290byBkb25lOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoJCS8qIGxldCB0aGUgY2FsbGVyIGhhbmRsZSB0aGlzIGxpbmUgKi8KCQlpZiAoaTxsZXZlbCB8fCAqKmJ1Zj09J1wwJykKCQkJZ290byBkb25lOwoKCQkvKiBpdCBjYW4gYmU6IGEgdmFsdWUgb3IgYSBrZXluYW1lLiBQYXJzZSB0aGUgbmFtZSBmaXJzdCAqLwoJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsJm5hbWUpOwoKCQkvKiBzd2l0Y2goKSBkZWZhdWx0OiBoYWNrIHRvIGF2b2lkIGdvdG9zICovCgkJc3dpdGNoICgwKSB7CgkJZGVmYXVsdDoKCQkJaWYgKCpzPT0nXDAnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwoJCQkJc3Via2V5PV9maW5kX29yX2FkZF9rZXkoaGtleSxuYW1lKTsKCQkJfSBlbHNlIHsKCQkJCUxQQllURQkJZGF0YTsKCQkJCWludAkJbGVuLGxhc3Rtb2RpZmllZCx0eXBlOwoKCQkJCWlmICgqcyE9Jz0nKSB7CgkJCQkJV0FSTigiVW5leHBlY3RlZCBjaGFyYWN0ZXI6ICVjXG4iLCpzKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCXMrKzsKCQkJCWlmICgyIT1zc2NhbmYocywiJWQsJWQsIiwmdHlwZSwmbGFzdG1vZGlmaWVkKSkgewoJCQkJCVdBUk4oIkhhdmVuJ3QgdW5kZXJzdG9vZCBwb3NzaWJsZSB2YWx1ZSBpbiB8JXN8LCBza2lwcGluZy5cbiIsKmJ1Zik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQkvKiBza2lwIHRoZSAyICwgKi8KCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlzPXN0cmNocihzLCcsJyk7CgkJCQlpZiAoIXMrKykgewoJCQkJCVdBUk4oIkhhdmVuJ3QgdW5kZXJzdG9vZCBwb3NzaWJsZSB2YWx1ZSBpbiB8JXN8LCBza2lwcGluZy5cbiIsKmJ1Zik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlpZiAodHlwZSA9PSBSRUdfU1ogfHwgdHlwZSA9PSBSRUdfRVhQQU5EX1NaKSB7CgkJCQkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywoTFBXU1RSKikmZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4gPSBsc3RybGVuVygoTFBXU1RSKWRhdGEpKjIrMjsKCQkJCX0gZWxzZSB7CgkJCQkJbGVuPXN0cmxlbihzKS8yOwoJCQkJCWRhdGEgPSAoTFBCWVRFKXhtYWxsb2MobGVuKzEpOwoJCQkJCWZvciAoaT0wO2k8bGVuO2krKykgewoJCQkJCQlkYXRhW2ldPTA7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldPSgqcy0nMCcpPDw0OwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ2EnKydceGEnKTw8NDsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV09KCpzLSdBJysnXHhhJyk8PDQ7CgkJCQkJCXMrKzsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV18PSpzLScwJzsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV18PSpzLSdhJysnXHhhJzsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV18PSpzLSdBJysnXHhhJzsKCQkJCQkJcysrOwoJCQkJCX0KCQkJCX0KCQkJCV9maW5kX29yX2FkZF92YWx1ZShoa2V5LG5hbWUsdHlwZSxkYXRhLGxlbik7CgkJCX0KCQl9CgkJLyogcmVhZCB0aGUgbmV4dCBsaW5lICovCgkJaWYgKCFfd2luZV9yZWFkX2xpbmUoRixidWYsYnVmbGVuKSkKCQkJZ290byBkb25lOwogICAgfQogZG9uZToKICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKICAgIHJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2Fkc3VicmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YnJlZyggRklMRSAqRiwgSEtFWSBoa2V5LCBjb25zdCBjaGFyICpmbiApCnsKCWludAl2ZXI7CgljaGFyCSpidWY7CglpbnQJYnVmbGVuOwoKCWJ1Zj14bWFsbG9jKDEwKTtidWZsZW49MTA7CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXNzY2FuZihidWYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAodmVyIT1SRUdJU1RSWV9TQVZFX1ZFUlNJT04pIHsKICAgICAgICAgICAgaWYgKHZlciA9PSAyKSAgLyogbmV3IHZlcnNpb24gKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSEFORExFIGZpbGU7CiAgICAgICAgICAgICAgICBpZiAoKGZpbGUgPSBGSUxFX0NyZWF0ZUZpbGUoIGZuLCBHRU5FUklDX1JFQUQsIDAsIE5VTEwsIE9QRU5fRVhJU1RJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfQVRUUklCVVRFX05PUk1BTCwgLTEgKSkgIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RydWN0IGxvYWRfcmVnaXN0cnlfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKICAgICAgICAgICAgICAgICAgICByZXEtPmhrZXkgICAgPSBoa2V5OwogICAgICAgICAgICAgICAgICAgIHJlcS0+ZmlsZSAgICA9IGZpbGU7CiAgICAgICAgICAgICAgICAgICAgcmVxLT5uYW1lWzBdID0gMDsKICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJfY2FsbCggUkVRX0xPQURfUkVHSVNUUlkgKTsKICAgICAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggZmlsZSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZnJlZSggYnVmICk7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKCQlUUkFDRSgiT2xkIGZvcm1hdCAoJWQpIHJlZ2lzdHJ5IGZvdW5kLCBpZ25vcmluZyBpdC4gKGJ1ZiB3YXMgJXMpLlxuIix2ZXIsYnVmKTsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCX0KCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfbG9hZHN1YmtleShGLGhrZXksMCwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJZnJlZShidWYpOwoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3dpbmVfbG9hZHJlZyggSEtFWSBoa2V5LCBjaGFyICpmbiApCnsKICAgIEZJTEUgKkY7CgogICAgVFJBQ0UoIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl9hKGZuKSk7CgogICAgRiA9IGZvcGVuKGZuLCJyYiIpOwogICAgaWYgKEY9PU5VTEwpIHsKICAgICAgICBXQVJOKCJDb3VsZG4ndCBvcGVuICVzIGZvciByZWFkaW5nOiAlc1xuIixmbixzdHJlcnJvcihlcnJubykgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBfd2luZV9sb2Fkc3VicmVnKEYsaGtleSxmbik7CiAgICBmY2xvc2UoRik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2ZsdXNoX3JlZ2lzdHJ5IFtJbnRlcm5hbF0KICogCiAqIFRoaXMgZnVuY3Rpb24gYWxsb3cgdG8gZmx1c2ggc2VjdGlvbiBvZiB0aGUgaW50ZXJuYWwgcmVnaXN0cnkuICBJdCBpcyBtYWlubHkKICogaW1wbGVtZW50cyB0byBmaXggYSBwcm9ibGVtIHdpdGggdGhlIGdsb2JhbCBIS1UgYW5kIHRoZSBsb2NhbCBIS1UuCiAqIFRob3NlIHR3byBmaWxlcyBhcmUgcmVhZCB0byBidWlsZCB0aGUgSEtVXC5EZWZhdWx0IGJyYW5jaCB0byBmaW5hbHkgY29weQogKiB0aGlzIGJyYW5jaCBvbnRvIEhLQ1UgaGl2ZSwgb25jZSB0aGlzIGlzIGRvbmUsIGlmIHdlIGtlZXAgdGhlIEhLVSBoaXZlIGFzIGlzLCAKICogYWxsIHRoZSBnbG9iYWwgSEtVIGFyZSBzYXZlZCBvbnRvIHRoZSB1c2VyJ3MgcGVyc29uYWwgdmVyc2lvbiBvZiBIS1UgaGl2ZS4KICogd2hpY2ggaXMgYmFkLi4uCiAqLwoKc3RhdGljIHZvaWQgX2ZsdXNoX3JlZ2lzdHJ5KCBIS0VZIGhrZXkgKQp7CiAgICBXQ0hBUiBuYW1lW01BWF9QQVRIXTsKCiAgICBmb3IgKDs7KQogICAgewogICAgICAgIEhLRVkgc3Via2V5OwogICAgICAgIC8qIEZJWE1FOiB3ZSBhc3N1bWUgdGhhdCBkZWxldGluZyBhIGtleSB3aWxsIG1vdmUgdGhlIG90aGVyIG9uZXMgdXAsICovCiAgICAgICAgLyogc28gdGhhdCB3ZSBjYW4gYWx3YXlzIHVzZSBpbmRleCAwIHVudGlsIHRoZXJlIGFyZSBubyBtb3JlIGtleXMgICAgKi8KICAgICAgICBpZiAoUmVnRW51bUtleVcoIGhrZXksIDAsIG5hbWUsIHNpemVvZihuYW1lKSApICE9IEVSUk9SX1NVQ0NFU1MpIGJyZWFrOwogICAgICAgIGlmIChSZWdPcGVuS2V5VyggaGtleSwgbmFtZSwgJnN1YmtleSApICE9IEVSUk9SX1NVQ0NFU1MpIGJyZWFrOwogICAgICAgIF9mbHVzaF9yZWdpc3RyeSggc3Via2V5ICk7CiAgICAgICAgaWYgKFJlZ0RlbGV0ZUtleVcoIHN1YmtleSwgTlVMTCApICE9IEVSUk9SX1NVQ0NFU1MpIGJyZWFrOwogICAgICAgIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2NvcHlfcmVnaXN0cnkgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX2NvcHlfcmVnaXN0cnkoIEhLRVkgZnJvbSwgSEtFWSB0byApCnsKICAgIGludCBpbmRleDsKICAgIEhLRVkgc3Via2V5OwogICAgRklMRVRJTUUgZnQ7CiAgICBEV09SRCB0eXBlLCBuYW1lX2xlbiwgbGVuOwogICAgc3RhdGljIFdDSEFSIG5hbWVbTUFYX1BBVEhdOwogICAgc3RhdGljIEJZVEUgZGF0YVsyMDQ4XTsKCiAgICAvKiBjb3B5IHZhbHVlcyAqLwogICAgaW5kZXggPSAwOwogICAgZm9yICg7OykKICAgIHsKICAgICAgICBsZW4gPSBzaXplb2YoZGF0YSk7CiAgICAgICAgbmFtZV9sZW4gPSBzaXplb2YobmFtZSk7CiAgICAgICAgaWYgKFJlZ0VudW1WYWx1ZVcoIGZyb20sIGluZGV4KyssIG5hbWUsICZuYW1lX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgJnR5cGUsIGRhdGEsICZsZW4gKSAhPSBFUlJPUl9TVUNDRVNTKSBicmVhazsKICAgICAgICBSZWdTZXRWYWx1ZUV4VyggdG8sIG5hbWUsIDAsIHR5cGUsIGRhdGEsIGxlbiApOwogICAgfQoKICAgIC8qIGNvcHkgc3Via2V5cyAqLwogICAgaW5kZXggPSAwOwogICAgZm9yICg7OykKICAgIHsKICAgICAgICBuYW1lX2xlbiA9IHNpemVvZihuYW1lKTsKICAgICAgICBpZiAoUmVnRW51bUtleUV4VyggZnJvbSwgaW5kZXgrKywgbmFtZSwgJm5hbWVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMLCAwLCAmZnQgKSAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgICAgICBicmVhazsKICAgICAgICBpZiAoUmVnT3BlbktleVcoIGZyb20sIG5hbWUsICZzdWJrZXkgKSA9PSBFUlJPUl9TVUNDRVNTKQogICAgICAgIHsKICAgICAgICAgICAgSEtFWSBuZXdzdWI7CiAgICAgICAgICAgIGlmIChSZWdDcmVhdGVLZXlXKCB0bywgbmFtZSwgJm5ld3N1YiApID09IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF9jb3B5X3JlZ2lzdHJ5KCBzdWJrZXksIG5ld3N1YiApOwogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoIG5ld3N1YiApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKICAgICAgICB9CiAgICB9Cn0KLyogTlQgUkVHSVNUUlkgTE9BREVSICovCgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgojaWZuZGVmIE1BUF9GQUlMRUQKI2RlZmluZSBNQVBfRkFJTEVEICgoTFBWT0lEKS0xKQojZW5kaWYKCiNkZWZpbmUgTE9OR19EVU1QIDEKCiNkZWZpbmUgIFJFR19CTE9DS19TSVpFCQkweDEwMDAKCiNkZWZpbmUgIFJFR19IRUFERVJfQkxPQ0tfSUQJMHg2NjY3NjU3MgkvKiByZWdmICovCiNkZWZpbmUgIFJFR19QT09MX0JMT0NLX0lECTB4NkU2OTYyNjgJLyogaGJpbiAqLwojZGVmaW5lICBSRUdfS0VZX0JMT0NLX0lECTB4NmI2ZQojZGVmaW5lCSBSRUdfVkFMVUVfQkxPQ0tfSUQJMHg2Yjc2CiNkZWZpbmUJIFJFR19IQVNIX0JMT0NLX0lECTB4NjY2YwojZGVmaW5lICBSRUdfTk9IQVNIX0JMT0NLX0lECTB4Njk2YwojZGVmaW5lICBSRUdfS0VZX0JMT0NLX1RZUEUJMHgyMAojZGVmaW5lICBSRUdfUk9PVF9LRVlfQkxPQ0tfVFlQRQkweDJjCgp0eXBlZGVmIHN0cnVjdCAKewoJRFdPUkQJaWQ7CQkvKiAweDY2Njc2NTcyICdyZWdmJyovCglEV09SRAl1azE7CQkvKiAweDA0ICovCglEV09SRAl1azI7CQkvKiAweDA4ICovCglGSUxFVElNRQlEYXRlTW9kaWZpZWQ7CS8qIDB4MGMgKi8KCURXT1JECXVrMzsJCS8qIDB4MTQgKi8KCURXT1JECXVrNDsJCS8qIDB4MTggKi8KCURXT1JECXVrNTsJCS8qIDB4MWMgKi8KCURXT1JECXVrNjsJCS8qIDB4MjAgKi8KCURXT1JECVJvb3RLZXlCbG9jazsJLyogMHgyNCAqLwoJRFdPUkQJQmxvY2tTaXplOwkvKiAweDI4ICovCglEV09SRCAgIHVrN1sxMTZdOwkKCURXT1JECUNoZWNrc3VtOyAvKiBhdCBvZmZzZXQgMHgxRkMgKi8KfSBudF9yZWdmOwoKdHlwZWRlZiBzdHJ1Y3QKewoJRFdPUkQJYmxvY2tzaXplOwoJQllURQlkYXRhWzFdOwp9IG50X2hiaW5fc3ViOwoKdHlwZWRlZiBzdHJ1Y3QKewoJRFdPUkQJaWQ7CQkvKiAweDZFNjk2MjY4ICdoYmluJyAqLwoJRFdPUkQJb2ZmX3ByZXY7CglEV09SRAlvZmZfbmV4dDsKCURXT1JECXVrMTsKCURXT1JECXVrMjsJCS8qIDB4MTAgKi8KCURXT1JECXVrMzsJCS8qIDB4MTQgKi8KCURXT1JECXVrNDsJCS8qIDB4MTggKi8KCURXT1JECXNpemU7CQkvKiAweDFDICovCgludF9oYmluX3N1YgloYmluX3N1YjsJLyogMHgyMCAqLwp9IG50X2hiaW47CgovKgogKiB0aGUgdmFsdWVfbGlzdCBjb25zaXN0cyBvZiBvZmZzZXRzIHRvIHRoZSB2YWx1ZXMgKHZrKQogKi8KdHlwZWRlZiBzdHJ1Y3QKewoJV09SRAlTdWJCbG9ja0lkOwkJLyogMHgwMCAweDZCNkUgKi8KCVdPUkQJVHlwZTsJCQkvKiAweDAyIGZvciB0aGUgcm9vdC1rZXk6IDB4MkMsIG90aGVyd2lzZSAweDIwKi8KCUZJTEVUSU1FCXdyaXRldGltZTsJLyogMHgwNCAqLwoJRFdPUkQJdWsxOwkJCS8qIDB4MEMgKi8KCURXT1JECXBhcmVudF9vZmY7CQkvKiAweDEwIE9mZnNldCBvZiBPd25lci9QYXJlbnQga2V5ICovCglEV09SRAlucl9zdWJrZXlzOwkJLyogMHgxNCBudW1iZXIgb2Ygc3ViLUtleXMgKi8KCURXT1JECXVrODsJCQkvKiAweDE4ICovCglEV09SRAlsZl9vZmY7CQkJLyogMHgxQyBPZmZzZXQgb2YgdGhlIHN1Yi1rZXkgbGYtUmVjb3JkcyAqLwoJRFdPUkQJdWsyOwkJCS8qIDB4MjAgKi8KCURXT1JECW5yX3ZhbHVlczsJCS8qIDB4MjQgbnVtYmVyIG9mIHZhbHVlcyAqLwoJRFdPUkQJdmFsdWVsaXN0X29mZjsJCS8qIDB4MjggT2Zmc2V0IG9mIHRoZSBWYWx1ZS1MaXN0ICovCglEV09SRAlvZmZfc2s7CQkJLyogMHgyYyBPZmZzZXQgb2YgdGhlIHNrLVJlY29yZCAqLwoJRFdPUkQJb2ZmX2NsYXNzOwkJLyogMHgzMCBPZmZzZXQgb2YgdGhlIENsYXNzLU5hbWUgKi8KCURXT1JECXVrMzsJCQkvKiAweDM0ICovCglEV09SRAl1azQ7CQkJLyogMHgzOCAqLwoJRFdPUkQJdWs1OwkJCS8qIDB4M2MgKi8KCURXT1JECXVrNjsJCQkvKiAweDQwICovCglEV09SRAl1azc7CQkJLyogMHg0NCAqLwoJV09SRAluYW1lX2xlbjsJCS8qIDB4NDggbmFtZS1sZW5ndGggKi8KCVdPUkQJY2xhc3NfbGVuOwkJLyogMHg0YSBjbGFzcy1uYW1lIGxlbmd0aCAqLwoJY2hhcgluYW1lWzFdOwkJLyogMHg0YyBrZXktbmFtZSAqLwp9IG50X25rOwoKdHlwZWRlZiBzdHJ1Y3QKewoJRFdPUkQJb2ZmX25rOwkvKiAweDAwICovCglEV09SRAluYW1lOwkvKiAweDA0ICovCn0gaGFzaF9yZWM7Cgp0eXBlZGVmIHN0cnVjdAp7CglXT1JECWlkOwkJLyogMHgwMCAweDY2NmMgKi8KCVdPUkQJbnJfa2V5czsJLyogMHgwNiAqLwoJaGFzaF9yZWMJaGFzaF9yZWNbMV07Cn0gbnRfbGY7Cgp0eXBlZGVmIHN0cnVjdAp7CglXT1JECWlkOwkJLyogMHgwMCAweDY5NmMgKi8KCVdPUkQJbnJfa2V5czsKCURXT1JECW9mZl9ua1sxXTsKfSBudF9pbDsKCnR5cGVkZWYgc3RydWN0CnsKCVdPUkQJaWQ7CQkvKiAweDAwICd2aycgKi8KCVdPUkQJbmFtX2xlbjsKCURXT1JECWRhdGFfbGVuOwoJRFdPUkQJZGF0YV9vZmY7CglEV09SRAl0eXBlOwoJV09SRAlmbGFnOwoJV09SRAl1azE7CgljaGFyCW5hbWVbMV07Cn0gbnRfdms7CgojZGVmaW5lIHZrX3N6CQkweDAwMDEKI2RlZmluZQl2a19leHBzegkweDAwMDIKI2RlZmluZQl2a19iaW4JCTB4MDAwMwojZGVmaW5lIHZrX2R3b3JkCTB4MDAwNAojZGVmaW5lIHZrX211bHRpc3oJMHgwMDA3CiNkZWZpbmUgdmtfdTIJCTB4MDAwOAojZGVmaW5lIHZrX3UxCQkweDAwMGEKCkxQU1RSIF9zdHJkdXBuQSggTFBDU1RSIHN0ciwgaW50IGxlbiApCnsKICAgIExQU1RSIHJldDsKCiAgICBpZiAoIXN0cikgcmV0dXJuIE5VTEw7CiAgICByZXQgPSBtYWxsb2MoIGxlbiArIDEgKTsKICAgIGxzdHJjcHluQSggcmV0LCBzdHIsIGxlbiApOwogICAgcmV0W2xlbl0gPSAweDAwOwogICAgcmV0dXJuIHJldDsKfQoKaW50IF9udF9wYXJzZV9uayhIS0VZIGhrZXksIGNoYXIgKiBiYXNlLCBudF9uayAqIG5rLCBpbnQgbGV2ZWwpOwppbnQgX250X3BhcnNlX3ZrKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIG50X3ZrICogdmssIGludCBsZXZlbCk7CmludCBfbnRfcGFyc2VfbGYoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgbnRfbGYgKiBsZiwgaW50IGxldmVsKTsKCgovKgogKiBnZXRzIGEgdmFsdWUKICoKICogdmstPmZsYWc6CiAqICAwIHZhbHVlIGlzIGEgZGVmYXVsdCB2YWx1ZQogKiAgMSB0aGUgdmFsdWUgaGFzIGEgbmFtZQogKgogKiB2ay0+ZGF0YV9sZW4KICogIGxlbiBvZiB0aGUgd2hvbGUgZGF0YSBibG9jawogKiAgLSByZWdfc3ogKHVuaWNvZGUpCiAqICAgIGJ5dGVzIGluY2x1ZGluZyB0aGUgdGVybWluYXRpbmcgXDAgPSAyKihudW1iZXJfb2ZfY2hhcnMrMSkKICogIC0gcmVnX2R3b3JkLCByZWdfYmluYXJ5OgogKiAgICBpZiBoaWdoZXN0IGJpdCBvZiBkYXRhX2xlbiBpcyBzZXQgZGF0YV9vZmYgY29udGFpbnMgdGhlIHZhbHVlCiAqLwppbnQgX250X3BhcnNlX3ZrKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIG50X3ZrICogdmssIGludCBsZXZlbCkKewoJV0NIQVIgbmFtZSBbMjU2XTsKCURXT1JEIHJldDsKCUJZVEUgKiBwZGF0YSA9IChCWVRFICopKGJhc2UrdmstPmRhdGFfb2ZmKzQpOyAvKiBzdGFydCBvZiBkYXRhICovCgoJaWYodmstPmlkICE9IFJFR19WQUxVRV9CTE9DS19JRCkgZ290byBlcnJvcjsKCglsc3RyY3B5bkF0b1cobmFtZSwgdmstPm5hbWUsIHZrLT5uYW1fbGVuKzEpOwoKCXJldCA9IFJlZ1NldFZhbHVlRXhXKCBoa2V5LCAodmstPmZsYWcgJiAweDAwMDAwMDAxKSA/IG5hbWUgOiBOVUxMLCAwLCB2ay0+dHlwZSwKCQkJKHZrLT5kYXRhX2xlbiAmIDB4ODAwMDAwMDApID8gKExQQllURSkmKHZrLT5kYXRhX29mZik6IHBkYXRhLAoJCQkodmstPmRhdGFfbGVuICYgMHg3ZmZmZmZmZikgKTsKCWlmIChyZXQpIEVSUigiUmVnU2V0VmFsdWVFeCBmYWlsZWQgKDB4JTA4bHgpXG4iLCByZXQpOwoJcmV0dXJuIFRSVUU7CmVycm9yOgoJRVJSXyhyZWcpKCJ2ayBibG9jayBpbnZhbGlkXG4iKTsKCXJldHVybiBGQUxTRTsKfQoKLyoKICogZ2V0IHRoZSBzdWJrZXlzCiAqCiAqIHRoaXMgc3RydWN0dXJlIGNvbnRhaW5zIHRoZSBoYXNoIG9mIGEga2V5bmFtZSBhbmQgcG9pbnRzIHRvIGFsbAogKiBzdWJrZXlzCiAqCiAqIGV4Y2VwdGlvbjogaWYgdGhlIGlkIGlzICdpbCcgdGhlcmUgYXJlIG5vIGhhc2ggdmFsdWVzIGFuZCBldmVyeSAKICogZHdvcmQgaXMgYSBvZmZzZXQKICovCmludCBfbnRfcGFyc2VfbGYoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgbnRfbGYgKiBsZiwgaW50IGxldmVsKQp7CglpbnQgaTsKCglpZiAobGYtPmlkID09IFJFR19IQVNIX0JMT0NLX0lEKQoJewoJICBmb3IgKGk9MDsgaTxsZi0+bnJfa2V5czsgaSsrKQoJICB7CgkgICAgaWYgKCFfbnRfcGFyc2VfbmsoaGtleSwgYmFzZSwgKG50X25rKikoYmFzZStsZi0+aGFzaF9yZWNbaV0ub2ZmX25rKzQpLCBsZXZlbCkpIGdvdG8gZXJyb3I7CgkgIH0KCSAgCgl9CgllbHNlIGlmIChsZi0+aWQgPT0gUkVHX05PSEFTSF9CTE9DS19JRCkKCXsKCSAgZm9yIChpPTA7IGk8bGYtPm5yX2tleXM7IGkrKykKCSAgewoJICAgIGlmICghX250X3BhcnNlX25rKGhrZXksIGJhc2UsIChudF9uayopKGJhc2UrKChudF9pbCopbGYpLT5vZmZfbmtbaV0rNCksIGxldmVsKSkgZ290byBlcnJvcjsKCSAgfQoJfQoJcmV0dXJuIFRSVUU7CgkKZXJyb3I6CUVSUl8ocmVnKSgiZXJyb3IgcmVhZGluZyBsZiBibG9ja1xuIik7CglyZXR1cm4gRkFMU0U7Cn0KCmludCBfbnRfcGFyc2VfbmsoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgbnRfbmsgKiBuaywgaW50IGxldmVsKQp7CgljaGFyICogbmFtZTsKCWludCBpOwoJRFdPUkQgKiB2bDsKCUhLRVkgc3Via2V5OwoKCWlmKG5rLT5TdWJCbG9ja0lkICE9IFJFR19LRVlfQkxPQ0tfSUQpIGdvdG8gZXJyb3I7CglpZigobmstPlR5cGUhPVJFR19ST09UX0tFWV9CTE9DS19UWVBFKSAmJgoJICAgKCgobnRfbmsqKShiYXNlK25rLT5wYXJlbnRfb2ZmKzQpKS0+U3ViQmxvY2tJZCAhPSBSRUdfS0VZX0JMT0NLX0lEKSkgZ290byBlcnJvcjsKCgkvKiBjcmVhdGUgdGhlIG5ldyBrZXkgKi8KCW5hbWUgPSBfc3RyZHVwbkEoIG5rLT5uYW1lLCBuay0+bmFtZV9sZW4rMSk7CglpZihSZWdDcmVhdGVLZXlBKCBoa2V5LCBuYW1lLCAmc3Via2V5ICkpIHsgZnJlZShuYW1lKTsgZ290byBlcnJvcjsgfQoJZnJlZShuYW1lKTsKCgkvKiBsb29wIHRocm91Z2ggdGhlIHN1YmtleXMgKi8KCWlmIChuay0+bnJfc3Via2V5cykKCXsKCSAgbnRfbGYgKiBsZiA9IChudF9sZiopKGJhc2UrbmstPmxmX29mZis0KTsKCSAgaWYgKG5rLT5ucl9zdWJrZXlzICE9IGxmLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCSAgaWYgKCFfbnRfcGFyc2VfbGYoc3Via2V5LCBiYXNlLCBsZiwgbGV2ZWwrMSkpIGdvdG8gZXJyb3IxOwoJfQoKCS8qIGxvb3AgdHJvdWdoIHRoZSB2YWx1ZSBsaXN0ICovCgl2bCA9IChEV09SRCAqKShiYXNlK25rLT52YWx1ZWxpc3Rfb2ZmKzQpOwoJZm9yIChpPTA7IGk8bmstPm5yX3ZhbHVlczsgaSsrKQoJewoJICBudF92ayAqIHZrID0gKG50X3ZrKikoYmFzZSt2bFtpXSs0KTsKCSAgaWYgKCFfbnRfcGFyc2Vfdmsoc3Via2V5LCBiYXNlLCB2aywgbGV2ZWwrMSApKSBnb3RvIGVycm9yMTsKCX0KCglSZWdDbG9zZUtleShzdWJrZXkpOwoJcmV0dXJuIFRSVUU7CgkKZXJyb3IxOglSZWdDbG9zZUtleShzdWJrZXkpOwplcnJvcjoJRVJSXyhyZWcpKCJlcnJvciByZWFkaW5nIG5rIGJsb2NrXG4iKTsKCXJldHVybiBGQUxTRTsKfQoKLyoKICogdGhpcyBmdW5jdGlvbiBpbnRlbnRpb25hbGx5IHVzZXMgdW5peCBmaWxlIGZ1bmN0aW9ucyB0byBtYWtlIGl0IHBvc3NpYmxlCiAqIHRvIG1vdmUgaXQgdG8gYSBzZXBlcmF0ZSByZWdpc3RyeSBoZWxwZXIgcHJvZ3JhbW0KICovCnN0YXRpYyBpbnQgX250X2xvYWRyZWcoIEhLRVkgaGtleSwgY2hhciogZm4gKQp7Cgl2b2lkICogYmFzZTsKCWludCBsZW4sIGZkOwoJc3RydWN0IHN0YXQgc3Q7CgludF9yZWdmICogcmVnZjsKCW50X2hiaW4gKiBoYmluOwoJbnRfaGJpbl9zdWIgKiBoYmluX3N1YjsKCW50X25rKiBuazsKCURPU19GVUxMX05BTUUgZnVsbF9uYW1lOwoJCglpZiAoIURPU0ZTX0dldEZ1bGxOYW1lKCBmbiwgMCwgJmZ1bGxfbmFtZSApKTsKCglUUkFDRV8ocmVnKSgiTG9hZGluZyBOVCByZWdpc3RyeSBkYXRhYmFzZSAnJXMnICclcydcbiIsZm4sIGZ1bGxfbmFtZS5sb25nX25hbWUpOwoKCWlmICgoZmQgPSBvcGVuKGZ1bGxfbmFtZS5sb25nX25hbWUsIE9fUkRPTkxZIHwgT19OT05CTE9DSykpID09IC0xKSByZXR1cm4gRkFMU0U7CglpZiAoZnN0YXQoZmQsICZzdCApID09IC0xKSBnb3RvIGVycm9yMTsKCWxlbiA9IHN0LnN0X3NpemU7CglpZiAoKGJhc2U9bW1hcChOVUxMLCBsZW4sIFBST1RfUkVBRCwgTUFQX1BSSVZBVEUsIGZkLCAwKSkgPT0gTUFQX0ZBSUxFRCkgZ290byBlcnJvcjE7CgoJLyogc3RhcnQgYmxvY2sgKi8KCXJlZ2YgPSBiYXNlOwoJaWYocmVnZi0+aWQgIT0gUkVHX0hFQURFUl9CTE9DS19JRCkJLyogJ3JlZ2YnICovCgl7CgkgIEVSUiggIiVzIGlzIG5vdCBhIG50LXJlZ2lzdHJ5XG4iLCBmbik7CgkgIGdvdG8gZXJyb3I7Cgl9CglUUkFDRV8ocmVnKSggIiVwIFtyZWdmXSBvZmZzZXQ9JWx4IHNpemU9JWx4XG4iLCByZWdmLCByZWdmLT5Sb290S2V5QmxvY2ssIHJlZ2YtPkJsb2NrU2l6ZSk7CgkKCS8qIGhiaW4gYmxvY2sgKi8KCWhiaW4gPSBiYXNlICsgMHgxMDAwOwoJaWYgKGhiaW4tPmlkICE9IFJFR19QT09MX0JMT0NLX0lEKQoJewoJICBFUlJfKHJlZykoICIlcyBoYmluIGJsb2NrIGludmFsaWRcbiIsIGZuKTsKCSAgZ290byBlcnJvcjsKCX0KCVRSQUNFXyhyZWcpKCAiJXAgW2hiaW5dICBwcmV2PSVseCBuZXh0PSVseCBzaXplPSVseFxuIiwgaGJpbiwgaGJpbi0+b2ZmX3ByZXYsIGhiaW4tPm9mZl9uZXh0LCBoYmluLT5zaXplKTsKCgkvKiBoYmluX3N1YiBibG9jayAqLwoJaGJpbl9zdWIgPSAobnRfaGJpbl9zdWIqKSYoaGJpbi0+aGJpbl9zdWIpOwoJaWYgKChoYmluX3N1Yi0+ZGF0YVswXSAhPSAnbicpIHx8IChoYmluX3N1Yi0+ZGF0YVsxXSAhPSAnaycpKQoJewoJICBFUlJfKHJlZykoICIlcyBoYmluX3N1YiBibG9jayBpbnZhbGlkXG4iLCBmbik7CgkgIGdvdG8gZXJyb3I7Cgl9CiAJVFJBQ0VfKHJlZykoICIlcCBbaGJpbiBzdWJdIHNpemU9JWx4XG4iLCBoYmluX3N1YiwgaGJpbl9zdWItPmJsb2Nrc2l6ZSk7CiAgICAgICAgICAgIAkKCS8qIG5rIGJsb2NrICovCgluayA9IChudF9uayopJihoYmluX3N1Yi0+ZGF0YVswXSk7CglpZiAobmstPlR5cGUgIT0gUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpCgl7CgkgIEVSUl8ocmVnKSggIiVzIHNwZWNpYWwgbmsgYmxvY2sgbm90IGZvdW5kXG4iLCBmbik7CgkgIGdvdG8gZXJyb3I7Cgl9CgoJX250X3BhcnNlX25rIChoa2V5LCBiYXNlKzB4MTAwMCwgbmssIDApOwoKCW11bm1hcChiYXNlLCBsZW4pOwoJY2xvc2UoZmQpOwoJcmV0dXJuIDE7CgplcnJvcjoJbXVubWFwKGJhc2UsIGxlbik7CmVycm9yMToJY2xvc2UoZmQpOwoJRVJSXyhyZWcpKCJlcnJvciByZWFkaW5nIHJlZ2lzdHJ5IGZpbGVcbiIpOwoJcmV0dXJuIDA7Cn0KLyogZW5kIG50IGxvYWRlciAqLwoKLyogV0lORE9XUyA5NSBSRUdJU1RSWSBMT0FERVIgKi8KLyogCiAqIFN0cnVjdHVyZSBvZiBhIHdpbjk1IHJlZ2lzdHJ5IGRhdGFiYXNlLgogKiBtYWluIGhlYWRlcjoKICogMCA6CSJDUkVHIgktIG1hZ2ljCiAqIDQgOglEV09SRCB2ZXJzaW9uCiAqIDggOglEV09SRCBvZmZzZXRfb2ZfUkdEQl9wYXJ0CiAqIDBDLi4wRjoJPyAoc29tZW9uZSBmaWxsIGluIHBsZWFzZSkKICogMTA6ICBXT1JECW51bWJlciBvZiBSR0RCIGJsb2NrcwogKiAxMjogIFdPUkQJPwogKiAxNDogIFdPUkQJYWx3YXlzIDAwMDA/CiAqIDE2OiAgV09SRAlhbHdheXMgMDAwMT8KICogMTguLjFGOgk/IChzb21lb25lIGZpbGwgaW4gcGxlYXNlKQogKgogKiAyMDogUkdLTl9zZWN0aW9uOgogKiAgIGhlYWRlcjoKICogCTAgOgkJIlJHS04iCS0gbWFnaWMKICogICAgICA0IDogRFdPUkQJb2Zmc2V0IHRvIGZpcnN0IFJHREIgc2VjdGlvbgogKiAgICAgIDggOiBEV09SRAlvZmZzZXQgdG8gdGhlIHJvb3QgcmVjb3JkCiAqIAlDLi4weDFCOiAJPyAoZmlsbCBpbikKICogICAgICAweDIwIC4uLiBvZmZzZXRfb2ZfUkdEQl9wYXJ0OiBEaXNrIEtleSBFbnRyeSBzdHJ1Y3R1cmVzCiAqCiAqICAgRGlzayBLZXkgRW50cnkgU3RydWN0dXJlOgogKgkwMDogRFdPUkQJLSBGcmVlIGVudHJ5IGluZGljYXRvcig/KQogKgkwNDogRFdPUkQJLSBIYXNoID0gc3VtIG9mIGJ5dGVzIG9mIGtleW5hbWUKICoJMDg6IERXT1JECS0gUm9vdCBrZXkgaW5kaWNhdG9yPyB1bmtub3duLCBidXQgdXN1YWxseSAweEZGRkZGRkZGIG9uIHdpbjk1IHN5c3RlbXMKICoJMEM6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIFByZXZpb3VzTGV2ZWwgS2V5LgogKgkxMDogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgTmV4dCBTdWJsZXZlbCBLZXkuCiAqCTE0OiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBOZXh0IEtleSAob24gc2FtZSBsZXZlbCkuCiAqIERLRVA+MTg6IFdPUkQJLSBOciwgTG93IFNpZ25pZmljYW50IHBhcnQuCiAqCTFBOiBXT1JECS0gTnIsIEhpZ2ggU2lnbmlmaWNhbnQgcGFydC4KICoKICogVGhlIGRpc2sgYWRkcmVzcyBhbHdheXMgcG9pbnRzIHRvIHRoZSBuciBwYXJ0IG9mIHRoZSBwcmV2aW91cyBrZXkgZW50cnkgCiAqIG9mIHRoZSByZWZlcmVuY2VkIGtleS4gRG9uJ3QgYXNrIG1lIHdoeSwgb3IgZXZlbiBpZiBJIGdvdCB0aGlzIGNvcnJlY3QKICogZnJvbSBzdGFyaW5nIGF0IDFrZyBvZiBoZXhkdW1wcy4gKERLRVApCiAqCiAqIFRoZSBIaWdoIHNpZ25pZmljYW50IHBhcnQgb2YgdGhlIHN0cnVjdHVyZSBzZWVtcyB0byBlcXVhbCB0aGUgbnVtYmVyCiAqIG9mIHRoZSBSR0RCIHNlY3Rpb24uIFRoZSBsb3cgc2lnbmlmaWNhbnQgcGFydCBpcyBhIHVuaXF1ZSBJRCB3aXRoaW4KICogdGhhdCBSR0RCIHNlY3Rpb24KICoKICogVGhlcmUgYXJlIHR3byBtaW5vciBjb3JyZWN0aW9ucyB0byB0aGUgcG9zaXRpb24gb2YgdGhhdCBzdHJ1Y3R1cmUuCiAqIDEuIElmIHRoZSBhZGRyZXNzIGlzIHh4eDAxNCBvciB4eHgwMTggaXQgd2lsbCBiZSBhbGlnbmVkIHRvIHh4eDAxYyBBTkQgCiAqICAgIHRoZSBES0UgcmVyZWFkIGZyb20gdGhlcmUuCiAqIDIuIElmIHRoZSBhZGRyZXNzIGlzIHh4eEZGeCBpdCB3aWxsIGJlIGFsaWduZWQgdG8gKHh4eCsxKTAwMC4KICogQ1BTIC0gSSBoYXZlIG5vdCBleHBlcmllbmNlZCB0aGUgYWJvdmUgcGhlbm9tZW5vbiBpbiBteSByZWdpc3RyeSBmaWxlcwogKgogKiBSR0RCX3NlY3Rpb246CiAqIAkwMDoJCSJSR0RCIgktIG1hZ2ljCiAqCTA0OiBEV09SRAlvZmZzZXQgdG8gbmV4dCBSR0RCIHNlY3Rpb24KICoJMDg6IERXT1JECT8KICoJMEM6IFdPUkQJYWx3YXlzIDAwMGQ/CiAqCTBFOiBXT1JECVJHREIgYmxvY2sgbnVtYmVyCiAqCTEwOglEV09SRAk/IChlcXVhbHMgdmFsdWUgYXQgb2Zmc2V0IDQgLSB2YWx1ZSBhdCBvZmZzZXQgOCkKICoJMTQuLjFGOgkJPwogKgkyMC4uLi4uOglkaXNrIGtleXMKICoKICogZGlzayBrZXk6CiAqIAkwMDogCURXT1JECW5leHRrZXlvZmZzZXQJLSBvZmZzZXQgdG8gdGhlIG5leHQgZGlzayBrZXkgc3RydWN0dXJlCiAqCTA4OiAJV09SRAluckxTCQktIGxvdyBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBBOiAJV09SRAluckhTCQktIGhpZ2ggc2lnbmlmaWNhbnQgcGFydCBvZiBOUgogKgkwQzogCURXT1JECWJ5dGVzdXNlZAktIGJ5dGVzIHVzZWQgaW4gdGhpcyBzdHJ1Y3R1cmUuCiAqCTEwOiAJV09SRAluYW1lX2xlbgktIGxlbmd0aCBvZiBuYW1lIGluIGJ5dGVzLiB3aXRob3V0IFwwCiAqCTEyOiAJV09SRAlucl9vZl92YWx1ZXMJLSBudW1iZXIgb2YgdmFsdWVzLgogKgkxNDogCWNoYXIJbmFtZVtuYW1lX2xlbl0JLSBuYW1lIHN0cmluZy4gTm8gXDAuCiAqCTE0K25hbWVfbGVuOiBkaXNrIHZhbHVlcwogKgluZXh0a2V5b2Zmc2V0OiAuLi4gbmV4dCBkaXNrIGtleQogKgogKiBkaXNrIHZhbHVlOgogKgkwMDoJRFdPUkQJdHlwZQkJLSB2YWx1ZSB0eXBlIChobW0sIGNvdWxkIGJlIFdPUkQgdG9vKQogKgkwNDoJRFdPUkQJCQktIHVua25vd24sIHVzdWFsbHkgMAogKgkwODoJV09SRAluYW1lbGVuCQktIGxlbmd0aCBvZiBOYW1lLiAwIG1lYW5zIG5hbWU9TlVMTAogKgkwQzoJV09SRAlkYXRhbGVuCQktIGxlbmd0aCBvZiBEYXRhLgogKgkxMDoJY2hhcgluYW1lW25hbWVsZW5dCS0gbmFtZSwgbm8gXDAKICoJMTArbmFtZWxlbjogQllURQlkYXRhW2RhdGFsZW5dIC0gZGF0YSwgd2l0aG91dCBcMCBpZiBzdHJpbmcKICoJMTArbmFtZWxlbitkYXRhbGVuOiBuZXh0IHZhbHVlcyBvciBkaXNrIGtleQogKgogKiBEaXNrIGtleXMgYXJlIGxheWVkIG91dCBmbGF0IC4uLiBCdXQsIHNvbWV0aW1lcywgbnJMUyBhbmQgbnJIUyBhcmUgYm90aAogKiAweEZGRkYsIHdoaWNoIG1lYW5zIHNraXBwaW5nIG92ZXIgbmV4dGtleW9mZnNldCBieXRlcyAoaW5jbHVkaW5nIHRoaXMKICogc3RydWN0dXJlKSBhbmQgcmVhZGluZyBhbm90aGVyIFJHREJfc2VjdGlvbi4KICogcmVwZWF0IHVudGlsIGVuZCBvZiBmaWxlLgogKgogKiBBbiBpbnRlcmVzdGluZyByZWxhdGlvbnNoaXAgZXhpc3RzIGluIFJHREJfc2VjdGlvbi4gVGhlIHZhbHVlIGF0IG9mZnNldAogKiAxMCBlcXVhbHMgdGhlIHZhbHVlIGF0IG9mZnNldCA0IG1pbnVzIHRoZSB2YWx1ZSBhdCBvZmZzZXQgOC4gSSBoYXZlIG5vCiAqIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKgogKiBGSVhNRTogdGhpcyBkZXNjcmlwdGlvbiBuZWVkcyBzb21lIHNlcmlvdXMgaGVscCwgeWVzLgogKi8KCnN0cnVjdAlfdzk1a2V5dmFsdWUgewoJdW5zaWduZWQgbG9uZwkJdHlwZTsKCXVuc2lnbmVkIHNob3J0CQlkYXRhbGVuOwoJY2hhcgkJCSpuYW1lOwoJdW5zaWduZWQgY2hhcgkJKmRhdGE7Cgl1bnNpZ25lZCBsb25nCQl4MTsKCWludAkJCWxhc3Rtb2RpZmllZDsKfTsKCnN0cnVjdCAJX3c5NWtleSB7CgljaGFyCQkJKm5hbWU7CglpbnQJCQlucm9mdmFsczsKCXN0cnVjdAlfdzk1a2V5dmFsdWUJKnZhbHVlczsKCXN0cnVjdCBfdzk1a2V5CQkqcHJldmx2bDsKCXN0cnVjdCBfdzk1a2V5CQkqbmV4dHN1YjsKCXN0cnVjdCBfdzk1a2V5CQkqbmV4dDsKfTsKCgpzdHJ1Y3QgX3c5NV9pbmZvIHsKICBjaGFyICpyZ2tuYnVmZmVyOwogIGludCAgcmdrbnNpemU7CiAgY2hhciAqcmdkYmJ1ZmZlcjsKICBpbnQgIHJnZGJzaXplOwogIGludCAgZGVwdGg7CiAgaW50ICBsYXN0bW9kaWZpZWQ7Cn07CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X3Byb2Nlc3NLZXkgW0ludGVybmFsXQogKi8Kc3RhdGljIEhLRVkgX3c5NV9wcm9jZXNzS2V5ICggSEtFWSBoa2V5LCBpbnQgbnJMUywgaW50IG5yTVMsIHN0cnVjdCBfdzk1X2luZm8gKmluZm8gKQoKewogIC8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCkgKi8KCXN0cnVjdAlka2ggewogICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZwkJbmV4dGtleW9mZjsgCgkJdW5zaWduZWQgc2hvcnQJCW5yTFM7CgkJdW5zaWduZWQgc2hvcnQJCW5yTVM7CgkJdW5zaWduZWQgbG9uZwkJYnl0ZXN1c2VkOwoJCXVuc2lnbmVkIHNob3J0CQlrZXluYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWx1ZXM7CgkJdW5zaWduZWQgbG9uZwkJeHgxOwoJCS8qIGtleW5hbWUgKi8KCQkvKiBkaXNrIGtleSB2YWx1ZXMgb3Igbm90aGluZyAqLwoJfTsKCS8qIERpc2sgS2V5IFZhbHVlIHN0cnVjdHVyZSAqLwoJc3RydWN0CWRrdiB7CgkJdW5zaWduZWQgbG9uZwkJdHlwZTsKCQl1bnNpZ25lZCBsb25nCQl4MTsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsbmFtZWxlbjsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsZGF0YWxlbjsKCQkvKiB2YWxuYW1lLCB2YWxkYXRhICovCgl9OwoKCQoJc3RydWN0CWRraCBka2g7CglpbnQJYnl0ZXNyZWFkID0gMDsKCWNoYXIgICAgKnJnZGJkYXRhID0gaW5mby0+cmdkYmJ1ZmZlcjsKCWludCAgICAgbmJ5dGVzID0gaW5mby0+cmdkYnNpemU7CgljaGFyICAgICpjdXJkYXRhID0gcmdkYmRhdGE7CgljaGFyICAgICplbmQgPSByZ2RiZGF0YSArIG5ieXRlczsKCWludCAgICAgb2ZmX25leHRfcmdkYjsKCWNoYXIgICAgKm5leHQgPSByZ2RiZGF0YTsKCWludCAgICAgbnJnZGIsIGk7CiAgICAgICAgSEtFWSBzdWJrZXk7CgkKCWRvIHsKCSAgY3VyZGF0YSA9IG5leHQ7CgkgIGlmIChzdHJuY21wKGN1cmRhdGEsICJSR0RCIiwgNCkpIHJldHVybiAwOwoJICAgIAoJICBtZW1jcHkoJm9mZl9uZXh0X3JnZGIsY3VyZGF0YSs0LDQpOwoJICBuZXh0ID0gY3VyZGF0YSArIG9mZl9uZXh0X3JnZGI7CgkgIG5yZ2RiID0gKGludCkgKigoc2hvcnQgKiljdXJkYXRhICsgNyk7CgoJfSB3aGlsZSAobnJnZGIgIT0gbnJNUyAmJiAobmV4dCA8IGVuZCkpOwoKCS8qIGN1cmRhdGEgbm93IHBvaW50cyB0byB0aGUgc3RhcnQgb2YgdGhlIHJpZ2h0IFJHREIgc2VjdGlvbiAqLwoJY3VyZGF0YSArPSAweDIwOwoKI2RlZmluZSBYUkVBRCh3aGVyZXRvLGxlbikgXAoJaWYgKChjdXJkYXRhICsgbGVuKSA8PSBlbmQpIHtcCgkJbWVtY3B5KHdoZXJldG8sY3VyZGF0YSxsZW4pO1wKCQljdXJkYXRhKz1sZW47XAoJCWJ5dGVzcmVhZCs9bGVuO1wKCX0KCgl3aGlsZSAoY3VyZGF0YSA8IG5leHQpIHsKCSAgc3RydWN0CWRraCAqeGRraCA9IChzdHJ1Y3QgZGtoKiljdXJkYXRhOwoKCSAgYnl0ZXNyZWFkICs9IHNpemVvZihka2gpOyAvKiBGSVhNRS4uLiBuZXh0a2V5b2ZmPyAqLwoJICBpZiAoeGRraC0+bnJMUyA9PSBuckxTKSB7CgkgIAltZW1jcHkoJmRraCx4ZGtoLHNpemVvZihka2gpKTsKCSAgCWN1cmRhdGEgKz0gc2l6ZW9mKGRraCk7CgkgIAlicmVhazsKCSAgfQoJICBjdXJkYXRhICs9IHhka2gtPm5leHRrZXlvZmY7Cgl9OwoKCWlmIChka2gubnJMUyAhPSBuckxTKSByZXR1cm4gMDsKCglpZiAobnJnZGIgIT0gZGtoLm5yTVMpCgkgIHJldHVybiAwOwoKICAgICAgICBhc3NlcnQoKGRraC5rZXluYW1lbGVuPDIpIHx8IGN1cmRhdGFbMF0pOwoJc3Via2V5PV9maW5kX29yX2FkZF9rZXkoaGtleSxzdHJjdnRBMlcoY3VyZGF0YSwgZGtoLmtleW5hbWVsZW4pKTsKCWN1cmRhdGEgKz0gZGtoLmtleW5hbWVsZW47CgoJZm9yIChpPTA7aTwgZGtoLnZhbHVlczsgaSsrKSB7CgkgIHN0cnVjdCBka3YgZGt2OwoJICBMUEJZVEUgZGF0YTsKCSAgaW50IGxlbjsKCSAgTFBXU1RSIG5hbWU7CgoJICBYUkVBRCgmZGt2LHNpemVvZihka3YpKTsKCgkgIG5hbWUgPSBzdHJjdnRBMlcoY3VyZGF0YSwgZGt2LnZhbG5hbWVsZW4pOwoJICBjdXJkYXRhICs9IGRrdi52YWxuYW1lbGVuOwoKCSAgaWYgKCgxIDw8IGRrdi50eXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkgICAgZGF0YSA9IChMUEJZVEUpIHN0cmN2dEEyVyhjdXJkYXRhLCBka3YudmFsZGF0YWxlbik7CgkgICAgbGVuID0gMiooZGt2LnZhbGRhdGFsZW4gKyAxKTsKCSAgfSBlbHNlIHsKCSAgICAvKiBJIGRvbid0IHRoaW5rIHdlIHdhbnQgdG8gTlVMTCB0ZXJtaW5hdGUgYWxsIGRhdGEgKi8KCSAgICBkYXRhID0geG1hbGxvYyhka3YudmFsZGF0YWxlbik7CgkgICAgbWVtY3B5IChkYXRhLCBjdXJkYXRhLCBka3YudmFsZGF0YWxlbik7CgkgICAgbGVuID0gZGt2LnZhbGRhdGFsZW47CgkgIH0KCgkgIGN1cmRhdGEgKz0gZGt2LnZhbGRhdGFsZW47CgkgIAoJICBfZmluZF9vcl9hZGRfdmFsdWUoIHN1YmtleSwgbmFtZSwgZGt2LnR5cGUsIGRhdGEsIGxlbiApOwoJfQoJcmV0dXJuIHN1YmtleTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X3dhbGtyZ2tuIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93OTVfd2Fsa3Jna24oIEhLRVkgcHJldmtleSwgY2hhciAqb2ZmLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IF93OTVfaW5mbyAqaW5mbyApCgp7CiAgLyogRGlzayBLZXkgRW50cnkgc3RydWN0dXJlIChSR0tOIHBhcnQpICovCiAgc3RydWN0CWRrZSB7CiAgICB1bnNpZ25lZCBsb25nCQl4MTsKICAgIHVuc2lnbmVkIGxvbmcJCXgyOwogICAgdW5zaWduZWQgbG9uZwkJeDM7Lyp1c3VhbGx5IDB4RkZGRkZGRkYgKi8KICAgIHVuc2lnbmVkIGxvbmcJCXByZXZsdmw7CiAgICB1bnNpZ25lZCBsb25nCQluZXh0c3ViOwogICAgdW5zaWduZWQgbG9uZwkJbmV4dDsKICAgIHVuc2lnbmVkIHNob3J0CQluckxTOwogICAgdW5zaWduZWQgc2hvcnQJCW5yTVM7CiAgfSAqZGtlID0gKHN0cnVjdCBka2UgKilvZmY7CiAgSEtFWSBzdWJrZXk7CgogIGlmIChka2UgPT0gTlVMTCkgewogICAgZGtlID0gKHN0cnVjdCBka2UgKikgKChjaGFyICopaW5mby0+cmdrbmJ1ZmZlcik7CiAgfQoKICBzdWJrZXkgPSBfdzk1X3Byb2Nlc3NLZXkocHJldmtleSwgZGtlLT5uckxTLCBka2UtPm5yTVMsIGluZm8pOwoKICBpZiAoZGtlLT5uZXh0c3ViICE9IC0xICYmIAogICAgICAoKGRrZS0+bmV4dHN1YiAtIDB4MjApIDwgaW5mby0+cmdrbnNpemUpIAogICAgICAmJiAoZGtlLT5uZXh0c3ViID4gMHgyMCkpIHsKICAgIAogICAgX3c5NV93YWxrcmdrbihzdWJrZXkgPyBzdWJrZXkgOiBwcmV2a2V5LCAvKiBYWFggPC0tIFRoaXMgaXMgYSBoYWNrKi8KCQkgIGluZm8tPnJna25idWZmZXIgKyBka2UtPm5leHRzdWIgLSAweDIwLCAKCQkgIGluZm8pOwogIH0KICBpZiAoc3Via2V5KSBSZWdDbG9zZUtleSggc3Via2V5ICk7CgogIGlmIChka2UtPm5leHQgIT0gLTEgJiYgCiAgICAgICgoZGtlLT5uZXh0IC0gMHgyMCkgPCBpbmZvLT5yZ2tuc2l6ZSkgJiYgCiAgICAgIChka2UtPm5leHQgPiAweDIwKSkgewogICAgX3c5NV93YWxrcmdrbihwcmV2a2V5LCAgCgkJICBpbmZvLT5yZ2tuYnVmZmVyICsgZGtlLT5uZXh0IC0gMHgyMCwKCQkgIGluZm8pOwogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9sb2FkcmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF93OTVfbG9hZHJlZyggY2hhciogZm4sIEhLRVkgaGtleSApCnsKCUhGSUxFCQloZmQ7CgljaGFyCQltYWdpY1s1XTsKCXVuc2lnbmVkIGxvbmcJd2hlcmUsdmVyc2lvbixyZ2Ric2VjdGlvbixlbmQ7CglzdHJ1Y3QgICAgICAgICAgX3c5NV9pbmZvIGluZm87CglPRlNUUlVDVAlvZnM7CglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmRpbmZvOwoKCVRSQUNFKCJMb2FkaW5nIFdpbjk1IHJlZ2lzdHJ5IGRhdGFiYXNlICclcydcbiIsZm4pOwoJaGZkPU9wZW5GaWxlKGZuLCZvZnMsT0ZfUkVBRCk7CglpZiAoaGZkPT1IRklMRV9FUlJPUikKCQlyZXR1cm47CgltYWdpY1s0XT0wOwoJaWYgKDQhPV9scmVhZChoZmQsbWFnaWMsNCkpCgkJcmV0dXJuOwoJaWYgKHN0cmNtcChtYWdpYywiQ1JFRyIpKSB7CgkJV0FSTigiJXMgaXMgbm90IGEgdzk1IHJlZ2lzdHJ5LlxuIixmbik7CgkJcmV0dXJuOwoJfQoJaWYgKDQhPV9scmVhZChoZmQsJnZlcnNpb24sNCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZChoZmQsJnJnZGJzZWN0aW9uLDQpKQoJCXJldHVybjsKCWlmICgtMT09X2xsc2VlayhoZmQsMHgyMCxTRUVLX1NFVCkpCgkJcmV0dXJuOwoJaWYgKDQhPV9scmVhZChoZmQsbWFnaWMsNCkpCgkJcmV0dXJuOwoJaWYgKHN0cmNtcChtYWdpYywiUkdLTiIpKSB7CgkJV0FSTigic2Vjb25kIElGRiBoZWFkZXIgbm90IFJHS04sIGJ1dCAlc1xuIiwgbWFnaWMpOwoJCXJldHVybjsKCX0KCgkvKiBTVEVQIDE6IEtleWxpbmsgc3RydWN0dXJlcyAqLwoJaWYgKC0xPT1fbGxzZWVrKGhmZCwweDQwLFNFRUtfU0VUKSkKCQlyZXR1cm47Cgl3aGVyZQk9IDB4NDA7CgllbmQJPSByZ2Ric2VjdGlvbjsKCglpbmZvLnJna25zaXplID0gZW5kIC0gd2hlcmU7CglpbmZvLnJna25idWZmZXIgPSAoY2hhciopeG1hbGxvYyhpbmZvLnJna25zaXplKTsKCWlmIChpbmZvLnJna25zaXplICE9IF9scmVhZChoZmQsaW5mby5yZ2tuYnVmZmVyLGluZm8ucmdrbnNpemUpKQoJCXJldHVybjsKCglpZiAoIUdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKGhmZCwmaGZkaW5mbykpCgkJcmV0dXJuOwoKCWVuZCA9IGhmZGluZm8ubkZpbGVTaXplTG93OwoJaW5mby5sYXN0bW9kaWZpZWQgPSBET1NGU19GaWxlVGltZVRvVW5peFRpbWUoJmhmZGluZm8uZnRMYXN0V3JpdGVUaW1lLE5VTEwpOwoKCWlmICgtMT09X2xsc2VlayhoZmQscmdkYnNlY3Rpb24sU0VFS19TRVQpKQoJCXJldHVybjsKCglpbmZvLnJnZGJidWZmZXIgPSAoY2hhciopeG1hbGxvYyhlbmQtcmdkYnNlY3Rpb24pOwoJaW5mby5yZ2Ric2l6ZSA9IGVuZCAtIHJnZGJzZWN0aW9uOwoKCWlmIChpbmZvLnJnZGJzaXplICE9X2xyZWFkKGhmZCxpbmZvLnJnZGJidWZmZXIsaW5mby5yZ2Ric2l6ZSkpCgkJcmV0dXJuOwoJX2xjbG9zZShoZmQpOwoKCV93OTVfd2Fsa3Jna24oaGtleSwgTlVMTCwgJmluZm8pOwoKCWZyZWUgKGluZm8ucmdkYmJ1ZmZlcik7CglmcmVlIChpbmZvLnJna25idWZmZXIpOwp9CgoKLyogV0lORE9XUyAzMSBSRUdJU1RSWSBMT0FERVIsIHN1cHBsaWVkIGJ5IFRvciBTavh3YWxsLCB0b3JAc24ubm8gKi8KCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VlZGVkIGJ5IGEgd29yZCBhdCBvZmZzZXQtMi4gVGhpcyB3b3JkCiAgICBoYXMgdGhlIHZhbHVlICgyKmluZGV4KSsxLCB3aGVyZSBpbmRleCBpcyB0aGUgcmVmZXJyaW5nIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGluIHRoZSB0YWJsZS4gSSBoYXZlIG5vIHN1Z2dlc3Rpb24gZm9yIHRoZSAyKiBhbmQgdGhlICsxLgogICAgRm9sbG93aW5nIHRoZSB3b3JkLCB0aGVyZSBhcmUgTiBieXRlcyBvZiBkYXRhLCBhcyBwZXIgdGhlIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGxlbmd0aC4gVGhlIG9mZnNldCBvZiB0aGUga2V5ZW50L3ZhbGVudCBlbnRyeSBpcyBmcm9tIHRoZSBzdGFydAogICAgb2YgdGhlIHRleHQgdGFibGUgdG8gdGhlIGZpcnN0IGRhdGEgYnl0ZS4KCiAgICBUaGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbSBNaWNyb3NvZnQuIFRoZSBkYXRhIGZvcm1hdCBpcwogICAgZGVkdWNlZCBmcm9tIHRoZSByZWcuZGF0IGZpbGUgYnkgbWUuIE1pc3Rha2VzIG1heQogICAgaGF2ZSBiZWVuIG1hZGUuIEkgY2xhaW0gbm8gcmlnaHRzIGFuZCBnaXZlIG5vIGd1YXJhbnRlZXMgZm9yIHRoaXMgcHJvZ3JhbS4KCiAgICBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vCiovCgovKiByZWcuZGF0IGhlYWRlciBmb3JtYXQgKi8Kc3RydWN0IF93MzFfaGVhZGVyIHsKCWNoYXIJCWNvb2tpZVs4XTsJLyogJ1NIQ0MzLjEwJyAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYxOwkvKiBvZmZzZXQgb2YgaGFzaCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYyOwkvKiBvZmZzZXQgb2YgaW5kZXggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFiY250OwkJLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gaW5kZXggdGFibGUgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dG9mZjsJLyogb2Zmc2V0IG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0c2l6ZTsJLyogYnl0ZSBzaXplIG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgc2hvcnQJaGFzaHNpemU7CS8qIGhhc2ggc2l6ZSAqLwoJdW5zaWduZWQgc2hvcnQJZnJlZWlkeDsJLyogZnJlZSBpbmRleCAqLwp9OwoKLyogZ2VuZXJpYyBmb3JtYXQgb2YgdGFibGUgZW50cmllcyAqLwpzdHJ1Y3QgX3czMV90YWJlbnQgewoJdW5zaWduZWQgc2hvcnQgdzAsIHcxLCB3MiwgdzM7Cn07CgovKiBkaXJlY3RvcnkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9kaXJlbnQgewoJdW5zaWduZWQgc2hvcnQJc2libGluZ19pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHNpYmxpbmcgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAljaGlsZF9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGNoaWxkIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJa2V5X2lkeDsJLyogdGFibGUgaW5kZXggb2Yga2V5IGtleWVudCAqLwoJdW5zaWduZWQgc2hvcnQJdmFsdWVfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiB2YWx1ZSB2YWxlbnQgKi8KfTsKCi8qIGtleSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2tleWVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogdmFsdWUgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV92YWxlbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdG8gZGlzcGxheSBhIGRpcmVjdG9yeSB0cmVlICovCnZvaWQKX193MzFfZHVtcHRyZWUoCXVuc2lnbmVkIHNob3J0IGlkeCwKCQl1bnNpZ25lZCBjaGFyICp0eHQsCgkJc3RydWN0IF93MzFfdGFiZW50ICp0YWIsCgkJc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAoJCUhLRVkgaGtleSwKCQl0aW1lX3QJCWxhc3Rtb2RpZmllZCwKCQlpbnQJCWxldmVsCikgewoJc3RydWN0IF93MzFfZGlyZW50CSpkaXI7CglzdHJ1Y3QgX3czMV9rZXllbnQJKmtleTsKCXN0cnVjdCBfdzMxX3ZhbGVudAkqdmFsOwogICAgICAgIEhLRVkgc3Via2V5ID0gMDsKCXN0YXRpYyBjaGFyCQl0YWlsWzQwMF07CgoJd2hpbGUgKGlkeCE9MCkgewoJCWRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgoJCWlmIChkaXItPmtleV9pZHgpIHsKCQkJa2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKCQkJbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKCQkJdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKCQkJLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZSAKCQkJICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwoJCQkgKi8KCQkJaWYgKCFsZXZlbCAmJiAhbHN0cmNtcEEodGFpbCwiLmNsYXNzZXMiKSkgewoJCQkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLGhrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCQkJaWR4PWRpci0+c2libGluZ19pZHg7CgkJCQljb250aW51ZTsKCQkJfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3Via2V5KSBSZWdDbG9zZUtleSggc3Via2V5ICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChSZWdDcmVhdGVLZXlBKCBoa2V5LCB0YWlsLCAmc3Via2V5ICkgIT0gRVJST1JfU1VDQ0VTUykgc3Via2V5ID0gMDsKCQkJLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCgkJCWlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKCQkJCWlmIChkaXItPnZhbHVlX2lkeCkgewoJCQkJCXZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKCQkJCQltZW1jcHkodGFpbCwmdHh0W3ZhbC0+c3RyaW5nX29mZl0sdmFsLT5sZW5ndGgpOwoJCQkJCXRhaWxbdmFsLT5sZW5ndGhdPSdcMCc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdTZXRWYWx1ZUEoIHN1YmtleSwgTlVMTCwgUkVHX1NaLCB0YWlsLCAwICk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQlUUkFDRSgic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKCQl9CgkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHN1YmtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJaWR4PWRpci0+c2libGluZ19pZHg7Cgl9CiAgICAgICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzMxX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kdm9pZCBfdzMxX2xvYWRyZWcodm9pZCkgewoJSEZJTEUJCQloZjsKCXN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwoJc3RydWN0IF93MzFfdGFiZW50CSp0YWI7Cgl1bnNpZ25lZCBjaGFyCQkqdHh0OwoJaW50CQkJbGVuOwoJT0ZTVFJVQ1QJCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmaW5mbzsKCXRpbWVfdAkJCWxhc3Rtb2RpZmllZDsKCglUUkFDRSgiKHZvaWQpXG4iKTsKCgloZiA9IE9wZW5GaWxlKCJyZWcuZGF0Iiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmPT1IRklMRV9FUlJPUikKCQlyZXR1cm47CgoJLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCglpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQoaGYsJmhlYWQsc2l6ZW9mKGhlYWQpKSkgewoJCUVSUigicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSE9MCkgewoJCUVSUigicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCglsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwoJLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwoJdGFiID0geG1hbGxvYyhsZW4pOwoJaWYgKGxlbiE9X2xyZWFkKGhmLHRhYixsZW4pKSB7CgkJRVJSKCJjb3VsZG4ndCByZWFkICVkIGJ5dGVzLlxuIixsZW4pOyAKCQlmcmVlKHRhYik7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCS8qIHJlYWQgdGV4dCAqLwoJdHh0ID0geG1hbGxvYyhoZWFkLnRleHRzaXplKTsKCWlmICgtMT09X2xsc2VlayhoZixoZWFkLnRleHRvZmYsU0VFS19TRVQpKSB7CgkJRVJSKCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWlmIChoZWFkLnRleHRzaXplIT1fbHJlYWQoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CgkJRVJSKCJ0ZXh0YmxvY2sgdG9vIHNob3J0ICglZCBpbnN0ZWFkIG9mICVsZCkuXG4iLGxlbixoZWFkLnRleHRzaXplKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZiwmaGZpbmZvKSkgewoJCUVSUigiR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUgZmFpbGVkPy5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCV9fdzMxX2R1bXB0cmVlKHRhYlswXS53MSx0eHQsdGFiLCZoZWFkLEhLRVlfQ0xBU1NFU19ST09ULGxhc3Rtb2RpZmllZCwwKTsKCWZyZWUodGFiKTsKCWZyZWUodHh0KTsKCV9sY2xvc2UoaGYpOwoJcmV0dXJuOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfTG9hZFJlZ2lzdHJ5IFtJbnRlcm5hbF0KICovCnZvaWQgU0hFTExfTG9hZFJlZ2lzdHJ5KCB2b2lkICkKewogIHN0cnVjdCBzZXRfcmVnaXN0cnlfbGV2ZWxzX3JlcXVlc3QgKnJlcSA9IGdldF9yZXFfYnVmZmVyKCk7CiAgaW50IHNhdmVfdGltZW91dDsKICBjaGFyCSAgICAgICpmbiwgKmhvbWU7CiAgSEtFWQkJICAgIGhrZXk7CgogIFRSQUNFKCIodm9pZClcbiIpOwoKICBSRUdJU1RSWV9Jbml0KCk7CgogIC8qIHNldCBsZXZlbCB0byAwIGZvciBsb2FkaW5nIHN5c3RlbSBmaWxlcyAqLwogIHJlcS0+Y3VycmVudCA9IDA7CiAgcmVxLT5zYXZpbmcgID0gMDsKICByZXEtPnZlcnNpb24gPSAxOwogIHNlcnZlcl9jYWxsKCBSRVFfU0VUX1JFR0lTVFJZX0xFVkVMUyApOwoKICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCAoInJlZ2lzdHJ5IiwgIkxvYWRXaW4zMTFSZWdpc3RyeUZpbGVzIiwgMSkpIAogIHsgCiAgICAgIC8qIExvYWQgd2luZG93cyAzLjEgZW50cmllcyAqLwogICAgICBfdzMxX2xvYWRyZWcoKTsKICB9CiAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2wgKCJyZWdpc3RyeSIsICJMb2FkV2luOTVSZWdpc3RyeUZpbGVzIiwgMSkpIAogIHsgCiAgICAgIC8qIExvYWQgd2luZG93cyA5NSBlbnRyaWVzICovCiAgICAgIF93OTVfbG9hZHJlZygiQzpcXHN5c3RlbS4xc3QiLCBIS0VZX0xPQ0FMX01BQ0hJTkUpOwogICAgICBfdzk1X2xvYWRyZWcoInN5c3RlbS5kYXQiLCBIS0VZX0xPQ0FMX01BQ0hJTkUpOwogICAgICBfdzk1X2xvYWRyZWcoInVzZXIuZGF0IiwgSEtFWV9VU0VSUyk7CiAgfQogIGlmIChQUk9GSUxFX0dldFdpbmVJbmlCb29sICgicmVnaXN0cnkiLCAiTG9hZFdpbk5UUmVnaXN0cnlGaWxlcyIsIDEpKSAKICB7IAogICAgICBmbiA9IHhtYWxsb2MoIE1BWF9QQVRITkFNRV9MRU4gKTsgCiAgICAgIGhvbWUgPSB4bWFsbG9jICggTUFYX1BBVEhOQU1FX0xFTiApOwogICAgICBpZiAoIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyggInJlZ2lzdHJ5IiwgIk5UVXNlciIsICIiLCBob21lLCBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpIAogICAgICB7CiAgICAgICAgIEdldFdpbmRvd3NEaXJlY3RvcnlBKCBmbiwgTUFYX1BBVEhOQU1FX0xFTiApOwoJIHN0cm5jYXQoZm4sICJcXFByb2ZpbGVzXFwiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKGZuKSAtIDEpOwoJIHN0cm5jYXQoZm4sIGhvbWUsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4oZm4pIC0gMSk7Cgkgc3RybmNhdChmbiwgIlxcbnR1c2VyLmRhdCIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4oZm4pIC0gMSk7CiAgICAgICAgIF9udF9sb2FkcmVnKCBIS0VZX1VTRVJTLCBmbiApOwogICAgICB9ICAgICAKICAgICAgLyoKICAgICAgKiBGSVhNRQogICAgICAqICBtYXAgSExNXFN5c3RlbVxDb250cm9sU2V0MDAxIHRvIEhMTVxTeXN0ZW1cQ3VycmVudENvbnRyb2xTZXQKICAgICAgKi8KICAgICAgR2V0U3lzdGVtRGlyZWN0b3J5QSggZm4sIE1BWF9QQVRITkFNRV9MRU4gKTsKCiAgICAgIHN0cmNweShob21lLCBmbik7CiAgICAgIHN0cm5jYXQoaG9tZSwgIlxcY29uZmlnXFxzeXN0ZW0iLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKGhvbWUpIC0gMSk7CiAgICAgIF9udF9sb2FkcmVnKEhLRVlfTE9DQUxfTUFDSElORSwgaG9tZSk7CgogICAgICBzdHJjcHkoaG9tZSwgZm4pOwogICAgICBzdHJuY2F0KGhvbWUsICJcXGNvbmZpZ1xcc29mdHdhcmUiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKGhvbWUpIC0gMSk7CiAgICAgIF9udF9sb2FkcmVnKEhLRVlfTE9DQUxfTUFDSElORSwgaG9tZSk7CgogICAgICBzdHJjcHkoaG9tZSwgZm4pOwogICAgICBzdHJuY2F0KGhvbWUsICJcXGNvbmZpZ1xcc2FtIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihob21lKSAtIDEpOwogICAgICBfbnRfbG9hZHJlZyhIS0VZX0xPQ0FMX01BQ0hJTkUsIGhvbWUpOwoKICAgICAgc3RyY3B5KGhvbWUsIGZuKTsKICAgICAgc3RybmNhdChob21lLCAiXFxjb25maWdcXHNlY3VyaXR5IiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihob21lKSAtIDEpOwogICAgICBfbnRfbG9hZHJlZyhIS0VZX0xPQ0FMX01BQ0hJTkUsIGhvbWUpOwoKICAgICAgZnJlZSAoaG9tZSk7CiAgICAgIGZyZWUgKGZuKTsKICAgICAgLyogdGhpcyBrZXkgaXMgZ2VuZXJhdGVkIHdoZW4gdGhlIG50LWNvcmUgYm9vdGVkIHN1Y2Nlc3NmdWxseSAqLwogICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXENsb25lIiwmaGtleSkpCiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgfQoKICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCAoInJlZ2lzdHJ5IiwiTG9hZEdsb2JhbFJlZ2lzdHJ5RmlsZXMiLCAxKSkKICB7CiAgICAgIC8qIAogICAgICAgKiBMb2FkIHRoZSBnbG9iYWwgSEtVIGhpdmUgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyCiAgICAgICAqLyAKICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9VU0VSUywgU0FWRV9VU0VSU19ERUZBVUxUICk7CgogICAgICAvKiAKICAgICAgICogTG9hZCB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgZGlyZWN0bHkgZm9ybSBzeXNjb25mZGlyCiAgICAgICAqLwogICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX0xPQ0FMX01BQ0hJTkUsIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUICk7CiAgfQoKICAvKiBzZXQgbGV2ZWwgdG8gMSBmb3IgbG9hZGluZyB1c2VyIGZpbGVzICovCiAgcmVxLT5jdXJyZW50ID0gMTsKICByZXEtPnNhdmluZyAgPSAwOwogIHJlcS0+dmVyc2lvbiA9IDE7CiAgc2VydmVyX2NhbGwoIFJFUV9TRVRfUkVHSVNUUllfTEVWRUxTICk7CgogIC8qCiAgICogTG9hZCB0aGUgdXNlciBzYXZlZCByZWdpc3RyaWVzIAogICAqLwogIGlmICghKGhvbWUgPSBnZXRlbnYoICJIT01FIiApKSkKICAgICAgV0FSTigiRmFpbGVkIHRvIGdldCBob21lZGlyZWN0b3J5IG9mIFVJRCAlbGQuXG4iLChsb25nKSBnZXR1aWQoKSk7CiAgZWxzZSBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgicmVnaXN0cnkiLCAiTG9hZEhvbWVSZWdpc3RyeUZpbGVzIiwgMSkpCiAgewogICAgICAvKiAKICAgICAgICogTG9hZCB1c2VyJ3MgcGVyc29uYWwgdmVyc2lvbnMgb2YgZ2xvYmFsIEhLVS8uRGVmYXVsdCBrZXlzCiAgICAgICAqLwogICAgICBmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKGhvbWUpKyBzdHJsZW4oV0lORV9QUkVGSVgpICsKICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpKzIpOwogICAgICBzdHJjcHkoZm4sIGhvbWUpOwogICAgICBzdHJjYXQoZm4sIFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKTsKICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9VU0VSUywgZm4gKTsgCiAgICAgIGZyZWUoZm4pOwoKICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKyBzdHJsZW4oU0FWRV9DVVJSRU5UX1VTRVIpKzIpOwogICAgICBzdHJjcHkoZm4sIGhvbWUpOwogICAgICBzdHJjYXQoZm4sIFdJTkVfUFJFRklYIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwogICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX0NVUlJFTlRfVVNFUiwgZm4gKTsKICAgICAgZnJlZShmbik7CgogICAgICAvKiAKICAgICAgICogTG9hZCBIS0xNLCBhdHRlbXB0IHRvIGdldCB0aGUgcmVnaXN0cnkgbG9jYXRpb24gZnJvbSB0aGUgY29uZmlnIAogICAgICAgKiBmaWxlIGZpcnN0LCBpZiBleGlzdCwgbG9hZCBhbmQga2VlcCBnb2luZy4KICAgICAgICovCiAgICAgIGZuPShjaGFyKil4bWFsbG9jKCBzdHJsZW4oaG9tZSkrIHN0cmxlbihXSU5FX1BSRUZJWCkrIHN0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwogICAgICBzdHJjcHkoZm4saG9tZSk7CiAgICAgIHN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfTUFDSElORSk7CiAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfTE9DQUxfTUFDSElORSwgZm4gKTsKICAgICAgZnJlZShmbik7CiAgfQogIAogIC8qIAogICAqIExvYWQgSEtDVSwgZ2V0IHRoZSByZWdpc3RyeSBsb2NhdGlvbiBmcm9tIHRoZSBjb25maWcgCiAgICogZmlsZSwgaWYgZXhpc3QsIGxvYWQgYW5kIGtlZXAgZ29pbmcuCiAgICovICAgICAgCiAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2wgKCAicmVnaXN0cnkiLCAiTG9hZEFsdFJlZ2lzdHJ5RmlsZXMiLCAxKSkKICB7CiAgICAgIGZuID0geG1hbGxvYyggTUFYX1BBVEhOQU1FX0xFTiApOyAKICAgICAgaWYgKCBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJyZWdpc3RyeSIsICJBbHRDdXJyZW50VXNlckZpbGUiLCAiIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiwgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKSAKICAgICAgIHsKICAgICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9DVVJSRU5UX1VTRVIsIGZuICk7CiAgICAgICB9CiAgICAgIGZyZWUgKGZuKTsKICAgICAgLyoKICAgICAgICogTG9hZCBIS1UsIGdldCB0aGUgcmVnaXN0cnkgbG9jYXRpb24gZnJvbSB0aGUgY29uZmlnCiAgICAgICAqIGZpbGUsIGlmIGV4aXN0LCBsb2FkIGFuZCBrZWVwIGdvaW5nLgogICAgICAgKi8KICAgICAgZm4gPSB4bWFsbG9jICggTUFYX1BBVEhOQU1FX0xFTiApOwogICAgICBpZiAoIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyAoICJyZWdpc3RyeSIsICJBbHRVc2VyRmlsZSIsICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZuLCBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpCiAgICAgICB7CiAgICAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfVVNFUlMsIGZuICk7CiAgICAgICB9CiAgICAgIGZyZWUgKGZuKTsKICAgICAgLyoKICAgICAgICogTG9hZCBIS0xNLCBnZXQgdGhlIHJlZ2lzdHJ5IGxvY2F0aW9uIGZyb20gdGhlIGNvbmZpZwogICAgICAgKiBmaWxlLCBpZiBleGlzdCwgbG9hZCBhbmQga2VlcCBnb2luZy4KICAgICAgICovCiAgICAgIGZuID0geG1hbGxvYyAoIE1BWF9QQVRITkFNRV9MRU4gKTsKICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyAoICJyZWdpc3RyeSIsICJBbHRMb2NhbE1hY2hpbmVGaWxlIiwgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiwgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKQogICAgICAgewogICAgICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX0xPQ0FMX01BQ0hJTkUsIGZuICk7CiAgICAgICB9CiAgICAgIGZyZWUgKGZuKTsKICAgIH0KICAKICAvKiAKICAgKiBPYnRhaW4gdGhlIGhhbmRsZSBvZiB0aGUgSEtVXC5EZWZhdWx0IGtleS4KICAgKiBpbiBvcmRlciB0byBjb3B5IEhLVVwuRGVmYXVsdFwqIG9udG8gSEtFWV9DVVJSRU5UX1VTRVIgCiAgICovCiAgaWYgKFJlZ0NyZWF0ZUtleUEoSEtFWV9VU0VSUywiLkRlZmF1bHQiLCZoa2V5KSAhPSBFUlJPUl9TVUNDRVNTKQogICAgICBXQVJOKCJDb3VsZCBub3QgY3JlYXRlIGdsb2JhbCB1c2VyIGRlZmF1bHQga2V5XG4iKTsKICBlbHNlCiAgICBfY29weV9yZWdpc3RyeSggaGtleSwgSEtFWV9DVVJSRU5UX1VTRVIgKTsKICBSZWdDbG9zZUtleShoa2V5KTsKCiAgLyogCiAgICogU2luY2UgSEtVIGlzIGJ1aWx0IGZyb20gdGhlIGdsb2JhbCBIS1UgYW5kIHRoZSBsb2NhbCB1c2VyIEhLVSBmaWxlIHdlIG11c3QKICAgKiBmbHVzaCB0aGUgSEtVIHRyZWUgd2UgaGF2ZSBidWlsdCBhdCB0aGlzIHBvaW50IG90aGVyd2lzZSB0aGUgcGFydCBicm91Z2h0CiAgICogaW4gZnJvbSB0aGUgZ2xvYmFsIEhLVSBpcyBzYXZlZCBpbnRvIHRoZSBsb2NhbCBIS1UuICBUbyBhdm9pZCB0aGlzIAogICAqIHVzZWxlc3MgZHVwcGxpY2F0aW9uIG9mIEhLVSBrZXlzIHdlIHJlcmVhZCB0aGUgbG9jYWwgSEtVIGtleS4KICAgKi8KCiAgLyogQWxsd2F5cyBmbHVzaCB0aGUgSEtVIGhpdmUgYW5kIHJlbG9hZCBpdCBvbmx5IHdpdGggdXNlcidzIHBlcnNvbmFsIEhLVSAqLwogIF9mbHVzaF9yZWdpc3RyeSggSEtFWV9VU0VSUyApOyAKCiAgLyogUmVsb2FkIHVzZXIncyBsb2NhbCBIS1UgaGl2ZSAqLwogIGlmIChob21lICYmIFBST0ZJTEVfR2V0V2luZUluaUJvb2wgKCJyZWdpc3RyeSIsIkxvYWRIb21lUmVnaXN0cnlGaWxlcyIsMSkpCiAgewogICAgICBmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKGhvbWUpICsgc3RybGVuKFdJTkVfUFJFRklYKQogICAgICAgICAgICAgICAgICAgICAgICAgKyBzdHJsZW4oU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKSArIDIpOwogICAgICAKICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpOwoKICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9VU0VSUywgZm4gKTsKCiAgICAgIGZyZWUoZm4pOwogIH0KCiAgLyogCiAgICogTWFrZSBzdXJlIHRoZSB1cGRhdGUgbW9kZSBpcyB0aGVyZQogICAqLwogIGlmIChFUlJPUl9TVUNDRVNTPT1SZWdDcmVhdGVLZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpKSAKICB7CiAgICBEV09SRAlqdW5rLHR5cGUsbGVuOwogICAgY2hhcglkYXRhWzVdOwoKICAgIGxlbj00OwogICAgaWYgKCgJUmVnUXVlcnlWYWx1ZUV4QSgKICAgICAgICAgICAgaGtleSwKICAgICAgICAgICAgVkFMX1NBVkVVUERBVEVELAogICAgICAgICAgICAmanVuaywKICAgICAgICAgICAgJnR5cGUsCiAgICAgICAgICAgIGRhdGEsCiAgICAgICAgICAgICZsZW4pICE9IEVSUk9SX1NVQ0NFU1MpIHx8ICh0eXBlICE9IFJFR19TWikpCiAgICB7CiAgICAgIFJlZ1NldFZhbHVlRXhBKGhrZXksVkFMX1NBVkVVUERBVEVELDAsUkVHX1NaLCJ5ZXMiLDQpOwogICAgfQoKICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogIH0KCiAgaWYgKChzYXZlX3RpbWVvdXQgPSBQUk9GSUxFX0dldFdpbmVJbmlJbnQoICJyZWdpc3RyeSIsICJQZXJpb2RpY1NhdmUiLCAwICkpKQogIHsKICAgICAgU0VSVklDRV9BZGRUaW1lciggc2F2ZV90aW1lb3V0ICogMTAwMDAwMCwgcGVyaW9kaWNfc2F2ZSwgMCApOwogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKiogQVBJIEZVTkNUSU9OUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0ZsdXNoS2V5IFtLRVJORUwuMjI3XSBbQURWQVBJMzIuMTQzXQogKiBJbW1lZGlhdGVseSB3cml0ZXMga2V5IHRvIHJlZ2lzdHJ5LgogKiBPbmx5IHJldHVybnMgYWZ0ZXIgZGF0YSBoYXMgYmVlbiB3cml0dGVuIHRvIGRpc2suCiAqCiAqIEZJWE1FOiBkb2VzIGl0IHJlYWxseSB3YWl0IHVudGlsIGRhdGEgaXMgd3JpdHRlbiA/CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdyaXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkoIEhLRVkgaGtleSApCnsKICAgIEZJWE1FKCAiKCV4KTogc3R1YlxuIiwgaGtleSApOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ29ubmVjdFJlZ2lzdHJ5MzJXIFtBRFZBUEkzMi4xMjhdCiAqCiAqIFBBUkFNUwogKiAgICBscE1hY2hpbmVOYW1lIFtJXSBBZGRyZXNzIG9mIG5hbWUgb2YgcmVtb3RlIGNvbXB1dGVyCiAqICAgIGhIZXkgICAgICAgICAgW0ldIFByZWRlZmluZWQgcmVnaXN0cnkgaGFuZGxlCiAqICAgIHBoa1Jlc3VsdCAgICAgW0ldIEFkZHJlc3Mgb2YgYnVmZmVyIGZvciByZW1vdGUgcmVnaXN0cnkgaGFuZGxlCiAqLwpMT05HIFdJTkFQSSBSZWdDb25uZWN0UmVnaXN0cnlXKCBMUENXU1RSIGxwTWFjaGluZU5hbWUsIEhLRVkgaEtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBIS0VZIHBoa1Jlc3VsdCApCnsKICAgIFRSQUNFKCIoJXMsJXgsJXApOiBzdHViXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSksaEtleSxwaGtSZXN1bHQpOwoKICAgIGlmICghbHBNYWNoaW5lTmFtZSB8fCAhKmxwTWFjaGluZU5hbWUpIHsKICAgICAgICAvKiBVc2UgdGhlIGxvY2FsIG1hY2hpbmUgbmFtZSAqLwogICAgICAgIHJldHVybiBSZWdPcGVuS2V5MTYoIGhLZXksICIiLCBwaGtSZXN1bHQgKTsKICAgIH0KCiAgICBGSVhNRSgiQ2Fubm90IGNvbm5lY3QgdG8gJXNcbiIsZGVidWdzdHJfdyhscE1hY2hpbmVOYW1lKSk7CiAgICByZXR1cm4gRVJST1JfQkFEX05FVFBBVEg7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyQSBbQURWQVBJMzIuMTI3XQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5QSggTFBDU1RSIG1hY2hpbmUsIEhLRVkgaGtleSwgTFBIS0VZIHJlc2tleSApCnsKICAgIERXT1JEIHJldDsKICAgIExQV1NUUiBtYWNoaW5lVyA9IHN0cmR1cEEyVyhtYWNoaW5lKTsKICAgIHJldCA9IFJlZ0Nvbm5lY3RSZWdpc3RyeVcoIG1hY2hpbmVXLCBoa2V5LCByZXNrZXkgKTsKICAgIGZyZWUobWFjaGluZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnR2V0S2V5U2VjdXJpdHkgW0FEVkFQSTMyLjE0NF0KICogUmV0cmlldmVzIGEgY29weSBvZiBzZWN1cml0eSBkZXNjcmlwdG9yIHByb3RlY3RpbmcgdGhlIHJlZ2lzdHJ5IGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgICAgICAgICBbSV0gICBPcGVuIGhhbmRsZSBvZiBrZXkgdG8gc2V0CiAqICAgIFNlY3VyaXR5SW5mb3JtYXRpb24gICAgW0ldICAgRGVzY3JpcHRvciBjb250ZW50cwogKiAgICBwU2VjdXJpdHlEZXNjcmlwdG9yICAgIFtPXSAgIEFkZHJlc3Mgb2YgZGVzY3JpcHRvciBmb3Iga2V5CiAqICAgIGxwY2JTZWN1cml0eURlc2NyaXB0b3IgW0kvT10gQWRkcmVzcyBvZiBzaXplIG9mIGJ1ZmZlciBhbmQgZGVzY3JpcHRpb24KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkxPTkcgV0lOQVBJIFJlZ0dldEtleVNlY3VyaXR5KCBIS0VZIGhrZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0VDVVJJVFlfSU5GT1JNQVRJT04gU2VjdXJpdHlJbmZvcm1hdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTRUNVUklUWV9ERVNDUklQVE9SIHBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JTZWN1cml0eURlc2NyaXB0b3IgKQp7CiAgICBUUkFDRSgiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksU2VjdXJpdHlJbmZvcm1hdGlvbixwU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvcj8qbHBjYlNlY3VyaXR5RGVzY3JpcHRvcjowKTsKCiAgICAvKiBGSVhNRTogQ2hlY2sgZm9yIHZhbGlkIFNlY3VyaXR5SW5mb3JtYXRpb24gdmFsdWVzICovCgogICAgaWYgKCpscGNiU2VjdXJpdHlEZXNjcmlwdG9yIDwgc2l6ZW9mKFNFQ1VSSVRZX0RFU0NSSVBUT1IpKQogICAgICAgIHJldHVybiBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSOwoKICAgIEZJWE1FKCIoJXgsJWxkLCVwLCVsZCk6IHN0dWJcbiIsaGtleSxTZWN1cml0eUluZm9ybWF0aW9uLAogICAgICAgICAgcFNlY3VyaXR5RGVzY3JpcHRvcixscGNiU2VjdXJpdHlEZXNjcmlwdG9yPypscGNiU2VjdXJpdHlEZXNjcmlwdG9yOjApOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdOb3RpZnlDaGFuZ2VLZXlWYWx1ZSBbQURWQVBJMzIuPz8/XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgIFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdhdGNoCiAqICAgIGZXYXRjaFN1YlRyZWUgICBbSV0gRmxhZyBmb3Igc3Via2V5IG5vdGlmaWNhdGlvbgogKiAgICBmZHdOb3RpZnlGaWx0ZXIgW0ldIENoYW5nZXMgdG8gYmUgcmVwb3J0ZWQKICogICAgaEV2ZW50ICAgICAgICAgIFtJXSBIYW5kbGUgb2Ygc2lnbmFsZWQgZXZlbnQKICogICAgZkFzeW5jICAgICAgICAgIFtJXSBGbGFnIGZvciBhc3luY2hyb25vdXMgcmVwb3J0aW5nCiAqLwpMT05HIFdJTkFQSSBSZWdOb3RpZnlDaGFuZ2VLZXlWYWx1ZSggSEtFWSBoa2V5LCBCT09MIGZXYXRjaFN1YlRyZWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZmR3Tm90aWZ5RmlsdGVyLCBIQU5ETEUgaEV2ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBmQXN5bmMgKQp7CiAgICBGSVhNRSgiKCV4LCVpLCVsZCwleCwlaSk6IHN0dWJcbiIsaGtleSxmV2F0Y2hTdWJUcmVlLGZkd05vdGlmeUZpbHRlciwKICAgICAgICAgIGhFdmVudCxmQXN5bmMpOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1VuTG9hZEtleTMyVyBbQURWQVBJMzIuMTczXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscFN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleSB0byB1bmxvYWQKICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSApCnsKICAgIEZJWE1FKCIoJXgsJXMpOiBzdHViXG4iLGhrZXksIGRlYnVnc3RyX3cobHBTdWJLZXkpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXkzMkEgW0FEVkFQSTMyLjE3Ml0KICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5ICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBTdWJLZXlXID0gc3RyZHVwQTJXKGxwU3ViS2V5KTsKICAgIHJldCA9IFJlZ1VuTG9hZEtleVcoIGhrZXksIGxwU3ViS2V5VyApOwogICAgaWYobHBTdWJLZXlXKSBmcmVlKGxwU3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTY3XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICBbSV0gT3BlbiBoYW5kbGUgb2Yga2V5IHRvIHNldAogKiAgICBTZWN1cml0eUluZm8gIFtJXSBEZXNjcmlwdG9yIGNvbnRlbnRzCiAqICAgIHBTZWN1cml0eURlc2MgW0ldIEFkZHJlc3Mgb2YgZGVzY3JpcHRvciBmb3Iga2V5CiAqLwpMT05HIFdJTkFQSSBSZWdTZXRLZXlTZWN1cml0eSggSEtFWSBoa2V5LCBTRUNVUklUWV9JTkZPUk1BVElPTiBTZWN1cml0eUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU0VDVVJJVFlfREVTQ1JJUFRPUiBwU2VjdXJpdHlEZXNjICkKewogICAgVFJBQ0UoIigleCwlbGQsJXApXG4iLGhrZXksU2VjdXJpdHlJbmZvLHBTZWN1cml0eURlc2MpOwoKICAgIC8qIEl0IHNlZW1zIHRvIHBlcmZvcm0gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICgoU2VjdXJpdHlJbmZvICYgT1dORVJfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIEdST1VQX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBEQUNMX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBTQUNMX1NFQ1VSSVRZX0lORk9STUFUSU9OKSkgewogICAgICAgIC8qIFBhcmFtIE9LICovCiAgICB9IGVsc2UKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgaWYgKCFwU2VjdXJpdHlEZXNjKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBGSVhNRSgiOigleCwlbGQsJXApOiBzdHViXG4iLGhrZXksU2VjdXJpdHlJbmZvLHBTZWN1cml0eURlc2MpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5MzJXIFtBRFZBUEkzMi4xNjRdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgIFtJXSBIYW5kbGUgb2Yga2V5IHdoZXJlIHJlc3RvcmUgYmVnaW5zCiAqICAgIGxwRmlsZSAgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgY29udGFpbmluZyBzYXZlZCB0cmVlCiAqICAgIGR3RmxhZ3MgW0ldIE9wdGlvbmFsIGZsYWdzCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIFRSQUNFKCIoJXgsJXMsJWxkKVxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBJdCBzZWVtcyB0byBkbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscEZpbGUgfHwgISpscEZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIEZJWE1FKCIoJXgsJXMsJWxkKTogc3R1YlxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBDaGVjayBmb3IgZmlsZSBleGlzdGVuY2UgKi8KCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleTMyQSBbQURWQVBJMzIuMTYzXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVzdG9yZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwRmlsZVcgPSBzdHJkdXBBMlcobHBGaWxlKTsKICAgIHJldCA9IFJlZ1Jlc3RvcmVLZXlXKCBoa2V5LCBscEZpbGVXLCBkd0ZsYWdzICk7CiAgICBpZihscEZpbGVXKSBmcmVlKGxwRmlsZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleTMyVyBbQURWQVBJMzIuMTYyXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBTdWJLZXkgIFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5CiAqICAgIGxwTmV3RmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgZmlsZSB3aXRoIG5ldyBkYXRhCiAqICAgIGxwT2xkRmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgYmFja3VwIGZpbGUKICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBTdWJLZXksIExQQ1dTVFIgbHBOZXdGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIGxwT2xkRmlsZSApCnsKICAgIEZJWE1FKCIoJXgsJXMsJXMsJXMpOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwU3ViS2V5KSwgCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5MzJBIFtBRFZBUEkzMi4xNjFdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXBsYWNlS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXksIExQQ1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscE9sZEZpbGUgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscFN1YktleVcgPSBzdHJkdXBBMlcobHBTdWJLZXkpOwogICAgTFBXU1RSIGxwTmV3RmlsZVcgPSBzdHJkdXBBMlcobHBOZXdGaWxlKTsKICAgIExQV1NUUiBscE9sZEZpbGVXID0gc3RyZHVwQTJXKGxwT2xkRmlsZSk7CiAgICByZXQgPSBSZWdSZXBsYWNlS2V5VyggaGtleSwgbHBTdWJLZXlXLCBscE5ld0ZpbGVXLCBscE9sZEZpbGVXICk7CiAgICBmcmVlKGxwT2xkRmlsZVcpOwogICAgZnJlZShscE5ld0ZpbGVXKTsKICAgIGZyZWUobHBTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgoKCgoKLyogMTYtYml0IGZ1bmN0aW9ucyAqLwoKLyogMCBhbmQgMSBhcmUgdmFsaWQgcm9vdGtleXMgaW4gd2luMTYgc2hlbGwuZGxsIGFuZCBhcmUgdXNlZCBieQogKiBzb21lIHByb2dyYW1zLiBEbyBub3QgcmVtb3ZlIHRob3NlIGNhc2VzLiAtTU0KICovCnN0YXRpYyBpbmxpbmUgdm9pZCBmaXhfd2luMTZfaGtleSggSEtFWSAqaGtleSApCnsKICAgIGlmICgqaGtleSA9PSAwIHx8ICpoa2V5ID09IDEpICpoa2V5ID0gSEtFWV9DTEFTU0VTX1JPT1Q7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0VudW1LZXkxNiAgIFtLRVJORUwuMjE2XSBbU0hFTEwuN10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MTYoIEhLRVkgaGtleSwgRFdPUkQgaW5kZXgsIExQU1RSIG5hbWUsIERXT1JEIG5hbWVfbGVuICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRW51bUtleUEoIGhrZXksIGluZGV4LCBuYW1lLCBuYW1lX2xlbiApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdPcGVuS2V5MTYgICBbS0VSTkVMLjIxN10gW1NIRUxMLjFdCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUEhLRVkgcmV0a2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnT3BlbktleUEoIGhrZXksIG5hbWUsIHJldGtleSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdDcmVhdGVLZXkxNiAgIFtLRVJORUwuMjE4XSBbU0hFTEwuMl0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBIS0VZIHJldGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0NyZWF0ZUtleUEoIGhrZXksIG5hbWUsIHJldGtleSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdEZWxldGVLZXkxNiAgIFtLRVJORUwuMjE5XSBbU0hFTEwuNF0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0RlbGV0ZUtleUEoIGhrZXksIG5hbWUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnQ2xvc2VLZXkxNiAgIFtLRVJORUwuMjIwXSBbU0hFTEwuM10KICovCkRXT1JEIFdJTkFQSSBSZWdDbG9zZUtleTE2KCBIS0VZIGhrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdDbG9zZUtleSggaGtleSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdTZXRWYWx1ZTE2ICAgW0tFUk5FTC4yMjFdIFtTSEVMTC41XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIERXT1JEIHR5cGUsIExQQ1NUUiBkYXRhLCBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlQSggaGtleSwgbmFtZSwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRGVsZXRlVmFsdWUxNiAgW0tFUk5FTC4yMjJdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUxNiggSEtFWSBoa2V5LCBMUFNUUiBuYW1lICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRGVsZXRlVmFsdWVBKCBoa2V5LCBuYW1lICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0VudW1WYWx1ZTE2ICAgW0tFUk5FTC4yMjNdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMTYoIEhLRVkgaGtleSwgRFdPUkQgaW5kZXgsIExQU1RSIHZhbHVlLCBMUERXT1JEIHZhbF9jb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIHJlc2VydmVkLCBMUERXT1JEIHR5cGUsIExQQllURSBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRW51bVZhbHVlQSggaGtleSwgaW5kZXgsIHZhbHVlLCB2YWxfY291bnQsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdRdWVyeVZhbHVlMTYgICBbS0VSTkVMLjIyNF0gW1NIRUxMLjZdCiAqCiAqIE5PVEVTCiAqICAgIElzIHRoaXMgSEFDSyBzdGlsbCBhcHBsaWNhYmxlPwogKgogKiBIQUNLCiAqICAgIFRoZSAxNmJpdCBSZWdRdWVyeVZhbHVlIGRvZXNuJ3QgaGFuZGxlIHNlbGVjdG9yYmxvY2tzIGFueXdheSwgc28gd2UganVzdAogKiAgICBtYXNrIG91dCB0aGUgaGlnaCAxNiBiaXQuICBUaGlzIChub3Qgc28gbXVjaCBpbmNpZGVudGx5KSBob3BlZnVsbHkgZml4ZXMKICogICAgQWxkdXMgRkg0KQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBTVFIgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgaWYgKGNvdW50KSAqY291bnQgJj0gMHhmZmZmOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVBKCBoa2V5LCBuYW1lLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdRdWVyeVZhbHVlRXgxNiAgIFtLRVJORUwuMjI1XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUERXT1JEIHJlc2VydmVkLCBMUERXT1JEIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlRXhBKCBoa2V5LCBuYW1lLCByZXNlcnZlZCwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnU2V0VmFsdWVFeDE2ICAgW0tFUk5FTC4yMjZdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBEV09SRCByZXNlcnZlZCwgRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09OU1QgQllURSAqZGF0YSwgRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUV4QSggaGtleSwgbmFtZSwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0K