LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICogQ29weXJpZ2h0IDE5OTkgU3lsdmFpbiBTdC1HZXJtYWluCiAqCiAqIERlY2VtYmVyIDIxLCAxOTk3IC0gS2V2aW4gQ296ZW5zCiAqIEZpeGVkIGJ1Z3MgaW4gdGhlIF93OTVfbG9hZHJlZygpIGZ1bmN0aW9uLiBBZGRlZCBleHRyYSBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgdGhlIGZvcm1hdCBvZiB0aGUgV2luZG93cyAnOTUgcmVnaXN0cnkgZmlsZXMuCiAqCiAqIE5PVEVTCiAqICAgIFdoZW4gY2hhbmdpbmcgdGhpcyBmaWxlLCBwbGVhc2UgcmUtcnVuIHRoZSByZWd0ZXN0IHByb2dyYW0gdG8gZW5zdXJlCiAqICAgIHRoZSBjb25kaXRpb25zIGFyZSBoYW5kbGVkIHByb3Blcmx5LgogKgogKiBUT0RPCiAqICAgIFNlY3VyaXR5IGFjY2VzcwogKiAgICBPcHRpb24gaGFuZGxpbmcKICogICAgVGltZSBmb3IgUmVnRW51bUtleSosIFJlZ1F1ZXJ5SW5mb0tleSoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpZmRlZiBIQVZFX1NZU19FUlJOT19ICiNpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmUvd2luZXN0cmluZy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgImRlYnVndG9vbHMuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIm9wdGlvbnMuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAic2VydmVyLmgiCiNpbmNsdWRlICJzZXJ2aWNlcy5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKHJlZykKCnN0YXRpYyB2b2lkIFJFR0lTVFJZX0luaXQodm9pZCk7Ci8qIEZJWE1FOiBmb2xsb3dpbmcgZGVmaW5lcyBzaG91bGQgYmUgY29uZmlndXJlZCBnbG9iYWwgLi4uICovCgovKiBOT1RFOiBkbyBub3QgYXBwZW5kIGEgLy4gbGludXgnIG1rZGlyKCkgV0lMTCBGQUlMIGlmIHlvdSBkbyB0aGF0ICovCiNkZWZpbmUgV0lORV9QUkVGSVggICAgICAgICAgICAgICAgICIvLndpbmUiCiNkZWZpbmUgU0FWRV9VU0VSU19ERUZBVUxUICAgICAgICAgIEVUQ0RJUiIvd2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUICBFVENESVIiL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0NVUlJFTlRfVVNFUiAgICAgICAgICAgInVzZXIucmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCAgICAid2luZS51c2VycmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORSAgICAgICAgICAic3lzdGVtLnJlZyIKCiNkZWZpbmUgS0VZX1JFR0lTVFJZICAgICAgICAgICAgICAgICJTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnkiCiNkZWZpbmUgVkFMX1NBVkVVUERBVEVEICAgICAgICAgICAgICJTYXZlT25seVVwZGF0ZWRLZXlzIgoKCi8qIHdoYXQgdmFsdWV0eXBlcyBkbyB3ZSBuZWVkIHRvIGNvbnZlcnQ/ICovCiNkZWZpbmUgVU5JQ09OVk1BU0sJKCgxPDxSRUdfU1opfCgxPDxSRUdfTVVMVElfU1opfCgxPDxSRUdfRVhQQU5EX1NaKSkKCgoKLyoKICogUVVFU1RJT04KICogICBBcmUgdGhlc2UgZG9pbmcgdGhlIHNhbWUgYXMgSEVBUF9zdHJkdXBBdG9XIGFuZCBIRUFQX3N0cmR1cFd0b0E/CiAqICAgSWYgc28sIGNhbiB3ZSByZW1vdmUgdGhlbT8KICogQU5TV0VSCiAqICAgTm8sIHRoZSBtZW1vcnkgaGFuZGxpbmcgZnVuY3Rpb25zIGFyZSBjYWxsZWQgdmVyeSBvZnRlbiBpbiBoZXJlLCAKICogICBqdXN0IHJlcGxhY2luZyB0aGVtIGJ5IEhlYXBBbGxvYyhTeXN0ZW1IZWFwLC4uLikgbWFrZXMgcmVnaXN0cnkKICogICBsb2FkaW5nIDEwMCB0aW1lcyBzbG93ZXIuIC1NTQogKi8Kc3RhdGljIExQV1NUUiBzdHJkdXBBMlcoTFBDU1RSIHNyYykKewogICAgaWYoc3JjKSB7CglMUFdTVFIgZGVzdD14bWFsbG9jKDIqc3RybGVuKHNyYykrMik7Cglsc3RyY3B5QXRvVyhkZXN0LHNyYyk7CglyZXR1cm4gZGVzdDsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgpMUFdTVFIgc3RyY3Z0QTJXKExQQ1NUUiBzcmMsIGludCBuY2hhcnMpCgp7CiAgIExQV1NUUiBkZXN0ID0geG1hbGxvYyAoMiAqIG5jaGFycyArIDIpOwoKICAgbHN0cmNweW5BdG9XKGRlc3Qsc3JjLG5jaGFycysxKTsKICAgcmV0dXJuIGRlc3Q7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSRUdJU1RSWV9Jbml0IFtJbnRlcm5hbF0KICogUmVnaXN0cnkgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBzb21lIGRlZmF1bHQga2V5cy4gCiAqLwpzdGF0aWMgdm9pZCBSRUdJU1RSWV9Jbml0KHZvaWQpIHsKCUhLRVkJaGtleTsKCWNoYXIJYnVmWzIwMF07CgoJVFJBQ0UoIih2b2lkKVxuIik7CgoJUmVnQ3JlYXRlS2V5QShIS0VZX0RZTl9EQVRBLCJQZXJmU3RhdHNcXFN0YXREYXRhIiwmaGtleSk7CglSZWdDbG9zZUtleShoa2V5KTsKCiAgICAgICAgLyogVGhpcyB3YXMgYW4gT3BlbiwgYnV0IHNpbmNlIGl0IGlzIGNhbGxlZCBiZWZvcmUgdGhlIHJlYWwgcmVnaXN0cmllcwogICAgICAgICAgIGFyZSBsb2FkZWQsIGl0IHdhcyBjaGFuZ2VkIHRvIGEgQ3JlYXRlIC0gTVRCIDk4MDUwNyovCglSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiSEFSRFdBUkVcXERFU0NSSVBUSU9OXFxTeXN0ZW0iLCZoa2V5KTsKCVJlZ1NldFZhbHVlRXhBKGhrZXksIklkZW50aWZpZXIiLDAsUkVHX1NaLCJTeXN0ZW1UeXBlIFdJTkUiLHN0cmxlbigiU3lzdGVtVHlwZSBXSU5FIikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogXFxTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3cgTlRcXEN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRWZXJzaW9uCgkgKgkJCQkJCUN1cnJlbnRCdWlsZE51bWJlcgoJICoJCQkJCQlDdXJyZW50VHlwZQoJICoJCQkJCXN0cmluZwlSZWdpc3RlcmVkT3duZXIKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE9yZ2FuaXphdGlvbgoJICoKCSAqLwoJLyogU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXFNOTVBcXFBhcmFtZXRlcnNcXFJGQzExNTZBZ2VudAoJICogCQkJCQlzdHJpbmcJU3lzQ29udGFjdAoJICogCQkJCQlzdHJpbmcJU3lzTG9jYXRpb24KCSAqIAkJCQkJCVN5c1NlcnZpY2VzCgkgKi8KCWlmICgtMSE9Z2V0aG9zdG5hbWUoYnVmLDIwMCkpIHsKCQlSZWdDcmVhdGVLZXlBKEhLRVlfTE9DQUxfTUFDSElORSwiU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcQ29tcHV0ZXJOYW1lXFxDb21wdXRlck5hbWUiLCZoa2V5KTsKCQlSZWdTZXRWYWx1ZUV4QShoa2V5LCJDb21wdXRlck5hbWUiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSsxKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKiogU0FWRSBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBSRUdJU1RSWV9TQVZFX1ZFUlNJT04JMHgwMDAwMDAwMQoKLyogUmVnaXN0cnkgc2F2ZWZvcm1hdDoKICogSWYgeW91IGNoYW5nZSBpdCwgaW5jcmVhc2UgYWJvdmUgbnVtYmVyIGJ5IDEsIHdoaWNoIHdpbGwgZmx1c2gKICogb2xkIHJlZ2lzdHJ5IGRhdGFiYXNlIGZpbGVzLgogKiAKICogR2xvYmFsOgogKiAJIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIKICogCXN1YmtleXMuLi4uCiAqIFN1YmtleXM6CiAqIAlrZXluYW1lCiAqCQl2YWx1ZW5hbWU9bGFzdG1vZGlmaWVkLHR5cGUsZGF0YQogKgkJLi4uCiAqCQlzdWJrZXlzCiAqCS4uLgogKiBrZXluYW1lLHZhbHVlbmFtZSxzdHJpbmdkYXRhOgogKgl0aGUgdXN1YWwgYXNjaWkgY2hhcmFjdGVycyBmcm9tIDB4MDAtMHhmZiAod2VsbCwgbm90IDB4MDApCiAqCWFuZCBcdVhYWFggYXMgVU5JQ09ERSB2YWx1ZSBYWFhYIHdpdGggWFhYWD4weGZmCiAqCSggIj1cXFx0IiBlc2NhcGVkIGluIFx1WFhYWCBmb3JtLikKICogdHlwZSxsYXN0bW9kaWZpZWQ6IAogKglpbnQKICogCiAqIEZJWE1FOiBkb2Vzbid0IHNhdmUgJ2NsYXNzJyAod2hhdCBkb2VzIGl0IG1lYW4gYW55d2F5PyksIG5vciBmbGFncy4KICoKICogW0hLRVlfQ1VSUkVOVF9VU0VSXFxTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnldCiAqIFNhdmVPbmx5VXBkYXRlZEtleXM9eWVzCiAqLwoKLyogU2FtZSBhcyBSZWdTYXZlS2V5IGJ1dCB3aXRoIFVuaXggcGF0aG5hbWVzICovCnN0YXRpYyB2b2lkIHNhdmVfa2V5KCBIS0VZIGhrZXksIGNvbnN0IGNoYXIgKmZpbGVuYW1lICkKewogICAgc3RydWN0IHNhdmVfcmVnaXN0cnlfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKICAgIGludCBjb3VudCA9IDA7CiAgICBEV09SRCByZXQ7CiAgICBIQU5ETEUgaGFuZGxlOwogICAgY2hhciAqcDsKICAgIGNoYXIgKm5hbWUgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihmaWxlbmFtZSkgKyAyMCApOwoKICAgIGlmICghbmFtZSkgcmV0dXJuOwogICAgc3RyY3B5KCBuYW1lLCBmaWxlbmFtZSApOwogICAgaWYgKChwID0gc3RycmNociggbmFtZSwgJy8nICkpKSBwKys7CiAgICBlbHNlIHAgPSBuYW1lOwoKICAgIGZvciAoOzspCiAgICB7CiAgICAgICAgc3ByaW50ZiggcCwgInJlZyUwNHgudG1wIiwgY291bnQrKyApOwogICAgICAgIGhhbmRsZSA9IEZJTEVfQ3JlYXRlRmlsZSggbmFtZSwgR0VORVJJQ19XUklURSwgMCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENSRUFURV9ORVcsIEZJTEVfQVRUUklCVVRFX05PUk1BTCwgLTEgKTsKICAgICAgICBpZiAoaGFuZGxlICE9IElOVkFMSURfSEFORExFX1ZBTFVFKSBicmVhazsKICAgICAgICBpZiAoKHJldCA9IEdldExhc3RFcnJvcigpKSAhPSBFUlJPUl9GSUxFX0VYSVNUUykgYnJlYWs7CiAgICB9CgogICAgaWYgKGhhbmRsZSAhPSBJTlZBTElEX0hBTkRMRV9WQUxVRSkKICAgIHsKICAgICAgICByZXEtPmhrZXkgPSBoa2V5OwogICAgICAgIHJlcS0+ZmlsZSA9IGhhbmRsZTsKICAgICAgICByZXQgPSBzZXJ2ZXJfY2FsbF9ub2VyciggUkVRX1NBVkVfUkVHSVNUUlkgKTsKICAgICAgICBDbG9zZUhhbmRsZSggaGFuZGxlICk7CiAgICAgICAgaWYgKHJldCkgdW5saW5rKCBuYW1lICk7CiAgICAgICAgZWxzZSBpZiAocmVuYW1lKCBuYW1lLCBmaWxlbmFtZSApID09IC0xKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCAiRmFpbGVkIHRvIG1vdmUgJXMgdG8gJXM6ICIsIG5hbWUsIGZpbGVuYW1lICk7CiAgICAgICAgICAgIHBlcnJvciggInJlbmFtZSIgKTsKICAgICAgICAgICAgdW5saW5rKCBuYW1lICk7CiAgICAgICAgfQogICAgfQogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIG5hbWUgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hFTExfU2F2ZVJlZ2lzdHJ5QnJhbmNoIFtJbnRlcm5hbF0KICoKICogU2F2ZXMgbWFpbiByZWdpc3RyeSBicmFuY2ggc3BlY2lmaWVkIGJ5IGhrZXkuCiAqLwpzdGF0aWMgdm9pZCBTSEVMTF9TYXZlUmVnaXN0cnlCcmFuY2goSEtFWSBoa2V5KQp7CiAgICBjaGFyICAgKmZuLCAqaG9tZTsKCiAgICAvKiBGaW5kIG91dCB3aGF0IHRvIHNhdmUgdG8sIGdldCBmcm9tIGNvbmZpZyBmaWxlICovCiAgICBCT09MIHdyaXRlVG9Ib21lID0gUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgicmVnaXN0cnkiLCJXcml0ZXRvSG9tZVJlZ2lzdHJpZXMiLDEpOwogICAgQk9PTCB3cml0ZVRvQWx0ID0gUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgicmVnaXN0cnkiLCJXcml0ZXRvQWx0UmVnaXN0cmllcyIsMSk7CgogICAgLyogRklYTUU6IGRvZXMgdGhpcyBjaGVjayBhcHBseSB0byBhbGwga2V5cyB3cml0dGVuIGJlbG93ID8gKi8KICAgIGlmICghKGhvbWUgPSBnZXRlbnYoICJIT01FIiApKSkKICAgICAgICBFUlIoIkZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWxkLlxuIiwobG9uZykgZ2V0dWlkKCkpOwoKICAgIC8qIEhLRVlfTE9DQUxfTUFDSElORSBjb250YWlucyB0aGUgSEtFWV9DTEFTU0VTX1JPT1QgYnJhbmNoICovCiAgICBpZiAoaGtleSA9PSBIS0VZX0NMQVNTRVNfUk9PVCkgaGtleSA9IEhLRVlfTE9DQUxfTUFDSElORTsKCiAgICBzd2l0Y2ggKGhrZXkpCiAgICB7CiAgICBjYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgogICAgICAgIGZuID0geG1hbGxvYyggTUFYX1BBVEhOQU1FX0xFTiApOyAKICAgICAgICBpZiAod3JpdGVUb0FsdCAmJiBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJyZWdpc3RyeSIsICJBbHRDdXJyZW50VXNlckZpbGUiLCAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZuLCBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpCiAgICAgICAgICAgIHNhdmVfa2V5KCBIS0VZX0NVUlJFTlRfVVNFUiwgZm4gKTsKICAgICAgICBmcmVlIChmbik7CgogICAgICAgIGlmIChob21lICYmIHdyaXRlVG9Ib21lKQogICAgICAgIHsKICAgICAgICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfQ1VSUkVOVF9VU0VSKSArIDIgKTsKICAgICAgICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICAgICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgpOwogIAogICAgICAgICAgICAvKiBjcmVhdGUgdGhlIGRpcmVjdG9yeS4gZG9uJ3QgY2FyZSBhYm91dCBlcnJvcmNvZGVzLiAqLwogICAgICAgICAgICBta2RpcihmbiwwNzU1KTsgLyogZHJ3eHIteHIteCAqLwogICAgICAgICAgICBzdHJjYXQoZm4sIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwogICAgICAgICAgICBzYXZlX2tleSggSEtFWV9DVVJSRU5UX1VTRVIsIGZuICk7CiAgICAgICAgICAgIGZyZWUoZm4pOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgSEtFWV9MT0NBTF9NQUNISU5FOgogICAgICAgIC8qIFRyeSBmaXJzdCBzYXZpbmcgYWNjb3JkaW5nIHRvIHRoZSBkZWZpbmVkIGxvY2F0aW9uIGluIC53aW5lcmMgKi8KICAgICAgICBmbiA9IHhtYWxsb2MgKCBNQVhfUEFUSE5BTUVfTEVOKTsKICAgICAgICBpZiAod3JpdGVUb0FsdCAmJiBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJSZWdpc3RyeSIsICJBbHRMb2NhbE1hY2hpbmVGaWxlIiwgIiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm4sIE1BWF9QQVRITkFNRV9MRU4gLSAxKSkKICAgICAgICAgICAgc2F2ZV9rZXkoIEhLRVlfTE9DQUxfTUFDSElORSwgZm4gKTsKICAgICAgICBmcmVlIChmbik7CgogICAgICAgIGlmIChob21lICYmIHdyaXRlVG9Ib21lKQogICAgICAgIHsKICAgICAgICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfTE9DQUxfTUFDSElORSkgKyAyKTsKICAgICAgICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICAgICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwogICAgICAgICAgICBzYXZlX2tleSggSEtFWV9MT0NBTF9NQUNISU5FLCBmbiApOwogICAgICAgICAgICBmcmVlKGZuKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEhLRVlfVVNFUlM6CiAgICAgICAgZm4gPSB4bWFsbG9jKCBNQVhfUEFUSE5BTUVfTEVOICk7CiAgICAgICAgaWYgKHdyaXRlVG9BbHQgJiYgUFJPRklMRV9HZXRXaW5lSW5pU3RyaW5nKCAiUmVnaXN0cnkiLCAiQWx0VXNlckZpbGUiLCAiIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiwgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKQogICAgICAgICAgICBzYXZlX2tleSggSEtFWV9VU0VSUywgZm4gKTsKICAgICAgICBmcmVlIChmbik7CgogICAgICAgIGlmIChob21lICYmIHdyaXRlVG9Ib21lKQogICAgICAgIHsKICAgICAgICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RybGVuKFNBVkVfTE9DQUxfVVNFUlNfREVGQVVMVCkgKyAyKTsKICAgICAgICAgICAgc3RyY3B5KGZuLGhvbWUpOwogICAgICAgICAgICBzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpOwogICAgICAgICAgICBzYXZlX2tleSggSEtFWV9VU0VSUywgZm4gKTsKICAgICAgICAgICAgZnJlZShmbik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBFUlIoInVua25vd24vaW52YWxpZCBrZXkgaGFuZGxlICFcbiIpOwogICAgICAgIGJyZWFrOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEVMTF9TYXZlUmVnaXN0cnkgW0ludGVybmFsXQogKi8Kdm9pZCBTSEVMTF9TYXZlUmVnaXN0cnkoIHZvaWQgKQp7CiAgICBzdHJ1Y3Qgc2V0X3JlZ2lzdHJ5X2xldmVsc19yZXF1ZXN0ICpyZXEgPSBnZXRfcmVxX2J1ZmZlcigpOwogICAgY2hhciAgIGJ1Zls0XTsKICAgIEhLRVkgICBoa2V5OwogICAgaW50ICAgIGFsbDsKCiAgICBUUkFDRSgiKHZvaWQpXG4iKTsKCiAgICBhbGw9MDsKICAgIGlmIChSZWdPcGVuS2V5QShIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpIT1FUlJPUl9TVUNDRVNTKSAKICAgIHsKICAgICAgICBzdHJjcHkoYnVmLCJ5ZXMiKTsKICAgIH0gCiAgICBlbHNlIAogICAgewogICAgICAgIERXT1JEIGxlbixqdW5rLHR5cGU7CgogICAgICAgIGxlbj00OwogICAgICAgIGlmICgoRVJST1JfU1VDQ0VTUyE9UmVnUXVlcnlWYWx1ZUV4QSggaGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBTF9TQVZFVVBEQVRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZqdW5rLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbGVuKSkgfHwgKHR5cGUhPVJFR19TWikpCiAgICAgICAgewogICAgICAgICAgICBzdHJjcHkoYnVmLCJ5ZXMiKTsKICAgICAgICB9CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICB9CgogICAgaWYgKGxzdHJjbXBpQShidWYsInllcyIpKSBhbGwgPSAxOwoKICAgIC8qIHNldCBzYXZpbmcgbGV2ZWwgKDAgZm9yIHNhdmluZyBldmVyeXRoaW5nLCAxIGZvciBzYXZpbmcgb25seSBtb2RpZmllZCBrZXlzKSAqLwogICAgcmVxLT5jdXJyZW50ID0gMTsKICAgIHJlcS0+c2F2aW5nICA9ICFhbGw7CiAgICByZXEtPnZlcnNpb24gPSBQUk9GSUxFX0dldFdpbmVJbmlCb29sKCAicmVnaXN0cnkiLCAiVXNlTmV3Rm9ybWF0IiwgMCApID8gMiA6IDE7CiAgICBzZXJ2ZXJfY2FsbCggUkVRX1NFVF9SRUdJU1RSWV9MRVZFTFMgKTsKCiAgICBTSEVMTF9TYXZlUmVnaXN0cnlCcmFuY2goSEtFWV9DVVJSRU5UX1VTRVIpOwogICAgU0hFTExfU2F2ZVJlZ2lzdHJ5QnJhbmNoKEhLRVlfTE9DQUxfTUFDSElORSk7CiAgICBTSEVMTF9TYXZlUmVnaXN0cnlCcmFuY2goSEtFWV9VU0VSUyk7Cn0KCi8qIFBlcmlvZGljIHNhdmUgY2FsbGJhY2sgKi8Kc3RhdGljIHZvaWQgQ0FMTEJBQ0sgcGVyaW9kaWNfc2F2ZSggVUxPTkdfUFRSIGR1bW15ICkKewogICAgU0hFTExfU2F2ZVJlZ2lzdHJ5KCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKiogTE9BRCBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF9rZXkgW0ludGVybmFsXQogKi8Kc3RhdGljIGlubGluZSBIS0VZIF9maW5kX29yX2FkZF9rZXkoIEhLRVkgaGtleSwgTFBXU1RSIGtleW5hbWUgKQp7CiAgICBIS0VZIHN1YmtleTsKICAgIGlmIChSZWdDcmVhdGVLZXlXKCBoa2V5LCBrZXluYW1lLCAmc3Via2V5ICkgIT0gRVJST1JfU1VDQ0VTUykgc3Via2V5ID0gMDsKICAgIGlmIChrZXluYW1lKSBmcmVlKCBrZXluYW1lICk7CiAgICByZXR1cm4gc3Via2V5Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF92YWx1ZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfZmluZF9vcl9hZGRfdmFsdWUoIEhLRVkgaGtleSwgTFBXU1RSIG5hbWUsIERXT1JEIHR5cGUsIExQQllURSBkYXRhLCBEV09SRCBsZW4gKQp7CiAgICBSZWdTZXRWYWx1ZUV4VyggaGtleSwgbmFtZSwgMCwgdHlwZSwgZGF0YSwgbGVuICk7CiAgICBpZiAobmFtZSkgZnJlZSggbmFtZSApOwogICAgaWYgKGRhdGEpIGZyZWUoIGRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3dpbmVfcmVhZF9saW5lIFtJbnRlcm5hbF0KICoKICogcmVhZHMgYSBsaW5lIGluY2x1ZGluZyBkeW5hbWljYWxseSBlbmxhcmdpbmcgdGhlIHJlYWRidWZmZXIgYW5kIHRocm93aW5nCiAqIGF3YXkgY29tbWVudHMKICovCnN0YXRpYyBpbnQgX3dpbmVfcmVhZF9saW5lKCBGSUxFICpGLCBjaGFyICoqYnVmLCBpbnQgKmxlbiApCnsKCWNoYXIJKnMsKmN1cnJlYWQ7CglpbnQJbXlsZW4sY3Vyb2ZmOwoKCWN1cnJlYWQJPSAqYnVmOwoJbXlsZW4JPSAqbGVuOwoJKipidWYJPSAnXDAnOwoJd2hpbGUgKDEpIHsKCQl3aGlsZSAoMSkgewoJCQlzPWZnZXRzKGN1cnJlYWQsbXlsZW4sRik7CgkJCWlmIChzPT1OVUxMKQoJCQkJcmV0dXJuIDA7IC8qIEVPRiAqLwoJCQlpZiAoTlVMTD09KHM9c3RyY2hyKGN1cnJlYWQsJ1xuJykpKSB7CgkJCQkvKiBidWZmZXIgd2Fzbid0IGxhcmdlIGVub3VnaCAqLwoJCQkJY3Vyb2ZmCT0gc3RybGVuKCpidWYpOwoJCQkJKmJ1Zgk9IHhyZWFsbG9jKCpidWYsKmxlbioyKTsKCQkJCWN1cnJlYWQJPSAqYnVmICsgY3Vyb2ZmOwoJCQkJbXlsZW4JPSAqbGVuOwkvKiB3ZSBmaWxsZWQgdXAgdGhlIGJ1ZmZlciBhbmQgCgkJCQkJCSAqIGdvdCBuZXcgJypsZW4nIGJ5dGVzIHRvIGZpbGwKCQkJCQkJICovCgkJCQkqbGVuCT0gKmxlbiAqIDI7CgkJCX0gZWxzZSB7CgkJCQkqcz0nXDAnOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJLyogdGhyb3cgYXdheSBjb21tZW50cyAqLwoJCWlmICgqKmJ1Zj09JyMnIHx8ICoqYnVmPT0nOycpIHsKCQkJY3VycmVhZAk9ICpidWY7CgkJCW15bGVuCT0gKmxlbjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzKSAJLyogZ290IGVuZCBvZiBsaW5lICovCgkJCWJyZWFrOwoJfQoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfVVNUUklORyBbSW50ZXJuYWxdCiAqCiAqIGNvbnZlcnRzIGEgY2hhciogaW50byBhIFVOSUNPREUgc3RyaW5nICh1cCB0byBhIHNwZWNpYWwgY2hhcikKICogYW5kIHJldHVybnMgdGhlIHBvc2l0aW9uIGV4YWN0bHkgYWZ0ZXIgdGhhdCBzdHJpbmcKICovCnN0YXRpYyBjaGFyKiBfd2luZV9yZWFkX1VTVFJJTkcoIGNoYXIgKmJ1ZiwgTFBXU1RSICpzdHIgKQp7CgljaGFyCSpzOwoJTFBXU1RSCXdzOwoKCS8qIHJlYWQgdXAgdG8gIj0iIG9yICJcMCIgb3IgIlxuIiAqLwoJcwk9IGJ1ZjsKCSpzdHIJPSAoTFBXU1RSKXhtYWxsb2MoMipzdHJsZW4oYnVmKSsyKTsKCXdzCT0gKnN0cjsKCXdoaWxlICgqcyAmJiAoKnMhPSdcbicpICYmICgqcyE9Jz0nKSkgewoJCWlmICgqcyE9J1xcJykKCQkJKndzKys9KigodW5zaWduZWQgY2hhciopcysrKTsKCQllbHNlIHsKCQkJcysrOwoJCQlpZiAoISpzKSB7CgkJCQkvKiBEYW5nbGluZyBcIC4uLiBtYXkgb25seSBoYXBwZW4gaWYgYSByZWdpc3RyeQoJCQkJICogd3JpdGUgd2FzIHNob3J0LiBGSVhNRTogV2hhdCBkbyB0bz8KCQkJCSAqLwoJCQkJIGJyZWFrOwoJCQl9CgkJCWlmICgqcz09J1xcJykgewoJCQkJKndzKys9J1xcJzsKCQkJCXMrKzsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWlmICgqcyE9J3UnKSB7CgkJCQlXQVJOKCJOb24gdW5pY29kZSBlc2NhcGUgc2VxdWVuY2UgXFwlYyBmb3VuZCBpbiB8JXN8XG4iLCpzLGJ1Zik7CgkJCQkqd3MrKz0nXFwnOwoJCQkJKndzKys9KnMrKzsKCQkJfSBlbHNlIHsKCQkJCWNoYXIJeGJ1Zls1XTsKCQkJCWludAl3YzsKCgkJCQlzKys7CgkJCQltZW1jcHkoeGJ1ZixzLDQpO3hidWZbNF09J1wwJzsKCQkJCWlmICghc3NjYW5mKHhidWYsIiV4Iiwmd2MpKQoJCQkJCVdBUk4oIlN0cmFuZ2UgZXNjYXBlIHNlcXVlbmNlICVzIGZvdW5kIGluIHwlc3xcbiIseGJ1ZixidWYpOwoJCQkJcys9NDsKCQkJCSp3cysrCT0odW5zaWduZWQgc2hvcnQpd2M7CgkJCX0KCQl9Cgl9Cgkqd3MJPSAwOwoJcmV0dXJuIHM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRzdWJrZXkgW0ludGVybmFsXQogKgogKiBOT1RFUwogKiAgICBJdCBzZWVtcyBsaWtlIHRoaXMgaXMgcmV0dXJuaW5nIGEgYm9vbGVhbi4gIFNob3VsZCBpdD8KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiAxCiAqICAgIEZhaWx1cmU6IDAKICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YmtleSggRklMRSAqRiwgSEtFWSBoa2V5LCBpbnQgbGV2ZWwsIGNoYXIgKipidWYsIGludCAqYnVmbGVuICkKewogICAgCUhLRVkgc3Via2V5OwoJaW50CQlpOwoJY2hhcgkJKnM7CglMUFdTVFIJCW5hbWU7CgogICAgVFJBQ0UoIiglcCwleCwlZCwlcywlZClcbiIsIEYsIGhrZXksIGxldmVsLCBkZWJ1Z3N0cl9hKCpidWYpLCAqYnVmbGVuKTsKCiAgICAvKiBHb29kLiAgV2UgYWxyZWFkeSBnb3QgYSBsaW5lIGhlcmUgLi4uIHNvIHBhcnNlIGl0ICovCiAgICBzdWJrZXkgPSAwOwogICAgd2hpbGUgKDEpIHsKICAgICAgICBpPTA7cz0qYnVmOwogICAgICAgIHdoaWxlICgqcz09J1x0JykgewogICAgICAgICAgICBzKys7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9CiAgICAgICAgaWYgKGk+bGV2ZWwpIHsKICAgICAgICAgICAgaWYgKCFzdWJrZXkpIHsKICAgICAgICAgICAgICAgIFdBUk4oIkdvdCBhIHN1YmhpZXJhcmNoeSB3aXRob3V0IHJlc3AuIGtleT9cbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCSAgICBpZiAoIV93aW5lX2xvYWRzdWJrZXkoRixzdWJrZXksbGV2ZWwrMSxidWYsYnVmbGVuKSkKCSAgICAgICBpZiAoIV93aW5lX3JlYWRfbGluZShGLGJ1ZixidWZsZW4pKQoJCSAgZ290byBkb25lOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoJCS8qIGxldCB0aGUgY2FsbGVyIGhhbmRsZSB0aGlzIGxpbmUgKi8KCQlpZiAoaTxsZXZlbCB8fCAqKmJ1Zj09J1wwJykKCQkJZ290byBkb25lOwoKCQkvKiBpdCBjYW4gYmU6IGEgdmFsdWUgb3IgYSBrZXluYW1lLiBQYXJzZSB0aGUgbmFtZSBmaXJzdCAqLwoJCXM9X3dpbmVfcmVhZF9VU1RSSU5HKHMsJm5hbWUpOwoKCQkvKiBzd2l0Y2goKSBkZWZhdWx0OiBoYWNrIHRvIGF2b2lkIGdvdG9zICovCgkJc3dpdGNoICgwKSB7CgkJZGVmYXVsdDoKCQkJaWYgKCpzPT0nXDAnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwoJCQkJc3Via2V5PV9maW5kX29yX2FkZF9rZXkoaGtleSxuYW1lKTsKCQkJfSBlbHNlIHsKCQkJCUxQQllURQkJZGF0YTsKCQkJCWludAkJbGVuLGxhc3Rtb2RpZmllZCx0eXBlOwoKCQkJCWlmICgqcyE9Jz0nKSB7CgkJCQkJV0FSTigiVW5leHBlY3RlZCBjaGFyYWN0ZXI6ICVjXG4iLCpzKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCXMrKzsKCQkJCWlmICgyIT1zc2NhbmYocywiJWQsJWQsIiwmdHlwZSwmbGFzdG1vZGlmaWVkKSkgewoJCQkJCVdBUk4oIkhhdmVuJ3QgdW5kZXJzdG9vZCBwb3NzaWJsZSB2YWx1ZSBpbiB8JXN8LCBza2lwcGluZy5cbiIsKmJ1Zik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQkvKiBza2lwIHRoZSAyICwgKi8KCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlzPXN0cmNocihzLCcsJyk7CgkJCQlpZiAoIXMrKykgewoJCQkJCVdBUk4oIkhhdmVuJ3QgdW5kZXJzdG9vZCBwb3NzaWJsZSB2YWx1ZSBpbiB8JXN8LCBza2lwcGluZy5cbiIsKmJ1Zik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlpZiAodHlwZSA9PSBSRUdfU1ogfHwgdHlwZSA9PSBSRUdfRVhQQU5EX1NaKSB7CgkJCQkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywoTFBXU1RSKikmZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4gPSBsc3RybGVuVygoTFBXU1RSKWRhdGEpKjIrMjsKCQkJCX0gZWxzZSB7CgkJCQkJbGVuPXN0cmxlbihzKS8yOwoJCQkJCWRhdGEgPSAoTFBCWVRFKXhtYWxsb2MobGVuKzEpOwoJCQkJCWZvciAoaT0wO2k8bGVuO2krKykgewoJCQkJCQlkYXRhW2ldPTA7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldPSgqcy0nMCcpPDw0OwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ2EnKydceGEnKTw8NDsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV09KCpzLSdBJysnXHhhJyk8PDQ7CgkJCQkJCXMrKzsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV18PSpzLScwJzsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV18PSpzLSdhJysnXHhhJzsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV18PSpzLSdBJysnXHhhJzsKCQkJCQkJcysrOwoJCQkJCX0KCQkJCX0KCQkJCV9maW5kX29yX2FkZF92YWx1ZShoa2V5LG5hbWUsdHlwZSxkYXRhLGxlbik7CgkJCX0KCQl9CgkJLyogcmVhZCB0aGUgbmV4dCBsaW5lICovCgkJaWYgKCFfd2luZV9yZWFkX2xpbmUoRixidWYsYnVmbGVuKSkKCQkJZ290byBkb25lOwogICAgfQogZG9uZToKICAgIGlmIChzdWJrZXkpIFJlZ0Nsb3NlS2V5KCBzdWJrZXkgKTsKICAgIHJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2Fkc3VicmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YnJlZyggRklMRSAqRiwgSEtFWSBoa2V5LCBjb25zdCBjaGFyICpmbiApCnsKCWludAl2ZXI7CgljaGFyCSpidWY7CglpbnQJYnVmbGVuOwoKCWJ1Zj14bWFsbG9jKDEwKTtidWZsZW49MTA7CglpZiAoIV93aW5lX3JlYWRfbGluZShGLCZidWYsJmJ1ZmxlbikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXNzY2FuZihidWYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIsJnZlcikpIHsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7Cgl9CglpZiAodmVyIT1SRUdJU1RSWV9TQVZFX1ZFUlNJT04pIHsKICAgICAgICAgICAgaWYgKHZlciA9PSAyKSAgLyogbmV3IHZlcnNpb24gKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSEFORExFIGZpbGU7CiAgICAgICAgICAgICAgICBpZiAoKGZpbGUgPSBGSUxFX0NyZWF0ZUZpbGUoIGZuLCBHRU5FUklDX1JFQUQsIDAsIE5VTEwsIE9QRU5fRVhJU1RJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfQVRUUklCVVRFX05PUk1BTCwgLTEgKSkgIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RydWN0IGxvYWRfcmVnaXN0cnlfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKICAgICAgICAgICAgICAgICAgICByZXEtPmhrZXkgICAgPSBoa2V5OwogICAgICAgICAgICAgICAgICAgIHJlcS0+ZmlsZSAgICA9IGZpbGU7CiAgICAgICAgICAgICAgICAgICAgcmVxLT5uYW1lWzBdID0gMDsKICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJfY2FsbCggUkVRX0xPQURfUkVHSVNUUlkgKTsKICAgICAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggZmlsZSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZnJlZSggYnVmICk7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKCQlUUkFDRSgiT2xkIGZvcm1hdCAoJWQpIHJlZ2lzdHJ5IGZvdW5kLCBpZ25vcmluZyBpdC4gKGJ1ZiB3YXMgJXMpLlxuIix2ZXIsYnVmKTsKCQlmcmVlKGJ1Zik7CgkJcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCX0KCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfbG9hZHN1YmtleShGLGhrZXksMCwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJZnJlZShidWYpOwoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3dpbmVfbG9hZHJlZyggSEtFWSBoa2V5LCBjaGFyICpmbiApCnsKICAgIEZJTEUgKkY7CgogICAgVFJBQ0UoIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl9hKGZuKSk7CgogICAgRiA9IGZvcGVuKGZuLCJyYiIpOwogICAgaWYgKEY9PU5VTEwpIHsKICAgICAgICBXQVJOKCJDb3VsZG4ndCBvcGVuICVzIGZvciByZWFkaW5nOiAlc1xuIixmbixzdHJlcnJvcihlcnJubykgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBfd2luZV9sb2Fkc3VicmVnKEYsaGtleSxmbik7CiAgICBmY2xvc2UoRik7Cn0KCi8qIE5UIFJFR0lTVFJZIExPQURFUiAqLwoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKI2lmbmRlZiBNQVBfRkFJTEVECiNkZWZpbmUgTUFQX0ZBSUxFRCAoKExQVk9JRCktMSkKI2VuZGlmCgojZGVmaW5lICBOVF9SRUdfQkxPQ0tfU0laRQkJMHgxMDAwCgojZGVmaW5lIE5UX1JFR19IRUFERVJfQkxPQ0tfSUQgICAgICAgMHg2NjY3NjU3MgkvKiByZWdmICovCiNkZWZpbmUgTlRfUkVHX1BPT0xfQkxPQ0tfSUQgICAgICAgICAweDZFNjk2MjY4CS8qIGhiaW4gKi8KI2RlZmluZSBOVF9SRUdfS0VZX0JMT0NLX0lEICAgICAgICAgIDB4NmI2ZQojZGVmaW5lIE5UX1JFR19WQUxVRV9CTE9DS19JRCAgICAgICAgMHg2Yjc2CiNkZWZpbmUgTlRfUkVHX0hBU0hfQkxPQ0tfSUQgICAgICAgICAweDY2NmMKI2RlZmluZSBOVF9SRUdfTk9IQVNIX0JMT0NLX0lEICAgICAgIDB4Njk2YwojZGVmaW5lIE5UX1JFR19LRVlfQkxPQ0tfVFlQRSAgICAgICAgMHgyMAojZGVmaW5lIE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFICAgMHgyYwoKdHlwZWRlZiBzdHJ1Y3QgCnsKCURXT1JECWlkOwkJLyogMHg2NjY3NjU3MiAncmVnZicqLwoJRFdPUkQJdWsxOwkJLyogMHgwNCAqLwoJRFdPUkQJdWsyOwkJLyogMHgwOCAqLwoJRklMRVRJTUUJRGF0ZU1vZGlmaWVkOwkvKiAweDBjICovCglEV09SRAl1azM7CQkvKiAweDE0ICovCglEV09SRAl1azQ7CQkvKiAweDE4ICovCglEV09SRAl1azU7CQkvKiAweDFjICovCglEV09SRAl1azY7CQkvKiAweDIwICovCglEV09SRAlSb290S2V5QmxvY2s7CS8qIDB4MjQgKi8KCURXT1JECUJsb2NrU2l6ZTsJLyogMHgyOCAqLwoJRFdPUkQgICB1azdbMTE2XTsJCglEV09SRAlDaGVja3N1bTsgLyogYXQgb2Zmc2V0IDB4MUZDICovCn0gbnRfcmVnZjsKCnR5cGVkZWYgc3RydWN0CnsKCURXT1JECWJsb2Nrc2l6ZTsKCUJZVEUJZGF0YVsxXTsKfSBudF9oYmluX3N1YjsKCnR5cGVkZWYgc3RydWN0CnsKCURXT1JECWlkOwkJLyogMHg2RTY5NjI2OCAnaGJpbicgKi8KCURXT1JECW9mZl9wcmV2OwoJRFdPUkQJb2ZmX25leHQ7CglEV09SRAl1azE7CglEV09SRAl1azI7CQkvKiAweDEwICovCglEV09SRAl1azM7CQkvKiAweDE0ICovCglEV09SRAl1azQ7CQkvKiAweDE4ICovCglEV09SRAlzaXplOwkJLyogMHgxQyAqLwoJbnRfaGJpbl9zdWIJaGJpbl9zdWI7CS8qIDB4MjAgKi8KfSBudF9oYmluOwoKLyoKICogdGhlIHZhbHVlX2xpc3QgY29uc2lzdHMgb2Ygb2Zmc2V0cyB0byB0aGUgdmFsdWVzICh2aykKICovCnR5cGVkZWYgc3RydWN0CnsKCVdPUkQJU3ViQmxvY2tJZDsJCS8qIDB4MDAgMHg2QjZFICovCglXT1JECVR5cGU7CQkJLyogMHgwMiBmb3IgdGhlIHJvb3Qta2V5OiAweDJDLCBvdGhlcndpc2UgMHgyMCovCglGSUxFVElNRQl3cml0ZXRpbWU7CS8qIDB4MDQgKi8KCURXT1JECXVrMTsJCQkvKiAweDBDICovCglEV09SRAlwYXJlbnRfb2ZmOwkJLyogMHgxMCBPZmZzZXQgb2YgT3duZXIvUGFyZW50IGtleSAqLwoJRFdPUkQJbnJfc3Via2V5czsJCS8qIDB4MTQgbnVtYmVyIG9mIHN1Yi1LZXlzICovCglEV09SRAl1azg7CQkJLyogMHgxOCAqLwoJRFdPUkQJbGZfb2ZmOwkJCS8qIDB4MUMgT2Zmc2V0IG9mIHRoZSBzdWIta2V5IGxmLVJlY29yZHMgKi8KCURXT1JECXVrMjsJCQkvKiAweDIwICovCglEV09SRAlucl92YWx1ZXM7CQkvKiAweDI0IG51bWJlciBvZiB2YWx1ZXMgKi8KCURXT1JECXZhbHVlbGlzdF9vZmY7CQkvKiAweDI4IE9mZnNldCBvZiB0aGUgVmFsdWUtTGlzdCAqLwoJRFdPUkQJb2ZmX3NrOwkJCS8qIDB4MmMgT2Zmc2V0IG9mIHRoZSBzay1SZWNvcmQgKi8KCURXT1JECW9mZl9jbGFzczsJCS8qIDB4MzAgT2Zmc2V0IG9mIHRoZSBDbGFzcy1OYW1lICovCglEV09SRAl1azM7CQkJLyogMHgzNCAqLwoJRFdPUkQJdWs0OwkJCS8qIDB4MzggKi8KCURXT1JECXVrNTsJCQkvKiAweDNjICovCglEV09SRAl1azY7CQkJLyogMHg0MCAqLwoJRFdPUkQJdWs3OwkJCS8qIDB4NDQgKi8KCVdPUkQJbmFtZV9sZW47CQkvKiAweDQ4IG5hbWUtbGVuZ3RoICovCglXT1JECWNsYXNzX2xlbjsJCS8qIDB4NGEgY2xhc3MtbmFtZSBsZW5ndGggKi8KCWNoYXIJbmFtZVsxXTsJCS8qIDB4NGMga2V5LW5hbWUgKi8KfSBudF9uazsKCnR5cGVkZWYgc3RydWN0CnsKCURXT1JECW9mZl9uazsJLyogMHgwMCAqLwoJRFdPUkQJbmFtZTsJLyogMHgwNCAqLwp9IGhhc2hfcmVjOwoKdHlwZWRlZiBzdHJ1Y3QKewoJV09SRAlpZDsJCS8qIDB4MDAgMHg2NjZjICovCglXT1JECW5yX2tleXM7CS8qIDB4MDYgKi8KCWhhc2hfcmVjCWhhc2hfcmVjWzFdOwp9IG50X2xmOwoKdHlwZWRlZiBzdHJ1Y3QKewoJV09SRAlpZDsJCS8qIDB4MDAgMHg2OTZjICovCglXT1JECW5yX2tleXM7CglEV09SRAlvZmZfbmtbMV07Cn0gbnRfaWw7Cgp0eXBlZGVmIHN0cnVjdAp7CglXT1JECWlkOwkJLyogMHgwMCAndmsnICovCglXT1JECW5hbV9sZW47CglEV09SRAlkYXRhX2xlbjsKCURXT1JECWRhdGFfb2ZmOwoJRFdPUkQJdHlwZTsKCVdPUkQJZmxhZzsKCVdPUkQJdWsxOwoJY2hhcgluYW1lWzFdOwp9IG50X3ZrOwoKTFBTVFIgX3N0cmR1cG5BKCBMUENTVFIgc3RyLCBpbnQgbGVuICkKewogICAgTFBTVFIgcmV0OwoKICAgIGlmICghc3RyKSByZXR1cm4gTlVMTDsKICAgIHJldCA9IG1hbGxvYyggbGVuICsgMSApOwogICAgbHN0cmNweW5BKCByZXQsIHN0ciwgbGVuICk7CiAgICByZXRbbGVuXSA9IDB4MDA7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IF9udF9wYXJzZV9uayhIS0VZIGhrZXksIGNoYXIgKiBiYXNlLCBudF9uayAqIG5rLCBpbnQgbGV2ZWwpOwpzdGF0aWMgaW50IF9udF9wYXJzZV92ayhIS0VZIGhrZXksIGNoYXIgKiBiYXNlLCBudF92ayAqIHZrKTsKc3RhdGljIGludCBfbnRfcGFyc2VfbGYoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgbnRfbGYgKiBsZiwgaW50IGxldmVsKTsKCgovKgogKiBnZXRzIGEgdmFsdWUKICoKICogdmstPmZsYWc6CiAqICAwIHZhbHVlIGlzIGEgZGVmYXVsdCB2YWx1ZQogKiAgMSB0aGUgdmFsdWUgaGFzIGEgbmFtZQogKgogKiB2ay0+ZGF0YV9sZW4KICogIGxlbiBvZiB0aGUgd2hvbGUgZGF0YSBibG9jawogKiAgLSByZWdfc3ogKHVuaWNvZGUpCiAqICAgIGJ5dGVzIGluY2x1ZGluZyB0aGUgdGVybWluYXRpbmcgXDAgPSAyKihudW1iZXJfb2ZfY2hhcnMrMSkKICogIC0gcmVnX2R3b3JkLCByZWdfYmluYXJ5OgogKiAgICBpZiBoaWdoZXN0IGJpdCBvZiBkYXRhX2xlbiBpcyBzZXQgZGF0YV9vZmYgY29udGFpbnMgdGhlIHZhbHVlCiAqLwpzdGF0aWMgaW50IF9udF9wYXJzZV92ayhIS0VZIGhrZXksIGNoYXIgKiBiYXNlLCBudF92ayAqIHZrKQp7CglXQ0hBUiBuYW1lIFsyNTZdOwoJRFdPUkQgcmV0OwoJQllURSAqIHBkYXRhID0gKEJZVEUgKikoYmFzZSt2ay0+ZGF0YV9vZmYrNCk7IC8qIHN0YXJ0IG9mIGRhdGEgKi8KCglpZih2ay0+aWQgIT0gTlRfUkVHX1ZBTFVFX0JMT0NLX0lEKSBnb3RvIGVycm9yOwoKCWxzdHJjcHluQXRvVyhuYW1lLCB2ay0+bmFtZSwgdmstPm5hbV9sZW4rMSk7CgoJcmV0ID0gUmVnU2V0VmFsdWVFeFcoIGhrZXksICh2ay0+ZmxhZyAmIDB4MDAwMDAwMDEpID8gbmFtZSA6IE5VTEwsIDAsIHZrLT50eXBlLAoJCQkodmstPmRhdGFfbGVuICYgMHg4MDAwMDAwMCkgPyAoTFBCWVRFKSYodmstPmRhdGFfb2ZmKTogcGRhdGEsCgkJCSh2ay0+ZGF0YV9sZW4gJiAweDdmZmZmZmZmKSApOwoJaWYgKHJldCkgRVJSKCJSZWdTZXRWYWx1ZUV4IGZhaWxlZCAoMHglMDhseClcbiIsIHJldCk7CglyZXR1cm4gVFJVRTsKZXJyb3I6CglFUlJfKHJlZykoInZrIGJsb2NrIGludmFsaWRcbiIpOwoJcmV0dXJuIEZBTFNFOwp9CgovKgogKiBnZXQgdGhlIHN1YmtleXMKICoKICogdGhpcyBzdHJ1Y3R1cmUgY29udGFpbnMgdGhlIGhhc2ggb2YgYSBrZXluYW1lIGFuZCBwb2ludHMgdG8gYWxsCiAqIHN1YmtleXMKICoKICogZXhjZXB0aW9uOiBpZiB0aGUgaWQgaXMgJ2lsJyB0aGVyZSBhcmUgbm8gaGFzaCB2YWx1ZXMgYW5kIGV2ZXJ5IAogKiBkd29yZCBpcyBhIG9mZnNldAogKi8Kc3RhdGljIGludCBfbnRfcGFyc2VfbGYoSEtFWSBoa2V5LCBjaGFyICogYmFzZSwgbnRfbGYgKiBsZiwgaW50IGxldmVsKQp7CglpbnQgaTsKCglpZiAobGYtPmlkID09IE5UX1JFR19IQVNIX0JMT0NLX0lEKQoJewoJICBmb3IgKGk9MDsgaTxsZi0+bnJfa2V5czsgaSsrKQoJICB7CgkgICAgaWYgKCFfbnRfcGFyc2VfbmsoaGtleSwgYmFzZSwgKG50X25rKikoYmFzZStsZi0+aGFzaF9yZWNbaV0ub2ZmX25rKzQpLCBsZXZlbCkpIGdvdG8gZXJyb3I7CgkgIH0KCSAgCgl9CgllbHNlIGlmIChsZi0+aWQgPT0gTlRfUkVHX05PSEFTSF9CTE9DS19JRCkKCXsKCSAgZm9yIChpPTA7IGk8bGYtPm5yX2tleXM7IGkrKykKCSAgewoJICAgIGlmICghX250X3BhcnNlX25rKGhrZXksIGJhc2UsIChudF9uayopKGJhc2UrKChudF9pbCopbGYpLT5vZmZfbmtbaV0rNCksIGxldmVsKSkgZ290byBlcnJvcjsKCSAgfQoJfQoJcmV0dXJuIFRSVUU7CgkKZXJyb3I6CUVSUl8ocmVnKSgiZXJyb3IgcmVhZGluZyBsZiBibG9ja1xuIik7CglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBpbnQgX250X3BhcnNlX25rKEhLRVkgaGtleSwgY2hhciAqIGJhc2UsIG50X25rICogbmssIGludCBsZXZlbCkKewoJY2hhciAqIG5hbWU7CglpbnQgaTsKCURXT1JEICogdmw7CglIS0VZIHN1YmtleSA9IGhrZXk7CgoJaWYobmstPlN1YkJsb2NrSWQgIT0gTlRfUkVHX0tFWV9CTE9DS19JRCkgZ290byBlcnJvcjsKCWlmKChuay0+VHlwZSE9TlRfUkVHX1JPT1RfS0VZX0JMT0NLX1RZUEUpICYmCgkgICAoKChudF9uayopKGJhc2UrbmstPnBhcmVudF9vZmYrNCkpLT5TdWJCbG9ja0lkICE9IE5UX1JFR19LRVlfQkxPQ0tfSUQpKSBnb3RvIGVycm9yOwoKCS8qIGNyZWF0ZSB0aGUgbmV3IGtleSAqLwoJaWYobGV2ZWwgPD0gMCkKCXsKCSAgbmFtZSA9IF9zdHJkdXBuQSggbmstPm5hbWUsIG5rLT5uYW1lX2xlbisxKTsKCSAgaWYoUmVnQ3JlYXRlS2V5QSggaGtleSwgbmFtZSwgJnN1YmtleSApKSB7IGZyZWUobmFtZSk7IGdvdG8gZXJyb3I7IH0KCSAgZnJlZShuYW1lKTsKCX0KCgkvKiBsb29wIHRocm91Z2ggdGhlIHN1YmtleXMgKi8KCWlmIChuay0+bnJfc3Via2V5cykKCXsKCSAgbnRfbGYgKiBsZiA9IChudF9sZiopKGJhc2UrbmstPmxmX29mZis0KTsKCSAgaWYgKG5rLT5ucl9zdWJrZXlzICE9IGxmLT5ucl9rZXlzKSBnb3RvIGVycm9yMTsKCSAgaWYgKCFfbnRfcGFyc2VfbGYoc3Via2V5LCBiYXNlLCBsZiwgbGV2ZWwtMSkpIGdvdG8gZXJyb3IxOwoJfQoKCS8qIGxvb3AgdHJvdWdoIHRoZSB2YWx1ZSBsaXN0ICovCgl2bCA9IChEV09SRCAqKShiYXNlK25rLT52YWx1ZWxpc3Rfb2ZmKzQpOwoJZm9yIChpPTA7IGk8bmstPm5yX3ZhbHVlczsgaSsrKQoJewoJICBudF92ayAqIHZrID0gKG50X3ZrKikoYmFzZSt2bFtpXSs0KTsKCSAgaWYgKCFfbnRfcGFyc2Vfdmsoc3Via2V5LCBiYXNlLCB2aykpIGdvdG8gZXJyb3IxOwoJfQoKCVJlZ0Nsb3NlS2V5KHN1YmtleSk7CglyZXR1cm4gVFJVRTsKCQplcnJvcjE6CVJlZ0Nsb3NlS2V5KHN1YmtleSk7CmVycm9yOglFUlJfKHJlZykoImVycm9yIHJlYWRpbmcgbmsgYmxvY2tcbiIpOwoJcmV0dXJuIEZBTFNFOwp9CgovKiBlbmQgbnQgbG9hZGVyICovCgovKiB3aW5kb3dzIDk1IHJlZ2lzdHJ5IGxvYWRlciAqLwoKLyogU0VDVElPTiAxOiBtYWluIGhlYWRlcgogKgogKiBvbmNlIGF0IG9mZnNldCAwCiAqLwojZGVmaW5lCVc5NV9SRUdfQ1JFR19JRAkweDQ3NDU1MjQzCgp0eXBlZGVmIHN0cnVjdCAKewoJRFdPUkQJaWQ7CQkvKiAiQ1JFRyIgPSBXOTVfUkVHX0NSRUdfSUQgKi8KCURXT1JECXZlcnNpb247CS8qID8/Pz8gMHgwMDAxMDAwMCAqLwoJRFdPUkQJcmdkYl9vZmY7CS8qIDB4MDggT2Zmc2V0IG9mIDFzdCBSR0RCLWJsb2NrICovCglEV09SRAl1azI7CQkvKiAweDBjICovCglXT1JECXJnZGJfbnVtOwkvKiAweDEwICMgb2YgUkdEQi1ibG9ja3MgKi8KCVdPUkQJdWszOwoJRFdPUkQJdWtbM107CgkvKiByZ2tuICovCn0gX3c5NWNyZWc7CgovKiBTRUNUSU9OIDI6IERpcmVjdG9yeSBpbmZvcm1hdGlvbiAodHJlZSBzdHJ1Y3R1cmUpCiAqCiAqIG9uY2Ugb24gb2Zmc2V0IDB4MjAKICoKICogc3RydWN0dXJlOiBbcmdrbl1bZGtlXSoJKHJlcGVhdCB0aWxsIHJna24tPnNpemUgaXMgcmVhY2hlZCkKICovCiNkZWZpbmUJVzk1X1JFR19SR0tOX0lECTB4NGU0YjQ3NTIKCnR5cGVkZWYgc3RydWN0CnsKCURXT1JECWlkOwkJLyoiUkdLTiIgPSBXOTVfUkVHX1JHS05fSUQgKi8KCURXT1JECXNpemU7CQkvKiBTaXplIG9mIHRoZSBSR0tOLWJsb2NrICovCglEV09SRAlyb290X29mZjsJLyogUmVsLiBPZmZzZXQgb2YgdGhlIHJvb3QtcmVjb3JkICovCglEV09SRAl1a1s1XTsKfSBfdzk1cmdrbjsKCi8qIERpc2sgS2V5IEVudHJ5IFN0cnVjdHVyZQogKgogKiB0aGUgMXN0IGVudHJ5IGluIGEgInVzdWFsIiByZWdpc3RyeSBmaWxlIGlzIGEgbnVsLWVudHJ5IHdpdGggc3Via2V5czogdGhlCiAqIGhpdmUgaXRzZWxmLiBJdCBsb29rcyB0aGUgc2FtZSBsaWtlIG90aGVyIGtleXMuIEV2ZW4gdGhlIElELW51bWJlciBjYW4KICogYmUgYW55IHZhbHVlLgogKgogKiBUaGUgImhhc2giLXZhbHVlIGlzIGEgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBrZXkncyBuYW1lLiBXaW5kb3dzIHdpbGwgbm90CiAqIHNlYXJjaCBmb3IgdGhlIG5hbWUsIGJ1dCBmb3IgYSBtYXRjaGluZyBoYXNoLXZhbHVlLiBpZiBpdCBmaW5kcyBvbmUsIGl0CiAqIHdpbGwgY29tcGFyZSB0aGUgYWN0dWFsIHN0cmluZyBpbmZvLCBvdGhlcndpc2UgY29udGludWUgd2l0aCB0aGUgbmV4dCBrZXkuCiAqIFRvIGNhbGN1bGF0ZSB0aGUgaGFzaCBpbml0aWFsaXplIGEgRC1Xb3JkIHdpdGggMCBhbmQgYWRkIGFsbCBBU0NJSS12YWx1ZXMgCiAqIG9mIHRoZSBzdHJpbmcgd2hpY2ggYXJlIHNtYWxsZXIgdGhhbiAweDgwICgxMjgpIHRvIHRoaXMgRC1Xb3JkLiAgIAogKgogKiBJZiB5b3Ugd2FudCB0byBtb2RpZnkga2V5IG5hbWVzLCBhbHNvIG1vZGlmeSB0aGUgaGFzaC12YWx1ZXMsIHNpbmNlIHRoZXkKICogY2Fubm90IGJlIGZvdW5kIGFnYWluIChhbHRob3VnaCB0aGV5IHdvdWxkIGJlIGRpc3BsYXllZCBpbiBSRUdFRElUKQogKiBFbmQgb2YgbGlzdC1wb2ludGVycyBhcmUgZmlsbGVkIHdpdGggMHhGRkZGRkZGRgogKgogKiBEaXNrIGtleXMgYXJlIGxheWVkIG91dCBmbGF0IC4uLiBCdXQsIHNvbWV0aW1lcywgbnJMUyBhbmQgbnJIUyBhcmUgYm90aAogKiAweEZGRkYsIHdoaWNoIG1lYW5zIHNraXBwaW5nIG92ZXIgbmV4dGtleW9mZnNldCBieXRlcyAoaW5jbHVkaW5nIHRoaXMKICogc3RydWN0dXJlKSBhbmQgcmVhZGluZyBhbm90aGVyIFJHREJfc2VjdGlvbi4KICoKICogdGhlcmUgaXMgYSBvbmUgdG8gb25lIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGRrZSBhbmQgZGtoCiAqLwogLyoga2V5IHN0cnVjdCwgb25jZSBwZXIga2V5ICovCnR5cGVkZWYgc3RydWN0CnsKCURXT1JECXgxOwkJLyogRnJlZSBlbnRyeSBpbmRpY2F0b3IoPykgKi8KCURXT1JECWhhc2g7CQkvKiBzdW0gb2YgYnl0ZXMgb2Yga2V5bmFtZSAqLwoJRFdPUkQJeDM7CQkvKiBSb290IGtleSBpbmRpY2F0b3I/IHVzdWFsbHkgMHhGRkZGRkZGRiAqLwoJRFdPUkQJcHJldmx2bDsJLyogb2Zmc2V0IG9mIHByZXZpb3VzIGtleSAqLwoJRFdPUkQJbmV4dHN1YjsJLyogb2Zmc2V0IG9mIGNoaWxkIGtleSAqLwoJRFdPUkQJbmV4dDsJCS8qIG9mZnNldCBvZiBzaWJsaW5nIGtleSAqLwoJV09SRAluckxTOwkJLyogaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCglXT1JECW5yTVM7CQkvKiBudW1iZXIgb2YgdGhlIHJnZGIgYmxvY2sgKi8KfSBfdzk1ZGtlOwoKLyogU0VDVElPTiAzOiBrZXkgaW5mb3JtYXRpb24sIHZhbHVlcyBhbmQgZGF0YQogKgogKiBzdHJ1Y3R1cmU6CiAqICBzZWN0aW9uOglbYmxvY2tzXSoJCShyZXBlYXQgY3JlZy0+cmdkYl9udW0gdGltZXMpCiAqICBibG9ja3M6CVtyZ2RiXSBbc3ViYmxvY2tzXSogCShyZXBlYXQgdGlsbCBibG9jayBzaXplIHJlYWNoZWQgKQogKiAgc3ViYmxvY2tzOglbZGtoXSBbZGt2XSoJCShyZXBlYXQgZGtoLT52YWx1ZXMgdGltZXMgKQogKgogKiBBbiBpbnRlcmVzdGluZyByZWxhdGlvbnNoaXAgZXhpc3RzIGluIFJHREJfc2VjdGlvbi4gVGhlIHZhbHVlIGF0IG9mZnNldAogKiAxMCBlcXVhbHMgdGhlIHZhbHVlIGF0IG9mZnNldCA0IG1pbnVzIHRoZSB2YWx1ZSBhdCBvZmZzZXQgOC4gSSBoYXZlIG5vCiAqIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKi8KCi8qIGJsb2NrIGhlYWRlciwgb25jZSBwZXIgYmxvY2sgKi8KI2RlZmluZSBXOTVfUkVHX1JHREJfSUQJMHg0MjQ0NDc1MgoKdHlwZWRlZiBzdHJ1Y3QKewoJRFdPUkQJaWQ7CS8qIDB4MDAgJ3JnZGInID0gVzk1X1JFR19SR0RCX0lEICovCglEV09SRAlzaXplOwkvKiAweDA0ICovCglEV09SRAl1azE7CS8qIDB4MDggKi8KCURXT1JECXVrMjsJLyogMHgwYyAqLwoJRFdPUkQJdWszOwkvKiAweDEwICovCglEV09SRAl1azQ7CS8qIDB4MTQgKi8KCURXT1JECXVrNTsJLyogMHgxOCAqLwoJRFdPUkQJdWs2OwkvKiAweDFjICovCgkvKiBka2ggKi8KfSBfdzk1cmdkYjsKCi8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCksIG9uY2UgcGVyIGtleSAqLwp0eXBlZGVmCXN0cnVjdCAKewoJRFdPUkQJbmV4dGtleW9mZjsgCS8qIDB4MDAgb2Zmc2V0IHRvIG5leHQgZGtoKi8KCVdPUkQJbnJMUzsJCS8qIDB4MDQgaWQgaW5zaWRlIHRoZSByZ2RiIGJsb2NrICovCglXT1JECW5yTVM7CQkvKiAweDA2IG51bWJlciBvZiB0aGUgcmdkYiBibG9jayAqLwoJRFdPUkQJYnl0ZXN1c2VkOwkvKiAweDA4ICovCglXT1JECWtleW5hbWVsZW47CS8qIDB4MGMgbGVuIG9mIG5hbWUgKi8KCVdPUkQJdmFsdWVzOwkJLyogMHgwZSBudW1iZXIgb2YgdmFsdWVzICovCglEV09SRAl4eDE7CQkvKiAweDEwICovCgljaGFyCW5hbWVbMV07CS8qIDB4MTQgKi8KCS8qIGRrdiAqLwkJLyogMHgxNCArIGtleW5hbWVsZW4gKi8KfSBfdzk1ZGtoOwoKLyogRGlzayBLZXkgVmFsdWUgc3RydWN0dXJlLCBvbmNlIHBlciB2YWx1ZSAqLwp0eXBlZGVmCXN0cnVjdAp7CglEV09SRAl0eXBlOwkJLyogMHgwMCAqLwoJRFdPUkQJeDE7CQkvKiAweDA0ICovCglXT1JECXZhbG5hbWVsZW47CS8qIDB4MDggbGVuZ3RoIG9mIG5hbWUsIDAgaXMgZGVmYXVsdCBrZXkgKi8KCVdPUkQJdmFsZGF0YWxlbjsJLyogMHgwQSBsZW5ndGggb2YgZGF0YSAqLwoJY2hhcgluYW1lWzFdOwkvKiAweDBjICovCgkvKiByYXcgZGF0YSAqLwkJLyogMHgwYyArIHZhbG5hbWVsZW4gKi8KfSBfdzk1ZGt2OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvb2t1cF9ka2ggW0ludGVybmFsXQogKgogKiBzZWVrcyB0aGUgZGtoIGJlbG9uZ2luZyB0byBhIGRrZQogKi8Kc3RhdGljIF93OTVka2ggKiBfdzk1X2xvb2t1cF9ka2ggKF93OTVjcmVnICpjcmVnLCBpbnQgbnJMUywgaW50IG5yTVMpCnsKCV93OTVyZ2RiICogcmdkYjsKCV93OTVka2ggKiBka2g7CglpbnQgaTsKCQoJcmdkYiA9IChfdzk1cmdkYiopKChjaGFyKiljcmVnK2NyZWctPnJnZGJfb2ZmKTsJCS8qIGdldCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZ2RiIGRhdGFzdG9yZSAqLwoJYXNzZXJ0IChjcmVnLT5yZ2RiX251bSA+IG5yTVMpOwkJCQkvKiBjaGVjazogcmVxdWVzdGVkIGJsb2NrIDwgbGFzdF9ibG9jaykgKi8KCQoJLyogZmluZCB0aGUgcmlnaHQgYmxvY2sgKi8KCWZvcihpPTA7IGk8bnJNUyA7aSsrKQoJewoJICBhc3NlcnQocmdkYi0+aWQgPT0gVzk1X1JFR19SR0RCX0lEKTsJCQkJLyogY2hlY2sgdGhlIG1hZ2ljICovCgkgIHJnZGIgPSAoX3c5NXJnZGIqKSAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSk7CQkvKiBmaW5kIG5leHQgYmxvY2sgKi8KCX0KCglka2ggPSAoX3c5NWRraCopKHJnZGIgKyAxKTsJCQkJLyogZmlyc3Qgc3ViIGJsb2NrIHdpdGhpbiB0aGUgcmdkYiAqLwoKCWRvCgl7CgkgIGlmKG5yTFM9PWRraC0+bnJMUyApIHJldHVybiBka2g7CgkgIGRraCA9IChfdzk1ZGtoKikoKGNoYXIqKWRraCArIGRraC0+bmV4dGtleW9mZik7CS8qIGZpbmQgbmV4dCBzdWJibG9jayAqLwoJfSB3aGlsZSAoKGNoYXIgKilka2ggPCAoKGNoYXIqKXJnZGIrcmdkYi0+c2l6ZSkpOwoKCXJldHVybiBOVUxMOwp9CQogCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3c5NV9wYXJzZV9ka3YgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfdzk1X3BhcnNlX2RrdiAoCglIS0VZIGhrZXksCglfdzk1ZGtoICogZGtoLAoJaW50IG5yTFMsCglpbnQgbnJNUyApCnsKCV93OTVka3YgKiBka3Y7CglpbnQgaTsKCURXT1JEIHJldDsKCWNoYXIgKiBuYW1lOwoJCQkKCS8qIGZpcnN0IHZhbHVlIGJsb2NrICovCglka3YgPSAoX3c5NWRrdiopKChjaGFyKilka2grZGtoLT5rZXluYW1lbGVuKzB4MTQpOwoKCS8qIGxvb3AgdHJvdWdodCB0aGUgdmFsdWVzICovCglmb3IgKGk9MDsgaTwgZGtoLT52YWx1ZXM7IGkrKykKCXsKCSAgbmFtZSA9IF9zdHJkdXBuQShka3YtPm5hbWUsIGRrdi0+dmFsbmFtZWxlbisxKTsKCSAgcmV0ID0gUmVnU2V0VmFsdWVFeEEoaGtleSwgbmFtZSwgMCwgZGt2LT50eXBlLCAmKGRrdi0+bmFtZVtka3YtPnZhbG5hbWVsZW5dKSxka3YtPnZhbGRhdGFsZW4pOyAKCSAgaWYgKHJldCkgRVJSKCJSZWdTZXRWYWx1ZUV4IGZhaWxlZCAoMHglMDhseClcbiIsIHJldCk7CgkgIGZyZWUgKG5hbWUpOwoKCSAgLyogbmV4dCB2YWx1ZSAqLwoJICBka3YgPSAoX3c5NWRrdiopKChjaGFyKilka3YrZGt2LT52YWxuYW1lbGVuK2Rrdi0+dmFsZGF0YWxlbisweDBjKTsKCX0KCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfcGFyc2VfZGtlIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3c5NV9wYXJzZV9ka2UoIAoJSEtFWSBoa2V5LAoJX3c5NWNyZWcgKiBjcmVnLAoJX3c5NXJna24gKnJna24sCglfdzk1ZGtlICogZGtlLAoJaW50IGxldmVsICkKewoJX3c5NWRraCAqIGRraDsKCUhLRVkgaHN1YmtleSA9IGhrZXk7CgljaGFyICogbmFtZTsKCWludCByZXQgPSBGQUxTRTsKCgkvKiBnZXQgc3RhcnQgYWRkcmVzcyBvZiByb290IGtleSBibG9jayAqLwoJaWYgKCFka2UpIGRrZSA9IChfdzk1ZGtlKikoKGNoYXIqKXJna24gKyByZ2tuLT5yb290X29mZik7CgkKCS8qIHNwZWNpYWwgcm9vdCBrZXkgKi8KCWlmIChka2UtPm5yTFMgPT0gMHhmZmZmIHx8IGRrZS0+bnJNUz09MHhmZmZmKQkJLyogZWcuIHRoZSByb290IGtleSBoYXMgbm8gbmFtZSAqLwoJewoJICAvKiBwYXJzZSB0aGUgb25lIHN1YmtleSovCgkgIGlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgCgkgIHsKICAgIAkgICAgcmV0dXJuIF93OTVfcGFyc2VfZGtlKGhzdWJrZXksIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSwgbGV2ZWwpOwoJICB9CgkgIC8qIGhhcyBubyBzaWJsaW5nIGtleXMgKi8KCSAgZ290byBlcnJvcjsKCX0KCgkvKiBzZWFyY2ggc3ViYmxvY2sgKi8KCWlmICghKGRraCA9IF93OTVfbG9va3VwX2RraChjcmVnLCBka2UtPm5yTFMsIGRrZS0+bnJNUykpKQoJewoJICBmcHJpbnRmKHN0ZGVyciwgImRrZSBwb2ludGluZyB0byBtaXNzaW5nIGRraCAhXG4iKTsKCSAgZ290byBlcnJvcjsKCX0KCglpZiAoIGxldmVsIDw9IDAgKQoJewoJICAvKiB3YWxrIHNpYmxpbmcga2V5cyAqLwoJICBpZiAoZGtlLT5uZXh0ICE9IDB4ZmZmZmZmZmYgKQoJICB7CiAgICAJICAgIGlmICghX3c5NV9wYXJzZV9ka2UoaGtleSwgY3JlZywgcmdrbiwgKF93OTVka2UqKSgoY2hhciopcmdrbitka2UtPm5leHQpLCBsZXZlbCkpIGdvdG8gZXJyb3I7CgkgIH0KCgkgIC8qIGNyZWF0ZSBzdWJrZXkgYW5kIGluc2VydCB2YWx1ZXMgKi8KCSAgbmFtZSA9IF9zdHJkdXBuQSggZGtoLT5uYW1lLCBka2gtPmtleW5hbWVsZW4rMSk7CgkgIGlmIChSZWdDcmVhdGVLZXlBKGhrZXksIG5hbWUsICZoc3Via2V5KSkgeyBmcmVlKG5hbWUpOyBnb3RvIGVycm9yOyB9CgkgIGZyZWUobmFtZSk7CgkgIGlmICghX3c5NV9wYXJzZV9ka3YoaHN1YmtleSwgZGtoLCBka2UtPm5yTFMsIGRrZS0+bnJNUykpIGdvdG8gZXJyb3IxOwoJfSAgCgkKIAkvKiBuZXh0IHN1YiBrZXkgKi8KCWlmIChka2UtPm5leHRzdWIgIT0gMHhmZmZmZmZmZikgCgl7CiAgICAJICBpZiAoIV93OTVfcGFyc2VfZGtlKGhzdWJrZXksIGNyZWcsIHJna24sIChfdzk1ZGtlKikoKGNoYXIqKXJna24rZGtlLT5uZXh0c3ViKSwgbGV2ZWwtMSkpIGdvdG8gZXJyb3IxOwoJfQoKCXJldCA9IFRSVUU7CmVycm9yMToJaWYgKGhzdWJrZXkgIT0gaGtleSkgUmVnQ2xvc2VLZXkoaHN1YmtleSk7CmVycm9yOglyZXR1cm4gcmV0Owp9Ci8qIGVuZCB3aW5kb3dzIDk1IGxvYWRlciAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglOYXRpdmVSZWdMb2FkS2V5IFtJbnRlcm5hbF0KICoKICogTG9hZHMgYSBuYXRpdmUgcmVnaXN0cnkgZmlsZSAod2luOTUvbnQpCiAqIAloa2V5CXJvb3Qga2V5CiAqCWZuCWZpbGVuYW1lCiAqCWxldmVsCW51bWJlciBvZiBsZXZlbHMgdG8gY3V0IGF3YXkgKGVnLiAiLkRlZmF1bHQiIGluIHVzZXIuZGF0KQogKgogKiB0aGlzIGZ1bmN0aW9uIGludGVudGlvbmFsbHkgdXNlcyB1bml4IGZpbGUgZnVuY3Rpb25zIHRvIG1ha2UgaXQgcG9zc2libGUKICogdG8gbW92ZSBpdCB0byBhIHNlcGVyYXRlIHJlZ2lzdHJ5IGhlbHBlciBwcm9ncmFtbQogKi8Kc3RhdGljIGludCBOYXRpdmVSZWdMb2FkS2V5KCBIS0VZIGhrZXksIGNoYXIqIGZuLCBpbnQgbGV2ZWwgKQp7CglpbnQgZmQgPSAwOwoJc3RydWN0IHN0YXQgc3Q7CiAgICAgICAgRE9TX0ZVTExfTkFNRSBmdWxsX25hbWU7CglpbnQgcmV0ID0gRkFMU0U7Cgl2b2lkICogYmFzZTsKCQkJCiAgICAgICAgaWYgKCFET1NGU19HZXRGdWxsTmFtZSggZm4sIDAsICZmdWxsX25hbWUgKSkgcmV0dXJuIEZBTFNFOwoJCgkvKiBtYXAgdGhlIHJlZ2lzdHJ5IGludG8gdGhlIG1lbW9yeSAqLwoJaWYgKChmZCA9IG9wZW4oZnVsbF9uYW1lLmxvbmdfbmFtZSwgT19SRE9OTFkgfCBPX05PTkJMT0NLKSkgPT0gLTEpIHJldHVybiBGQUxTRTsKCWlmICgoZnN0YXQoZmQsICZzdCkgPT0gLTEpKSBnb3RvIGVycm9yOwoJaWYgKChiYXNlID0gbW1hcChOVUxMLCBzdC5zdF9zaXplLCBQUk9UX1JFQUQsIE1BUF9QUklWQVRFLCBmZCwgMCkpID09IE1BUF9GQUlMRUQpIGdvdG8gZXJyb3I7CgoJc3dpdGNoICgqKExQRFdPUkQpYmFzZSkKCXsKCSAgLyogd2luZG93cyA5NSAnY3JlZycgKi8KCSAgY2FzZSBXOTVfUkVHX0NSRUdfSUQ6CgkgICAgewoJICAgICAgX3c5NWNyZWcgKiBjcmVnOwoJICAgICAgX3c5NXJna24gKiByZ2tuOwoJICAgICAgY3JlZyA9IGJhc2U7CgkgICAgICBUUkFDRV8ocmVnKSgiTG9hZGluZyB3aW45NSByZWdpc3RyeSAnJXMnICclcydcbiIsZm4sIGZ1bGxfbmFtZS5sb25nX25hbWUpOwoKCSAgICAgIC8qIGxvYWQgdGhlIGhlYWRlciAocmdrbikgKi8KCSAgICAgIHJna24gPSAoX3c5NXJna24qKShjcmVnICsgMSk7CgkgICAgICBpZiAocmdrbi0+aWQgIT0gVzk1X1JFR19SR0tOX0lEKSAKCSAgICAgIHsKCQlFUlIoInNlY29uZCBJRkYgaGVhZGVyIG5vdCBSR0tOLCBidXQgJWx4XG4iLCByZ2tuLT5pZCk7CgkJZ290byBlcnJvcjE7CgkgICAgICB9CgoJICAgICAgcmV0ID0gX3c5NV9wYXJzZV9ka2UoaGtleSwgY3JlZywgcmdrbiwgTlVMTCwgbGV2ZWwpOwoJICAgIH0KCSAgICBicmVhazsKCSAgLyogbnQgJ3JlZ2YnKi8KCSAgY2FzZSBOVF9SRUdfSEVBREVSX0JMT0NLX0lEOgoJICAgIHsKCSAgICAgIG50X3JlZ2YgKiByZWdmOwoJICAgICAgbnRfaGJpbiAqIGhiaW47CgkgICAgICBudF9oYmluX3N1YiAqIGhiaW5fc3ViOwoJICAgICAgbnRfbmsqIG5rOwoKCSAgICAgIFRSQUNFXyhyZWcpKCJMb2FkaW5nIG50IHJlZ2lzdHJ5ICclcycgJyVzJ1xuIixmbiwgZnVsbF9uYW1lLmxvbmdfbmFtZSk7CgoJICAgICAgLyogc3RhcnQgYmxvY2sgKi8KCSAgICAgIHJlZ2YgPSBiYXNlOwoKCSAgICAgIC8qIGhiaW4gYmxvY2sgKi8KCSAgICAgIGhiaW4gPSBiYXNlICsgMHgxMDAwOwoJICAgICAgaWYgKGhiaW4tPmlkICE9IE5UX1JFR19QT09MX0JMT0NLX0lEKQoJICAgICAgewoJICAgICAgICBFUlJfKHJlZykoICIlcyBoYmluIGJsb2NrIGludmFsaWRcbiIsIGZuKTsKCSAgICAgICAgZ290byBlcnJvcjE7CgkgICAgICB9CgoJICAgICAgLyogaGJpbl9zdWIgYmxvY2sgKi8KCSAgICAgIGhiaW5fc3ViID0gKG50X2hiaW5fc3ViKikmKGhiaW4tPmhiaW5fc3ViKTsKCSAgICAgIGlmICgoaGJpbl9zdWItPmRhdGFbMF0gIT0gJ24nKSB8fCAoaGJpbl9zdWItPmRhdGFbMV0gIT0gJ2snKSkKCSAgICAgIHsKCSAgICAgICAgRVJSXyhyZWcpKCAiJXMgaGJpbl9zdWIgYmxvY2sgaW52YWxpZFxuIiwgZm4pOwoJICAgICAgICBnb3RvIGVycm9yMTsKCSAgICAgIH0KCgkgICAgICAvKiBuayBibG9jayAqLwoJICAgICAgbmsgPSAobnRfbmsqKSYoaGJpbl9zdWItPmRhdGFbMF0pOwoJICAgICAgaWYgKG5rLT5UeXBlICE9IE5UX1JFR19ST09UX0tFWV9CTE9DS19UWVBFKQoJICAgICAgewoJICAgICAgICBFUlJfKHJlZykoICIlcyBzcGVjaWFsIG5rIGJsb2NrIG5vdCBmb3VuZFxuIiwgZm4pOwoJICAgICAgICBnb3RvIGVycm9yMTsKCSAgICAgIH0KCgkgICAgICByZXQgPSBfbnRfcGFyc2VfbmsgKGhrZXksIGJhc2UrMHgxMDAwLCBuaywgbGV2ZWwpOwoJICAgIH0KCSAgICBicmVhazsKCSAgZGVmYXVsdDoKCSAgICB7CgkgICAgICBFUlIoInVua25vd24gc2lnbmF0dXJlIGluIHJlZ2lzdHJ5IGZpbGUgJXMuXG4iLGZuKTsKCSAgICAgIGdvdG8gZXJyb3IxOwoJICAgIH0KCX0KCWlmKCFyZXQpIEVSUigiZXJyb3IgbG9hZGluZyByZWdpc3RyeSBmaWxlICVzXG4iLCBmbik7CmVycm9yMToJbXVubWFwKGJhc2UsIHN0LnN0X3NpemUpOwplcnJvcjoJY2xvc2UoZmQpOwoJcmV0dXJuIHJldDsJCn0KCi8qIFdJTkRPV1MgMzEgUkVHSVNUUlkgTE9BREVSLCBzdXBwbGllZCBieSBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vICovCi8qCiAgICByZWdoYWNrIC0gd2luZG93cyAzLjExIHJlZ2lzdHJ5IGRhdGEgZm9ybWF0IGRlbW8gcHJvZ3JhbS4KCiAgICBUaGUgcmVnLmRhdCBmaWxlIGhhcyAzIHBhcnRzLCBhIGhlYWRlciwgYSB0YWJsZSBvZiA4LWJ5dGUgZW50cmllcyB0aGF0IGlzCiAgICBhIGNvbWJpbmVkIGhhc2ggdGFibGUgYW5kIHRyZWUgZGVzY3JpcHRpb24sIGFuZCBmaW5hbGx5IGEgdGV4dCB0YWJsZS4KCiAgICBUaGUgaGVhZGVyIGlzIG9idmlvdXMgZnJvbSB0aGUgc3RydWN0IGhlYWRlci4gVGhlIHRhYm9mZjEgYW5kIHRhYm9mZjIKICAgIGZpZWxkcyBhcmUgYWx3YXlzIDB4MjAsIGFuZCB0aGVpciB1c2FnZSBpcyB1bmtub3duLgoKICAgIFRoZSA4LWJ5dGUgZW50cnkgdGFibGUgaGFzIHZhcmlvdXMgZW50cnkgdHlwZXMuCgogICAgdGFiZW50WzBdIGlzIGEgcm9vdCBpbmRleC4gVGhlIHNlY29uZCB3b3JkIGhhcyB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YKICAgICAgICAgICAgdGhlIGRpcmVjdG9yeS4KICAgIHRhYmVudFsxLi5oYXNoc2l6ZV0gaXMgYSBoYXNoIHRhYmxlLiBUaGUgZmlyc3Qgd29yZCBpbiB0aGUgaGFzaCBlbnRyeSBpcwogICAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGtleS92YWx1ZSB0aGF0IGhhcyB0aGF0IGhhc2guIERhdGEgd2l0aCB0aGUgc2FtZQogICAgICAgICAgICBoYXNoIHZhbHVlIGFyZSBvbiBhIGNpcmN1bGFyIGxpc3QuIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUKICAgICAgICAgICAgaGFzaCBlbnRyeSBhcmUgYWx3YXlzIHplcm8uCiAgICB0YWJlbnRbaGFzaHNpemUuLnRhYmNudF0gaXMgdGhlIHRyZWUgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mCiAgICAgICAgICAgIGVudHJ5OiBkaXJlbnQgYW5kIGtleWVudC92YWxlbnQuIFRoZXkgYXJlIGlkZW50aWZpZWQgYnkgY29udGV4dC4KICAgIHRhYmVudFtmcmVlaWR4XSBpcyB0aGUgZmlyc3QgZnJlZSBlbnRyeS4gVGhlIGZpcnN0IHdvcmQgaW4gYSBmcmVlIGVudHJ5CiAgICAgICAgICAgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBmcmVlIGVudHJ5LiBUaGUgbGFzdCBoYXMgMCBhcyBhIGxpbmsuCiAgICAgICAgICAgIFRoZSBvdGhlciB0aHJlZSB3b3JkcyBpbiB0aGUgZnJlZSBsaXN0IGFyZSBwcm9iYWJseSBpcnJlbGV2YW50LgoKICAgIEVudHJpZXMgaW4gdGV4dCB0YWJsZSBhcmUgcHJlY2VlZGVkIGJ5IGEgd29yZCBhdCBvZmZzZXQtMi4gVGhpcyB3b3JkCiAgICBoYXMgdGhlIHZhbHVlICgyKmluZGV4KSsxLCB3aGVyZSBpbmRleCBpcyB0aGUgcmVmZXJyaW5nIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGluIHRoZSB0YWJsZS4gSSBoYXZlIG5vIHN1Z2dlc3Rpb24gZm9yIHRoZSAyKiBhbmQgdGhlICsxLgogICAgRm9sbG93aW5nIHRoZSB3b3JkLCB0aGVyZSBhcmUgTiBieXRlcyBvZiBkYXRhLCBhcyBwZXIgdGhlIGtleWVudC92YWxlbnQKICAgIGVudHJ5IGxlbmd0aC4gVGhlIG9mZnNldCBvZiB0aGUga2V5ZW50L3ZhbGVudCBlbnRyeSBpcyBmcm9tIHRoZSBzdGFydAogICAgb2YgdGhlIHRleHQgdGFibGUgdG8gdGhlIGZpcnN0IGRhdGEgYnl0ZS4KCiAgICBUaGlzIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUgZnJvbSBNaWNyb3NvZnQuIFRoZSBkYXRhIGZvcm1hdCBpcwogICAgZGVkdWNlZCBmcm9tIHRoZSByZWcuZGF0IGZpbGUgYnkgbWUuIE1pc3Rha2VzIG1heQogICAgaGF2ZSBiZWVuIG1hZGUuIEkgY2xhaW0gbm8gcmlnaHRzIGFuZCBnaXZlIG5vIGd1YXJhbnRlZXMgZm9yIHRoaXMgcHJvZ3JhbS4KCiAgICBUb3IgU2r4d2FsbCwgdG9yQHNuLm5vCiovCgovKiByZWcuZGF0IGhlYWRlciBmb3JtYXQgKi8Kc3RydWN0IF93MzFfaGVhZGVyIHsKCWNoYXIJCWNvb2tpZVs4XTsJLyogJ1NIQ0MzLjEwJyAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYxOwkvKiBvZmZzZXQgb2YgaGFzaCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJvZmYyOwkvKiBvZmZzZXQgb2YgaW5kZXggdGFibGUgKD8/KSA9IDB4MjAgKi8KCXVuc2lnbmVkIGxvbmcJdGFiY250OwkJLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gaW5kZXggdGFibGUgKi8KCXVuc2lnbmVkIGxvbmcJdGV4dG9mZjsJLyogb2Zmc2V0IG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0c2l6ZTsJLyogYnl0ZSBzaXplIG9mIHRleHQgcGFydCAqLwoJdW5zaWduZWQgc2hvcnQJaGFzaHNpemU7CS8qIGhhc2ggc2l6ZSAqLwoJdW5zaWduZWQgc2hvcnQJZnJlZWlkeDsJLyogZnJlZSBpbmRleCAqLwp9OwoKLyogZ2VuZXJpYyBmb3JtYXQgb2YgdGFibGUgZW50cmllcyAqLwpzdHJ1Y3QgX3czMV90YWJlbnQgewoJdW5zaWduZWQgc2hvcnQgdzAsIHcxLCB3MiwgdzM7Cn07CgovKiBkaXJlY3RvcnkgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV9kaXJlbnQgewoJdW5zaWduZWQgc2hvcnQJc2libGluZ19pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHNpYmxpbmcgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAljaGlsZF9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIGNoaWxkIGRpcmVudCAqLwoJdW5zaWduZWQgc2hvcnQJa2V5X2lkeDsJLyogdGFibGUgaW5kZXggb2Yga2V5IGtleWVudCAqLwoJdW5zaWduZWQgc2hvcnQJdmFsdWVfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiB2YWx1ZSB2YWxlbnQgKi8KfTsKCi8qIGtleSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2tleWVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogdmFsdWUgdGFiZW50OiAqLwpzdHJ1Y3QgX3czMV92YWxlbnQgewoJdW5zaWduZWQgc2hvcnQJaGFzaF9pZHg7CS8qIGhhc2ggY2hhaW4gaW5kZXggZm9yIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJcmVmY250OwkJLyogcmVmZXJlbmNlIGNvdW50ICovCgl1bnNpZ25lZCBzaG9ydAlsZW5ndGg7CQkvKiBsZW5ndGggb2Ygc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlzdHJpbmdfb2ZmOwkvKiBvZmZzZXQgb2Ygc3RyaW5nIGluIHRleHQgdGFibGUgKi8KfTsKCi8qIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdG8gZGlzcGxheSBhIGRpcmVjdG9yeSB0cmVlICovCnZvaWQKX193MzFfZHVtcHRyZWUoCXVuc2lnbmVkIHNob3J0IGlkeCwKCQl1bnNpZ25lZCBjaGFyICp0eHQsCgkJc3RydWN0IF93MzFfdGFiZW50ICp0YWIsCgkJc3RydWN0IF93MzFfaGVhZGVyICpoZWFkLAoJCUhLRVkgaGtleSwKCQl0aW1lX3QJCWxhc3Rtb2RpZmllZCwKCQlpbnQJCWxldmVsCikgewoJc3RydWN0IF93MzFfZGlyZW50CSpkaXI7CglzdHJ1Y3QgX3czMV9rZXllbnQJKmtleTsKCXN0cnVjdCBfdzMxX3ZhbGVudAkqdmFsOwogICAgICAgIEhLRVkgc3Via2V5ID0gMDsKCXN0YXRpYyBjaGFyCQl0YWlsWzQwMF07CgoJd2hpbGUgKGlkeCE9MCkgewoJCWRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgoJCWlmIChkaXItPmtleV9pZHgpIHsKCQkJa2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKCQkJbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKCQkJdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKCQkJLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZSAKCQkJICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwoJCQkgKi8KCQkJaWYgKCFsZXZlbCAmJiAhbHN0cmNtcEEodGFpbCwiLmNsYXNzZXMiKSkgewoJCQkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLGhrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCQkJaWR4PWRpci0+c2libGluZ19pZHg7CgkJCQljb250aW51ZTsKCQkJfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3Via2V5KSBSZWdDbG9zZUtleSggc3Via2V5ICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChSZWdDcmVhdGVLZXlBKCBoa2V5LCB0YWlsLCAmc3Via2V5ICkgIT0gRVJST1JfU1VDQ0VTUykgc3Via2V5ID0gMDsKCQkJLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCgkJCWlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKCQkJCWlmIChkaXItPnZhbHVlX2lkeCkgewoJCQkJCXZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKCQkJCQltZW1jcHkodGFpbCwmdHh0W3ZhbC0+c3RyaW5nX29mZl0sdmFsLT5sZW5ndGgpOwoJCQkJCXRhaWxbdmFsLT5sZW5ndGhdPSdcMCc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdTZXRWYWx1ZUEoIHN1YmtleSwgTlVMTCwgUkVHX1NaLCB0YWlsLCAwICk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQlUUkFDRSgic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKCQl9CgkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHN1YmtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJaWR4PWRpci0+c2libGluZ19pZHg7Cgl9CiAgICAgICAgaWYgKHN1YmtleSkgUmVnQ2xvc2VLZXkoIHN1YmtleSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzMxX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kdm9pZCBfdzMxX2xvYWRyZWcodm9pZCkgewoJSEZJTEUJCQloZjsKCXN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwoJc3RydWN0IF93MzFfdGFiZW50CSp0YWI7Cgl1bnNpZ25lZCBjaGFyCQkqdHh0OwoJaW50CQkJbGVuOwoJT0ZTVFJVQ1QJCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmaW5mbzsKCXRpbWVfdAkJCWxhc3Rtb2RpZmllZDsKCglUUkFDRSgiKHZvaWQpXG4iKTsKCgloZiA9IE9wZW5GaWxlKCJyZWcuZGF0Iiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmPT1IRklMRV9FUlJPUikKCQlyZXR1cm47CgoJLyogcmVhZCAmIGR1bXAgaGVhZGVyICovCglpZiAoc2l6ZW9mKGhlYWQpIT1fbHJlYWQoaGYsJmhlYWQsc2l6ZW9mKGhlYWQpKSkgewoJCUVSUigicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAobWVtY21wKGhlYWQuY29va2llLCAiU0hDQzMuMTAiLCBzaXplb2YoaGVhZC5jb29raWUpKSE9MCkgewoJCUVSUigicmVnLmRhdCBoYXMgYmFkIHNpZ25hdHVyZS5cbiIpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCglsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwoJLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwoJdGFiID0geG1hbGxvYyhsZW4pOwoJaWYgKGxlbiE9X2xyZWFkKGhmLHRhYixsZW4pKSB7CgkJRVJSKCJjb3VsZG4ndCByZWFkICVkIGJ5dGVzLlxuIixsZW4pOyAKCQlmcmVlKHRhYik7CgkJX2xjbG9zZShoZik7CgkJcmV0dXJuOwoJfQoKCS8qIHJlYWQgdGV4dCAqLwoJdHh0ID0geG1hbGxvYyhoZWFkLnRleHRzaXplKTsKCWlmICgtMT09X2xsc2VlayhoZixoZWFkLnRleHRvZmYsU0VFS19TRVQpKSB7CgkJRVJSKCJjb3VsZG4ndCBzZWVrIHRvIHRleHRibG9jay5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWlmIChoZWFkLnRleHRzaXplIT1fbHJlYWQoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CgkJRVJSKCJ0ZXh0YmxvY2sgdG9vIHNob3J0ICglZCBpbnN0ZWFkIG9mICVsZCkuXG4iLGxlbixoZWFkLnRleHRzaXplKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlKGhmKTsKCQlyZXR1cm47Cgl9CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZiwmaGZpbmZvKSkgewoJCUVSUigiR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUgZmFpbGVkPy5cbiIpOyAKCQlmcmVlKHRhYik7CgkJZnJlZSh0eHQpOwoJCV9sY2xvc2UoaGYpOwoJCXJldHVybjsKCX0KCWxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCV9fdzMxX2R1bXB0cmVlKHRhYlswXS53MSx0eHQsdGFiLCZoZWFkLEhLRVlfQ0xBU1NFU19ST09ULGxhc3Rtb2RpZmllZCwwKTsKCWZyZWUodGFiKTsKCWZyZWUodHh0KTsKCV9sY2xvc2UoaGYpOwoJcmV0dXJuOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTZXRMb2FkTGV2ZWwgW0ludGVybmFsXQogKgogKiBzZXQgbGV2ZWwgdG8gMCBmb3IgbG9hZGluZyBzeXN0ZW0gZmlsZXMKICogc2V0IGxldmVsIHRvIDEgZm9yIGxvYWRpbmcgdXNlciBmaWxlcwogKi8Kc3RhdGljIHZvaWQgU2V0TG9hZExldmVsKGludCBsZXZlbCkKewoJc3RydWN0IHNldF9yZWdpc3RyeV9sZXZlbHNfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKCglyZXEtPmN1cnJlbnQgPSBsZXZlbDsKCXJlcS0+c2F2aW5nICA9IDA7CglyZXEtPnZlcnNpb24gPSAxOwoJc2VydmVyX2NhbGwoIFJFUV9TRVRfUkVHSVNUUllfTEVWRUxTICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX0xvYWRSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwp2b2lkIFNIRUxMX0xvYWRSZWdpc3RyeSggdm9pZCApCnsKICBpbnQJc2F2ZV90aW1lb3V0OwogIGNoYXIJKmZuLCAqaG9tZTsKICBIS0VZCWhrZXk7CgogIFRSQUNFKCIodm9pZClcbiIpOwoKICBSRUdJU1RSWV9Jbml0KCk7CiAgU2V0TG9hZExldmVsKDApOwoKICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCAoInJlZ2lzdHJ5IiwgIkxvYWRXaW4zMTFSZWdpc3RyeUZpbGVzIiwgMSkpIAogIHsgCiAgICAgIC8qIExvYWQgd2luZG93cyAzLjEgZW50cmllcyAqLwogICAgICBfdzMxX2xvYWRyZWcoKTsKICB9CiAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2wgKCJyZWdpc3RyeSIsICJMb2FkV2luOTVSZWdpc3RyeUZpbGVzIiwgMSkpIAogIHsgCiAgICAgIC8qIExvYWQgd2luZG93cyA5NSBlbnRyaWVzICovCiAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoSEtFWV9MT0NBTF9NQUNISU5FLCAiQzpcXHN5c3RlbS4xc3QiLCAwKTsKICAgICAgTmF0aXZlUmVnTG9hZEtleShIS0VZX0xPQ0FMX01BQ0hJTkUsICJzeXN0ZW0uZGF0IiwgMCk7CiAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoSEtFWV9DVVJSRU5UX1VTRVIsICJ1c2VyLmRhdCIsIDEpOwogIH0KICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCAoInJlZ2lzdHJ5IiwgIkxvYWRXaW5OVFJlZ2lzdHJ5RmlsZXMiLCAxKSkgCiAgeyAKICAgICAgZm4gPSB4bWFsbG9jKCBNQVhfUEFUSE5BTUVfTEVOICk7IAogICAgICBob21lID0geG1hbGxvYyAoIE1BWF9QQVRITkFNRV9MRU4gKTsKICAgICAgaWYgKCBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJyZWdpc3RyeSIsICJOVFVzZXIiLCAiIiwgaG9tZSwgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKSAKICAgICAgewogICAgICAgICBHZXRXaW5kb3dzRGlyZWN0b3J5QSggZm4sIE1BWF9QQVRITkFNRV9MRU4gKTsKCSBzdHJuY2F0KGZuLCAiXFxQcm9maWxlc1xcIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihmbikgLSAxKTsKCSBzdHJuY2F0KGZuLCBob21lLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKGZuKSAtIDEpOwoJIHN0cm5jYXQoZm4sICJcXG50dXNlci5kYXQiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKGZuKSAtIDEpOwogICAgICAgICBOYXRpdmVSZWdMb2FkS2V5KCBIS0VZX0NVUlJFTlRfVVNFUiwgZm4sIDEgKTsKICAgICAgfSAgICAgCiAgICAgIC8qCiAgICAgICogRklYTUUKICAgICAgKiAgbWFwIEhMTVxTeXN0ZW1cQ29udHJvbFNldDAwMSB0byBITE1cU3lzdGVtXEN1cnJlbnRDb250cm9sU2V0CiAgICAgICovCiAgICAgIEdldFN5c3RlbURpcmVjdG9yeUEoIGZuLCBNQVhfUEFUSE5BTUVfTEVOICk7CgogICAgICBzdHJjcHkoaG9tZSwgZm4pOwogICAgICBzdHJuY2F0KGhvbWUsICJcXGNvbmZpZ1xcc3lzdGVtIiwgTUFYX1BBVEhOQU1FX0xFTiAtIHN0cmxlbihob21lKSAtIDEpOwogICAgICBOYXRpdmVSZWdMb2FkS2V5KEhLRVlfTE9DQUxfTUFDSElORSwgaG9tZSwgMCk7CgogICAgICBzdHJjcHkoaG9tZSwgZm4pOwogICAgICBzdHJuY2F0KGhvbWUsICJcXGNvbmZpZ1xcc29mdHdhcmUiLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKGhvbWUpIC0gMSk7CiAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoSEtFWV9MT0NBTF9NQUNISU5FLCBob21lLCAwKTsKCiAgICAgIHN0cmNweShob21lLCBmbik7CiAgICAgIHN0cm5jYXQoaG9tZSwgIlxcY29uZmlnXFxzYW0iLCBNQVhfUEFUSE5BTUVfTEVOIC0gc3RybGVuKGhvbWUpIC0gMSk7CiAgICAgIE5hdGl2ZVJlZ0xvYWRLZXkoSEtFWV9MT0NBTF9NQUNISU5FLCBob21lLCAwKTsKCiAgICAgIHN0cmNweShob21lLCBmbik7CiAgICAgIHN0cm5jYXQoaG9tZSwgIlxcY29uZmlnXFxzZWN1cml0eSIsIE1BWF9QQVRITkFNRV9MRU4gLSBzdHJsZW4oaG9tZSkgLSAxKTsKICAgICAgTmF0aXZlUmVnTG9hZEtleShIS0VZX0xPQ0FMX01BQ0hJTkUsIGhvbWUsIDApOwoKICAgICAgZnJlZSAoaG9tZSk7CiAgICAgIGZyZWUgKGZuKTsKICAgICAgLyogdGhpcyBrZXkgaXMgZ2VuZXJhdGVkIHdoZW4gdGhlIG50LWNvcmUgYm9vdGVkIHN1Y2Nlc3NmdWxseSAqLwogICAgICBpZiAoIVJlZ0NyZWF0ZUtleUEoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXENsb25lIiwmaGtleSkpCiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgfQoKICBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCAoInJlZ2lzdHJ5IiwiTG9hZEdsb2JhbFJlZ2lzdHJ5RmlsZXMiLCAxKSkKICB7CiAgICAgIC8qIAogICAgICAgKiBMb2FkIHRoZSBnbG9iYWwgSEtVIGhpdmUgZGlyZWN0bHkgZnJvbSBzeXNjb25mZGlyCiAgICAgICAqLyAKICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9VU0VSUywgU0FWRV9VU0VSU19ERUZBVUxUICk7CgogICAgICAvKiAKICAgICAgICogTG9hZCB0aGUgZ2xvYmFsIG1hY2hpbmUgZGVmYXVsdHMgZGlyZWN0bHkgZm9ybSBzeXNjb25mZGlyCiAgICAgICAqLwogICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX0xPQ0FMX01BQ0hJTkUsIFNBVkVfTE9DQUxfTUFDSElORV9ERUZBVUxUICk7CiAgfQoKICBTZXRMb2FkTGV2ZWwoMSk7CgogIC8qCiAgICogTG9hZCB0aGUgdXNlciBzYXZlZCByZWdpc3RyaWVzIAogICAqLwogIGlmICghKGhvbWUgPSBnZXRlbnYoICJIT01FIiApKSkKICAgICAgV0FSTigiRmFpbGVkIHRvIGdldCBob21lZGlyZWN0b3J5IG9mIFVJRCAlbGQuXG4iLChsb25nKSBnZXR1aWQoKSk7CiAgZWxzZSBpZiAoUFJPRklMRV9HZXRXaW5lSW5pQm9vbCgicmVnaXN0cnkiLCAiTG9hZEhvbWVSZWdpc3RyeUZpbGVzIiwgMSkpCiAgewogICAgICAvKiAKICAgICAgICogTG9hZCB1c2VyJ3MgcGVyc29uYWwgdmVyc2lvbnMgb2YgZ2xvYmFsIEhLVS8uRGVmYXVsdCBrZXlzCiAgICAgICAqLwogICAgICBmbj0oY2hhciopeG1hbGxvYyggc3RybGVuKGhvbWUpKyBzdHJsZW4oV0lORV9QUkVGSVgpICsKICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbihTQVZFX0xPQ0FMX1VTRVJTX0RFRkFVTFQpKzIpOwogICAgICBzdHJjcHkoZm4sIGhvbWUpOwogICAgICBzdHJjYXQoZm4sIFdJTkVfUFJFRklYIi8iU0FWRV9MT0NBTF9VU0VSU19ERUZBVUxUKTsKICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9VU0VSUywgZm4gKTsgCiAgICAgIGZyZWUoZm4pOwoKICAgICAgZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihob21lKSArIHN0cmxlbihXSU5FX1BSRUZJWCkgKyBzdHJsZW4oU0FWRV9DVVJSRU5UX1VTRVIpKzIpOwogICAgICBzdHJjcHkoZm4sIGhvbWUpOwogICAgICBzdHJjYXQoZm4sIFdJTkVfUFJFRklYIi8iU0FWRV9DVVJSRU5UX1VTRVIpOwogICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX0NVUlJFTlRfVVNFUiwgZm4gKTsKICAgICAgZnJlZShmbik7CgogICAgICAvKiAKICAgICAgICogTG9hZCBIS0xNLCBhdHRlbXB0IHRvIGdldCB0aGUgcmVnaXN0cnkgbG9jYXRpb24gZnJvbSB0aGUgY29uZmlnIAogICAgICAgKiBmaWxlIGZpcnN0LCBpZiBleGlzdCwgbG9hZCBhbmQga2VlcCBnb2luZy4KICAgICAgICovCiAgICAgIGZuPShjaGFyKil4bWFsbG9jKCBzdHJsZW4oaG9tZSkrIHN0cmxlbihXSU5FX1BSRUZJWCkrIHN0cmxlbihTQVZFX0xPQ0FMX01BQ0hJTkUpKzIpOwogICAgICBzdHJjcHkoZm4saG9tZSk7CiAgICAgIHN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfTUFDSElORSk7CiAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfTE9DQUxfTUFDSElORSwgZm4gKTsKICAgICAgZnJlZShmbik7CiAgfQogIAogIC8qIAogICAqIExvYWQgSEtDVSwgZ2V0IHRoZSByZWdpc3RyeSBsb2NhdGlvbiBmcm9tIHRoZSBjb25maWcgCiAgICogZmlsZSwgaWYgZXhpc3QsIGxvYWQgYW5kIGtlZXAgZ29pbmcuCiAgICovICAgICAgCiAgaWYgKFBST0ZJTEVfR2V0V2luZUluaUJvb2wgKCAicmVnaXN0cnkiLCAiTG9hZEFsdFJlZ2lzdHJ5RmlsZXMiLCAxKSkKICB7CiAgICAgIGZuID0geG1hbGxvYyggTUFYX1BBVEhOQU1FX0xFTiApOyAKICAgICAgaWYgKCBQUk9GSUxFX0dldFdpbmVJbmlTdHJpbmcoICJyZWdpc3RyeSIsICJBbHRDdXJyZW50VXNlckZpbGUiLCAiIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiwgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKSAKICAgICAgIHsKICAgICAgICAgX3dpbmVfbG9hZHJlZyggSEtFWV9DVVJSRU5UX1VTRVIsIGZuICk7CiAgICAgICB9CiAgICAgIGZyZWUgKGZuKTsKICAgICAgLyoKICAgICAgICogTG9hZCBIS1UsIGdldCB0aGUgcmVnaXN0cnkgbG9jYXRpb24gZnJvbSB0aGUgY29uZmlnCiAgICAgICAqIGZpbGUsIGlmIGV4aXN0LCBsb2FkIGFuZCBrZWVwIGdvaW5nLgogICAgICAgKi8KICAgICAgZm4gPSB4bWFsbG9jICggTUFYX1BBVEhOQU1FX0xFTiApOwogICAgICBpZiAoIFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyAoICJyZWdpc3RyeSIsICJBbHRVc2VyRmlsZSIsICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZuLCBNQVhfUEFUSE5BTUVfTEVOIC0gMSkpCiAgICAgICB7CiAgICAgICAgIF93aW5lX2xvYWRyZWcoIEhLRVlfVVNFUlMsIGZuICk7CiAgICAgICB9CiAgICAgIGZyZWUgKGZuKTsKICAgICAgLyoKICAgICAgICogTG9hZCBIS0xNLCBnZXQgdGhlIHJlZ2lzdHJ5IGxvY2F0aW9uIGZyb20gdGhlIGNvbmZpZwogICAgICAgKiBmaWxlLCBpZiBleGlzdCwgbG9hZCBhbmQga2VlcCBnb2luZy4KICAgICAgICovCiAgICAgIGZuID0geG1hbGxvYyAoIE1BWF9QQVRITkFNRV9MRU4gKTsKICAgICAgaWYgKFBST0ZJTEVfR2V0V2luZUluaVN0cmluZyAoICJyZWdpc3RyeSIsICJBbHRMb2NhbE1hY2hpbmVGaWxlIiwgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbiwgTUFYX1BBVEhOQU1FX0xFTiAtIDEpKQogICAgICAgewogICAgICAgICBfd2luZV9sb2FkcmVnKCBIS0VZX0xPQ0FMX01BQ0hJTkUsIGZuICk7CiAgICAgICB9CiAgICAgIGZyZWUgKGZuKTsKICB9CiAgCiAgLyogCiAgICogTWFrZSBzdXJlIHRoZSB1cGRhdGUgbW9kZSBpcyB0aGVyZQogICAqLwogIGlmIChFUlJPUl9TVUNDRVNTPT1SZWdDcmVhdGVLZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpKSAKICB7CiAgICBEV09SRAlqdW5rLHR5cGUsbGVuOwogICAgY2hhcglkYXRhWzVdOwoKICAgIGxlbj00OwogICAgaWYgKCgJUmVnUXVlcnlWYWx1ZUV4QSgKICAgICAgICAgICAgaGtleSwKICAgICAgICAgICAgVkFMX1NBVkVVUERBVEVELAogICAgICAgICAgICAmanVuaywKICAgICAgICAgICAgJnR5cGUsCiAgICAgICAgICAgIGRhdGEsCiAgICAgICAgICAgICZsZW4pICE9IEVSUk9SX1NVQ0NFU1MpIHx8ICh0eXBlICE9IFJFR19TWikpCiAgICB7CiAgICAgIFJlZ1NldFZhbHVlRXhBKGhrZXksVkFMX1NBVkVVUERBVEVELDAsUkVHX1NaLCJ5ZXMiLDQpOwogICAgfQoKICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogIH0KCiAgaWYgKChzYXZlX3RpbWVvdXQgPSBQUk9GSUxFX0dldFdpbmVJbmlJbnQoICJyZWdpc3RyeSIsICJQZXJpb2RpY1NhdmUiLCAwICkpKQogIHsKICAgICAgU0VSVklDRV9BZGRUaW1lciggc2F2ZV90aW1lb3V0ICogMTAwMDAwMCwgcGVyaW9kaWNfc2F2ZSwgMCApOwogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKiogQVBJIEZVTkNUSU9OUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0ZsdXNoS2V5IFtLRVJORUwuMjI3XSBbQURWQVBJMzIuMTQzXQogKiBJbW1lZGlhdGVseSB3cml0ZXMga2V5IHRvIHJlZ2lzdHJ5LgogKiBPbmx5IHJldHVybnMgYWZ0ZXIgZGF0YSBoYXMgYmVlbiB3cml0dGVuIHRvIGRpc2suCiAqCiAqIEZJWE1FOiBkb2VzIGl0IHJlYWxseSB3YWl0IHVudGlsIGRhdGEgaXMgd3JpdHRlbiA/CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5IFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdyaXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRmx1c2hLZXkoIEhLRVkgaGtleSApCnsKICAgIEZJWE1FKCAiKCV4KTogc3R1YlxuIiwgaGtleSApOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ29ubmVjdFJlZ2lzdHJ5MzJXIFtBRFZBUEkzMi4xMjhdCiAqCiAqIFBBUkFNUwogKiAgICBscE1hY2hpbmVOYW1lIFtJXSBBZGRyZXNzIG9mIG5hbWUgb2YgcmVtb3RlIGNvbXB1dGVyCiAqICAgIGhIZXkgICAgICAgICAgW0ldIFByZWRlZmluZWQgcmVnaXN0cnkgaGFuZGxlCiAqICAgIHBoa1Jlc3VsdCAgICAgW0ldIEFkZHJlc3Mgb2YgYnVmZmVyIGZvciByZW1vdGUgcmVnaXN0cnkgaGFuZGxlCiAqLwpMT05HIFdJTkFQSSBSZWdDb25uZWN0UmVnaXN0cnlXKCBMUENXU1RSIGxwTWFjaGluZU5hbWUsIEhLRVkgaEtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBIS0VZIHBoa1Jlc3VsdCApCnsKICAgIFRSQUNFKCIoJXMsJXgsJXApOiBzdHViXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSksaEtleSxwaGtSZXN1bHQpOwoKICAgIGlmICghbHBNYWNoaW5lTmFtZSB8fCAhKmxwTWFjaGluZU5hbWUpIHsKICAgICAgICAvKiBVc2UgdGhlIGxvY2FsIG1hY2hpbmUgbmFtZSAqLwogICAgICAgIHJldHVybiBSZWdPcGVuS2V5MTYoIGhLZXksICIiLCBwaGtSZXN1bHQgKTsKICAgIH0KCiAgICBGSVhNRSgiQ2Fubm90IGNvbm5lY3QgdG8gJXNcbiIsZGVidWdzdHJfdyhscE1hY2hpbmVOYW1lKSk7CiAgICByZXR1cm4gRVJST1JfQkFEX05FVFBBVEg7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyQSBbQURWQVBJMzIuMTI3XQogKi8KTE9ORyBXSU5BUEkgUmVnQ29ubmVjdFJlZ2lzdHJ5QSggTFBDU1RSIG1hY2hpbmUsIEhLRVkgaGtleSwgTFBIS0VZIHJlc2tleSApCnsKICAgIERXT1JEIHJldDsKICAgIExQV1NUUiBtYWNoaW5lVyA9IHN0cmR1cEEyVyhtYWNoaW5lKTsKICAgIHJldCA9IFJlZ0Nvbm5lY3RSZWdpc3RyeVcoIG1hY2hpbmVXLCBoa2V5LCByZXNrZXkgKTsKICAgIGZyZWUobWFjaGluZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnR2V0S2V5U2VjdXJpdHkgW0FEVkFQSTMyLjE0NF0KICogUmV0cmlldmVzIGEgY29weSBvZiBzZWN1cml0eSBkZXNjcmlwdG9yIHByb3RlY3RpbmcgdGhlIHJlZ2lzdHJ5IGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgICAgICAgICBbSV0gICBPcGVuIGhhbmRsZSBvZiBrZXkgdG8gc2V0CiAqICAgIFNlY3VyaXR5SW5mb3JtYXRpb24gICAgW0ldICAgRGVzY3JpcHRvciBjb250ZW50cwogKiAgICBwU2VjdXJpdHlEZXNjcmlwdG9yICAgIFtPXSAgIEFkZHJlc3Mgb2YgZGVzY3JpcHRvciBmb3Iga2V5CiAqICAgIGxwY2JTZWN1cml0eURlc2NyaXB0b3IgW0kvT10gQWRkcmVzcyBvZiBzaXplIG9mIGJ1ZmZlciBhbmQgZGVzY3JpcHRpb24KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkxPTkcgV0lOQVBJIFJlZ0dldEtleVNlY3VyaXR5KCBIS0VZIGhrZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0VDVVJJVFlfSU5GT1JNQVRJT04gU2VjdXJpdHlJbmZvcm1hdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTRUNVUklUWV9ERVNDUklQVE9SIHBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JTZWN1cml0eURlc2NyaXB0b3IgKQp7CiAgICBUUkFDRSgiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksU2VjdXJpdHlJbmZvcm1hdGlvbixwU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvcj8qbHBjYlNlY3VyaXR5RGVzY3JpcHRvcjowKTsKCiAgICAvKiBGSVhNRTogQ2hlY2sgZm9yIHZhbGlkIFNlY3VyaXR5SW5mb3JtYXRpb24gdmFsdWVzICovCgogICAgaWYgKCpscGNiU2VjdXJpdHlEZXNjcmlwdG9yIDwgc2l6ZW9mKFNFQ1VSSVRZX0RFU0NSSVBUT1IpKQogICAgICAgIHJldHVybiBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSOwoKICAgIEZJWE1FKCIoJXgsJWxkLCVwLCVsZCk6IHN0dWJcbiIsaGtleSxTZWN1cml0eUluZm9ybWF0aW9uLAogICAgICAgICAgcFNlY3VyaXR5RGVzY3JpcHRvcixscGNiU2VjdXJpdHlEZXNjcmlwdG9yPypscGNiU2VjdXJpdHlEZXNjcmlwdG9yOjApOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdOb3RpZnlDaGFuZ2VLZXlWYWx1ZSBbQURWQVBJMzIuPz8/XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICAgIFtJXSBIYW5kbGUgb2Yga2V5IHRvIHdhdGNoCiAqICAgIGZXYXRjaFN1YlRyZWUgICBbSV0gRmxhZyBmb3Igc3Via2V5IG5vdGlmaWNhdGlvbgogKiAgICBmZHdOb3RpZnlGaWx0ZXIgW0ldIENoYW5nZXMgdG8gYmUgcmVwb3J0ZWQKICogICAgaEV2ZW50ICAgICAgICAgIFtJXSBIYW5kbGUgb2Ygc2lnbmFsZWQgZXZlbnQKICogICAgZkFzeW5jICAgICAgICAgIFtJXSBGbGFnIGZvciBhc3luY2hyb25vdXMgcmVwb3J0aW5nCiAqLwpMT05HIFdJTkFQSSBSZWdOb3RpZnlDaGFuZ2VLZXlWYWx1ZSggSEtFWSBoa2V5LCBCT09MIGZXYXRjaFN1YlRyZWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZmR3Tm90aWZ5RmlsdGVyLCBIQU5ETEUgaEV2ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBmQXN5bmMgKQp7CiAgICBGSVhNRSgiKCV4LCVpLCVsZCwleCwlaSk6IHN0dWJcbiIsaGtleSxmV2F0Y2hTdWJUcmVlLGZkd05vdGlmeUZpbHRlciwKICAgICAgICAgIGhFdmVudCxmQXN5bmMpOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1VuTG9hZEtleTMyVyBbQURWQVBJMzIuMTczXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscFN1YktleSBbSV0gQWRkcmVzcyBvZiBuYW1lIG9mIHN1YmtleSB0byB1bmxvYWQKICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleVcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSApCnsKICAgIEZJWE1FKCIoJXgsJXMpOiBzdHViXG4iLGhrZXksIGRlYnVnc3RyX3cobHBTdWJLZXkpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdVbkxvYWRLZXkzMkEgW0FEVkFQSTMyLjE3Ml0KICovCkxPTkcgV0lOQVBJIFJlZ1VuTG9hZEtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwU3ViS2V5ICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBTdWJLZXlXID0gc3RyZHVwQTJXKGxwU3ViS2V5KTsKICAgIHJldCA9IFJlZ1VuTG9hZEtleVcoIGhrZXksIGxwU3ViS2V5VyApOwogICAgaWYobHBTdWJLZXlXKSBmcmVlKGxwU3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTY3XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICBbSV0gT3BlbiBoYW5kbGUgb2Yga2V5IHRvIHNldAogKiAgICBTZWN1cml0eUluZm8gIFtJXSBEZXNjcmlwdG9yIGNvbnRlbnRzCiAqICAgIHBTZWN1cml0eURlc2MgW0ldIEFkZHJlc3Mgb2YgZGVzY3JpcHRvciBmb3Iga2V5CiAqLwpMT05HIFdJTkFQSSBSZWdTZXRLZXlTZWN1cml0eSggSEtFWSBoa2V5LCBTRUNVUklUWV9JTkZPUk1BVElPTiBTZWN1cml0eUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU0VDVVJJVFlfREVTQ1JJUFRPUiBwU2VjdXJpdHlEZXNjICkKewogICAgVFJBQ0UoIigleCwlbGQsJXApXG4iLGhrZXksU2VjdXJpdHlJbmZvLHBTZWN1cml0eURlc2MpOwoKICAgIC8qIEl0IHNlZW1zIHRvIHBlcmZvcm0gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICgoU2VjdXJpdHlJbmZvICYgT1dORVJfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIEdST1VQX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBEQUNMX1NFQ1VSSVRZX0lORk9STUFUSU9OKSB8fAogICAgICAgIChTZWN1cml0eUluZm8gJiBTQUNMX1NFQ1VSSVRZX0lORk9STUFUSU9OKSkgewogICAgICAgIC8qIFBhcmFtIE9LICovCiAgICB9IGVsc2UKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgaWYgKCFwU2VjdXJpdHlEZXNjKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBGSVhNRSgiOigleCwlbGQsJXApOiBzdHViXG4iLGhrZXksU2VjdXJpdHlJbmZvLHBTZWN1cml0eURlc2MpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5MzJXIFtBRFZBUEkzMi4xNjRdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgIFtJXSBIYW5kbGUgb2Yga2V5IHdoZXJlIHJlc3RvcmUgYmVnaW5zCiAqICAgIGxwRmlsZSAgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgY29udGFpbmluZyBzYXZlZCB0cmVlCiAqICAgIGR3RmxhZ3MgW0ldIE9wdGlvbmFsIGZsYWdzCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5VyggSEtFWSBoa2V5LCBMUENXU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIFRSQUNFKCIoJXgsJXMsJWxkKVxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBJdCBzZWVtcyB0byBkbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscEZpbGUgfHwgISpscEZpbGUpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIEZJWE1FKCIoJXgsJXMsJWxkKTogc3R1YlxuIixoa2V5LGRlYnVnc3RyX3cobHBGaWxlKSxkd0ZsYWdzKTsKCiAgICAvKiBDaGVjayBmb3IgZmlsZSBleGlzdGVuY2UgKi8KCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVzdG9yZUtleTMyQSBbQURWQVBJMzIuMTYzXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVzdG9yZUtleUEoIEhLRVkgaGtleSwgTFBDU1RSIGxwRmlsZSwgRFdPUkQgZHdGbGFncyApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwRmlsZVcgPSBzdHJkdXBBMlcobHBGaWxlKTsKICAgIHJldCA9IFJlZ1Jlc3RvcmVLZXlXKCBoa2V5LCBscEZpbGVXLCBkd0ZsYWdzICk7CiAgICBpZihscEZpbGVXKSBmcmVlKGxwRmlsZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleTMyVyBbQURWQVBJMzIuMTYyXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBTdWJLZXkgIFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5CiAqICAgIGxwTmV3RmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgZmlsZSB3aXRoIG5ldyBkYXRhCiAqICAgIGxwT2xkRmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgYmFja3VwIGZpbGUKICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXlXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBTdWJLZXksIExQQ1dTVFIgbHBOZXdGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIGxwT2xkRmlsZSApCnsKICAgIEZJWE1FKCIoJXgsJXMsJXMsJXMpOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwU3ViS2V5KSwgCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXBsYWNlS2V5MzJBIFtBRFZBUEkzMi4xNjFdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXBsYWNlS2V5QSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXksIExQQ1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscE9sZEZpbGUgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscFN1YktleVcgPSBzdHJkdXBBMlcobHBTdWJLZXkpOwogICAgTFBXU1RSIGxwTmV3RmlsZVcgPSBzdHJkdXBBMlcobHBOZXdGaWxlKTsKICAgIExQV1NUUiBscE9sZEZpbGVXID0gc3RyZHVwQTJXKGxwT2xkRmlsZSk7CiAgICByZXQgPSBSZWdSZXBsYWNlS2V5VyggaGtleSwgbHBTdWJLZXlXLCBscE5ld0ZpbGVXLCBscE9sZEZpbGVXICk7CiAgICBmcmVlKGxwT2xkRmlsZVcpOwogICAgZnJlZShscE5ld0ZpbGVXKTsKICAgIGZyZWUobHBTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgoKCgoKLyogMTYtYml0IGZ1bmN0aW9ucyAqLwoKLyogMCBhbmQgMSBhcmUgdmFsaWQgcm9vdGtleXMgaW4gd2luMTYgc2hlbGwuZGxsIGFuZCBhcmUgdXNlZCBieQogKiBzb21lIHByb2dyYW1zLiBEbyBub3QgcmVtb3ZlIHRob3NlIGNhc2VzLiAtTU0KICovCnN0YXRpYyBpbmxpbmUgdm9pZCBmaXhfd2luMTZfaGtleSggSEtFWSAqaGtleSApCnsKICAgIGlmICgqaGtleSA9PSAwIHx8ICpoa2V5ID09IDEpICpoa2V5ID0gSEtFWV9DTEFTU0VTX1JPT1Q7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0VudW1LZXkxNiAgIFtLRVJORUwuMjE2XSBbU0hFTEwuN10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MTYoIEhLRVkgaGtleSwgRFdPUkQgaW5kZXgsIExQU1RSIG5hbWUsIERXT1JEIG5hbWVfbGVuICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRW51bUtleUEoIGhrZXksIGluZGV4LCBuYW1lLCBuYW1lX2xlbiApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdPcGVuS2V5MTYgICBbS0VSTkVMLjIxN10gW1NIRUxMLjFdCiAqLwpEV09SRCBXSU5BUEkgUmVnT3BlbktleTE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUEhLRVkgcmV0a2V5ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnT3BlbktleUEoIGhrZXksIG5hbWUsIHJldGtleSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdDcmVhdGVLZXkxNiAgIFtLRVJORUwuMjE4XSBbU0hFTEwuMl0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBIS0VZIHJldGtleSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0NyZWF0ZUtleUEoIGhrZXksIG5hbWUsIHJldGtleSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdEZWxldGVLZXkxNiAgIFtLRVJORUwuMjE5XSBbU0hFTEwuNF0KICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVLZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ0RlbGV0ZUtleUEoIGhrZXksIG5hbWUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnQ2xvc2VLZXkxNiAgIFtLRVJORUwuMjIwXSBbU0hFTEwuM10KICovCkRXT1JEIFdJTkFQSSBSZWdDbG9zZUtleTE2KCBIS0VZIGhrZXkgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdDbG9zZUtleSggaGtleSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdTZXRWYWx1ZTE2ICAgW0tFUk5FTC4yMjFdIFtTSEVMTC41XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMTYoIEhLRVkgaGtleSwgTFBDU1RSIG5hbWUsIERXT1JEIHR5cGUsIExQQ1NUUiBkYXRhLCBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgcmV0dXJuIFJlZ1NldFZhbHVlQSggaGtleSwgbmFtZSwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnRGVsZXRlVmFsdWUxNiAgW0tFUk5FTC4yMjJdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUxNiggSEtFWSBoa2V5LCBMUFNUUiBuYW1lICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRGVsZXRlVmFsdWVBKCBoa2V5LCBuYW1lICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJlZ0VudW1WYWx1ZTE2ICAgW0tFUk5FTC4yMjNdCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bVZhbHVlMTYoIEhLRVkgaGtleSwgRFdPUkQgaW5kZXgsIExQU1RSIHZhbHVlLCBMUERXT1JEIHZhbF9jb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIHJlc2VydmVkLCBMUERXT1JEIHR5cGUsIExQQllURSBkYXRhLCBMUERXT1JEIGNvdW50ICkKewogICAgZml4X3dpbjE2X2hrZXkoICZoa2V5ICk7CiAgICByZXR1cm4gUmVnRW51bVZhbHVlQSggaGtleSwgaW5kZXgsIHZhbHVlLCB2YWxfY291bnQsIHJlc2VydmVkLCB0eXBlLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdRdWVyeVZhbHVlMTYgICBbS0VSTkVMLjIyNF0gW1NIRUxMLjZdCiAqCiAqIE5PVEVTCiAqICAgIElzIHRoaXMgSEFDSyBzdGlsbCBhcHBsaWNhYmxlPwogKgogKiBIQUNLCiAqICAgIFRoZSAxNmJpdCBSZWdRdWVyeVZhbHVlIGRvZXNuJ3QgaGFuZGxlIHNlbGVjdG9yYmxvY2tzIGFueXdheSwgc28gd2UganVzdAogKiAgICBtYXNrIG91dCB0aGUgaGlnaCAxNiBiaXQuICBUaGlzIChub3Qgc28gbXVjaCBpbmNpZGVudGx5KSBob3BlZnVsbHkgZml4ZXMKICogICAgQWxkdXMgRkg0KQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUxNiggSEtFWSBoa2V5LCBMUENTVFIgbmFtZSwgTFBTVFIgZGF0YSwgTFBEV09SRCBjb3VudCApCnsKICAgIGZpeF93aW4xNl9oa2V5KCAmaGtleSApOwogICAgaWYgKGNvdW50KSAqY291bnQgJj0gMHhmZmZmOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVBKCBoa2V5LCBuYW1lLCBkYXRhLCBjb3VudCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSZWdRdWVyeVZhbHVlRXgxNiAgIFtLRVJORUwuMjI1XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBMUERXT1JEIHJlc2VydmVkLCBMUERXT1JEIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGRhdGEsIExQRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdRdWVyeVZhbHVlRXhBKCBoa2V5LCBuYW1lLCByZXNlcnZlZCwgdHlwZSwgZGF0YSwgY291bnQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUmVnU2V0VmFsdWVFeDE2ICAgW0tFUk5FTC4yMjZdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWVFeDE2KCBIS0VZIGhrZXksIExQQ1NUUiBuYW1lLCBEV09SRCByZXNlcnZlZCwgRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09OU1QgQllURSAqZGF0YSwgRFdPUkQgY291bnQgKQp7CiAgICBmaXhfd2luMTZfaGtleSggJmhrZXkgKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUV4QSggaGtleSwgbmFtZSwgcmVzZXJ2ZWQsIHR5cGUsIGRhdGEsIGNvdW50ICk7Cn0K