LyoKICogCVJlZ2lzdHJ5IEZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NiBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTWF0dGhldyBCZWNrZXIKICoKICogRGVjZW1iZXIgMjEsIDE5OTcgLSBLZXZpbiBDb3plbnMKICogRml4ZWQgYnVncyBpbiB0aGUgX3c5NV9sb2FkcmVnKCkgZnVuY3Rpb24uIEFkZGVkIGV4dHJhIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyB0aGUgZm9ybWF0IG9mIHRoZSBXaW5kb3dzICc5NSByZWdpc3RyeSBmaWxlcy4KICoKICogTk9URVMKICogICAgV2hlbiBjaGFuZ2luZyB0aGlzIGZpbGUsIHBsZWFzZSByZS1ydW4gdGhlIHJlZ3Rlc3QgcHJvZ3JhbSB0byBlbnN1cmUKICogICAgdGhlIGNvbmRpdGlvbnMgYXJlIGhhbmRsZWQgcHJvcGVybHkuCiAqCiAqIFRPRE8KICogICAgU2VjdXJpdHkgYWNjZXNzCiAqICAgIE9wdGlvbiBoYW5kbGluZwogKiAgICBUaW1lIGZvciBSZWdFbnVtS2V5KiwgUmVnUXVlcnlJbmZvS2V5KgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPHN5cy9lcnJuby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxwd2QuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAid2luLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAiaGVhcC5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKc3RhdGljIHZvaWQgUkVHSVNUUllfSW5pdCgpOwovKiBGSVhNRTogZm9sbG93aW5nIGRlZmluZXMgc2hvdWxkIGJlIGNvbmZpZ3VyZWQgZ2xvYmFsIC4uLiAqLwoKLyogTk9URTogZG8gbm90IGFwcGVuZCBhIC8uIGxpbnV4JyBta2RpcigpIFdJTEwgRkFJTCBpZiB5b3UgZG8gdGhhdCAqLwojZGVmaW5lIFdJTkVfUFJFRklYCQkJIi8ud2luZSIKI2RlZmluZSBTQVZFX1VTRVJTX0RFRkFVTFQJCSIvdXNyL2xvY2FsL2V0Yy93aW5lLnVzZXJyZWciCiNkZWZpbmUgU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQJIi91c3IvbG9jYWwvZXRjL3dpbmUuc3lzdGVtcmVnIgoKLyogcmVsYXRpdmUgaW4gfnVzZXIvLndpbmUvIDogKi8KI2RlZmluZSBTQVZFX0NVUlJFTlRfVVNFUgkJInVzZXIucmVnIgojZGVmaW5lIFNBVkVfTE9DQUxfTUFDSElORQkJInN5c3RlbS5yZWciCgojZGVmaW5lIEtFWV9SRUdJU1RSWQkiU29mdHdhcmVcXFRoZSBXSU5FIHRlYW1cXFdJTkVcXFJlZ2lzdHJ5IgojZGVmaW5lIFZBTF9TQVZFVVBEQVRFRAkiU2F2ZU9ubHlVcGRhdGVkS2V5cyIKCi8qIG9uZSB2YWx1ZSBvZiBhIGtleSAqLwp0eXBlZGVmIHN0cnVjdCB0YWdLRVlWQUxVRQp7CiAgICBMUFdTVFIgICBuYW1lOyAgICAgICAgICAvKiBuYW1lIG9mIHZhbHVlIChVTklDT0RFKSBvciBOVUxMIGZvciB3aW4zMSAqLwogICAgRFdPUkQgICAgdHlwZTsgICAgICAgICAgLyogdHlwZSBvZiB2YWx1ZSAqLwogICAgRFdPUkQgICAgbGVuOyAgICAgICAgICAgLyogbGVuZ3RoIG9mIGRhdGEgaW4gQllURXMgKi8KICAgIERXT1JEICAgIGxhc3Rtb2RpZmllZDsgIC8qIHRpbWUgb2Ygc2Vjb25kcyBzaW5jZSAxLjEuMTk3MCAqLwogICAgTFBCWVRFICAgZGF0YTsgICAgICAgICAgLyogY29udGVudCwgbWF5IGJlIHN0cmluZ3MsIGJpbmFyaWVzLCBldGMuICovCn0gS0VZVkFMVUUsKkxQS0VZVkFMVUU7CgovKiBhIHJlZ2lzdHJ5IGtleSAqLwp0eXBlZGVmIHN0cnVjdCB0YWdLRVlTVFJVQ1QKewogICAgTFBXU1RSICAgICAgICAgICAgICAga2V5bmFtZTsgICAgICAgLyogbmFtZSBvZiBUSElTIGtleSAoVU5JQ09ERSkgKi8KICAgIERXT1JEICAgICAgICAgICAgICAgIGZsYWdzOyAgICAgICAgIC8qIGZsYWdzLiAqLwogICAgTFBXU1RSICAgICAgICAgICAgICAgY2xhc3M7CiAgICAvKiB2YWx1ZXMgKi8KICAgIERXT1JEICAgICAgICAgICAgICAgIG5yb2Z2YWx1ZXM7ICAgIC8qIG5yIG9mIHZhbHVlcyBpbiBUSElTIGtleSAqLwogICAgTFBLRVlWQUxVRSAgICAgICAgICAgdmFsdWVzOyAgICAgICAgLyogdmFsdWVzIGluIFRISVMga2V5ICovCiAgICAvKiBrZXkgbWFuYWdlbWVudCBwb2ludGVycyAqLwogICAgc3RydWN0IHRhZ0tFWVNUUlVDVAkqbmV4dDsgICAgICAgICAgLyogbmV4dCBrZXkgb24gc2FtZSBoaWVyYXJjaHkgKi8KICAgIHN0cnVjdCB0YWdLRVlTVFJVQ1QJKm5leHRzdWI7ICAgICAgIC8qIGtleXMgdGhhdCBoYW5nIGJlbG93IFRISVMga2V5ICovCn0gS0VZU1RSVUNULCAqTFBLRVlTVFJVQ1Q7CgoKc3RhdGljIEtFWVNUUlVDVAkqa2V5X2NsYXNzZXNfcm9vdD1OVUxMOwkvKiB3aW5kb3dzIDMuMSBnbG9iYWwgdmFsdWVzICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jdXJyZW50X3VzZXI9TlVMTDsJLyogdXNlciBzcGVjaWZpYyB2YWx1ZXMgKi8Kc3RhdGljIEtFWVNUUlVDVAkqa2V5X2xvY2FsX21hY2hpbmU9TlVMTDsvKiBtYWNoaW5lIHNwZWNpZmljIHZhbHVlcyAqLwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfdXNlcnM9TlVMTDsJLyogYWxsIHVzZXJzPyAqLwoKLyogZHluYW1pYywgbm90IHNhdmVkICovCnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9wZXJmb3JtYW5jZV9kYXRhPU5VTEw7CnN0YXRpYyBLRVlTVFJVQ1QJKmtleV9jdXJyZW50X2NvbmZpZz1OVUxMOwpzdGF0aWMgS0VZU1RSVUNUCSprZXlfZHluX2RhdGE9TlVMTDsKCi8qIHdoYXQgdmFsdWV0eXBlcyBkbyB3ZSBuZWVkIHRvIGNvbnZlcnQ/ICovCiNkZWZpbmUgVU5JQ09OVk1BU0sJKCgxPDxSRUdfU1opfCgxPDxSRUdfTVVMVElfU1opfCgxPDxSRUdfRVhQQU5EX1NaKSkKCgpzdGF0aWMgc3RydWN0IG9wZW5oYW5kbGUgewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglIS0VZCQloa2V5OwoJUkVHU0FNCQlhY2Nlc3NtYXNrOwp9ICAqb3BlbmhhbmRsZXM9TlVMTDsKc3RhdGljIGludAlucm9mb3BlbmhhbmRsZXM9MDsKLyogU3RhcnRzIGFmdGVyIDEgYmVjYXVzZSAwLDEgYXJlIHJlc2VydmVkIGZvciBXaW4xNiAqLwovKiBOb3RlOiBTaG91bGQgYWx3YXlzIGJlIGV2ZW4sIGFzIFdpbjk1IEFEVkFQSTMyLkRMTCByZXNlcnZlcyBvZGQKICAgICAgICAgSEtFWXMgZm9yIHJlbW90ZSByZWdpc3RyeSBhY2Nlc3MgKi8Kc3RhdGljIGludAljdXJyZW50aGFuZGxlPTI7CgoKLyoKICogUVVFU1RJT04KICogICBBcmUgdGhlc2UgZG9pbmcgdGhlIHNhbWUgYXMgSEVBUF9zdHJkdXBBdG9XIGFuZCBIRUFQX3N0cmR1cFd0b0E/CiAqICAgSWYgc28sIGNhbiB3ZSByZW1vdmUgdGhlbT8KICogQU5TV0VSCiAqICAgTm8sIHRoZSBtZW1vcnkgaGFuZGxpbmcgZnVuY3Rpb25zIGFyZSBjYWxsZWQgdmVyeSBvZnRlbiBpbiBoZXJlLCAKICogICBqdXN0IHJlcGxhY2luZyB0aGVtIGJ5IEhlYXBBbGxvYyhTeXN0ZW1IZWFwLC4uLikgbWFrZXMgcmVnaXN0cnkKICogICBsb2FkaW5nIDEwMCB0aW1lcyBzbG93ZXIuIC1NTQogKi8Kc3RhdGljIExQV1NUUiBzdHJkdXBBMlcoTFBDU1RSIHNyYykKewogICAgaWYoc3JjKSB7CglMUFdTVFIgZGVzdD14bWFsbG9jKDIqc3RybGVuKHNyYykrMik7Cglsc3RyY3B5QXRvVyhkZXN0LHNyYyk7CglyZXR1cm4gZGVzdDsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMgTFBXU1RSIHN0cmR1cFcoTFBDV1NUUiBhKSB7CglMUFdTVFIJYjsKCWludAlsZW47CgogICAgaWYoYSkgewoJbGVuPXNpemVvZihXQ0hBUikqKGxzdHJsZW4zMlcoYSkrMSk7CgliPShMUFdTVFIpeG1hbGxvYyhsZW4pOwoJbWVtY3B5KGIsYSxsZW4pOwoJcmV0dXJuIGI7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKTFBXU1RSIHN0cmN2dEEyVyhMUENTVFIgc3JjLCBpbnQgbmNoYXJzKQoKewogICBMUFdTVFIgZGVzdCA9IHhtYWxsb2MgKDIgKiBuY2hhcnMgKyAyKTsKCiAgIGxzdHJjcHluQXRvVyhkZXN0LHNyYyxuY2hhcnMrMSk7CiAgIGRlc3RbbmNoYXJzXSA9IDA7CiAgIHJldHVybiBkZXN0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBpc19zdGFuZGFyZF9oa2V5IFtJbnRlcm5hbF0KICogRGV0ZXJtaW5lcyBpZiBhIGhrZXkgaXMgYSBzdGFuZGFyZCBrZXkKICovCnN0YXRpYyBCT09MMzIgaXNfc3RhbmRhcmRfaGtleSggSEtFWSBoa2V5ICkKewogICAgc3dpdGNoKGhrZXkpIHsKICAgICAgICBjYXNlIDB4MDAwMDAwMDA6CiAgICAgICAgY2FzZSAweDAwMDAwMDAxOgogICAgICAgIGNhc2UgSEtFWV9DTEFTU0VTX1JPT1Q6CiAgICAgICAgY2FzZSBIS0VZX0NVUlJFTlRfQ09ORklHOgogICAgICAgIGNhc2UgSEtFWV9DVVJSRU5UX1VTRVI6CiAgICAgICAgY2FzZSBIS0VZX0xPQ0FMX01BQ0hJTkU6CiAgICAgICAgY2FzZSBIS0VZX1VTRVJTOgogICAgICAgIGNhc2UgSEtFWV9QRVJGT1JNQU5DRV9EQVRBOgogICAgICAgIGNhc2UgSEtFWV9EWU5fREFUQToKICAgICAgICAgICAgcmV0dXJuIFRSVUU7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGFkZF9oYW5kbGUgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgYWRkX2hhbmRsZSggSEtFWSBoa2V5LCBMUEtFWVNUUlVDVCBscGtleSwgUkVHU0FNIGFjY2Vzc21hc2sgKQp7CiAgICBpbnQgaTsKCiAgICBUUkFDRShyZWcsIigweCV4LCVwLDB4JWx4KVxuIixoa2V5LGxwa2V5LGFjY2Vzc21hc2spOwogICAgLyogQ2hlY2sgZm9yIGR1cGxpY2F0ZXMgKi8KICAgIGZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykgewogICAgICAgIGlmIChvcGVuaGFuZGxlc1tpXS5scGtleT09bHBrZXkpIHsKICAgICAgICAgICAgLyogVGhpcyBpcyBub3QgcmVhbGx5IGFuIGVycm9yIC0gdGhlIHVzZXIgaXMgYWxsb3dlZCB0byBjcmVhdGUKICAgICAgICAgICAgICAgdHdvIChvciBtb3JlKSBoYW5kbGVzIHRvIHRoZSBzYW1lIGtleSAqLwogICAgICAgICAgICAvKldBUk4ocmVnLCAiQWRkaW5nIGtleSAlcCB0d2ljZVxuIixscGtleSk7Ki8KICAgICAgICB9CiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXk9PWhrZXkpIHsKICAgICAgICAgICAgV0FSTihyZWcsICJBZGRpbmcgaGFuZGxlICV4IHR3aWNlXG4iLGhrZXkpOwogICAgICAgIH0KICAgIH0KICAgIG9wZW5oYW5kbGVzPXhyZWFsbG9jKCBvcGVuaGFuZGxlcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzKzEpKTsKCiAgICBvcGVuaGFuZGxlc1tpXS5scGtleSA9IGxwa2V5OwogICAgb3BlbmhhbmRsZXNbaV0uaGtleSA9IGhrZXk7CiAgICBvcGVuaGFuZGxlc1tpXS5hY2Nlc3NtYXNrID0gYWNjZXNzbWFzazsKICAgIG5yb2ZvcGVuaGFuZGxlcysrOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBnZXRfaGFuZGxlIFtJbnRlcm5hbF0KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBQb2ludGVyIHRvIGtleQogKiAgICBGYWlsdXJlOiBOVUxMCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgZ2V0X2hhbmRsZSggSEtFWSBoa2V5ICkKewogICAgaW50IGk7CgogICAgZm9yIChpPTA7IGk8bnJvZm9wZW5oYW5kbGVzOyBpKyspCiAgICAgICAgaWYgKG9wZW5oYW5kbGVzW2ldLmhrZXkgPT0gaGtleSkKICAgICAgICAgICAgcmV0dXJuIG9wZW5oYW5kbGVzW2ldLmxwa2V5OwogICAgV0FSTihyZWcsICJDb3VsZCBub3QgZmluZCBoYW5kbGUgMHgleFxuIixoa2V5KTsKICAgIHJldHVybiBOVUxMOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiByZW1vdmVfaGFuZGxlIFtJbnRlcm5hbF0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgW0ldIEhhbmRsZSBvZiBrZXkgdG8gcmVtb3ZlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFUlJPUl9JTlZBTElEX0hBTkRMRQogKi8Kc3RhdGljIERXT1JEIHJlbW92ZV9oYW5kbGUoIEhLRVkgaGtleSApCnsKICAgIGludCBpOwoKICAgIGZvciAoaT0wO2k8bnJvZm9wZW5oYW5kbGVzO2krKykKICAgICAgICBpZiAob3BlbmhhbmRsZXNbaV0uaGtleT09aGtleSkKICAgICAgICAgICAgYnJlYWs7CgogICAgaWYgKGkgPT0gbnJvZm9wZW5oYW5kbGVzKSB7CiAgICAgICAgV0FSTihyZWcsICJDb3VsZCBub3QgZmluZCBoYW5kbGUgMHgleFxuIixoa2V5KTsKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CiAgICB9CgogICAgbWVtY3B5KCBvcGVuaGFuZGxlcytpLAogICAgICAgICAgICBvcGVuaGFuZGxlcytpKzEsCiAgICAgICAgICAgIHNpemVvZihzdHJ1Y3Qgb3BlbmhhbmRsZSkqKG5yb2ZvcGVuaGFuZGxlcy1pLTEpCiAgICApOwogICAgb3BlbmhhbmRsZXM9eHJlYWxsb2Mob3BlbmhhbmRsZXMsc2l6ZW9mKHN0cnVjdCBvcGVuaGFuZGxlKSoobnJvZm9wZW5oYW5kbGVzLTEpKTsKICAgIG5yb2ZvcGVuaGFuZGxlcy0tOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogbG9va3VwX2hrZXkgW0ludGVybmFsXQogKiAKICogSnVzdCBhcyB0aGUgbmFtZSBzYXlzLiBDcmVhdGVzIHRoZSByb290IGtleXMgb24gZGVtYW5kLCBzbyB3ZSBjYW4gY2FsbCB0aGUKICogUmVnKiBmdW5jdGlvbnMgYXQgYW55IHRpbWUuCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogUG9pbnRlciB0byBrZXkgc3RydWN0dXJlCiAqICAgIEZhaWx1cmU6IE5VTEwKICovCiNkZWZpbmUgQUREX1JPT1RfS0VZKHh4KSBcCgl4eCA9IChMUEtFWVNUUlVDVCl4bWFsbG9jKHNpemVvZihLRVlTVFJVQ1QpKTtcCgltZW1zZXQoeHgsJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7XAoJeHgtPmtleW5hbWU9IHN0cmR1cEEyVygiPHNob3VsZF9ub3RfYXBwZWFyX2FueXdoZXJlPiIpOwoKc3RhdGljIExQS0VZU1RSVUNUIGxvb2t1cF9oa2V5KCBIS0VZIGhrZXkgKQp7Cglzd2l0Y2ggKGhrZXkpIHsKCS8qIDAgYW5kIDEgYXJlIHZhbGlkIHJvb3RrZXlzIGluIHdpbjE2IHNoZWxsLmRsbCBhbmQgYXJlIHVzZWQgYnkKCSAqIHNvbWUgcHJvZ3JhbXMuIERvIG5vdCByZW1vdmUgdGhvc2UgY2FzZXMuIC1NTQoJICovCiAgICAJY2FzZSAweDAwMDAwMDAwOgoJY2FzZSAweDAwMDAwMDAxOgoJY2FzZSBIS0VZX0NMQVNTRVNfUk9PVDogewoJCWlmICgha2V5X2NsYXNzZXNfcm9vdCkgewoJCQlIS0VZCWNsX3JfaGtleTsKCgkJCS8qIGNhbGxzIGxvb2t1cF9oa2V5IHJlY3Vyc2l2ZWx5LCBUV0lDRSAqLwoJCQlpZiAoUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJTT0ZUV0FSRVxcQ2xhc3NlcyIsJmNsX3JfaGtleSkhPUVSUk9SX1NVQ0NFU1MpIHsKCQkJCUVSUihyZWcsIkNvdWxkIG5vdCBjcmVhdGUgSEtMTVxcU09GVFdBUkVcXENsYXNzZXMuIFRoaXMgaXMgaW1wb3NzaWJsZS5cbiIpOwoJCQkJZXhpdCgxKTsKCQkJfQoJCQlrZXlfY2xhc3Nlc19yb290ID0gbG9va3VwX2hrZXkoY2xfcl9oa2V5KTsKCQl9CgkJcmV0dXJuIGtleV9jbGFzc2VzX3Jvb3Q7Cgl9CgljYXNlIEhLRVlfQ1VSUkVOVF9VU0VSOgoJCWlmICgha2V5X2N1cnJlbnRfdXNlcikgewoJCQlIS0VZCWNfdV9oa2V5OwoJCQlzdHJ1Y3QJcGFzc3dkCSpwd2Q7CgoJCQlwd2Q9Z2V0cHd1aWQoZ2V0dWlkKCkpOwoJCQkvKiBjYWxscyBsb29rdXBfaGtleSByZWN1cnNpdmVseSwgVFdJQ0UgKi8KCQkJaWYgKHB3ZCAmJiBwd2QtPnB3X25hbWUpIHsKCQkJCWlmIChSZWdDcmVhdGVLZXkxNihIS0VZX1VTRVJTLHB3ZC0+cHdfbmFtZSwmY191X2hrZXkpIT1FUlJPUl9TVUNDRVNTKSB7CgkJCQkJRVJSKHJlZywiQ291bGQgbm90IGNyZWF0ZSBIVVxcJXMuIFRoaXMgaXMgaW1wb3NzaWJsZS5cbiIscHdkLT5wd19uYW1lKTsKCQkJCQlleGl0KDEpOwoJCQkJfQoJCQkJa2V5X2N1cnJlbnRfdXNlciA9IGxvb2t1cF9oa2V5KGNfdV9oa2V5KTsKCQkJfSBlbHNlIHsKCQkJCS8qIG5vdGhpbmcgZm91bmQsIHVzZSBzdGFuZGFsb25lICovCgkJCQlBRERfUk9PVF9LRVkoa2V5X2N1cnJlbnRfdXNlcik7CgkJCX0KCQl9CgkJcmV0dXJuIGtleV9jdXJyZW50X3VzZXI7CgljYXNlIEhLRVlfTE9DQUxfTUFDSElORToKCQlpZiAoIWtleV9sb2NhbF9tYWNoaW5lKSB7CgkJCUFERF9ST09UX0tFWShrZXlfbG9jYWxfbWFjaGluZSk7CgkJCVJFR0lTVFJZX0luaXQoKTsKCQl9CgkJcmV0dXJuIGtleV9sb2NhbF9tYWNoaW5lOwoJY2FzZSBIS0VZX1VTRVJTOgoJCWlmICgha2V5X3VzZXJzKSB7CgkJCUFERF9ST09UX0tFWShrZXlfdXNlcnMpOwoJCX0KCQlyZXR1cm4ga2V5X3VzZXJzOwoJY2FzZSBIS0VZX1BFUkZPUk1BTkNFX0RBVEE6CgkJaWYgKCFrZXlfcGVyZm9ybWFuY2VfZGF0YSkgewoJCQlBRERfUk9PVF9LRVkoa2V5X3BlcmZvcm1hbmNlX2RhdGEpOwoJCX0KCQlyZXR1cm4ga2V5X3BlcmZvcm1hbmNlX2RhdGE7CgljYXNlIEhLRVlfRFlOX0RBVEE6CgkJaWYgKCFrZXlfZHluX2RhdGEpIHsKCQkJQUREX1JPT1RfS0VZKGtleV9keW5fZGF0YSk7CgkJfQoJCXJldHVybiBrZXlfZHluX2RhdGE7CgljYXNlIEhLRVlfQ1VSUkVOVF9DT05GSUc6CgkJaWYgKCFrZXlfY3VycmVudF9jb25maWcpIHsKCQkJQUREX1JPT1RfS0VZKGtleV9jdXJyZW50X2NvbmZpZyk7CgkJfQoJCXJldHVybiBrZXlfY3VycmVudF9jb25maWc7CglkZWZhdWx0OgoJCXJldHVybiBnZXRfaGFuZGxlKGhrZXkpOwoJfQoJLypOT1RSRUFDSEVEKi8KfQojdW5kZWYgQUREX1JPT1RfS0VZCi8qIHNvIHdlIGRvbid0IGFjY2lkZW50bHkgYWNjZXNzIHRoZW0gLi4uICovCiNkZWZpbmUga2V5X2N1cnJlbnRfY29uZmlnIE5VTEwgTlVMTAojZGVmaW5lIGtleV9jdXJyZW50X3VzZXIgTlVMTCBOVUxMCiNkZWZpbmUga2V5X3VzZXJzIE5VTEwgTlVMTAojZGVmaW5lIGtleV9sb2NhbF9tYWNoaW5lIE5VTEwgTlVMTAojZGVmaW5lIGtleV9jbGFzc2VzX3Jvb3QgTlVMTCBOVUxMCiNkZWZpbmUga2V5X2R5bl9kYXRhIE5VTEwgTlVMTAojZGVmaW5lIGtleV9wZXJmb3JtYW5jZV9kYXRhIE5VTEwgTlVMTAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBzcGxpdF9rZXlwYXRoIFtJbnRlcm5hbF0KICogc3BsaXRzIHRoZSB1bmljb2RlIHN0cmluZyAnd3AnIGludG8gYW4gYXJyYXkgb2Ygc3RyaW5ncy4KICogdGhlIGFycmF5IGlzIGFsbG9jYXRlZCBieSB0aGlzIGZ1bmN0aW9uLiAKICogRnJlZSB0aGUgYXJyYXkgdXNpbmcgRlJFRV9LRVlfUEFUSAogKgogKiBQQVJBTVMKICogICAgd3AgIFtJXSBTdHJpbmcgdG8gc3BsaXQgdXAKICogICAgd3B2IFtPXSBBcnJheSBvZiBwb2ludGVycyB0byBzdHJpbmdzCiAqICAgIHdwYyBbT10gTnVtYmVyIG9mIGNvbXBvbmVudHMKICovCnN0YXRpYyB2b2lkIHNwbGl0X2tleXBhdGgoIExQQ1dTVFIgd3AsIExQV1NUUiAqKndwdiwgaW50ICp3cGMpCnsKICAgIGludAlpLGosbGVuOwogICAgTFBXU1RSIHdzOwoKICAgIFRSQUNFKHJlZywiKCVzLCVwLCVwKVxuIixkZWJ1Z3N0cl93KHdwKSx3cHYsd3BjKTsKCiAgICB3cwk9IEhFQVBfc3RyZHVwVyggU3lzdGVtSGVhcCwgMCwgd3AgKTsKCiAgICAvKiBXZSBrbm93IHdlIGhhdmUgYXQgbGVhc3Qgb25lIHN1YnN0cmluZyAqLwogICAgKndwYyA9IDE7CgogICAgLyogUmVwbGFjZSBlYWNoIGJhY2tzbGFzaCB3aXRoIE5VTEwsIGFuZCBpbmNyZW1lbnQgdGhlIGNvdW50ICovCiAgICBmb3IgKGk9MDt3c1tpXTtpKyspIHsKICAgICAgICBpZiAod3NbaV09PSdcXCcpIHsKICAgICAgICAgICAgd3NbaV09MDsKICAgICAgICAgICAgKCp3cGMpKys7CiAgICAgICAgfQogICAgfQoKICAgIGxlbiA9IGk7CgogICAgLyogQWxsb2NhdGUgdGhlIHNwYWNlIGZvciB0aGUgYXJyYXkgb2YgcG9pbnRlcnMsIGxlYXZpbmcgcm9vbSBmb3IgdGhlCiAgICAgICBOVUxMIGF0IHRoZSBlbmQgKi8KICAgICp3cHYgPSAoTFBXU1RSKilIZWFwQWxsb2MoIFN5c3RlbUhlYXAsIDAsIHNpemVvZihMUFdTVFIpKigqd3BjKzIpKTsKICAgICgqd3B2KVswXT0gd3M7CgogICAgLyogQXNzaWduIGVhY2ggcG9pbnRlciB0byB0aGUgYXBwcm9wcmlhdGUgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcgKi8KICAgIGogPSAxOwogICAgZm9yIChpPTE7aTxsZW47aSsrKQogICAgICAgIGlmICh3c1tpLTFdPT0wKSB7CiAgICAgICAgICAgICgqd3B2KVtqKytdPXdzK2k7CiAgICAgICAgICAgIC8qIFRSQUNFKHJlZywgIiBTdWJpdGVtICVkID0gJXNcbiIsai0xLGRlYnVnc3RyX3coKCp3cHYpW2otMV0pKTsgKi8KICAgICAgICB9CgogICAgKCp3cHYpW2pdPU5VTEw7Cn0KI2RlZmluZSBGUkVFX0tFWV9QQVRIIEhlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHNbMF0pO0hlYXBGcmVlKFN5c3RlbUhlYXAsMCx3cHMpOwoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSRUdJU1RSWV9Jbml0IFtJbnRlcm5hbF0KICogUmVnaXN0cnkgaW5pdGlhbGlzYXRpb24sIGFsbG9jYXRlcyBzb21lIGRlZmF1bHQga2V5cy4gCiAqLwpzdGF0aWMgdm9pZCBSRUdJU1RSWV9Jbml0KCkgewoJSEtFWQloa2V5OwoJY2hhcglidWZbMjAwXTsKCglUUkFDRShyZWcsIih2b2lkKVxuIik7CgoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9EWU5fREFUQSwiUGVyZlN0YXRzXFxTdGF0RGF0YSIsJmhrZXkpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgogICAgICAgIC8qIFRoaXMgd2FzIGFuIE9wZW4sIGJ1dCBzaW5jZSBpdCBpcyBjYWxsZWQgYmVmb3JlIHRoZSByZWFsIHJlZ2lzdHJpZXMKICAgICAgICAgICBhcmUgbG9hZGVkLCBpdCB3YXMgY2hhbmdlZCB0byBhIENyZWF0ZSAtIE1UQiA5ODA1MDcqLwoJUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJIQVJEV0FSRVxcREVTQ1JJUFRJT05cXFN5c3RlbSIsJmhrZXkpOwoJUmVnU2V0VmFsdWVFeDMyQShoa2V5LCJJZGVudGlmaWVyIiwwLFJFR19TWiwiU3lzdGVtVHlwZSBXSU5FIixzdHJsZW4oIlN5c3RlbVR5cGUgV0lORSIpKTsKCVJlZ0Nsb3NlS2V5KGhrZXkpOwoKCS8qIFxcU09GVFdBUkVcXE1pY3Jvc29mdFxcV2luZG93IE5UXFxDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50VmVyc2lvbgoJICoJCQkJCQlDdXJyZW50QnVpbGROdW1iZXIKCSAqCQkJCQkJQ3VycmVudFR5cGUKCSAqCQkJCQlzdHJpbmcJUmVnaXN0ZXJlZE93bmVyCgkgKgkJCQkJc3RyaW5nCVJlZ2lzdGVyZWRPcmdhbml6YXRpb24KCSAqCgkgKi8KCS8qIFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXFNlcnZpY2VzXFxTTk1QXFxQYXJhbWV0ZXJzXFxSRkMxMTU2QWdlbnQKCSAqIAkJCQkJc3RyaW5nCVN5c0NvbnRhY3QKCSAqIAkJCQkJc3RyaW5nCVN5c0xvY2F0aW9uCgkgKiAJCQkJCQlTeXNTZXJ2aWNlcwoJICovCQkJCQkJCglpZiAoLTEhPWdldGhvc3RuYW1lKGJ1ZiwyMDApKSB7CgkJUmVnQ3JlYXRlS2V5MTYoSEtFWV9MT0NBTF9NQUNISU5FLCJTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxDb250cm9sXFxDb21wdXRlck5hbWVcXENvbXB1dGVyTmFtZSIsJmhrZXkpOwoJCVJlZ1NldFZhbHVlRXgxNihoa2V5LCJDb21wdXRlck5hbWUiLDAsUkVHX1NaLGJ1ZixzdHJsZW4oYnVmKSsxKTsKCQlSZWdDbG9zZUtleShoa2V5KTsKCX0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKiogU0FWRSBSZWdpc3RyeSBGdW5jdGlvbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBSRUdJU1RSWV9TQVZFX1ZFUlNJT04JMHgwMDAwMDAwMQoKLyogUmVnaXN0cnkgc2F2ZWZvcm1hdDoKICogSWYgeW91IGNoYW5nZSBpdCwgaW5jcmVhc2UgYWJvdmUgbnVtYmVyIGJ5IDEsIHdoaWNoIHdpbGwgZmx1c2gKICogb2xkIHJlZ2lzdHJ5IGRhdGFiYXNlIGZpbGVzLgogKiAKICogR2xvYmFsOgogKiAJIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZCIKICogCXN1YmtleXMuLi4uCiAqIFN1YmtleXM6CiAqIAlrZXluYW1lCiAqCQl2YWx1ZW5hbWU9bGFzdG1vZGlmaWVkLHR5cGUsZGF0YQogKgkJLi4uCiAqCQlzdWJrZXlzCiAqCS4uLgogKiBrZXluYW1lLHZhbHVlbmFtZSxzdHJpbmdkYXRhOgogKgl0aGUgdXN1YWwgYXNjaWkgY2hhcmFjdGVycyBmcm9tIDB4MDAtMHhmZiAod2VsbCwgbm90IDB4MDApCiAqCWFuZCBcdVhYWFggYXMgVU5JQ09ERSB2YWx1ZSBYWFhYIHdpdGggWFhYWD4weGZmCiAqCSggIj1cXFx0IiBlc2NhcGVkIGluIFx1WFhYWCBmb3JtLikKICogdHlwZSxsYXN0bW9kaWZpZWQ6IAogKglpbnQKICogCiAqIEZJWE1FOiBkb2Vzbid0IHNhdmUgJ2NsYXNzJyAod2hhdCBkb2VzIGl0IG1lYW4gYW55d2F5PyksIG5vciBmbGFncy4KICoKICogW0hLRVlfQ1VSUkVOVF9VU0VSXFxTb2Z0d2FyZVxcVGhlIFdJTkUgdGVhbVxcV0lORVxcUmVnaXN0cnldCiAqIFNhdmVPbmx5VXBkYXRlZEtleXM9eWVzCiAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZV9jaGVja190YWludGVkIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3NhdmVfY2hlY2tfdGFpbnRlZCggTFBLRVlTVFJVQ1QgbHBrZXkgKQp7CglpbnQJCXRhaW50ZWQ7CgoJaWYgKCFscGtleSkKCQlyZXR1cm4gMDsKCWlmIChscGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1RBSU5URUQpCgkJdGFpbnRlZCA9IDE7CgllbHNlCgkJdGFpbnRlZCA9IDA7Cgl3aGlsZSAobHBrZXkpIHsKCQlpZiAoX3NhdmVfY2hlY2tfdGFpbnRlZChscGtleS0+bmV4dHN1YikpIHsKCQkJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCQkJdGFpbnRlZCA9IDE7CgkJfQoJCWxwa2V5CT0gbHBrZXktPm5leHQ7Cgl9CglyZXR1cm4gdGFpbnRlZDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZV9VU1RSSU5HIFtJbnRlcm5hbF0KICovCnN0YXRpYyB2b2lkIF9zYXZlX1VTVFJJTkcoIEZJTEUgKkYsIExQV1NUUiB3c3RyLCBpbnQgZXNjYXBlZXEgKQp7CglMUFdTVFIJczsKCWludAlkb2VzY2FwZTsKCglpZiAod3N0cj09TlVMTCkKCQlyZXR1cm47CglzPXdzdHI7Cgl3aGlsZSAoKnMpIHsKCQlkb2VzY2FwZT0wOwoJCWlmICgqcz4weGZmKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKCpzPT0nXG4nKQoJCQlkb2VzY2FwZSA9IDE7CgkJaWYgKGVzY2FwZWVxICYmICpzPT0nPScpCgkJCWRvZXNjYXBlID0gMTsKCQlpZiAoKnM9PSdcXCcpCiAgICAgICAgICAgICAgICAgICAgICAgIGZwdXRjKCpzLEYpOyAvKiBpZiBcXCB0aGVuIHB1dCBpdCB0d2ljZS4gKi8KCQlpZiAoZG9lc2NhcGUpCgkJCWZwcmludGYoRiwiXFx1JTA0eCIsKigodW5zaWduZWQgc2hvcnQqKXMpKTsKCQllbHNlCgkJCWZwdXRjKCpzLEYpOwoJCXMrKzsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfc2F2ZXN1YmtleSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgaW50IF9zYXZlc3Via2V5KCBGSUxFICpGLCBMUEtFWVNUUlVDVCBscGtleSwgaW50IGxldmVsLCBpbnQgYWxsICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5OwoJaW50CQlpLHRhYnMsajsKCglscHhrZXkJPSBscGtleTsKCXdoaWxlIChscHhrZXkpIHsKCQlpZiAoCSEobHB4a2V5LT5mbGFncyAmIFJFR19PUFRJT05fVk9MQVRJTEUpICYmCgkJCShhbGwgfHwgKGxweGtleS0+ZmxhZ3MgJiBSRUdfT1BUSU9OX1RBSU5URUQpKQoJCSkgewoJCQlmb3IgKHRhYnM9bGV2ZWw7dGFicy0tOykKCQkJCWZwdXRjKCdcdCcsRik7CgkJCV9zYXZlX1VTVFJJTkcoRixscHhrZXktPmtleW5hbWUsMSk7CgkJCWZwdXRzKCJcbiIsRik7CgkJCWZvciAoaT0wO2k8bHB4a2V5LT5ucm9mdmFsdWVzO2krKykgewoJCQkJTFBLRVlWQUxVRQl2YWw9bHB4a2V5LT52YWx1ZXMraTsKCgkJCQlmb3IgKHRhYnM9bGV2ZWwrMTt0YWJzLS07KQoJCQkJCWZwdXRjKCdcdCcsRik7CgkJCQlfc2F2ZV9VU1RSSU5HKEYsdmFsLT5uYW1lLDApOwoJCQkJZnB1dGMoJz0nLEYpOwoJCQkJZnByaW50ZihGLCIlbGQsJWxkLCIsdmFsLT50eXBlLHZhbC0+bGFzdG1vZGlmaWVkKTsKCQkJCWlmICgoMTw8dmFsLT50eXBlKSAmIFVOSUNPTlZNQVNLKQoJCQkJCV9zYXZlX1VTVFJJTkcoRiwoTFBXU1RSKXZhbC0+ZGF0YSwwKTsKCQkJCWVsc2UKCQkJCQlmb3IgKGo9MDtqPHZhbC0+bGVuO2orKykKCQkJCQkJZnByaW50ZihGLCIlMDJ4IiwqKCh1bnNpZ25lZCBjaGFyKil2YWwtPmRhdGEraikpOwoJCQkJZnB1dHMoIlxuIixGKTsKCQkJfQoJCQkvKiBkZXNjZW5kIHJlY3Vyc2l2ZWx5ICovCgkJCWlmICghX3NhdmVzdWJrZXkoRixscHhrZXktPm5leHRzdWIsbGV2ZWwrMSxhbGwpKQoJCQkJcmV0dXJuIDA7CgkJfQoJCWxweGtleT1scHhrZXktPm5leHQ7Cgl9CglyZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX3NhdmVzdWJyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIGludCBfc2F2ZXN1YnJlZyggRklMRSAqRiwgTFBLRVlTVFJVQ1QgbHBrZXksIGludCBhbGwgKQp7CglmcHJpbnRmKEYsIldJTkUgUkVHSVNUUlkgVmVyc2lvbiAlZFxuIixSRUdJU1RSWV9TQVZFX1ZFUlNJT04pOwoJX3NhdmVfY2hlY2tfdGFpbnRlZChscGtleS0+bmV4dHN1Yik7CglyZXR1cm4gX3NhdmVzdWJrZXkoRixscGtleS0+bmV4dHN1YiwwLGFsbCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9zYXZlcmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBCT09MMzIgX3NhdmVyZWcoIExQS0VZU1RSVUNUIGxwa2V5LCBjaGFyICpmbiwgaW50IGFsbCApCnsKCUZJTEUJKkY7CgoJRj1mb3BlbihmbiwidyIpOwoJaWYgKEY9PU5VTEwpIHsKCQlXQVJOKHJlZywiQ291bGRuJ3Qgb3BlbiAlcyBmb3Igd3JpdGluZzogJXNcbiIsCgkJCWZuLHN0cmVycm9yKGVycm5vKQoJCSk7CgkJcmV0dXJuIEZBTFNFOwoJfQoJaWYgKCFfc2F2ZXN1YnJlZyhGLGxwa2V5LGFsbCkpIHsKCQlmY2xvc2UoRik7CgkJdW5saW5rKGZuKTsKCQlXQVJOKHJlZywiRmFpbGVkIHRvIHNhdmUga2V5cywgcGVyaGFwcyBubyBtb3JlIGRpc2tzcGFjZSBmb3IgJXM/XG4iLGZuKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglmY2xvc2UoRik7CiAgICAgICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX1NhdmVSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwp2b2lkIFNIRUxMX1NhdmVSZWdpc3RyeSggdm9pZCApCnsKCWNoYXIJKmZuOwoJc3RydWN0CXBhc3N3ZAkqcHdkOwoJY2hhcglidWZbNF07CglIS0VZCWhrZXk7CglpbnQJYWxsOwoKICAgIFRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCglhbGw9MDsKCWlmIChSZWdPcGVuS2V5MTYoSEtFWV9DVVJSRU5UX1VTRVIsS0VZX1JFR0lTVFJZLCZoa2V5KSE9RVJST1JfU1VDQ0VTUykgewoJCXN0cmNweShidWYsInllcyIpOwoJfSBlbHNlIHsKCQlEV09SRCBsZW4sanVuayx0eXBlOwoKCQlsZW49NDsKCQlpZiAoCShFUlJPUl9TVUNDRVNTIT1SZWdRdWVyeVZhbHVlRXgzMkEoCgkJCQloa2V5LAoJCQkJVkFMX1NBVkVVUERBVEVELAoJCQkJJmp1bmssCgkJCQkmdHlwZSwKCQkJCWJ1ZiwKCQkJCSZsZW4KCQkJKSl8fCAodHlwZSE9UkVHX1NaKQoJCSkKCQkJc3RyY3B5KGJ1ZiwieWVzIik7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9CglpZiAobHN0cmNtcGkzMkEoYnVmLCJ5ZXMiKSkKCQlhbGw9MTsKCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CglpZiAocHdkIT1OVUxMICYmIHB3ZC0+cHdfZGlyIT1OVUxMKQogICAgICAgIHsKICAgICAgICAgICAgICAgIGNoYXIgKnRtcDsKCgkJZm49KGNoYXIqKXhtYWxsb2MoIHN0cmxlbihwd2QtPnB3X2RpcikgKyBzdHJsZW4oV0lORV9QUkVGSVgpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJsZW4oU0FWRV9DVVJSRU5UX1VTRVIpICsgMiApOwoJCXN0cmNweShmbixwd2QtPnB3X2Rpcik7CgkJc3RyY2F0KGZuLFdJTkVfUFJFRklYKTsKCQkvKiBjcmVhdGUgdGhlIGRpcmVjdG9yeS4gZG9uJ3QgY2FyZSBhYm91dCBlcnJvcmNvZGVzLiAqLwoJCW1rZGlyKGZuLDA3NTUpOyAvKiBkcnd4ci14ci14ICovCgkJc3RyY2F0KGZuLCIvIlNBVkVfQ1VSUkVOVF9VU0VSKTsKCQl0bXAgPSAoY2hhciopeG1hbGxvYyhzdHJsZW4oZm4pK3N0cmxlbigiLnRtcCIpKzEpOwoJCXN0cmNweSh0bXAsZm4pO3N0cmNhdCh0bXAsIi50bXAiKTsKCQlpZiAoX3NhdmVyZWcobG9va3VwX2hrZXkoSEtFWV9DVVJSRU5UX1VTRVIpLHRtcCxhbGwpKSB7CgkJCWlmICgtMT09cmVuYW1lKHRtcCxmbikpIHsKCQkJCXBlcnJvcigicmVuYW1lIHRtcCByZWdpc3RyeSIpOwoJCQkJdW5saW5rKHRtcCk7CgkJCX0KCQl9CgkJZnJlZSh0bXApOwoJCWZyZWUoZm4pOwoJCWZuPShjaGFyKil4bWFsbG9jKHN0cmxlbihwd2QtPnB3X2Rpcikrc3RybGVuKFdJTkVfUFJFRklYKStzdHJsZW4oU0FWRV9MT0NBTF9NQUNISU5FKSsyKTsKCQlzdHJjcHkoZm4scHdkLT5wd19kaXIpOwoJCXN0cmNhdChmbixXSU5FX1BSRUZJWCIvIlNBVkVfTE9DQUxfTUFDSElORSk7CgkJdG1wID0gKGNoYXIqKXhtYWxsb2Moc3RybGVuKGZuKStzdHJsZW4oIi50bXAiKSsxKTsKCQlzdHJjcHkodG1wLGZuKTtzdHJjYXQodG1wLCIudG1wIik7CgkJaWYgKF9zYXZlcmVnKGxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSksdG1wLGFsbCkpIHsKCQkJaWYgKC0xPT1yZW5hbWUodG1wLGZuKSkgewoJCQkJcGVycm9yKCJyZW5hbWUgdG1wIHJlZ2lzdHJ5Iik7CgkJCQl1bmxpbmsodG1wKTsKCQkJfQoJCX0KCQlmcmVlKHRtcCk7CgkJZnJlZShmbik7Cgl9IGVsc2UKCQlXQVJOKHJlZywiRmFpbGVkIHRvIGdldCBob21lZGlyZWN0b3J5IG9mIFVJRCAlZC5cbiIsZ2V0dWlkKCkpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKiBMT0FEIFJlZ2lzdHJ5IEZ1bmN0aW9uICoqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX2ZpbmRfb3JfYWRkX2tleSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgTFBLRVlTVFJVQ1QgX2ZpbmRfb3JfYWRkX2tleSggTFBLRVlTVFJVQ1QgbHBrZXksIExQV1NUUiBrZXluYW1lICkKewoJTFBLRVlTVFJVQ1QJbHB4a2V5LCpscGxwa2V5OwoKCWlmICgoIWtleW5hbWUpIHx8IChrZXluYW1lWzBdPT0wKSkgewoJCWZyZWUoa2V5bmFtZSk7CgkJcmV0dXJuIGxwa2V5OwoJfQoJbHBscGtleT0gJihscGtleS0+bmV4dHN1Yik7CglscHhrZXkJPSAqbHBscGtleTsKCXdoaWxlIChscHhrZXkpIHsKCQlpZiAoCShscHhrZXktPmtleW5hbWVbMF09PWtleW5hbWVbMF0pICYmIAoJCQkhbHN0cmNtcGkzMlcobHB4a2V5LT5rZXluYW1lLGtleW5hbWUpCgkJKQoJCQlicmVhazsKCQlscGxwa2V5CT0gJihscHhrZXktPm5leHQpOwoJCWxweGtleQk9ICpscGxwa2V5OwoJfQoJaWYgKGxweGtleT09TlVMTCkgewoJCSpscGxwa2V5ID0gKExQS0VZU1RSVUNUKXhtYWxsb2Moc2l6ZW9mKEtFWVNUUlVDVCkpOwoJCWxweGtleQk9ICpscGxwa2V5OwoJCW1lbXNldChscHhrZXksJ1wwJyxzaXplb2YoS0VZU1RSVUNUKSk7CgkJbHB4a2V5LT5rZXluYW1lCT0ga2V5bmFtZTsKCX0gZWxzZQoJCWZyZWUoa2V5bmFtZSk7CglyZXR1cm4gbHB4a2V5Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9maW5kX29yX2FkZF92YWx1ZSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfZmluZF9vcl9hZGRfdmFsdWUoIExQS0VZU1RSVUNUIGxwa2V5LCBMUFdTVFIgbmFtZSwgRFdPUkQgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgZGF0YSwgRFdPUkQgbGVuLCBEV09SRCBsYXN0bW9kaWZpZWQgKQp7CglMUEtFWVZBTFVFCXZhbD1OVUxMOwoJaW50CQlpOwoKCWlmIChuYW1lICYmICEqbmFtZSkgey8qIGVtcHR5IHN0cmluZyBlcXVhbHMgZGVmYXVsdCAoTlVMTCkgdmFsdWUgKi8KCQlmcmVlKG5hbWUpOwoJCW5hbWUgPSBOVUxMOwoJfQoKCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKSB7CgkJdmFsPWxwa2V5LT52YWx1ZXMraTsKCQlpZiAobmFtZT09TlVMTCkgewoJCQlpZiAodmFsLT5uYW1lPT1OVUxMKQoJCQkJYnJlYWs7CgkJfSBlbHNlIHsKCQkJaWYgKAl2YWwtPm5hbWUhPU5VTEwgJiYgCgkJCQl2YWwtPm5hbWVbMF09PW5hbWVbMF0gJiYKCQkJCSFsc3RyY21waTMyVyh2YWwtPm5hbWUsbmFtZSkKCQkJKQoJCQkJYnJlYWs7CgkJfQoJfQoJaWYgKGk9PWxwa2V5LT5ucm9mdmFsdWVzKSB7CgkJbHBrZXktPnZhbHVlcyA9IHhyZWFsbG9jKAoJCQlscGtleS0+dmFsdWVzLAoJCQkoKytscGtleS0+bnJvZnZhbHVlcykqc2l6ZW9mKEtFWVZBTFVFKQoJCSk7CgkJdmFsPWxwa2V5LT52YWx1ZXMraTsKCQltZW1zZXQodmFsLCdcMCcsc2l6ZW9mKEtFWVZBTFVFKSk7CgkJdmFsLT5uYW1lID0gbmFtZTsKCX0gZWxzZSB7CgkJaWYgKG5hbWUpCgkJCWZyZWUobmFtZSk7Cgl9CglpZiAodmFsLT5sYXN0bW9kaWZpZWQ8bGFzdG1vZGlmaWVkKSB7CgkJdmFsLT5sYXN0bW9kaWZpZWQ9bGFzdG1vZGlmaWVkOwoJCXZhbC0+dHlwZSA9IHR5cGU7CgkJdmFsLT5sZW4gID0gbGVuOwoJCWlmICh2YWwtPmRhdGEpIAoJCQlmcmVlKHZhbC0+ZGF0YSk7CgkJdmFsLT5kYXRhID0gZGF0YTsKCX0gZWxzZQoJCWZyZWUoZGF0YSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX3JlYWRfbGluZSBbSW50ZXJuYWxdCiAqCiAqIHJlYWRzIGEgbGluZSBpbmNsdWRpbmcgZHluYW1pY2FsbHkgZW5sYXJnaW5nIHRoZSByZWFkYnVmZmVyIGFuZCB0aHJvd2luZwogKiBhd2F5IGNvbW1lbnRzCiAqLwpzdGF0aWMgaW50IF93aW5lX3JlYWRfbGluZSggRklMRSAqRiwgY2hhciAqKmJ1ZiwgaW50ICpsZW4gKQp7CgljaGFyCSpzLCpjdXJyZWFkOwoJaW50CW15bGVuLGN1cm9mZjsKCgljdXJyZWFkCT0gKmJ1ZjsKCW15bGVuCT0gKmxlbjsKCSoqYnVmCT0gJ1wwJzsKCXdoaWxlICgxKSB7CgkJd2hpbGUgKDEpIHsKCQkJcz1mZ2V0cyhjdXJyZWFkLG15bGVuLEYpOwoJCQlpZiAocz09TlVMTCkKCQkJCXJldHVybiAwOyAvKiBFT0YgKi8KCQkJaWYgKE5VTEw9PShzPXN0cmNocihjdXJyZWFkLCdcbicpKSkgewoJCQkJLyogYnVmZmVyIHdhc24ndCBsYXJnZSBlbm91Z2ggKi8KCQkJCWN1cm9mZgk9IHN0cmxlbigqYnVmKTsKCQkJCSpidWYJPSB4cmVhbGxvYygqYnVmLCpsZW4qMik7CgkJCQljdXJyZWFkCT0gKmJ1ZiArIGN1cm9mZjsKCQkJCW15bGVuCT0gKmxlbjsJLyogd2UgZmlsbGVkIHVwIHRoZSBidWZmZXIgYW5kIAoJCQkJCQkgKiBnb3QgbmV3ICcqbGVuJyBieXRlcyB0byBmaWxsCgkJCQkJCSAqLwoJCQkJKmxlbgk9ICpsZW4gKiAyOwoJCQl9IGVsc2UgewoJCQkJKnM9J1wwJzsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCS8qIHRocm93IGF3YXkgY29tbWVudHMgKi8KCQlpZiAoKipidWY9PScjJyB8fCAqKmJ1Zj09JzsnKSB7CgkJCWN1cnJlYWQJPSAqYnVmOwoJCQlteWxlbgk9ICpsZW47CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAocykgCS8qIGdvdCBlbmQgb2YgbGluZSAqLwoJCQlicmVhazsKCX0KCXJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9yZWFkX1VTVFJJTkcgW0ludGVybmFsXQogKgogKiBjb252ZXJ0cyBhIGNoYXIqIGludG8gYSBVTklDT0RFIHN0cmluZyAodXAgdG8gYSBzcGVjaWFsIGNoYXIpCiAqIGFuZCByZXR1cm5zIHRoZSBwb3NpdGlvbiBleGFjdGx5IGFmdGVyIHRoYXQgc3RyaW5nCiAqLwpzdGF0aWMgY2hhciogX3dpbmVfcmVhZF9VU1RSSU5HKCBjaGFyICpidWYsIExQV1NUUiAqc3RyICkKewoJY2hhcgkqczsKCUxQV1NUUgl3czsKCgkvKiByZWFkIHVwIHRvICI9IiBvciAiXDAiIG9yICJcbiIgKi8KCXMJPSBidWY7CglpZiAoKnMgPT0gJz0nKSB7CgkJLyogZW1wdHkgc3RyaW5nIGlzIHRoZSB3aW4zLjEgZGVmYXVsdCB2YWx1ZShOVUxMKSovCgkJKnN0cgk9IE5VTEw7CgkJcmV0dXJuIHM7Cgl9Cgkqc3RyCT0gKExQV1NUUil4bWFsbG9jKDIqc3RybGVuKGJ1ZikrMik7Cgl3cwk9ICpzdHI7Cgl3aGlsZSAoKnMgJiYgKCpzIT0nXG4nKSAmJiAoKnMhPSc9JykpIHsKCQlpZiAoKnMhPSdcXCcpCgkJCSp3cysrPSooKHVuc2lnbmVkIGNoYXIqKXMrKyk7CgkJZWxzZSB7CgkJCXMrKzsKCQkJaWYgKCpzPT0nXFwnKSB7CgkJCQkqd3MrKz0nXFwnOwoJCQkJcysrOwoJCQkJY29udGludWU7CgkJCX0KCQkJaWYgKCpzIT0ndScpIHsKCQkJCVdBUk4ocmVnLCJOb24gdW5pY29kZSBlc2NhcGUgc2VxdWVuY2UgXFwlYyBmb3VuZCBpbiB8JXN8XG4iLCpzLGJ1Zik7CgkJCQkqd3MrKz0nXFwnOwoJCQkJKndzKys9KnMrKzsKCQkJfSBlbHNlIHsKCQkJCWNoYXIJeGJ1Zls1XTsKCQkJCWludAl3YzsKCgkJCQlzKys7CgkJCQltZW1jcHkoeGJ1ZixzLDQpO3hidWZbNF09J1wwJzsKCQkJCWlmICghc3NjYW5mKHhidWYsIiV4Iiwmd2MpKQoJCQkJCVdBUk4ocmVnLCJTdHJhbmdlIGVzY2FwZSBzZXF1ZW5jZSAlcyBmb3VuZCBpbiB8JXN8XG4iLHhidWYsYnVmKTsKCQkJCXMrPTQ7CgkJCQkqd3MrKwk9KHVuc2lnbmVkIHNob3J0KXdjOwoJCQl9CgkJfQoJfQoJKndzCT0gMDsKCXdzCT0gKnN0cjsKCWlmICgqd3MpCgkJKnN0cgk9IHN0cmR1cFcoKnN0cik7CgllbHNlCgkJKnN0cgk9IE5VTEw7CglmcmVlKHdzKTsKCXJldHVybiBzOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2Fkc3Via2V5IFtJbnRlcm5hbF0KICoKICogTk9URVMKICogICAgSXQgc2VlbXMgbGlrZSB0aGlzIGlzIHJldHVybmluZyBhIGJvb2xlYW4uICBTaG91bGQgaXQ/CiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogMQogKiAgICBGYWlsdXJlOiAwCiAqLwpzdGF0aWMgaW50IF93aW5lX2xvYWRzdWJrZXkoIEZJTEUgKkYsIExQS0VZU1RSVUNUIGxwa2V5LCBpbnQgbGV2ZWwsIGNoYXIgKipidWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICpidWZsZW4sIERXT1JEIG9wdGZsYWcgKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWk7CgljaGFyCQkqczsKCUxQV1NUUgkJbmFtZTsKCiAgICBUUkFDRShyZWcsIiglcCwlcCwlZCwlcywlZCwlbHgpXG4iLCBGLCBscGtleSwgbGV2ZWwsIGRlYnVnc3RyX2EoKmJ1ZiksCiAgICAgICAgICAqYnVmbGVuLCBvcHRmbGFnKTsKCiAgICBscGtleS0+ZmxhZ3MgfD0gb3B0ZmxhZzsKCiAgICAvKiBHb29kLiAgV2UgYWxyZWFkeSBnb3QgYSBsaW5lIGhlcmUgLi4uIHNvIHBhcnNlIGl0ICovCiAgICBscHhrZXkgPSBOVUxMOwogICAgd2hpbGUgKDEpIHsKICAgICAgICBpPTA7cz0qYnVmOwogICAgICAgIHdoaWxlICgqcz09J1x0JykgewogICAgICAgICAgICBzKys7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9CiAgICAgICAgaWYgKGk+bGV2ZWwpIHsKICAgICAgICAgICAgaWYgKGxweGtleT09TlVMTCkgewogICAgICAgICAgICAgICAgV0FSTihyZWcsIkdvdCBhIHN1YmhpZXJhcmNoeSB3aXRob3V0IHJlc3AuIGtleT9cbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3dpbmVfbG9hZHN1YmtleShGLGxweGtleSxsZXZlbCsxLGJ1ZixidWZsZW4sb3B0ZmxhZyk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCgkJLyogbGV0IHRoZSBjYWxsZXIgaGFuZGxlIHRoaXMgbGluZSAqLwoJCWlmIChpPGxldmVsIHx8ICoqYnVmPT0nXDAnKQoJCQlyZXR1cm4gMTsKCgkJLyogaXQgY2FuIGJlOiBhIHZhbHVlIG9yIGEga2V5bmFtZS4gUGFyc2UgdGhlIG5hbWUgZmlyc3QgKi8KCQlzPV93aW5lX3JlYWRfVVNUUklORyhzLCZuYW1lKTsKCgkJLyogc3dpdGNoKCkgZGVmYXVsdDogaGFjayB0byBhdm9pZCBnb3RvcyAqLwoJCXN3aXRjaCAoMCkgewoJCWRlZmF1bHQ6CgkJCWlmICgqcz09J1wwJykgewoJCQkJbHB4a2V5PV9maW5kX29yX2FkZF9rZXkobHBrZXksbmFtZSk7CgkJCX0gZWxzZSB7CgkJCQlMUEJZVEUJCWRhdGE7CgkJCQlpbnQJCWxlbixsYXN0bW9kaWZpZWQsdHlwZTsKCgkJCQlpZiAoKnMhPSc9JykgewoJCQkJCVdBUk4ocmVnLCJVbmV4cGVjdGVkIGNoYXJhY3RlcjogJWNcbiIsKnMpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJcysrOwoJCQkJaWYgKDIhPXNzY2FuZihzLCIlZCwlZCwiLCZ0eXBlLCZsYXN0bW9kaWZpZWQpKSB7CgkJCQkJV0FSTihyZWcsIkhhdmVuJ3QgdW5kZXJzdG9vZCBwb3NzaWJsZSB2YWx1ZSBpbiB8JXN8LCBza2lwcGluZy5cbiIsKmJ1Zik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQkvKiBza2lwIHRoZSAyICwgKi8KCQkJCXM9c3RyY2hyKHMsJywnKTtzKys7CgkJCQlzPXN0cmNocihzLCcsJyk7cysrOwoJCQkJaWYgKCgxPDx0eXBlKSAmIFVOSUNPTlZNQVNLKSB7CgkJCQkJcz1fd2luZV9yZWFkX1VTVFJJTkcocywoTFBXU1RSKikmZGF0YSk7CgkJCQkJaWYgKGRhdGEpCgkJCQkJCWxlbiA9IGxzdHJsZW4zMlcoKExQV1NUUilkYXRhKSoyKzI7CgkJCQkJZWxzZQkKCQkJCQkJbGVuID0gMDsKCQkJCX0gZWxzZSB7CgkJCQkJbGVuPXN0cmxlbihzKS8yOwoJCQkJCWRhdGEgPSAoTFBCWVRFKXhtYWxsb2MobGVuKzEpOwoJCQkJCWZvciAoaT0wO2k8bGVuO2krKykgewoJCQkJCQlkYXRhW2ldPTA7CgkJCQkJCWlmICgqcz49JzAnICYmICpzPD0nOScpCgkJCQkJCQlkYXRhW2ldPSgqcy0nMCcpPDw0OwoJCQkJCQlpZiAoKnM+PSdhJyAmJiAqczw9J2YnKQoJCQkJCQkJZGF0YVtpXT0oKnMtJ2EnKydceGEnKTw8NDsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV09KCpzLSdBJysnXHhhJyk8PDQ7CgkJCQkJCXMrKzsKCQkJCQkJaWYgKCpzPj0nMCcgJiYgKnM8PSc5JykKCQkJCQkJCWRhdGFbaV18PSpzLScwJzsKCQkJCQkJaWYgKCpzPj0nYScgJiYgKnM8PSdmJykKCQkJCQkJCWRhdGFbaV18PSpzLSdhJysnXHhhJzsKCQkJCQkJaWYgKCpzPj0nQScgJiYgKnM8PSdGJykKCQkJCQkJCWRhdGFbaV18PSpzLSdBJysnXHhhJzsKCQkJCQkJcysrOwoJCQkJCX0KCQkJCX0KCQkJCV9maW5kX29yX2FkZF92YWx1ZShscGtleSxuYW1lLHR5cGUsZGF0YSxsZW4sbGFzdG1vZGlmaWVkKTsKCQkJfQoJCX0KCQkvKiByZWFkIHRoZSBuZXh0IGxpbmUgKi8KCQlpZiAoIV93aW5lX3JlYWRfbGluZShGLGJ1ZixidWZsZW4pKQoJCQlyZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfd2luZV9sb2Fkc3VicmVnIFtJbnRlcm5hbF0KICovCnN0YXRpYyBpbnQgX3dpbmVfbG9hZHN1YnJlZyggRklMRSAqRiwgTFBLRVlTVFJVQ1QgbHBrZXksIERXT1JEIG9wdGZsYWcgKQp7CglpbnQJdmVyOwoJY2hhcgkqYnVmOwoJaW50CWJ1ZmxlbjsKCglidWY9eG1hbGxvYygxMCk7YnVmbGVuPTEwOwoJaWYgKCFfd2luZV9yZWFkX2xpbmUoRiwmYnVmLCZidWZsZW4pKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFzc2NhbmYoYnVmLCJXSU5FIFJFR0lTVFJZIFZlcnNpb24gJWQiLCZ2ZXIpKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJaWYgKHZlciE9UkVHSVNUUllfU0FWRV9WRVJTSU9OKSB7CgkJVFJBQ0UocmVnLCJPbGQgZm9ybWF0ICglZCkgcmVnaXN0cnkgZm91bmQsIGlnbm9yaW5nIGl0LiAoYnVmIHdhcyAlcykuXG4iLHZlcixidWYpOwoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfcmVhZF9saW5lKEYsJmJ1ZiwmYnVmbGVuKSkgewoJCWZyZWUoYnVmKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghX3dpbmVfbG9hZHN1YmtleShGLGxwa2V5LDAsJmJ1ZiwmYnVmbGVuLG9wdGZsYWcpKSB7CgkJZnJlZShidWYpOwoJCXJldHVybiAwOwoJfQoJZnJlZShidWYpOwoJcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93aW5lX2xvYWRyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3dpbmVfbG9hZHJlZyggTFBLRVlTVFJVQ1QgbHBrZXksIGNoYXIgKmZuLCBEV09SRCBvcHRmbGFnICkKewogICAgRklMRSAqRjsKCiAgICBUUkFDRShyZWcsIiglcCwlcywlbHgpXG4iLGxwa2V5LGRlYnVnc3RyX2EoZm4pLG9wdGZsYWcpOwoKICAgIEYgPSBmb3BlbihmbiwicmIiKTsKICAgIGlmIChGPT1OVUxMKSB7CiAgICAgICAgV0FSTihyZWcsIkNvdWxkbid0IG9wZW4gJXMgZm9yIHJlYWRpbmc6ICVzXG4iLGZuLHN0cmVycm9yKGVycm5vKSApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmICghX3dpbmVfbG9hZHN1YnJlZyhGLGxwa2V5LG9wdGZsYWcpKSB7CiAgICAgICAgZmNsb3NlKEYpOwogICAgICAgIHVubGluayhmbik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgZmNsb3NlKEYpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfY29weV9yZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwpzdGF0aWMgdm9pZCBfY29weV9yZWdpc3RyeSggTFBLRVlTVFJVQ1QgZnJvbSwgTFBLRVlTVFJVQ1QgdG8gKQp7CglMUEtFWVNUUlVDVAlscHhrZXk7CglpbnQJCWo7CglMUEtFWVZBTFVFCXZhbGZyb207CgoJZnJvbT1mcm9tLT5uZXh0c3ViOwoJd2hpbGUgKGZyb20pIHsKCQlscHhrZXkgPSBfZmluZF9vcl9hZGRfa2V5KHRvLHN0cmR1cFcoZnJvbS0+a2V5bmFtZSkpOwoKCQlmb3IgKGo9MDtqPGZyb20tPm5yb2Z2YWx1ZXM7aisrKSB7CgkJCUxQV1NUUgluYW1lOwoJCQlMUEJZVEUJZGF0YTsKCgkJCXZhbGZyb20gPSBmcm9tLT52YWx1ZXMrajsKCQkJbmFtZT12YWxmcm9tLT5uYW1lOwoJCQlpZiAobmFtZSkgbmFtZT1zdHJkdXBXKG5hbWUpOwoJCQlkYXRhPShMUEJZVEUpeG1hbGxvYyh2YWxmcm9tLT5sZW4pOwoJCQltZW1jcHkoZGF0YSx2YWxmcm9tLT5kYXRhLHZhbGZyb20tPmxlbik7CgoJCQlfZmluZF9vcl9hZGRfdmFsdWUoCgkJCQlscHhrZXksCgkJCQluYW1lLAoJCQkJdmFsZnJvbS0+dHlwZSwKCQkJCWRhdGEsCgkJCQl2YWxmcm9tLT5sZW4sCgkJCQl2YWxmcm9tLT5sYXN0bW9kaWZpZWQKCQkJKTsKCQl9CgkJX2NvcHlfcmVnaXN0cnkoZnJvbSxscHhrZXkpOwoJCWZyb20gPSBmcm9tLT5uZXh0OwoJfQp9CgoKLyogV0lORE9XUyA5NSBSRUdJU1RSWSBMT0FERVIgKi8KLyogCiAqIFN0cnVjdHVyZSBvZiBhIHdpbjk1IHJlZ2lzdHJ5IGRhdGFiYXNlLgogKiBtYWluIGhlYWRlcjoKICogMCA6CSJDUkVHIgktIG1hZ2ljCiAqIDQgOglEV09SRCB2ZXJzaW9uCiAqIDggOglEV09SRCBvZmZzZXRfb2ZfUkdEQl9wYXJ0CiAqIDBDLi4wRjoJPyAoc29tZW9uZSBmaWxsIGluIHBsZWFzZSkKICogMTA6ICBXT1JECW51bWJlciBvZiBSR0RCIGJsb2NrcwogKiAxMjogIFdPUkQJPwogKiAxNDogIFdPUkQJYWx3YXlzIDAwMDA/CiAqIDE2OiAgV09SRAlhbHdheXMgMDAwMT8KICogMTguLjFGOgk/IChzb21lb25lIGZpbGwgaW4gcGxlYXNlKQogKgogKiAyMDogUkdLTl9zZWN0aW9uOgogKiAgIGhlYWRlcjoKICogCTAgOgkJIlJHS04iCS0gbWFnaWMKICogICAgICA0IDogRFdPUkQJb2Zmc2V0IHRvIGZpcnN0IFJHREIgc2VjdGlvbgogKiAgICAgIDggOiBEV09SRAlvZmZzZXQgdG8gdGhlIHJvb3QgcmVjb3JkCiAqIAlDLi4weDFCOiAJPyAoZmlsbCBpbikKICogICAgICAweDIwIC4uLiBvZmZzZXRfb2ZfUkdEQl9wYXJ0OiBEaXNrIEtleSBFbnRyeSBzdHJ1Y3R1cmVzCiAqCiAqICAgRGlzayBLZXkgRW50cnkgU3RydWN0dXJlOgogKgkwMDogRFdPUkQJLSBGcmVlIGVudHJ5IGluZGljYXRvcig/KQogKgkwNDogRFdPUkQJLSBIYXNoID0gc3VtIG9mIGJ5dGVzIG9mIGtleW5hbWUKICoJMDg6IERXT1JECS0gUm9vdCBrZXkgaW5kaWNhdG9yPyB1bmtub3duLCBidXQgdXN1YWxseSAweEZGRkZGRkZGIG9uIHdpbjk1IHN5c3RlbXMKICoJMEM6IERXT1JECS0gZGlzayBhZGRyZXNzIG9mIFByZXZpb3VzTGV2ZWwgS2V5LgogKgkxMDogRFdPUkQJLSBkaXNrIGFkZHJlc3Mgb2YgTmV4dCBTdWJsZXZlbCBLZXkuCiAqCTE0OiBEV09SRAktIGRpc2sgYWRkcmVzcyBvZiBOZXh0IEtleSAob24gc2FtZSBsZXZlbCkuCiAqIERLRVA+MTg6IFdPUkQJLSBOciwgTG93IFNpZ25pZmljYW50IHBhcnQuCiAqCTFBOiBXT1JECS0gTnIsIEhpZ2ggU2lnbmlmaWNhbnQgcGFydC4KICoKICogVGhlIGRpc2sgYWRkcmVzcyBhbHdheXMgcG9pbnRzIHRvIHRoZSBuciBwYXJ0IG9mIHRoZSBwcmV2aW91cyBrZXkgZW50cnkgCiAqIG9mIHRoZSByZWZlcmVuY2VkIGtleS4gRG9uJ3QgYXNrIG1lIHdoeSwgb3IgZXZlbiBpZiBJIGdvdCB0aGlzIGNvcnJlY3QKICogZnJvbSBzdGFyaW5nIGF0IDFrZyBvZiBoZXhkdW1wcy4gKERLRVApCiAqCiAqIFRoZSBIaWdoIHNpZ25pZmljYW50IHBhcnQgb2YgdGhlIHN0cnVjdHVyZSBzZWVtcyB0byBlcXVhbCB0aGUgbnVtYmVyCiAqIG9mIHRoZSBSR0RCIHNlY3Rpb24uIFRoZSBsb3cgc2lnbmlmaWNhbnQgcGFydCBpcyBhIHVuaXF1ZSBJRCB3aXRoaW4KICogdGhhdCBSR0RCIHNlY3Rpb24KICoKICogVGhlcmUgYXJlIHR3byBtaW5vciBjb3JyZWN0aW9ucyB0byB0aGUgcG9zaXRpb24gb2YgdGhhdCBzdHJ1Y3R1cmUuCiAqIDEuIElmIHRoZSBhZGRyZXNzIGlzIHh4eDAxNCBvciB4eHgwMTggaXQgd2lsbCBiZSBhbGlnbmVkIHRvIHh4eDAxYyBBTkQgCiAqICAgIHRoZSBES0UgcmVyZWFkIGZyb20gdGhlcmUuCiAqIDIuIElmIHRoZSBhZGRyZXNzIGlzIHh4eEZGeCBpdCB3aWxsIGJlIGFsaWduZWQgdG8gKHh4eCsxKTAwMC4KICogQ1BTIC0gSSBoYXZlIG5vdCBleHBlcmllbmNlZCB0aGUgYWJvdmUgcGhlbm9tZW5vbiBpbiBteSByZWdpc3RyeSBmaWxlcwogKgogKiBSR0RCX3NlY3Rpb246CiAqIAkwMDoJCSJSR0RCIgktIG1hZ2ljCiAqCTA0OiBEV09SRAlvZmZzZXQgdG8gbmV4dCBSR0RCIHNlY3Rpb24KICoJMDg6IERXT1JECT8KICoJMEM6IFdPUkQJYWx3YXlzIDAwMGQ/CiAqCTBFOiBXT1JECVJHREIgYmxvY2sgbnVtYmVyCiAqCTEwOglEV09SRAk/IChlcXVhbHMgdmFsdWUgYXQgb2Zmc2V0IDQgLSB2YWx1ZSBhdCBvZmZzZXQgOCkKICoJMTQuLjFGOgkJPwogKgkyMC4uLi4uOglkaXNrIGtleXMKICoKICogZGlzayBrZXk6CiAqIAkwMDogCURXT1JECW5leHRrZXlvZmZzZXQJLSBvZmZzZXQgdG8gdGhlIG5leHQgZGlzayBrZXkgc3RydWN0dXJlCiAqCTA4OiAJV09SRAluckxTCQktIGxvdyBzaWduaWZpY2FudCBwYXJ0IG9mIE5SCiAqCTBBOiAJV09SRAluckhTCQktIGhpZ2ggc2lnbmlmaWNhbnQgcGFydCBvZiBOUgogKgkwQzogCURXT1JECWJ5dGVzdXNlZAktIGJ5dGVzIHVzZWQgaW4gdGhpcyBzdHJ1Y3R1cmUuCiAqCTEwOiAJV09SRAluYW1lX2xlbgktIGxlbmd0aCBvZiBuYW1lIGluIGJ5dGVzLiB3aXRob3V0IFwwCiAqCTEyOiAJV09SRAlucl9vZl92YWx1ZXMJLSBudW1iZXIgb2YgdmFsdWVzLgogKgkxNDogCWNoYXIJbmFtZVtuYW1lX2xlbl0JLSBuYW1lIHN0cmluZy4gTm8gXDAuCiAqCTE0K25hbWVfbGVuOiBkaXNrIHZhbHVlcwogKgluZXh0a2V5b2Zmc2V0OiAuLi4gbmV4dCBkaXNrIGtleQogKgogKiBkaXNrIHZhbHVlOgogKgkwMDoJRFdPUkQJdHlwZQkJLSB2YWx1ZSB0eXBlIChobW0sIGNvdWxkIGJlIFdPUkQgdG9vKQogKgkwNDoJRFdPUkQJCQktIHVua25vd24sIHVzdWFsbHkgMAogKgkwODoJV09SRAluYW1lbGVuCQktIGxlbmd0aCBvZiBOYW1lLiAwIG1lYW5zIG5hbWU9TlVMTAogKgkwQzoJV09SRAlkYXRhbGVuCQktIGxlbmd0aCBvZiBEYXRhLgogKgkxMDoJY2hhcgluYW1lW25hbWVsZW5dCS0gbmFtZSwgbm8gXDAKICoJMTArbmFtZWxlbjogQllURQlkYXRhW2RhdGFsZW5dIC0gZGF0YSwgd2l0aG91dCBcMCBpZiBzdHJpbmcKICoJMTArbmFtZWxlbitkYXRhbGVuOiBuZXh0IHZhbHVlcyBvciBkaXNrIGtleQogKgogKiBEaXNrIGtleXMgYXJlIGxheWVkIG91dCBmbGF0IC4uLiBCdXQsIHNvbWV0aW1lcywgbnJMUyBhbmQgbnJIUyBhcmUgYm90aAogKiAweEZGRkYsIHdoaWNoIG1lYW5zIHNraXBwaW5nIG92ZXIgbmV4dGtleW9mZnNldCBieXRlcyAoaW5jbHVkaW5nIHRoaXMKICogc3RydWN0dXJlKSBhbmQgcmVhZGluZyBhbm90aGVyIFJHREJfc2VjdGlvbi4KICogcmVwZWF0IHVudGlsIGVuZCBvZiBmaWxlLgogKgogKiBBbiBpbnRlcmVzdGluZyByZWxhdGlvbnNoaXAgZXhpc3RzIGluIFJHREJfc2VjdGlvbi4gVGhlIHZhbHVlIGF0IG9mZnNldAogKiAxMCBlcXVhbHMgdGhlIHZhbHVlIGF0IG9mZnNldCA0IG1pbnVzIHRoZSB2YWx1ZSBhdCBvZmZzZXQgOC4gSSBoYXZlIG5vCiAqIGlkZWEgYXQgdGhlIG1vbWVudCB3aGF0IHRoaXMgbWVhbnMuICAoS2V2aW4gQ296ZW5zKQogKgogKiBGSVhNRTogdGhpcyBkZXNjcmlwdGlvbiBuZWVkcyBzb21lIHNlcmlvdXMgaGVscCwgeWVzLgogKi8KCnN0cnVjdAlfdzk1a2V5dmFsdWUgewoJdW5zaWduZWQgbG9uZwkJdHlwZTsKCXVuc2lnbmVkIHNob3J0CQlkYXRhbGVuOwoJY2hhcgkJCSpuYW1lOwoJdW5zaWduZWQgY2hhcgkJKmRhdGE7Cgl1bnNpZ25lZCBsb25nCQl4MTsKCWludAkJCWxhc3Rtb2RpZmllZDsKfTsKCnN0cnVjdCAJX3c5NWtleSB7CgljaGFyCQkJKm5hbWU7CglpbnQJCQlucm9mdmFsczsKCXN0cnVjdAlfdzk1a2V5dmFsdWUJKnZhbHVlczsKCXN0cnVjdCBfdzk1a2V5CQkqcHJldmx2bDsKCXN0cnVjdCBfdzk1a2V5CQkqbmV4dHN1YjsKCXN0cnVjdCBfdzk1a2V5CQkqbmV4dDsKfTsKCgpzdHJ1Y3QgX3c5NV9pbmZvIHsKICBjaGFyICpyZ2tuYnVmZmVyOwogIGludCAgcmdrbnNpemU7CiAgY2hhciAqcmdkYmJ1ZmZlcjsKICBpbnQgIHJnZGJzaXplOwogIGludCAgZGVwdGg7CiAgaW50ICBsYXN0bW9kaWZpZWQ7Cn07CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X3Byb2Nlc3NLZXkgW0ludGVybmFsXQogKi8Kc3RhdGljIExQS0VZU1RSVUNUIF93OTVfcHJvY2Vzc0tleSAoIExQS0VZU1RSVUNUIGxwa2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnJMUywgaW50IG5yTVMsIHN0cnVjdCBfdzk1X2luZm8gKmluZm8gKQoKewogIC8qIERpc2sgS2V5IEhlYWRlciBzdHJ1Y3R1cmUgKFJHREIgcGFydCkgKi8KCXN0cnVjdAlka2ggewogICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZwkJbmV4dGtleW9mZjsgCgkJdW5zaWduZWQgc2hvcnQJCW5yTFM7CgkJdW5zaWduZWQgc2hvcnQJCW5yTVM7CgkJdW5zaWduZWQgbG9uZwkJYnl0ZXN1c2VkOwoJCXVuc2lnbmVkIHNob3J0CQlrZXluYW1lbGVuOwoJCXVuc2lnbmVkIHNob3J0CQl2YWx1ZXM7CgkJdW5zaWduZWQgbG9uZwkJeHgxOwoJCS8qIGtleW5hbWUgKi8KCQkvKiBkaXNrIGtleSB2YWx1ZXMgb3Igbm90aGluZyAqLwoJfTsKCS8qIERpc2sgS2V5IFZhbHVlIHN0cnVjdHVyZSAqLwoJc3RydWN0CWRrdiB7CgkJdW5zaWduZWQgbG9uZwkJdHlwZTsKCQl1bnNpZ25lZCBsb25nCQl4MTsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsbmFtZWxlbjsKCQl1bnNpZ25lZCBzaG9ydAkJdmFsZGF0YWxlbjsKCQkvKiB2YWxuYW1lLCB2YWxkYXRhICovCgl9OwoKCQoJc3RydWN0CWRraCBka2g7CglpbnQJYnl0ZXNyZWFkID0gMDsKCWNoYXIgICAgKnJnZGJkYXRhID0gaW5mby0+cmdkYmJ1ZmZlcjsKCWludCAgICAgbmJ5dGVzID0gaW5mby0+cmdkYnNpemU7CgljaGFyICAgICpjdXJkYXRhID0gcmdkYmRhdGE7CgljaGFyICAgICplbmQgPSByZ2RiZGF0YSArIG5ieXRlczsKCWludCAgICAgb2ZmX25leHRfcmdkYjsKCWNoYXIgICAgKm5leHQgPSByZ2RiZGF0YTsKCWludCAgICAgbnJnZGIsIGk7CglMUEtFWVNUUlVDVAlscHhrZXk7CgkKCWRvIHsKCSAgY3VyZGF0YSA9IG5leHQ7CgkgIGlmIChzdHJuY21wKGN1cmRhdGEsICJSR0RCIiwgNCkpIHJldHVybiAoTlVMTCk7CgkgICAgCgkgIG1lbWNweSgmb2ZmX25leHRfcmdkYixjdXJkYXRhKzQsNCk7CgkgIG5leHQgPSBjdXJkYXRhICsgb2ZmX25leHRfcmdkYjsKCSAgbnJnZGIgPSAoaW50KSAqKChzaG9ydCAqKWN1cmRhdGEgKyA3KTsKCgl9IHdoaWxlIChucmdkYiAhPSBuck1TICYmIChuZXh0IDwgZW5kKSk7CgoJLyogY3VyZGF0YSBub3cgcG9pbnRzIHRvIHRoZSBzdGFydCBvZiB0aGUgcmlnaHQgUkdEQiBzZWN0aW9uICovCgljdXJkYXRhICs9IDB4MjA7CgojZGVmaW5lIFhSRUFEKHdoZXJldG8sbGVuKSBcCglpZiAoKGN1cmRhdGEgKyBsZW4pIDxlbmQpIHtcCgkJbWVtY3B5KHdoZXJldG8sY3VyZGF0YSxsZW4pO1wKCQljdXJkYXRhKz1sZW47XAoJCWJ5dGVzcmVhZCs9bGVuO1wKCX0KCgl3aGlsZSAoY3VyZGF0YSA8IG5leHQpIHsKCSAgc3RydWN0CWRraCAqeGRraCA9IChzdHJ1Y3QgZGtoKiljdXJkYXRhOwoKCSAgYnl0ZXNyZWFkICs9IHNpemVvZihka2gpOyAvKiBGSVhNRS4uLiBuZXh0a2V5b2ZmPyAqLwoJICBpZiAoeGRraC0+bnJMUyA9PSBuckxTKSB7CgkgIAltZW1jcHkoJmRraCx4ZGtoLHNpemVvZihka2gpKTsKCSAgCWN1cmRhdGEgKz0gc2l6ZW9mKGRraCk7CgkgIAlicmVhazsKCSAgfQoJICBjdXJkYXRhICs9IHhka2gtPm5leHRrZXlvZmY7Cgl9OwoKCWlmIChka2gubnJMUyAhPSBuckxTKSByZXR1cm4gKE5VTEwpOwoKCWlmIChucmdkYiAhPSBka2gubnJNUykKCSAgcmV0dXJuIChOVUxMKTsKCiAgICAgICAgYXNzZXJ0KChka2gua2V5bmFtZWxlbjwyKSB8fCBjdXJkYXRhWzBdKTsKCWxweGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LHN0cmN2dEEyVyhjdXJkYXRhLCBka2gua2V5bmFtZWxlbikpOwoJY3VyZGF0YSArPSBka2gua2V5bmFtZWxlbjsKCglmb3IgKGk9MDtpPCBka2gudmFsdWVzOyBpKyspIHsKCSAgc3RydWN0IGRrdiBka3Y7CgkgIExQQllURSBkYXRhOwoJICBpbnQgbGVuOwoJICBMUFdTVFIgbmFtZTsKCgkgIFhSRUFEKCZka3Ysc2l6ZW9mKGRrdikpOwoKCSAgbmFtZSA9IHN0cmN2dEEyVyhjdXJkYXRhLCBka3YudmFsbmFtZWxlbik7CgkgIGN1cmRhdGEgKz0gZGt2LnZhbG5hbWVsZW47CgoJICBpZiAoKDEgPDwgZGt2LnR5cGUpICYgVU5JQ09OVk1BU0spIHsKCSAgICBkYXRhID0gKExQQllURSkgc3RyY3Z0QTJXKGN1cmRhdGEsIGRrdi52YWxkYXRhbGVuKTsKCSAgICBsZW4gPSAyKihka3YudmFsZGF0YWxlbiArIDEpOwoJICB9IGVsc2UgewoJICAgIC8qIEkgZG9uJ3QgdGhpbmsgd2Ugd2FudCB0byBOVUxMIHRlcm1pbmF0ZSBhbGwgZGF0YSAqLwoJICAgIGRhdGEgPSB4bWFsbG9jKGRrdi52YWxkYXRhbGVuKTsKCSAgICBtZW1jcHkgKGRhdGEsIGN1cmRhdGEsIGRrdi52YWxkYXRhbGVuKTsKCSAgICBsZW4gPSBka3YudmFsZGF0YWxlbjsKCSAgfQoKCSAgY3VyZGF0YSArPSBka3YudmFsZGF0YWxlbjsKCSAgCgkgIF9maW5kX29yX2FkZF92YWx1ZSgKCQkJICAgICBscHhrZXksCgkJCSAgICAgbmFtZSwKCQkJICAgICBka3YudHlwZSwKCQkJICAgICBkYXRhLAoJCQkgICAgIGxlbiwKCQkJICAgICBpbmZvLT5sYXN0bW9kaWZpZWQKCQkJICAgICApOwoJfQoJcmV0dXJuIChscHhrZXkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93OTVfd2Fsa3Jna24gW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3c5NV93YWxrcmdrbiggTFBLRVlTVFJVQ1QgcHJldmtleSwgY2hhciAqb2ZmLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IF93OTVfaW5mbyAqaW5mbyApCgp7CiAgLyogRGlzayBLZXkgRW50cnkgc3RydWN0dXJlIChSR0tOIHBhcnQpICovCiAgc3RydWN0CWRrZSB7CiAgICB1bnNpZ25lZCBsb25nCQl4MTsKICAgIHVuc2lnbmVkIGxvbmcJCXgyOwogICAgdW5zaWduZWQgbG9uZwkJeDM7Lyp1c3VhbGx5IDB4RkZGRkZGRkYgKi8KICAgIHVuc2lnbmVkIGxvbmcJCXByZXZsdmw7CiAgICB1bnNpZ25lZCBsb25nCQluZXh0c3ViOwogICAgdW5zaWduZWQgbG9uZwkJbmV4dDsKICAgIHVuc2lnbmVkIHNob3J0CQluckxTOwogICAgdW5zaWduZWQgc2hvcnQJCW5yTVM7CiAgfSAqZGtlID0gKHN0cnVjdCBka2UgKilvZmY7CiAgTFBLRVlTVFJVQ1QgIGxweGtleTsKCiAgaWYgKGRrZSA9PSBOVUxMKSB7CiAgICBka2UgPSAoc3RydWN0IGRrZSAqKSAoKGNoYXIgKilpbmZvLT5yZ2tuYnVmZmVyKTsKICB9CgogIGxweGtleSA9IF93OTVfcHJvY2Vzc0tleShwcmV2a2V5LCBka2UtPm5yTFMsIGRrZS0+bnJNUywgaW5mbyk7CiAgLyogWFhYIDwtLSBUaGlzIGlzIGEgaGFjayovCiAgaWYgKCFscHhrZXkpIHsKICAgIGxweGtleSA9IHByZXZrZXk7CiAgfQoKICBpZiAoZGtlLT5uZXh0c3ViICE9IC0xICYmIAogICAgICAoKGRrZS0+bmV4dHN1YiAtIDB4MjApIDwgaW5mby0+cmdrbnNpemUpIAogICAgICAmJiAoZGtlLT5uZXh0c3ViID4gMHgyMCkpIHsKICAgIAogICAgX3c5NV93YWxrcmdrbihscHhrZXksIAoJCSAgaW5mby0+cmdrbmJ1ZmZlciArIGRrZS0+bmV4dHN1YiAtIDB4MjAsIAoJCSAgaW5mbyk7CiAgfQogIAogIGlmIChka2UtPm5leHQgIT0gLTEgJiYgCiAgICAgICgoZGtlLT5uZXh0IC0gMHgyMCkgPCBpbmZvLT5yZ2tuc2l6ZSkgJiYgCiAgICAgIChka2UtPm5leHQgPiAweDIwKSkgewogICAgX3c5NV93YWxrcmdrbihwcmV2a2V5LCAgCgkJICBpbmZvLT5yZ2tuYnVmZmVyICsgZGtlLT5uZXh0IC0gMHgyMCwKCQkgIGluZm8pOwogIH0KCiAgcmV0dXJuOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfdzk1X2xvYWRyZWcgW0ludGVybmFsXQogKi8Kc3RhdGljIHZvaWQgX3c5NV9sb2FkcmVnKCBjaGFyKiBmbiwgTFBLRVlTVFJVQ1QgbHBrZXkgKQp7CglIRklMRTMyCQloZmQ7CgljaGFyCQltYWdpY1s1XTsKCXVuc2lnbmVkIGxvbmcJd2hlcmUsdmVyc2lvbixyZ2Ric2VjdGlvbixlbmQ7CglzdHJ1Y3QgICAgICAgICAgX3c5NV9pbmZvIGluZm87CglPRlNUUlVDVAlvZnM7CglCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBoZmRpbmZvOwoKCVRSQUNFKHJlZywiTG9hZGluZyBXaW45NSByZWdpc3RyeSBkYXRhYmFzZSAnJXMnXG4iLGZuKTsKCWhmZD1PcGVuRmlsZTMyKGZuLCZvZnMsT0ZfUkVBRCk7CglpZiAoaGZkPT1IRklMRV9FUlJPUjMyKQoJCXJldHVybjsKCW1hZ2ljWzRdPTA7CglpZiAoNCE9X2xyZWFkMzIoaGZkLG1hZ2ljLDQpKQoJCXJldHVybjsKCWlmIChzdHJjbXAobWFnaWMsIkNSRUciKSkgewoJCVdBUk4ocmVnLCIlcyBpcyBub3QgYSB3OTUgcmVnaXN0cnkuXG4iLGZuKTsKCQlyZXR1cm47Cgl9CglpZiAoNCE9X2xyZWFkMzIoaGZkLCZ2ZXJzaW9uLDQpKQoJCXJldHVybjsKCWlmICg0IT1fbHJlYWQzMihoZmQsJnJnZGJzZWN0aW9uLDQpKQoJCXJldHVybjsKCWlmICgtMT09X2xsc2VlazMyKGhmZCwweDIwLFNFRUtfU0VUKSkKCQlyZXR1cm47CglpZiAoNCE9X2xyZWFkMzIoaGZkLG1hZ2ljLDQpKQoJCXJldHVybjsKCWlmIChzdHJjbXAobWFnaWMsIlJHS04iKSkgewoJCVdBUk4ocmVnLCAic2Vjb25kIElGRiBoZWFkZXIgbm90IFJHS04sIGJ1dCAlc1xuIiwgbWFnaWMpOwoJCXJldHVybjsKCX0KCgkvKiBTVEVQIDE6IEtleWxpbmsgc3RydWN0dXJlcyAqLwoJaWYgKC0xPT1fbGxzZWVrMzIoaGZkLDB4NDAsU0VFS19TRVQpKQoJCXJldHVybjsKCXdoZXJlCT0gMHg0MDsKCWVuZAk9IHJnZGJzZWN0aW9uOwoKCWluZm8ucmdrbnNpemUgPSBlbmQgLSB3aGVyZTsKCWluZm8ucmdrbmJ1ZmZlciA9IChjaGFyKil4bWFsbG9jKGluZm8ucmdrbnNpemUpOwoJaWYgKGluZm8ucmdrbnNpemUgIT0gX2xyZWFkMzIoaGZkLGluZm8ucmdrbmJ1ZmZlcixpbmZvLnJna25zaXplKSkKCQlyZXR1cm47CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZmQsJmhmZGluZm8pKQoJCXJldHVybjsKCgllbmQgPSBoZmRpbmZvLm5GaWxlU2l6ZUxvdzsKCWluZm8ubGFzdG1vZGlmaWVkID0gRE9TRlNfRmlsZVRpbWVUb1VuaXhUaW1lKCZoZmRpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCglpZiAoLTE9PV9sbHNlZWszMihoZmQscmdkYnNlY3Rpb24sU0VFS19TRVQpKQoJCXJldHVybjsKCglpbmZvLnJnZGJidWZmZXIgPSAoY2hhciopeG1hbGxvYyhlbmQtcmdkYnNlY3Rpb24pOwoJaW5mby5yZ2Ric2l6ZSA9IGVuZCAtIHJnZGJzZWN0aW9uOwoKCWlmIChpbmZvLnJnZGJzaXplICE9X2xyZWFkMzIoaGZkLGluZm8ucmdkYmJ1ZmZlcixpbmZvLnJnZGJzaXplKSkKCQlyZXR1cm47CglfbGNsb3NlMzIoaGZkKTsKCglfdzk1X3dhbGtyZ2tuKGxwa2V5LCBOVUxMLCAmaW5mbyk7CgoJZnJlZSAoaW5mby5yZ2RiYnVmZmVyKTsKCWZyZWUgKGluZm8ucmdrbmJ1ZmZlcik7Cn0KCgovKiBXSU5ET1dTIDMxIFJFR0lTVFJZIExPQURFUiwgc3VwcGxpZWQgYnkgVG9yIFNq+HdhbGwsIHRvckBzbi5ubyAqLwoKLyoKICAgIHJlZ2hhY2sgLSB3aW5kb3dzIDMuMTEgcmVnaXN0cnkgZGF0YSBmb3JtYXQgZGVtbyBwcm9ncmFtLgoKICAgIFRoZSByZWcuZGF0IGZpbGUgaGFzIDMgcGFydHMsIGEgaGVhZGVyLCBhIHRhYmxlIG9mIDgtYnl0ZSBlbnRyaWVzIHRoYXQgaXMKICAgIGEgY29tYmluZWQgaGFzaCB0YWJsZSBhbmQgdHJlZSBkZXNjcmlwdGlvbiwgYW5kIGZpbmFsbHkgYSB0ZXh0IHRhYmxlLgoKICAgIFRoZSBoZWFkZXIgaXMgb2J2aW91cyBmcm9tIHRoZSBzdHJ1Y3QgaGVhZGVyLiBUaGUgdGFib2ZmMSBhbmQgdGFib2ZmMgogICAgZmllbGRzIGFyZSBhbHdheXMgMHgyMCwgYW5kIHRoZWlyIHVzYWdlIGlzIHVua25vd24uCgogICAgVGhlIDgtYnl0ZSBlbnRyeSB0YWJsZSBoYXMgdmFyaW91cyBlbnRyeSB0eXBlcy4KCiAgICB0YWJlbnRbMF0gaXMgYSByb290IGluZGV4LiBUaGUgc2Vjb25kIHdvcmQgaGFzIHRoZSBpbmRleCBvZiB0aGUgcm9vdCBvZgogICAgICAgICAgICB0aGUgZGlyZWN0b3J5LgogICAgdGFiZW50WzEuLmhhc2hzaXplXSBpcyBhIGhhc2ggdGFibGUuIFRoZSBmaXJzdCB3b3JkIGluIHRoZSBoYXNoIGVudHJ5IGlzCiAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUga2V5L3ZhbHVlIHRoYXQgaGFzIHRoYXQgaGFzaC4gRGF0YSB3aXRoIHRoZSBzYW1lCiAgICAgICAgICAgIGhhc2ggdmFsdWUgYXJlIG9uIGEgY2lyY3VsYXIgbGlzdC4gVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZQogICAgICAgICAgICBoYXNoIGVudHJ5IGFyZSBhbHdheXMgemVyby4KICAgIHRhYmVudFtoYXNoc2l6ZS4udGFiY250XSBpcyB0aGUgdHJlZSBzdHJ1Y3R1cmUuIFRoZXJlIGFyZSB0d28ga2luZHMgb2YKICAgICAgICAgICAgZW50cnk6IGRpcmVudCBhbmQga2V5ZW50L3ZhbGVudC4gVGhleSBhcmUgaWRlbnRpZmllZCBieSBjb250ZXh0LgogICAgdGFiZW50W2ZyZWVpZHhdIGlzIHRoZSBmaXJzdCBmcmVlIGVudHJ5LiBUaGUgZmlyc3Qgd29yZCBpbiBhIGZyZWUgZW50cnkKICAgICAgICAgICAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGZyZWUgZW50cnkuIFRoZSBsYXN0IGhhcyAwIGFzIGEgbGluay4KICAgICAgICAgICAgVGhlIG90aGVyIHRocmVlIHdvcmRzIGluIHRoZSBmcmVlIGxpc3QgYXJlIHByb2JhYmx5IGlycmVsZXZhbnQuCgogICAgRW50cmllcyBpbiB0ZXh0IHRhYmxlIGFyZSBwcmVjZWVkZWQgYnkgYSB3b3JkIGF0IG9mZnNldC0yLiBUaGlzIHdvcmQKICAgIGhhcyB0aGUgdmFsdWUgKDIqaW5kZXgpKzEsIHdoZXJlIGluZGV4IGlzIHRoZSByZWZlcnJpbmcga2V5ZW50L3ZhbGVudAogICAgZW50cnkgaW4gdGhlIHRhYmxlLiBJIGhhdmUgbm8gc3VnZ2VzdGlvbiBmb3IgdGhlIDIqIGFuZCB0aGUgKzEuCiAgICBGb2xsb3dpbmcgdGhlIHdvcmQsIHRoZXJlIGFyZSBOIGJ5dGVzIG9mIGRhdGEsIGFzIHBlciB0aGUga2V5ZW50L3ZhbGVudAogICAgZW50cnkgbGVuZ3RoLiBUaGUgb2Zmc2V0IG9mIHRoZSBrZXllbnQvdmFsZW50IGVudHJ5IGlzIGZyb20gdGhlIHN0YXJ0CiAgICBvZiB0aGUgdGV4dCB0YWJsZSB0byB0aGUgZmlyc3QgZGF0YSBieXRlLgoKICAgIFRoaXMgaW5mb3JtYXRpb24gaXMgbm90IGF2YWlsYWJsZSBmcm9tIE1pY3Jvc29mdC4gVGhlIGRhdGEgZm9ybWF0IGlzCiAgICBkZWR1Y2VkIGZyb20gdGhlIHJlZy5kYXQgZmlsZSBieSBtZS4gTWlzdGFrZXMgbWF5CiAgICBoYXZlIGJlZW4gbWFkZS4gSSBjbGFpbSBubyByaWdodHMgYW5kIGdpdmUgbm8gZ3VhcmFudGVlcyBmb3IgdGhpcyBwcm9ncmFtLgoKICAgIFRvciBTavh3YWxsLCB0b3JAc24ubm8KKi8KCi8qIHJlZy5kYXQgaGVhZGVyIGZvcm1hdCAqLwpzdHJ1Y3QgX3czMV9oZWFkZXIgewoJY2hhcgkJY29va2llWzhdOwkvKiAnU0hDQzMuMTAnICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjE7CS8qIG9mZnNldCBvZiBoYXNoIHRhYmxlICg/PykgPSAweDIwICovCgl1bnNpZ25lZCBsb25nCXRhYm9mZjI7CS8qIG9mZnNldCBvZiBpbmRleCB0YWJsZSAoPz8pID0gMHgyMCAqLwoJdW5zaWduZWQgbG9uZwl0YWJjbnQ7CQkvKiBudW1iZXIgb2YgZW50cmllcyBpbiBpbmRleCB0YWJsZSAqLwoJdW5zaWduZWQgbG9uZwl0ZXh0b2ZmOwkvKiBvZmZzZXQgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBsb25nCXRleHRzaXplOwkvKiBieXRlIHNpemUgb2YgdGV4dCBwYXJ0ICovCgl1bnNpZ25lZCBzaG9ydAloYXNoc2l6ZTsJLyogaGFzaCBzaXplICovCgl1bnNpZ25lZCBzaG9ydAlmcmVlaWR4OwkvKiBmcmVlIGluZGV4ICovCn07CgovKiBnZW5lcmljIGZvcm1hdCBvZiB0YWJsZSBlbnRyaWVzICovCnN0cnVjdCBfdzMxX3RhYmVudCB7Cgl1bnNpZ25lZCBzaG9ydCB3MCwgdzEsIHcyLCB3MzsKfTsKCi8qIGRpcmVjdG9yeSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX2RpcmVudCB7Cgl1bnNpZ25lZCBzaG9ydAlzaWJsaW5nX2lkeDsJLyogdGFibGUgaW5kZXggb2Ygc2libGluZyBkaXJlbnQgKi8KCXVuc2lnbmVkIHNob3J0CWNoaWxkX2lkeDsJLyogdGFibGUgaW5kZXggb2YgY2hpbGQgZGlyZW50ICovCgl1bnNpZ25lZCBzaG9ydAlrZXlfaWR4OwkvKiB0YWJsZSBpbmRleCBvZiBrZXkga2V5ZW50ICovCgl1bnNpZ25lZCBzaG9ydAl2YWx1ZV9pZHg7CS8qIHRhYmxlIGluZGV4IG9mIHZhbHVlIHZhbGVudCAqLwp9OwoKLyoga2V5IHRhYmVudDogKi8Kc3RydWN0IF93MzFfa2V5ZW50IHsKCXVuc2lnbmVkIHNob3J0CWhhc2hfaWR4OwkvKiBoYXNoIGNoYWluIGluZGV4IGZvciBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXJlZmNudDsJCS8qIHJlZmVyZW5jZSBjb3VudCAqLwoJdW5zaWduZWQgc2hvcnQJbGVuZ3RoOwkJLyogbGVuZ3RoIG9mIHN0cmluZyAqLwoJdW5zaWduZWQgc2hvcnQJc3RyaW5nX29mZjsJLyogb2Zmc2V0IG9mIHN0cmluZyBpbiB0ZXh0IHRhYmxlICovCn07CgovKiB2YWx1ZSB0YWJlbnQ6ICovCnN0cnVjdCBfdzMxX3ZhbGVudCB7Cgl1bnNpZ25lZCBzaG9ydAloYXNoX2lkeDsJLyogaGFzaCBjaGFpbiBpbmRleCBmb3Igc3RyaW5nICovCgl1bnNpZ25lZCBzaG9ydAlyZWZjbnQ7CQkvKiByZWZlcmVuY2UgY291bnQgKi8KCXVuc2lnbmVkIHNob3J0CWxlbmd0aDsJCS8qIGxlbmd0aCBvZiBzdHJpbmcgKi8KCXVuc2lnbmVkIHNob3J0CXN0cmluZ19vZmY7CS8qIG9mZnNldCBvZiBzdHJpbmcgaW4gdGV4dCB0YWJsZSAqLwp9OwoKLyogcmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBkaXNwbGF5IGEgZGlyZWN0b3J5IHRyZWUgKi8Kdm9pZApfX3czMV9kdW1wdHJlZSgJdW5zaWduZWQgc2hvcnQgaWR4LAoJCXVuc2lnbmVkIGNoYXIgKnR4dCwKCQlzdHJ1Y3QgX3czMV90YWJlbnQgKnRhYiwKCQlzdHJ1Y3QgX3czMV9oZWFkZXIgKmhlYWQsCgkJTFBLRVlTVFJVQ1QJbHBrZXksCgkJdGltZV90CQlsYXN0bW9kaWZpZWQsCgkJaW50CQlsZXZlbAopIHsKCXN0cnVjdCBfdzMxX2RpcmVudAkqZGlyOwoJc3RydWN0IF93MzFfa2V5ZW50CSprZXk7CglzdHJ1Y3QgX3czMV92YWxlbnQJKnZhbDsKCUxQS0VZU1RSVUNUCQl4bHBrZXkgPSBOVUxMOwoJTFBXU1RSCQkJbmFtZSx2YWx1ZTsKCXN0YXRpYyBjaGFyCQl0YWlsWzQwMF07CgoJd2hpbGUgKGlkeCE9MCkgewoJCWRpcj0oc3RydWN0IF93MzFfZGlyZW50KikmdGFiW2lkeF07CgoJCWlmIChkaXItPmtleV9pZHgpIHsKCQkJa2V5ID0gKHN0cnVjdCBfdzMxX2tleWVudCopJnRhYltkaXItPmtleV9pZHhdOwoKCQkJbWVtY3B5KHRhaWwsJnR4dFtrZXktPnN0cmluZ19vZmZdLGtleS0+bGVuZ3RoKTsKCQkJdGFpbFtrZXktPmxlbmd0aF09J1wwJzsKCQkJLyogYWxsIHRvcGxldmVsIGVudHJpZXMgQU5EIHRoZSBlbnRyaWVzIGluIHRoZSAKCQkJICogdG9wbGV2ZWwgc3ViZGlyZWN0b3J5IGJlbG9uZyB0byBcU09GVFdBUkVcQ2xhc3NlcwoJCQkgKi8KCQkJaWYgKCFsZXZlbCAmJiAhbHN0cmNtcDMyQSh0YWlsLCIuY2xhc3NlcyIpKSB7CgkJCQlfX3czMV9kdW1wdHJlZShkaXItPmNoaWxkX2lkeCx0eHQsdGFiLGhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLGxldmVsKzEpOwoJCQkJaWR4PWRpci0+c2libGluZ19pZHg7CgkJCQljb250aW51ZTsKCQkJfQoJCQluYW1lPXN0cmR1cEEyVyh0YWlsKTsKCgkJCXhscGtleT1fZmluZF9vcl9hZGRfa2V5KGxwa2V5LG5hbWUpOwoKCQkJLyogb25seSBhZGQgaWYgbGVhZiBub2RlIG9yIHZhbHVlZCBub2RlICovCgkJCWlmIChkaXItPnZhbHVlX2lkeCE9MHx8ZGlyLT5jaGlsZF9pZHg9PTApIHsKCQkJCWlmIChkaXItPnZhbHVlX2lkeCkgewoJCQkJCXZhbD0oc3RydWN0IF93MzFfdmFsZW50KikmdGFiW2Rpci0+dmFsdWVfaWR4XTsKCQkJCQltZW1jcHkodGFpbCwmdHh0W3ZhbC0+c3RyaW5nX29mZl0sdmFsLT5sZW5ndGgpOwoJCQkJCXRhaWxbdmFsLT5sZW5ndGhdPSdcMCc7CgkJCQkJdmFsdWU9c3RyZHVwQTJXKHRhaWwpOwoJCQkJCV9maW5kX29yX2FkZF92YWx1ZSh4bHBrZXksTlVMTCxSRUdfU1osKExQQllURSl2YWx1ZSxsc3RybGVuMzJXKHZhbHVlKSoyKzIsbGFzdG1vZGlmaWVkKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCVRSQUNFKHJlZywic3RyYW5nZTogbm8gZGlyZWN0b3J5IGtleSBuYW1lLCBpZHg9JTA0eFxuIiwgaWR4KTsKCQl9CgkJX193MzFfZHVtcHRyZWUoZGlyLT5jaGlsZF9pZHgsdHh0LHRhYixoZWFkLHhscGtleSxsYXN0bW9kaWZpZWQsbGV2ZWwrMSk7CgkJaWR4PWRpci0+c2libGluZ19pZHg7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF93MzFfbG9hZHJlZyBbSW50ZXJuYWxdCiAqLwp2b2lkIF93MzFfbG9hZHJlZygpIHsKCUhGSUxFMzIJCQloZjsKCXN0cnVjdCBfdzMxX2hlYWRlcgloZWFkOwoJc3RydWN0IF93MzFfdGFiZW50CSp0YWI7Cgl1bnNpZ25lZCBjaGFyCQkqdHh0OwoJaW50CQkJbGVuOwoJT0ZTVFJVQ1QJCW9mczsKCUJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGhmaW5mbzsKCXRpbWVfdAkJCWxhc3Rtb2RpZmllZDsKCUxQS0VZU1RSVUNUCQlscGtleTsKCglUUkFDRShyZWcsIih2b2lkKVxuIik7CgoJaGYgPSBPcGVuRmlsZTMyKCJyZWcuZGF0Iiwmb2ZzLE9GX1JFQUQpOwoJaWYgKGhmPT1IRklMRV9FUlJPUjMyKQoJCXJldHVybjsKCgkvKiByZWFkICYgZHVtcCBoZWFkZXIgKi8KCWlmIChzaXplb2YoaGVhZCkhPV9scmVhZDMyKGhmLCZoZWFkLHNpemVvZihoZWFkKSkpIHsKCQlFUlIocmVnLCAicmVnLmRhdCBpcyB0b28gc2hvcnQuXG4iKTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCWlmIChtZW1jbXAoaGVhZC5jb29raWUsICJTSENDMy4xMCIsIHNpemVvZihoZWFkLmNvb2tpZSkpIT0wKSB7CgkJRVJSKHJlZywgInJlZy5kYXQgaGFzIGJhZCBzaWduYXR1cmUuXG4iKTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCglsZW4gPSBoZWFkLnRhYmNudCAqIHNpemVvZihzdHJ1Y3QgX3czMV90YWJlbnQpOwoJLyogcmVhZCBhbmQgZHVtcCBpbmRleCB0YWJsZSAqLwoJdGFiID0geG1hbGxvYyhsZW4pOwoJaWYgKGxlbiE9X2xyZWFkMzIoaGYsdGFiLGxlbikpIHsKCQlFUlIocmVnLCJjb3VsZG4ndCByZWFkICVkIGJ5dGVzLlxuIixsZW4pOyAKCQlmcmVlKHRhYik7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CgoJLyogcmVhZCB0ZXh0ICovCgl0eHQgPSB4bWFsbG9jKGhlYWQudGV4dHNpemUpOwoJaWYgKC0xPT1fbGxzZWVrMzIoaGYsaGVhZC50ZXh0b2ZmLFNFRUtfU0VUKSkgewoJCUVSUihyZWcsImNvdWxkbid0IHNlZWsgdG8gdGV4dGJsb2NrLlxuIik7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CglpZiAoaGVhZC50ZXh0c2l6ZSE9X2xyZWFkMzIoaGYsdHh0LGhlYWQudGV4dHNpemUpKSB7CgkJRVJSKHJlZywidGV4dGJsb2NrIHRvbyBzaG9ydCAoJWQgaW5zdGVhZCBvZiAlbGQpLlxuIixsZW4saGVhZC50ZXh0c2l6ZSk7IAoJCWZyZWUodGFiKTsKCQlmcmVlKHR4dCk7CgkJX2xjbG9zZTMyKGhmKTsKCQlyZXR1cm47Cgl9CgoJaWYgKCFHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoZiwmaGZpbmZvKSkgewoJCUVSUihyZWcsIkdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlIGZhaWxlZD8uXG4iKTsgCgkJZnJlZSh0YWIpOwoJCWZyZWUodHh0KTsKCQlfbGNsb3NlMzIoaGYpOwoJCXJldHVybjsKCX0KCWxhc3Rtb2RpZmllZCA9IERPU0ZTX0ZpbGVUaW1lVG9Vbml4VGltZSgmaGZpbmZvLmZ0TGFzdFdyaXRlVGltZSxOVUxMKTsKCWxwa2V5ID0gbG9va3VwX2hrZXkoSEtFWV9DTEFTU0VTX1JPT1QpOwoJX193MzFfZHVtcHRyZWUodGFiWzBdLncxLHR4dCx0YWIsJmhlYWQsbHBrZXksbGFzdG1vZGlmaWVkLDApOwoJZnJlZSh0YWIpOwoJZnJlZSh0eHQpOwoJX2xjbG9zZTMyKGhmKTsKCXJldHVybjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMX0xvYWRSZWdpc3RyeSBbSW50ZXJuYWxdCiAqLwp2b2lkIFNIRUxMX0xvYWRSZWdpc3RyeSggdm9pZCApCnsKCWNoYXIJKmZuOwoJc3RydWN0CXBhc3N3ZAkqcHdkOwoJTFBLRVlTVFJVQ1QJbHBrZXk7CglIS0VZCQloa2V5OwoKCVRSQUNFKHJlZywiKHZvaWQpXG4iKTsKCgkvKiBMb2FkIHdpbmRvd3MgMy4xIGVudHJpZXMgKi8KCV93MzFfbG9hZHJlZygpOwoJLyogTG9hZCB3aW5kb3dzIDk1IGVudHJpZXMgKi8KCV93OTVfbG9hZHJlZygiQzpcXHN5c3RlbS4xc3QiLAlsb29rdXBfaGtleShIS0VZX0xPQ0FMX01BQ0hJTkUpKTsKCV93OTVfbG9hZHJlZygic3lzdGVtLmRhdCIsCWxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSkpOwoJX3c5NV9sb2FkcmVnKCJ1c2VyLmRhdCIsCWxvb2t1cF9oa2V5KEhLRVlfVVNFUlMpKTsKCgkvKiB0aGUgZ2xvYmFsIHVzZXIgZGVmYXVsdCBpcyBsb2FkZWQgdW5kZXIgSEtFWV9VU0VSU1xcLkRlZmF1bHQgKi8KCVJlZ0NyZWF0ZUtleTE2KEhLRVlfVVNFUlMsIi5EZWZhdWx0IiwmaGtleSk7CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgICAgIGlmKCFscGtleSkKICAgICAgICAgICAgV0FSTihyZWcsIkNvdWxkIG5vdCBjcmVhdGUgZ2xvYmFsIHVzZXIgZGVmYXVsdCBrZXlcbiIpOwoJX3dpbmVfbG9hZHJlZyhscGtleSxTQVZFX1VTRVJTX0RFRkFVTFQsMCk7CgoJLyogSEtFWV9VU0VSU1xcLkRlZmF1bHQgaXMgY29waWVkIHRvIEhLRVlfQ1VSUkVOVF9VU0VSICovCglfY29weV9yZWdpc3RyeShscGtleSxsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUikpOwoJUmVnQ2xvc2VLZXkoaGtleSk7CgoJLyogdGhlIGdsb2JhbCBtYWNoaW5lIGRlZmF1bHRzICovCglfd2luZV9sb2FkcmVnKGxvb2t1cF9oa2V5KEhLRVlfTE9DQUxfTUFDSElORSksU0FWRV9MT0NBTF9NQUNISU5FX0RFRkFVTFQsMCk7CgoJLyogbG9hZCB0aGUgdXNlciBzYXZlZCByZWdpc3RyaWVzICovCgoJLyogRklYTUU6IHVzZSBnZXRlbnYoIkhPTUUiKSBvciBnZXRwd3VpZChnZXR1aWQoKSktPnB3X2RpciA/PyAqLwoKCXB3ZD1nZXRwd3VpZChnZXR1aWQoKSk7CglpZiAocHdkIT1OVUxMICYmIHB3ZC0+cHdfZGlyIT1OVUxMKSB7CgkJZm49KGNoYXIqKXhtYWxsb2Moc3RybGVuKHB3ZC0+cHdfZGlyKStzdHJsZW4oV0lORV9QUkVGSVgpK3N0cmxlbihTQVZFX0NVUlJFTlRfVVNFUikrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0NVUlJFTlRfVVNFUik7CgkJX3dpbmVfbG9hZHJlZyhsb29rdXBfaGtleShIS0VZX0NVUlJFTlRfVVNFUiksZm4sUkVHX09QVElPTl9UQUlOVEVEKTsKCQlmcmVlKGZuKTsKCQlmbj0oY2hhciopeG1hbGxvYyhzdHJsZW4ocHdkLT5wd19kaXIpK3N0cmxlbihXSU5FX1BSRUZJWCkrc3RybGVuKFNBVkVfTE9DQUxfTUFDSElORSkrMik7CgkJc3RyY3B5KGZuLHB3ZC0+cHdfZGlyKTsKCQlzdHJjYXQoZm4sV0lORV9QUkVGSVgiLyJTQVZFX0xPQ0FMX01BQ0hJTkUpOwoJCV93aW5lX2xvYWRyZWcobG9va3VwX2hrZXkoSEtFWV9MT0NBTF9NQUNISU5FKSxmbixSRUdfT1BUSU9OX1RBSU5URUQpOwoJCWZyZWUoZm4pOwoJfSBlbHNlCgkJV0FSTihyZWcsIkZhaWxlZCB0byBnZXQgaG9tZWRpcmVjdG9yeSBvZiBVSUQgJWQuXG4iLGdldHVpZCgpKTsKCWlmIChFUlJPUl9TVUNDRVNTPT1SZWdDcmVhdGVLZXkxNihIS0VZX0NVUlJFTlRfVVNFUixLRVlfUkVHSVNUUlksJmhrZXkpKSB7CgkJRFdPUkQJanVuayx0eXBlLGxlbjsKCQljaGFyCWRhdGFbNV07CgoJCWxlbj00OwoJCWlmICgoCVJlZ1F1ZXJ5VmFsdWVFeDMyQSgKCQkJCWhrZXksCgkJCQlWQUxfU0FWRVVQREFURUQsCgkJCQkmanVuaywKCQkJCSZ0eXBlLAoJCQkJZGF0YSwKCQkJCSZsZW4KCQkJKSE9RVJST1JfU1VDQ0VTUykgfHwKCQkJdHlwZSAhPSBSRUdfU1oKCQkpCgkJCVJlZ1NldFZhbHVlRXgzMkEoaGtleSxWQUxfU0FWRVVQREFURUQsMCxSRUdfU1osInllcyIsNCk7CgkJUmVnQ2xvc2VLZXkoaGtleSk7Cgl9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIEFQSSBGVU5DVElPTlMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKgogKiBPcGVuIEtleXMuCiAqCiAqIEFsbCBmdW5jdGlvbnMgYXJlIHN0dWJzIHRvIFJlZ09wZW5LZXlFeDMyVyB3aGVyZSBhbGwgdGhlCiAqIG1hZ2ljIGhhcHBlbnMuIAogKgogKiBDYWxscGF0aDoKICogUmVnT3BlbktleTE2IC0+IFJlZ09wZW5LZXkzMkEgLT4gUmVnT3BlbktleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnT3BlbktleTMyVyAgIC0+IFJlZ09wZW5LZXlFeDMyVyAKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5RXgzMlcgW0FEVkFQSTMyLjE1MF0KICogT3BlbnMgdGhlIHNwZWNpZmllZCBrZXkKICoKICogVW5saWtlIFJlZ0NyZWF0ZUtleUV4LCB0aGlzIGRvZXMgbm90IGNyZWF0ZSB0aGUga2V5IGlmIGl0IGRvZXMgbm90IGV4aXN0LgogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIE5hbWUgb2Ygc3Via2V5IHRvIG9wZW4KICogICAgZHdSZXNlcnZlZCBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIHplcm8KICogICAgc2FtRGVzaXJlZCBbSV0gU2VjdXJpdHkgYWNjZXNzIG1hc2sKICogICAgcmV0a2V5ICAgICBbT10gQWRkcmVzcyBvZiBoYW5kbGUgb2Ygb3BlbiBrZXkKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5RXgzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdTQU0gc2FtRGVzaXJlZCwgTFBIS0VZIHJldGtleSApCnsKCUxQS0VZU1RSVUNUCWxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKICAgIFRSQUNFKHJlZywiKDB4JXgsJXMsJWxkLCVseCwlcClcbiIsIGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxkd1Jlc2VydmVkLAogICAgICAgICAgc2FtRGVzaXJlZCxyZXRrZXkpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwTmV4dEtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkgewogICAgICAgIC8qIEVpdGhlciBOVUxMIG9yIHBvaW50ZXIgdG8gZW1wdHkgc3RyaW5nLCBzbyByZXR1cm4gYSBuZXcgaGFuZGxlCiAgICAgICAgICAgdG8gdGhlIG9yaWdpbmFsIGhrZXkgKi8KICAgICAgICBjdXJyZW50aGFuZGxlICs9IDI7CiAgICAgICAgYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKICAgICAgICAqcmV0a2V5PWN1cnJlbnRoYW5kbGU7CiAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CiAgICB9CgogICAgaWYgKGxwc3pTdWJLZXlbMF0gPT0gJ1xcJykgewogICAgICAgIFdBUk4ocmVnLCJTdWJrZXkgJXMgbXVzdCBub3QgYmVnaW4gd2l0aCBiYWNrc2xhc2guXG4iLGRlYnVnc3RyX3cobHBzelN1YktleSkpOwogICAgICAgIHJldHVybiBFUlJPUl9CQURfUEFUSE5BTUU7CiAgICB9CgoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpID0gMDsKCXdoaWxlICgoaTx3cGMpICYmICh3cHNbaV1bMF09PSdcMCcpKSBpKys7CglscHhrZXkgPSBscE5leHRLZXk7CgogICAgd2hpbGUgKHdwc1tpXSkgewogICAgICAgIGxweGtleT1scE5leHRLZXktPm5leHRzdWI7CiAgICAgICAgd2hpbGUgKGxweGtleSkgewogICAgICAgICAgICBpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBscHhrZXk9bHB4a2V5LT5uZXh0OwogICAgICAgIH0KCiAgICAgICAgaWYgKCFscHhrZXkpIHsKICAgICAgICAgICAgVFJBQ0UocmVnLCJDb3VsZCBub3QgZmluZCBzdWJrZXkgJXNcbiIsZGVidWdzdHJfdyh3cHNbaV0pKTsKICAgICAgICAgICAgRlJFRV9LRVlfUEFUSDsKICAgICAgICAgICAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwogICAgICAgIH0KICAgICAgICBpKys7CiAgICAgICAgbHBOZXh0S2V5ID0gbHB4a2V5OwogICAgfQoKICAgIGN1cnJlbnRoYW5kbGUgKz0gMjsKICAgIGFkZF9oYW5kbGUoY3VycmVudGhhbmRsZSxscHhrZXksc2FtRGVzaXJlZCk7CiAgICAqcmV0a2V5ID0gY3VycmVudGhhbmRsZTsKICAgIFRSQUNFKHJlZywiICBSZXR1cm5pbmcgJXhcbiIsIGN1cnJlbnRoYW5kbGUpOwogICAgRlJFRV9LRVlfUEFUSDsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5RXgzMkEgW0FEVkFQSTMyLjE0OV0KICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5RXgzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3UmVzZXJ2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFR1NBTSBzYW1EZXNpcmVkLCBMUEhLRVkgcmV0a2V5ICkKewogICAgTFBXU1RSIGxwc3pTdWJLZXlXID0gc3RyZHVwQTJXKGxwc3pTdWJLZXkpOwogICAgRFdPUkQgcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbHgsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxkd1Jlc2VydmVkLAogICAgICAgICAgc2FtRGVzaXJlZCxyZXRrZXkpOwogICAgcmV0ID0gUmVnT3BlbktleUV4MzJXKCBoa2V5LCBscHN6U3ViS2V5VywgZHdSZXNlcnZlZCwgc2FtRGVzaXJlZCwgcmV0a2V5ICk7CiAgICBmcmVlKGxwc3pTdWJLZXlXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ09wZW5LZXkzMlcgW0FEVkFQSTMyLjE1MV0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgW0ldIEhhbmRsZSBvZiBvcGVuIGtleQogKiAgICBscHN6U3ViS2V5IFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5IHRvIG9wZW4KICogICAgcmV0a2V5ICAgICBbT10gQWRkcmVzcyBvZiBoYW5kbGUgb2Ygb3BlbiBrZXkKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdPcGVuS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdPcGVuS2V5RXgzMlcoIGhrZXksIGxwc3pTdWJLZXksIDAsIEtFWV9BTExfQUNDRVNTLCByZXRrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnT3BlbktleTMyQSBbQURWQVBJMzIuMTQ4XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBEV09SRCByZXQ7CiAgICBMUFdTVFIgbHBzelN1YktleVcgPSBzdHJkdXBBMlcobHBzelN1YktleSk7CiAgICBUUkFDRShyZWcsIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICByZXQgPSAgUmVnT3BlbktleTMyVyggaGtleSwgbHBzelN1YktleVcsIHJldGtleSApOwogICAgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdPcGVuS2V5MTYgW1NIRUxMLjFdIFtLRVJORUwuMjE3XQogKi8KRFdPUkQgV0lOQVBJIFJlZ09wZW5LZXkxNiggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBIS0VZIHJldGtleSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSkscmV0a2V5KTsKICAgIHJldHVybiBSZWdPcGVuS2V5MzJBKCBoa2V5LCBscHN6U3ViS2V5LCByZXRrZXkgKTsKfQoKCi8qIAogKiBDcmVhdGUga2V5cwogKiAKICogQWxsIHRob3NlIGZ1bmN0aW9ucyBjb252ZXJ0IHRoZWlyIHJlc3BlY3RpdmUgCiAqIGFyZ3VtZW50cyBhbmQgY2FsbCBSZWdDcmVhdGVLZXlFeFcgYXQgdGhlIGVuZC4KICoKICogV2Ugc3RheSBhd2F5IGZyb20gdGhlIEV4IGZ1bmN0aW9ucyBhcyBsb25nIGFzIHBvc3NpYmxlIGJlY2F1c2UgdGhlcmUgYXJlCiAqIGRpZmZlcmVuY2VzIGluIHRoZSByZXR1cm4gdmFsdWVzCiAqCiAqIENhbGxwYXRoOgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnQ3JlYXRlS2V5RXgzMkEgXAogKiBSZWdDcmVhdGVLZXkxNiAtPiBSZWdDcmVhdGVLZXkzMkEgLT4gUmVnQ3JlYXRlS2V5MzJXICAgLT4gUmVnQ3JlYXRlS2V5RXgzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXlFeDMyVyBbQURWQVBJMzIuMTMxXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgIFtJXSBIYW5kbGUgb2YgYW4gb3BlbiBrZXkKICogICAgbHBzelN1YktleSAgIFtJXSBBZGRyZXNzIG9mIHN1YmtleSBuYW1lCiAqICAgIGR3UmVzZXJ2ZWQgICBbSV0gUmVzZXJ2ZWQgLSBtdXN0IGJlIDAKICogICAgbHBzekNsYXNzICAgIFtJXSBBZGRyZXNzIG9mIGNsYXNzIHN0cmluZwogKiAgICBmZHdPcHRpb25zICAgW0ldIFNwZWNpYWwgb3B0aW9ucyBmbGFnCiAqICAgIHNhbURlc2lyZWQgICBbSV0gRGVzaXJlZCBzZWN1cml0eSBhY2Nlc3MKICogICAgbHBTZWNBdHRyaWJzIFtJXSBBZGRyZXNzIG9mIGtleSBzZWN1cml0eSBzdHJ1Y3R1cmUKICogICAgcmV0a2V5ICAgICAgIFtPXSBBZGRyZXNzIG9mIGJ1ZmZlciBmb3Igb3BlbmVkIGhhbmRsZQogKiAgICBscERpc3BvcyAgICAgW09dIFJlY2VpdmVzIFJFR19DUkVBVEVEX05FV19LRVkgb3IgUkVHX09QRU5FRF9FWElTVElOR19LRVkKICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXlFeDMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3UmVzZXJ2ZWQsIExQV1NUUiBscHN6Q2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGZkd09wdGlvbnMsIFJFR1NBTSBzYW1EZXNpcmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBscFNlY0F0dHJpYnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSByZXRrZXksIExQRFdPUkQgbHBEaXNwb3MgKQp7CglMUEtFWVNUUlVDVAkqbHBscFByZXZLZXksbHBOZXh0S2V5LGxweGtleTsKCUxQV1NUUgkJKndwczsKCWludAkJd3BjLGk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVseCwlbHgsJXAsJXAsJXApXG4iLCBoa2V5LAoJCWRlYnVnc3RyX3cobHBzelN1YktleSksIGR3UmVzZXJ2ZWQsIGRlYnVnc3RyX3cobHBzekNsYXNzKSwKCQlmZHdPcHRpb25zLCBzYW1EZXNpcmVkLCBscFNlY0F0dHJpYnMsIHJldGtleSwgbHBEaXNwb3MpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIENoZWNrIGZvciB2YWxpZCBvcHRpb25zICovCiAgICBzd2l0Y2goZmR3T3B0aW9ucykgewogICAgICAgIGNhc2UgUkVHX09QVElPTl9OT05fVk9MQVRJTEU6CiAgICAgICAgY2FzZSBSRUdfT1BUSU9OX1ZPTEFUSUxFOgogICAgICAgIGNhc2UgUkVHX09QVElPTl9CQUNLVVBfUkVTVE9SRToKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwogICAgfQoKICAgIC8qIFNhbSBoYXMgdG8gYmUgYSBjb21iaW5hdGlvbiBvZiB0aGUgZm9sbG93aW5nICovCiAgICBpZiAoIShzYW1EZXNpcmVkICYgCiAgICAgICAgICAoS0VZX0FMTF9BQ0NFU1MgfCBLRVlfQ1JFQVRFX0xJTksgfCBLRVlfQ1JFQVRFX1NVQl9LRVkgfCAKICAgICAgICAgICBLRVlfRU5VTUVSQVRFX1NVQl9LRVlTIHwgS0VZX0VYRUNVVEUgfCBLRVlfTk9USUZZIHwKICAgICAgICAgICBLRVlfUVVFUllfVkFMVUUgfCBLRVlfUkVBRCB8IEtFWV9TRVRfVkFMVUUgfCBLRVlfV1JJVEUpKSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgoJaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkgewogICAgICAgICAgICAgICAgY3VycmVudGhhbmRsZSArPSAyOwoJCWFkZF9oYW5kbGUoY3VycmVudGhhbmRsZSxscE5leHRLZXksc2FtRGVzaXJlZCk7CgkJKnJldGtleT1jdXJyZW50aGFuZGxlOwogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCQlscE5leHRLZXktPmZsYWdzfD1SRUdfT1BUSU9OX1RBSU5URUQ7CgkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cgl9CgogICAgaWYgKGxwc3pTdWJLZXlbMF0gPT0gJ1xcJykgewogICAgICAgIFdBUk4ocmVnLCJTdWJrZXkgJXMgbXVzdCBub3QgYmVnaW4gd2l0aCBiYWNrc2xhc2guXG4iLGRlYnVnc3RyX3cobHBzelN1YktleSkpOwogICAgICAgIHJldHVybiBFUlJPUl9CQURfUEFUSE5BTUU7CiAgICB9CgoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7Cgl3aGlsZSAoKGk8d3BjKSAmJiAod3BzW2ldWzBdPT0nXDAnKSkgaSsrOwoJbHB4a2V5CT0gbHBOZXh0S2V5OwoJd2hpbGUgKHdwc1tpXSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQkJYnJlYWs7CgkJCWxweGtleT1scHhrZXktPm5leHQ7CgkJfQoJCWlmICghbHB4a2V5KQoJCQlicmVhazsKCQlpKys7CgkJbHBOZXh0S2V5CT0gbHB4a2V5OwoJfQoJaWYgKGxweGtleSkgewogICAgICAgICAgICAgICAgY3VycmVudGhhbmRsZSArPSAyOwoJCWFkZF9oYW5kbGUoY3VycmVudGhhbmRsZSxscHhrZXksc2FtRGVzaXJlZCk7CgkJbHB4a2V5LT5mbGFncyAgfD0gUkVHX09QVElPTl9UQUlOVEVEOwoJCSpyZXRrZXkJCT0gY3VycmVudGhhbmRsZTsKICAgICAgICAgICAgICAgIFRSQUNFKHJlZywgIlJldHVybmluZyAleFxuIiwgY3VycmVudGhhbmRsZSk7CgkJaWYgKGxwRGlzcG9zKQoJCQkqbHBEaXNwb3MJPSBSRUdfT1BFTkVEX0VYSVNUSU5HX0tFWTsKCQlGUkVFX0tFWV9QQVRIOwoJCXJldHVybiBFUlJPUl9TVUNDRVNTOwoJfQoKCS8qIEdvb2QuICBOb3cgdGhlIGhhcmQgcGFydCAqLwoJd2hpbGUgKHdwc1tpXSkgewoJCWxwbHBQcmV2S2V5CT0gJihscE5leHRLZXktPm5leHRzdWIpOwoJCWxweGtleQkJPSAqbHBscFByZXZLZXk7CgkJd2hpbGUgKGxweGtleSkgewoJCQlscGxwUHJldktleQk9ICYobHB4a2V5LT5uZXh0KTsKCQkJbHB4a2V5CQk9ICpscGxwUHJldktleTsKCQl9CgkJKmxwbHBQcmV2S2V5PW1hbGxvYyhzaXplb2YoS0VZU1RSVUNUKSk7CgkJaWYgKCEqbHBscFByZXZLZXkpIHsKCQkJRlJFRV9LRVlfUEFUSDsKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nIE9VVE9GTUVNT1JZXG4iKTsKCQkJcmV0dXJuIEVSUk9SX09VVE9GTUVNT1JZOwoJCX0KCQltZW1zZXQoKmxwbHBQcmV2S2V5LCdcMCcsc2l6ZW9mKEtFWVNUUlVDVCkpOwogICAgICAgICAgICAgICAgVFJBQ0UocmVnLCJBZGRpbmcgJXNcbiIsIGRlYnVnc3RyX3cod3BzW2ldKSk7CgkJKCpscGxwUHJldktleSktPmtleW5hbWUJPSBzdHJkdXBXKHdwc1tpXSk7CgkJKCpscGxwUHJldktleSktPm5leHQJPSBOVUxMOwoJCSgqbHBscFByZXZLZXkpLT5uZXh0c3ViCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+dmFsdWVzCT0gTlVMTDsKCQkoKmxwbHBQcmV2S2V5KS0+bnJvZnZhbHVlcyA9IDA7CgkJKCpscGxwUHJldktleSktPmZsYWdzIAk9IFJFR19PUFRJT05fVEFJTlRFRDsKCQlpZiAobHBzekNsYXNzKQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBzdHJkdXBXKGxwc3pDbGFzcyk7CgkJZWxzZQoJCQkoKmxwbHBQcmV2S2V5KS0+Y2xhc3MgPSBOVUxMOwoJCWxwTmV4dEtleQk9ICpscGxwUHJldktleTsKCQlpKys7Cgl9CiAgICAgICAgY3VycmVudGhhbmRsZSArPSAyOwoJYWRkX2hhbmRsZShjdXJyZW50aGFuZGxlLGxwTmV4dEtleSxzYW1EZXNpcmVkKTsKCgkvKkZJWE1FOiBmbGFnIGhhbmRsaW5nIGNvcnJlY3Q/ICovCglscE5leHRLZXktPmZsYWdzPSBmZHdPcHRpb25zIHxSRUdfT1BUSU9OX1RBSU5URUQ7CglpZiAobHBzekNsYXNzKQoJCWxwTmV4dEtleS0+Y2xhc3MgPSBzdHJkdXBXKGxwc3pDbGFzcyk7CgllbHNlCgkJbHBOZXh0S2V5LT5jbGFzcyA9IE5VTEw7CgkqcmV0a2V5CQk9IGN1cnJlbnRoYW5kbGU7CiAgICAgICAgVFJBQ0UocmVnLCAiUmV0dXJuaW5nICV4XG4iLCBjdXJyZW50aGFuZGxlKTsKCWlmIChscERpc3BvcykKCQkqbHBEaXNwb3MJPSBSRUdfQ1JFQVRFRF9ORVdfS0VZOwoJRlJFRV9LRVlfUEFUSDsKCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXlFeDMyQSBbQURWQVBJMzIuMTMwXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleUV4MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGxwc3pDbGFzcywgRFdPUkQgZmR3T3B0aW9ucywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVHU0FNIHNhbURlc2lyZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBscFNlY0F0dHJpYnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQSEtFWSByZXRrZXksIExQRFdPUkQgbHBEaXNwb3MgKQp7CiAgICBMUFdTVFIgbHBzelN1YktleVcsIGxwc3pDbGFzc1c7CiAgICBEV09SRCAgcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlcywlbHgsJWx4LCVwLCVwLCVwKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelN1YktleSksCiAgICAgICAgICBkd1Jlc2VydmVkLGRlYnVnc3RyX2EobHBzekNsYXNzKSxmZHdPcHRpb25zLHNhbURlc2lyZWQsbHBTZWNBdHRyaWJzLAogICAgICAgICAgcmV0a2V5LGxwRGlzcG9zKTsKCiAgICBscHN6U3ViS2V5VyA9IGxwc3pTdWJLZXk/c3RyZHVwQTJXKGxwc3pTdWJLZXkpOk5VTEw7CiAgICBscHN6Q2xhc3NXID0gbHBzekNsYXNzP3N0cmR1cEEyVyhscHN6Q2xhc3MpOk5VTEw7CgogICAgcmV0ID0gUmVnQ3JlYXRlS2V5RXgzMlcoIGhrZXksIGxwc3pTdWJLZXlXLCBkd1Jlc2VydmVkLCBscHN6Q2xhc3NXLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZHdPcHRpb25zLCBzYW1EZXNpcmVkLCBscFNlY0F0dHJpYnMsIHJldGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBEaXNwb3MgKTsKCiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICBpZihscHN6Q2xhc3NXKSBmcmVlKGxwc3pDbGFzc1cpOwoKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0NyZWF0ZUtleTMyVyBbQURWQVBJMzIuMTMyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0NyZWF0ZUtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBEV09SRCBqdW5rOwogICAgTFBLRVlTVFJVQ1QJbHBOZXh0S2V5OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwKVxuIiwgaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLHJldGtleSk7CgogICAgLyogVGhpcyBjaGVjayBpcyBoZXJlIGJlY2F1c2UgdGhlIHJldHVybiB2YWx1ZSBpcyBkaWZmZXJlbnQgdGhhbiB0aGUKICAgICAgIG9uZSBmcm9tIHRoZSBFeCBmdW5jdGlvbnMgKi8KICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0JBREtFWTsKCiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5RXgzMlcoIGhrZXksIGxwc3pTdWJLZXksIDAsIE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX0FMTF9BQ0NFU1MsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldGtleSwgJmp1bmspOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXkzMkEgW0FEVkFQSTMyLjEyOV0KICovCkRXT1JEIFdJTkFQSSBSZWdDcmVhdGVLZXkzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBEV09SRCByZXQ7CiAgICBMUFdTVFIgbHBzelN1YktleVc7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXApXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSxyZXRrZXkpOwogICAgbHBzelN1YktleVcgPSBscHN6U3ViS2V5P3N0cmR1cEEyVyhscHN6U3ViS2V5KTpOVUxMOwogICAgcmV0ID0gUmVnQ3JlYXRlS2V5MzJXKCBoa2V5LCBscHN6U3ViS2V5VywgcmV0a2V5ICk7CiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDcmVhdGVLZXkxNiBbU0hFTEwuMl0gW0tFUk5FTC4yMThdCiAqLwpEV09SRCBXSU5BUEkgUmVnQ3JlYXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcywlcClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLHJldGtleSk7CiAgICByZXR1cm4gUmVnQ3JlYXRlS2V5MzJBKCBoa2V5LCBscHN6U3ViS2V5LCByZXRrZXkgKTsKfQoKCi8qIAogKiBRdWVyeSBWYWx1ZSBGdW5jdGlvbnMKICogV2luMzIgZGlmZmVycyBiZXR3ZWVuIGtleW5hbWVzIGFuZCB2YWx1ZW5hbWVzLiAKICogbXVsdGlwbGUgdmFsdWVzIG1heSBiZWxvbmcgdG8gb25lIGtleSwgdGhlIHNwZWNpYWwgdmFsdWUKICogd2l0aCBuYW1lIE5VTEwgaXMgdGhlIGRlZmF1bHQgdmFsdWUgdXNlZCBieSB0aGUgd2luMzEKICogY29tcGF0IGZ1bmN0aW9ucy4KICoKICogQ2FsbHBhdGg6CiAqIFJlZ1F1ZXJ5VmFsdWUxNiAtPiBSZWdRdWVyeVZhbHVlMzJBIC0+IFJlZ1F1ZXJ5VmFsdWVFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1F1ZXJ5VmFsdWUzMlcgLT4gUmVnUXVlcnlWYWx1ZUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZUV4MzJXIFtBRFZBUEkzMi4xNThdCiAqIFJldHJpZXZlcyB0eXBlIGFuZCBkYXRhIGZvciBhIHNwZWNpZmllZCBuYW1lIGFzc29jaWF0ZWQgd2l0aCBhbiBvcGVuIGtleQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICBbSV0gICBIYW5kbGUgb2Yga2V5IHRvIHF1ZXJ5CiAqICAgIGxwVmFsdWVOYW1lICAgW0ldICAgTmFtZSBvZiB2YWx1ZSB0byBxdWVyeQogKiAgICBscGR3UmVzZXJ2ZWQgIFtJXSAgIFJlc2VydmVkIC0gbXVzdCBiZSBOVUxMCiAqICAgIGxwZHdUeXBlICAgICAgW09dICAgQWRkcmVzcyBvZiBidWZmZXIgZm9yIHZhbHVlIHR5cGUuICBJZiBOVUxMLCB0aGUgdHlwZQogKiAgICAgICAgICAgICAgICAgICAgICAgIGlzIG5vdCByZXF1aXJlZC4KICogICAgbHBiRGF0YSAgICAgICBbT10gICBBZGRyZXNzIG9mIGRhdGEgYnVmZmVyLiAgSWYgTlVMTCwgdGhlIGFjdHVhbCBkYXRhIGlzCiAqICAgICAgICAgICAgICAgICAgICAgICAgbm90IHJlcXVpcmVkLgogKiAgICBscGNiRGF0YSAgICAgIFtJL09dIEFkZHJlc3Mgb2YgZGF0YSBidWZmZXIgc2l6ZQogKgogKiBSRVRVUk5TIAogKiAgICBFUlJPUl9TVUNDRVNTOiAgIFN1Y2Nlc3MKICogICAgRVJST1JfTU9SRV9EQVRBOiBUaGUgc3BlY2lmaWVkIGJ1ZmZlciBpcyBub3QgYmlnIGVub3VnaCB0byBob2xkIHRoZSBkYXRhCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZUV4MzJXKCBIS0VZIGhrZXksIExQV1NUUiBscFZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3UmVzZXJ2ZWQsIExQRFdPUkQgbHBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBscGJEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglpbnQJCWk7CgogICAgVFJBQ0UocmVnLCIoMHgleCwlcywlcCwlcCwlcCwlbGQpXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwVmFsdWVOYW1lKSwKICAgICAgICAgIGxwZHdSZXNlcnZlZCwgbHBkd1R5cGUsIGxwYkRhdGEsIGxwY2JEYXRhPypscGNiRGF0YTowKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgLyogUmVzZXJ2ZWQgbXVzdCBiZSBOVUxMIChhdCBsZWFzdCBmb3Igbm93KSAqLwogICAgaWYgKGxwZHdSZXNlcnZlZCkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgLyogQW4gZW1wdHkgbmFtZSBzdHJpbmcgaXMgZXF1aXZhbGVudCB0byBOVUxMICovCiAgICBpZiAobHBWYWx1ZU5hbWUgJiYgISpscFZhbHVlTmFtZSkKICAgICAgICBscFZhbHVlTmFtZSA9IE5VTEw7CgoJaWYgKGxwVmFsdWVOYW1lPT1OVUxMKSB7CiAgICAgICAgICAgICAgICAvKiBVc2Uga2V5J3MgdW5uYW1lZCBvciBkZWZhdWx0IHZhbHVlLCBpZiBhbnkgKi8KCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIFNlYXJjaCBmb3IgdGhlIGtleSBuYW1lICovCgkJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspCgkJCWlmICgJbHBrZXktPnZhbHVlc1tpXS5uYW1lICYmCgkJCQkhbHN0cmNtcGkzMlcobHBWYWx1ZU5hbWUsbHBrZXktPnZhbHVlc1tpXS5uYW1lKQoJCQkpCgkJCQlicmVhazsKCX0KCglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKICAgICAgICAgICAgICAgIFRSQUNFKHJlZywiS2V5IG5vdCBmb3VuZFxuIik7CgkJaWYgKGxwVmFsdWVOYW1lPT1OVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEVtcHR5IGtleW5hbWUgbm90IGZvdW5kICovCgkJCWlmIChscGJEYXRhKSB7CgkJCQkqKFdDSEFSKilscGJEYXRhID0gMDsKCQkJCSpscGNiRGF0YQk9IDI7CgkJCX0KCQkJaWYgKGxwZHdUeXBlKQoJCQkJKmxwZHdUeXBlCT0gUkVHX1NaOwogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRShyZWcsICJSZXR1cm5pbmcgYW4gZW1wdHkgc3RyaW5nXG4iKTsKCQkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CgkJfQoJCXJldHVybiBFUlJPUl9CQURfUEFUSE5BTUU7Cgl9CgogICAgaWYgKGxwZHdUeXBlKQogICAgICAgICpscGR3VHlwZSA9IGxwa2V5LT52YWx1ZXNbaV0udHlwZTsKCiAgICBpZiAobHBiRGF0YT09TlVMTCkgewogICAgICAgIC8qIERhdGEgaXMgbm90IHJlcXVpcmVkICovCiAgICAgICAgaWYgKGxwY2JEYXRhPT1OVUxMKSB7CiAgICAgICAgICAgIC8qIEFuZCBkYXRhIHNpemUgaXMgbm90IHJlcXVpcmVkICovCiAgICAgICAgICAgIC8qIFNvIGFsbCB0aGF0IGlzIHJldHVybmVkIGlzIHRoZSB0eXBlIChzZXQgYWJvdmUpICovCiAgICAgICAgICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwogICAgICAgIH0KICAgICAgICAvKiBTZXQgdGhlIHNpemUgcmVxdWlyZWQgYW5kIHJldHVybiBzdWNjZXNzICovCiAgICAgICAgKmxwY2JEYXRhID0gbHBrZXktPnZhbHVlc1tpXS5sZW47CiAgICAgICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CiAgICB9CgogICAgaWYgKCpscGNiRGF0YTxscGtleS0+dmFsdWVzW2ldLmxlbikgewogICAgICAgIC8qIFRoZSBzaXplIHdhcyBzcGVjaWZpZWQsIGJ1dCB0aGUgZGF0YSBpcyB0b28gYmlnIGZvciBpdCAqLwogICAgICAgIC8qIEluc3RlYWQgb2Ygc2V0dGluZyBpdCB0byBOVUxMLCBmaWxsIGluIHdpdGggYXMgbXVjaCBhcyBwb3NzaWJsZSAqLwogICAgICAgIC8qIEJ1dCB0aGUgZG9jcyBkbyBub3Qgc3BlY2lmeSBob3cgdG8gaGFuZGxlIHRoZSBscGJEYXRhIGhlcmUgKi8KICAgICAgICAvKiAqKFdDSEFSKilscGJEYXRhPSAwOyAqLwogICAgICAgIG1lbWNweShscGJEYXRhLGxwa2V5LT52YWx1ZXNbaV0uZGF0YSwqbHBjYkRhdGEpOwogICAgICAgICpscGNiRGF0YSA9IGxwa2V5LT52YWx1ZXNbaV0ubGVuOwogICAgICAgIHJldHVybiBFUlJPUl9NT1JFX0RBVEE7CiAgICB9CgogICAgbWVtY3B5KGxwYkRhdGEsbHBrZXktPnZhbHVlc1tpXS5kYXRhLGxwa2V5LT52YWx1ZXNbaV0ubGVuKTsKCiAgICAvKiBFeHRyYSBkZWJ1Z2dpbmcgb3V0cHV0ICovCiAgICBpZiAobHBkd1R5cGUpIHsKICAgICAgICBzd2l0Y2goKmxwZHdUeXBlKXsKICAgICAgICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsIiBEYXRhKHN6KT0lc1xuIixkZWJ1Z3N0cl93KChMUENXU1RSKWxwYkRhdGEpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFR19EV09SRDoKICAgICAgICAgICAgICAgIFRSQUNFKHJlZywiIERhdGEoZHdvcmQpPSVseFxuIiwgKERXT1JEKSpscGJEYXRhKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFR19CSU5BUlk6CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsIiBEYXRhKGJpbmFyeSlcbiIpOwogICAgICAgICAgICAgICAgLyogSXMgdGhlcmUgYSB3YXkgb2YgcHJpbnRpbmcgdGhpcyBpbiByZWFkYWJsZSBmb3JtPyAqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBUUkFDRShyZWcsICJVbmtub3duIGRhdGEgdHlwZSAlbGRcbiIsICpscGR3VHlwZSk7CiAgICAgICAgfSAvKiBzd2l0Y2ggKi8KICAgIH0gLyogaWYgKi8KCiAgICAvKiBTZXQgdGhlIGFjdHVhbCBzaXplICovCiAgICAqbHBjYkRhdGEgPSBscGtleS0+dmFsdWVzW2ldLmxlbjsKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlMzJXIFtBRFZBUEkzMi4xNTldCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlWYWx1ZTMyVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzelN1YktleSwgTFBXU1RSIGxwc3pEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKCUhLRVkJeGhrZXk7CglEV09SRAlyZXQsbHBkd1R5cGU7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksbHBzekRhdGEsCiAgICAgICAgICBscGNiRGF0YT8qbHBjYkRhdGE6MCk7CgogICAgLyogT25seSBvcGVuIHN1YmtleSwgaWYgd2UgcmVhbGx5IGRvIGRlc2NlbmQgKi8KICAgIGlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CiAgICAgICAgcmV0ID0gUmVnT3BlbktleTMyVyggaGtleSwgbHBzelN1YktleSwgJnhoa2V5ICk7CiAgICAgICAgaWYgKHJldCAhPSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIFdBUk4ocmVnLCAiQ291bGQgbm90IG9wZW4gJXNcbiIsIGRlYnVnc3RyX3cobHBzelN1YktleSkpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgIH0gZWxzZQogICAgICAgIHhoa2V5ID0gaGtleTsKCiAgICBscGR3VHlwZSA9IFJFR19TWjsKICAgIHJldCA9IFJlZ1F1ZXJ5VmFsdWVFeDMyVyggeGhrZXksIE5VTEwsIE5VTEwsICZscGR3VHlwZSwgKExQQllURSlscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBjYkRhdGEgKTsKICAgIGlmICh4aGtleSAhPSBoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KHhoa2V5KTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWVFeDMyQSBbQURWQVBJMzIuMTU3XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWVFeDMyQSggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGxwYkRhdGEsIExQRFdPUkQgbHBjYkRhdGEgKQp7CglMUFdTVFIJbHBzelZhbHVlTmFtZVc7CglMUEJZVEUJYnVmOwoJRFdPUkQJcmV0LG15eGxlbjsKCURXT1JECSpteWxlbjsKCURXT1JECXR5cGU7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIiwgaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgbHBkd1Jlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIGxwc3pWYWx1ZU5hbWVXID0gbHBzelZhbHVlTmFtZT9zdHJkdXBBMlcobHBzelZhbHVlTmFtZSk6TlVMTDsKCiAgICAvKiBXaHkgd291bGQgdGhpcyBiZSBzZXQ/IEl0IGlzIGp1c3QgYW4gb3V0cHV0ICovCiAgICBpZiAobHBkd1R5cGUpCiAgICAgICAgdHlwZSA9ICpscGR3VHlwZTsKCglpZiAobHBiRGF0YSkgewoJCW15eGxlbiAgPSAwOwoJCW15bGVuCT0gJm15eGxlbjsKCQlidWYJPSB4bWFsbG9jKDQpOwogICAgICAgICAgICAgICAgLyogT25seSBnZXQgdGhlIHNpemUgZm9yIG5vdyAqLwoJCXJldCA9IFJlZ1F1ZXJ5VmFsdWVFeDMyVyggaGtleSwgbHBzelZhbHVlTmFtZVcsIGxwZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnR5cGUsIGJ1ZiwgbXlsZW4gKTsKCQlmcmVlKGJ1Zik7CgkJaWYgKHJldD09RVJST1JfTU9SRV9EQVRBKSB7CgkJCWJ1Zgk9IChMUEJZVEUpeG1hbGxvYygqbXlsZW4pOwoJCX0gZWxzZSB7CgkJCWJ1Zgk9IChMUEJZVEUpeG1hbGxvYygyKigqbHBjYkRhdGEpKTsKCQkJbXl4bGVuICA9IDIqKCpscGNiRGF0YSk7CgkJfQoJfSBlbHNlIHsKCQkvKiBEYXRhIGlzIG5vdCByZXF1aXJlZCAqLwoJCWJ1Zj1OVUxMOwoJCWlmIChscGNiRGF0YSkgewoJCQlteXhsZW4JPSAqbHBjYkRhdGEqMjsKCQkJbXlsZW4JPSAmbXl4bGVuOwoJCX0gZWxzZQoJCQlteWxlbgk9IE5VTEw7Cgl9CgogICAgICAgIC8qIE5vdyBnZXQgdGhlIGRhdGEgKi8KCXJldCA9IFJlZ1F1ZXJ5VmFsdWVFeDMyVyggaGtleSwgbHBzelZhbHVlTmFtZVcsIGxwZHdSZXNlcnZlZCwgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYsIG15bGVuICk7CglpZiAobHBkd1R5cGUpIAoJCSpscGR3VHlwZT10eXBlOwoKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MpIHsKCQlpZiAoYnVmKSB7CgkJCWlmIChVTklDT05WTUFTSyAmICgxPDwodHlwZSkpKSB7CgkJCQkvKiBjb252ZXJ0IFVOSUNPREUgdG8gQVNDSUkgKi8KCQkJCWxzdHJjcHlXdG9BKGxwYkRhdGEsKExQV1NUUilidWYpOwoJCQkJKmxwY2JEYXRhCT0gbXl4bGVuLzI7CgkJCX0gZWxzZSB7CgkJCQlpZiAobXl4bGVuPipscGNiRGF0YSkKCQkJCQlyZXQJPSBFUlJPUl9NT1JFX0RBVEE7CgkJCQllbHNlCgkJCQkJbWVtY3B5KGxwYkRhdGEsYnVmLG15eGxlbik7CgoJCQkJKmxwY2JEYXRhCT0gbXl4bGVuOwoJCQl9CgkJfSBlbHNlIHsKCQkJaWYgKChVTklDT05WTUFTSyAmICgxPDwodHlwZSkpKSAmJiBscGNiRGF0YSkKCQkJCSpscGNiRGF0YQk9IG15eGxlbi8yOwoJCX0KCX0gZWxzZSB7CgkJaWYgKChVTklDT05WTUFTSyAmICgxPDwodHlwZSkpKSAmJiBscGNiRGF0YSkKCQkJKmxwY2JEYXRhCT0gbXl4bGVuLzI7Cgl9CgogICAgaWYoYnVmKSBmcmVlKGJ1Zik7CiAgICBpZihscHN6VmFsdWVOYW1lVykgZnJlZShscHN6VmFsdWVOYW1lVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeVZhbHVlRXgxNiBbS0VSTkVMLjIyNV0KICovCkRXT1JEIFdJTkFQSSBSZWdRdWVyeVZhbHVlRXgxNiggSEtFWSBoa2V5LCBMUFNUUiBscHN6VmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1Jlc2VydmVkLCBMUERXT1JEIGxwZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBscGJEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXAsJXAsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlTmFtZSksCiAgICAgICAgICBscGR3UmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YT8qbHBjYkRhdGE6MCk7CiAgICByZXR1cm4gUmVnUXVlcnlWYWx1ZUV4MzJBKCBoa2V5LCBscHN6VmFsdWVOYW1lLCBscGR3UmVzZXJ2ZWQsIGxwZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBiRGF0YSwgbHBjYkRhdGEgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlWYWx1ZTMyQSBbQURWQVBJMzIuMTU2XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUzMkEoIEhLRVkgaGtleSwgTFBTVFIgbHBzelN1YktleSwgTFBTVFIgbHBzekRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewogICAgSEtFWSB4aGtleTsKICAgIERXT1JEIHJldCwgZHdUeXBlOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGxwc3pEYXRhLAogICAgICAgICAgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIGlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CiAgICAgICAgcmV0ID0gUmVnT3BlbktleTE2KCBoa2V5LCBscHN6U3ViS2V5LCAmeGhrZXkgKTsKICAgICAgICBpZiggcmV0ICE9IEVSUk9SX1NVQ0NFU1MgKQogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgfSBlbHNlCiAgICAgICAgeGhrZXkgPSBoa2V5OwoKICAgIGR3VHlwZSA9IFJFR19TWjsKICAgIHJldCA9IFJlZ1F1ZXJ5VmFsdWVFeDMyQSggeGhrZXksIE5VTEwsTlVMTCwgJmR3VHlwZSwgKExQQllURSlscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBjYkRhdGEgKTsKICAgIGlmKCB4aGtleSAhPSBoa2V5ICkKICAgICAgICBSZWdDbG9zZUtleSggeGhrZXkgKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1F1ZXJ5VmFsdWUxNiBbU0hFTEwuNl0gW0tFUk5FTC4yMjRdCiAqCiAqIE5PVEVTCiAqICAgIElzIHRoaXMgSEFDSyBzdGlsbCBhcHBsaWNhYmxlPwogKgogKiBIQUNLCiAqICAgIFRoZSAxNmJpdCBSZWdRdWVyeVZhbHVlIGRvZXNuJ3QgaGFuZGxlIHNlbGVjdG9yYmxvY2tzIGFueXdheSwgc28gd2UganVzdAogKiAgICBtYXNrIG91dCB0aGUgaGlnaCAxNiBiaXQuICBUaGlzIChub3Qgc28gbXVjaCBpbmNpZGVudGx5KSBob3BlZnVsbHkgZml4ZXMKICogICAgQWxkdXMgRkg0KQogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5VmFsdWUxNiggSEtFWSBoa2V5LCBMUFNUUiBscHN6U3ViS2V5LCBMUFNUUiBscHN6RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiRGF0YSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVwLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGxwc3pEYXRhLAogICAgICAgICAgbHBjYkRhdGE/KmxwY2JEYXRhOjApOwoKICAgIGlmIChscGNiRGF0YSkKICAgICAgICAqbHBjYkRhdGEgJj0gMHhGRkZGOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWUzMkEoaGtleSxscHN6U3ViS2V5LGxwc3pEYXRhLGxwY2JEYXRhKTsKfQoKCi8qCiAqIFNldHRpbmcgdmFsdWVzIG9mIFJlZ2lzdHJ5IGtleXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ1NldFZhbHVlMTYgLT4gUmVnU2V0VmFsdWUzMkEgLT4gUmVnU2V0VmFsdWVFeDMyQSBcCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnU2V0VmFsdWUzMlcgICAtPiBSZWdTZXRWYWx1ZUV4MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWVFeDMyVyBbQURWQVBJMzIuMTcwXQogKiBTZXRzIHRoZSBkYXRhIGFuZCB0eXBlIG9mIGEgdmFsdWUgdW5kZXIgYSByZWdpc3RlciBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgW0ldIEhhbmRsZSBvZiBrZXkgdG8gc2V0IHZhbHVlIGZvcgogKiAgICBscHN6VmFsdWVOYW1lIFtJXSBOYW1lIG9mIHZhbHVlIHRvIHNldAogKiAgICBkd1Jlc2VydmVkICAgIFtJXSBSZXNlcnZlZCAtIG11c3QgYmUgemVybwogKiAgICBkd1R5cGUgICAgICAgIFtJXSBGbGFnIGZvciB2YWx1ZSB0eXBlCiAqICAgIGxwYkRhdGEgICAgICAgW0ldIEFkZHJlc3Mgb2YgdmFsdWUgZGF0YQogKiAgICBjYkRhdGEgICAgICAgIFtJXSBTaXplIG9mIHZhbHVlIGRhdGEKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MzJXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6VmFsdWVOYW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3UmVzZXJ2ZWQsIERXT1JEIGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBjYkRhdGEpCnsKICAgIExQS0VZU1RSVUNUIGxwa2V5OwogICAgaW50IGk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwc3pWYWx1ZU5hbWUpLAogICAgICAgICAgZHdSZXNlcnZlZCwgZHdUeXBlLCBscGJEYXRhLCBjYkRhdGEpOwoKICAgIHN3aXRjaCAoZHdUeXBlKSB7CiAgICAgICAgY2FzZSBSRUdfU1o6CiAgICAgICAgICAgIFRSQUNFKHJlZywiIERhdGEoc3opPSVzXG4iLCBkZWJ1Z3N0cl93KChMUENXU1RSKWxwYkRhdGEpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSRUdfQklOQVJZOgogICAgICAgICAgICBUUkFDRShyZWcsIiBEYXRhKGJpbmFyeSlcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJFR19EV09SRDoKICAgICAgICAgICAgVFJBQ0UocmVnLCIgRGF0YShkd29yZCk9JWx4XG4iLCAoRFdPUkQpbHBiRGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFRSQUNFKHJlZywiVW5rbm93biB0eXBlOiAlbGRcbiIsIGR3VHlwZSk7CiAgICB9CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJbHBrZXktPmZsYWdzIHw9IFJFR19PUFRJT05fVEFJTlRFRDsKCglpZiAobHBzelZhbHVlTmFtZT09TlVMTCkgewogICAgICAgICAgICAgLyogU2V0cyB0eXBlIGFuZCBuYW1lIGZvciBrZXkncyB1bm5hbWVkIG9yIGRlZmF1bHQgdmFsdWUgKi8KCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJfSBlbHNlIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKAlscGtleS0+dmFsdWVzW2ldLm5hbWUgJiYKCQkJCSFsc3RyY21waTMyVyhscHN6VmFsdWVOYW1lLGxwa2V5LT52YWx1ZXNbaV0ubmFtZSkKCQkJKQoJCQkJYnJlYWs7Cgl9CglpZiAoaT09bHBrZXktPm5yb2Z2YWx1ZXMpIHsKCQlscGtleS0+dmFsdWVzID0gKExQS0VZVkFMVUUpeHJlYWxsb2MoCgkJCQkJbHBrZXktPnZhbHVlcywKCQkJCQkobHBrZXktPm5yb2Z2YWx1ZXMrMSkqc2l6ZW9mKEtFWVZBTFVFKQoJCQkJKTsKCQlscGtleS0+bnJvZnZhbHVlcysrOwoJCW1lbXNldChscGtleS0+dmFsdWVzK2ksJ1wwJyxzaXplb2YoS0VZVkFMVUUpKTsKCX0KCWlmIChscGtleS0+dmFsdWVzW2ldLm5hbWU9PU5VTEwpIHsKCQlpZiAobHBzelZhbHVlTmFtZSkKCQkJbHBrZXktPnZhbHVlc1tpXS5uYW1lID0gc3RyZHVwVyhscHN6VmFsdWVOYW1lKTsKCQllbHNlCgkJCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSA9IE5VTEw7Cgl9CglscGtleS0+dmFsdWVzW2ldLmxlbgk9IGNiRGF0YTsKCWxwa2V5LT52YWx1ZXNbaV0udHlwZQk9IGR3VHlwZTsKCWlmIChscGtleS0+dmFsdWVzW2ldLmRhdGEgIT1OVUxMKQoJCWZyZWUobHBrZXktPnZhbHVlc1tpXS5kYXRhKTsKCWxwa2V5LT52YWx1ZXNbaV0uZGF0YQk9IChMUEJZVEUpeG1hbGxvYyhjYkRhdGEpOwoJbHBrZXktPnZhbHVlc1tpXS5sYXN0bW9kaWZpZWQgPSB0aW1lKE5VTEwpOwoJbWVtY3B5KGxwa2V5LT52YWx1ZXNbaV0uZGF0YSxscGJEYXRhLGNiRGF0YSk7CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2V0VmFsdWVFeDMyQSBbQURWQVBJMzIuMTY5XQogKgogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlRXgzMkEoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3UmVzZXJ2ZWQsIERXT1JEIGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBjYkRhdGEgKQp7CglMUEJZVEUJYnVmOwoJTFBXU1RSCWxwc3pWYWx1ZU5hbWVXOwoJRFdPUkQJcmV0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVzLCVsZCwlbGQsJXAsJWxkKVxuIixoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlTmFtZSksCiAgICAgICAgICBkd1Jlc2VydmVkLGR3VHlwZSxscGJEYXRhLGNiRGF0YSk7CgoJaWYgKCgxPDxkd1R5cGUpICYgVU5JQ09OVk1BU0spIHsKCQlidWY9KExQQllURSlzdHJkdXBBMlcobHBiRGF0YSk7CgkJY2JEYXRhPTIqc3RybGVuKGxwYkRhdGEpKzI7Cgl9IGVsc2UKCQlidWY9bHBiRGF0YTsKCWlmIChscHN6VmFsdWVOYW1lKQoJCWxwc3pWYWx1ZU5hbWVXID0gc3RyZHVwQTJXKGxwc3pWYWx1ZU5hbWUpOwoJZWxzZQoJCWxwc3pWYWx1ZU5hbWVXID0gTlVMTDsKCXJldD1SZWdTZXRWYWx1ZUV4MzJXKGhrZXksbHBzelZhbHVlTmFtZVcsZHdSZXNlcnZlZCxkd1R5cGUsYnVmLGNiRGF0YSk7CglpZiAobHBzelZhbHVlTmFtZVcpCgkJZnJlZShscHN6VmFsdWVOYW1lVyk7CglpZiAoYnVmIT1scGJEYXRhKQoJCWZyZWUoYnVmKTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlRXgxNiBbS0VSTkVMLjIyNl0KICovCkRXT1JEIFdJTkFQSSBSZWdTZXRWYWx1ZUV4MTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlTmFtZSwgRFdPUkQgZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdUeXBlLCBMUEJZVEUgbHBiRGF0YSwgRFdPUkQgY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVsZCwlcCwlbGQpXG4iLGhrZXksZGVidWdzdHJfYShscHN6VmFsdWVOYW1lKSwKICAgICAgICAgIGR3UmVzZXJ2ZWQsZHdUeXBlLGxwYkRhdGEsY2JEYXRhKTsKICAgIHJldHVybiBSZWdTZXRWYWx1ZUV4MzJBKCBoa2V5LCBscHN6VmFsdWVOYW1lLCBkd1Jlc2VydmVkLCBkd1R5cGUsIGxwYkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2JEYXRhICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMzJXCVtBRFZBUEkzMi4xNzFdCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBEV09SRCBkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBscHN6RGF0YSwgRFdPUkQgY2JEYXRhICkKewoJSEtFWQl4aGtleTsKCURXT1JECXJldDsKCglUUkFDRShyZWcsIigleCwlcywlbGQsJXMsJWxkKVxuIiwKCQloa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSksZHdUeXBlLGRlYnVnc3RyX3cobHBzekRhdGEpLGNiRGF0YQoJKTsKCWlmIChscHN6U3ViS2V5ICYmICpscHN6U3ViS2V5KSB7CgkJcmV0PVJlZ0NyZWF0ZUtleTMyVyhoa2V5LGxwc3pTdWJLZXksJnhoa2V5KTsKCQlpZiAocmV0IT1FUlJPUl9TVUNDRVNTKQoJCQlyZXR1cm4gcmV0OwoJfSBlbHNlCgkJeGhrZXk9aGtleTsKCWlmIChkd1R5cGUhPVJFR19TWikgewoJCVRSQUNFKHJlZywiZHdUeXBlPSVsZCAtIENoYW5naW5nIHRvIFJFR19TWlxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT0yKmxzdHJsZW4zMlcobHBzekRhdGEpKzIpIHsKCQlUUkFDRShyZWcsIkxlbj0lbGQgIT0gc3RybGVuKCVzKSsxPSVkIVxuIiwKCQkJY2JEYXRhLGRlYnVnc3RyX3cobHBzekRhdGEpLDIqbHN0cmxlbjMyVyhscHN6RGF0YSkrMgoJCSk7CgkJY2JEYXRhPTIqbHN0cmxlbjMyVyhscHN6RGF0YSkrMjsKCX0KCXJldD1SZWdTZXRWYWx1ZUV4MzJXKHhoa2V5LE5VTEwsMCxkd1R5cGUsKExQQllURSlscHN6RGF0YSxjYkRhdGEpOwoJaWYgKGhrZXkhPXhoa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMzJBIFtBRFZBUEkzMi4xNjhdCiAqCiAqLwpEV09SRCBXSU5BUEkgUmVnU2V0VmFsdWUzMkEoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JEIGR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgbHBzekRhdGEsIERXT1JEIGNiRGF0YSApCnsKCURXT1JECXJldDsKCUhLRVkJeGhrZXk7CgoJVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEpOwoJaWYgKGxwc3pTdWJLZXkgJiYgKmxwc3pTdWJLZXkpIHsKCQlyZXQ9UmVnQ3JlYXRlS2V5MTYoaGtleSxscHN6U3ViS2V5LCZ4aGtleSk7CgkJaWYgKHJldCE9RVJST1JfU1VDQ0VTUykKCQkJcmV0dXJuIHJldDsKCX0gZWxzZQoJCXhoa2V5PWhrZXk7CgoJaWYgKGR3VHlwZSE9UkVHX1NaKSB7CgkJVFJBQ0UocmVnLCJkd1R5cGU9JWxkIVxuIixkd1R5cGUpOwoJCWR3VHlwZT1SRUdfU1o7Cgl9CglpZiAoY2JEYXRhIT1zdHJsZW4obHBzekRhdGEpKzEpCgkJY2JEYXRhPXN0cmxlbihscHN6RGF0YSkrMTsKCXJldD1SZWdTZXRWYWx1ZUV4MzJBKHhoa2V5LE5VTEwsMCxkd1R5cGUsKExQQllURSlscHN6RGF0YSxjYkRhdGEpOwoJaWYgKHhoa2V5IT1oa2V5KQoJCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1NldFZhbHVlMTYgW0tFUk5FTC4yMjFdIFtTSEVMTC41XQogKi8KRFdPUkQgV0lOQVBJIFJlZ1NldFZhbHVlMTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXksIERXT1JECWR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscHN6RGF0YSwgRFdPUkQgY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMsJWxkLCVzLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpLGR3VHlwZSwKICAgICAgICAgIGRlYnVnc3RyX2EobHBzekRhdGEpLGNiRGF0YSk7CiAgICByZXR1cm4gUmVnU2V0VmFsdWUzMkEoaGtleSxscHN6U3ViS2V5LGR3VHlwZSxscHN6RGF0YSxjYkRhdGEpOwp9CgoKLyogCiAqIEtleSBFbnVtZXJhdGlvbgogKgogKiBDYWxscGF0aDoKICogUmVnRW51bUtleTE2IC0+IFJlZ0VudW1LZXkzMkEgLT4gUmVnRW51bUtleUV4MzJBIFwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnRW51bUtleTMyVyAgIC0+IFJlZ0VudW1LZXlFeDMyVwogKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXlFeDMyVyBbQURWQVBJMzIuMTM5XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgIFtJXSBIYW5kbGUgdG8ga2V5IHRvIGVudW1lcmF0ZQogKiAgICBpU3ViS2V5ICAgICAgW0ldIEluZGV4IG9mIHN1YmtleSB0byBlbnVtZXJhdGUKICogICAgbHBzek5hbWUgICAgIFtPXSBCdWZmZXIgZm9yIHN1YmtleSBuYW1lCiAqICAgIGxwY2NoTmFtZSAgICBbT10gU2l6ZSBvZiBzdWJrZXkgYnVmZmVyCiAqICAgIGxwZHdSZXNlcnZlZCBbSV0gUmVzZXJ2ZWQKICogICAgbHBzekNsYXNzICAgIFtPXSBCdWZmZXIgZm9yIGNsYXNzIHN0cmluZwogKiAgICBscGNjaENsYXNzICAgW09dIFNpemUgb2YgY2xhc3MgYnVmZmVyCiAqICAgIGZ0ICAgICAgICAgICBbT10gVGltZSBrZXkgbGFzdCB3cml0dGVuIHRvCiAqLwpEV09SRCBXSU5BUEkgUmVnRW51bUtleUV4MzJXKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQV1NUUiBscHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaE5hbWUsIExQRFdPUkQgbHBkd1Jlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgbHBzekNsYXNzLCBMUERXT1JEIGxwY2NoQ2xhc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFVElNRSAqZnQgKQp7CglMUEtFWVNUUlVDVAlscGtleSxscHhrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZCwlcCwlcCwlcCwlcClcbiIsaGtleSxpU3Via2V5LGxwc3pOYW1lLAogICAgICAgICAgKmxwY2NoTmFtZSxscGR3UmVzZXJ2ZWQsbHBzekNsYXNzLGxwY2NoQ2xhc3MsZnQpOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKCWlmICghbHBrZXktPm5leHRzdWIpCgkJcmV0dXJuIEVSUk9SX05PX01PUkVfSVRFTVM7CglscHhrZXk9bHBrZXktPm5leHRzdWI7CgogICAgLyogVHJhdmVyc2UgdGhlIHN1YmtleXMgKi8KCXdoaWxlIChpU3Via2V5ICYmIGxweGtleSkgewoJCWlTdWJrZXktLTsKCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoKCWlmIChpU3Via2V5IHx8ICFscHhrZXkpCgkJcmV0dXJuIEVSUk9SX05PX01PUkVfSVRFTVM7CglpZiAoMipsc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSkrMj4qbHBjY2hOYW1lKQoJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgltZW1jcHkobHBzek5hbWUsbHB4a2V5LT5rZXluYW1lLGxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKSoyKzIpOwoKICAgICAgICBpZiAoKmxwY2NoTmFtZSkKICAgICAgICAgICAgKmxwY2NoTmFtZSA9IGxzdHJsZW4zMlcobHBzek5hbWUpOwoKCWlmIChscHN6Q2xhc3MpIHsKCQkvKiBGSVhNRTogd2hhdCBzaG91bGQgd2Ugd3JpdGUgaW50byBpdD8gKi8KCQkqbHBzekNsYXNzCT0gMDsKCQkqbHBjY2hDbGFzcwk9IDI7Cgl9CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleTMyVyBbQURWQVBJMzIuMTQwXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1LZXkzMlcoIEhLRVkgaGtleSwgRFdPUkQgaVN1YmtleSwgTFBXU1RSIGxwc3pOYW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGxwY2NoTmFtZSApCnsKICAgIEZJTEVUSU1FCWZ0OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwogICAgcmV0dXJuIFJlZ0VudW1LZXlFeDMyVyhoa2V5LGlTdWJrZXksbHBzek5hbWUsJmxwY2NoTmFtZSxOVUxMLE5VTEwsTlVMTCwmZnQpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtS2V5RXgzMkEgW0FEVkFQSTMyLjEzOF0KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5RXgzMkEoIEhLRVkgaGtleSwgRFdPUkQgaVN1YmtleSwgTFBTVFIgbHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hOYW1lLCBMUERXT1JEIGxwZHdSZXNlcnZlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGxwc3pDbGFzcywgTFBEV09SRCBscGNjaENsYXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRVRJTUUgKmZ0ICkKewoJRFdPUkQJcmV0LGxwY2NoTmFtZVcsbHBjY2hDbGFzc1c7CglMUFdTVFIJbHBzek5hbWVXLGxwc3pDbGFzc1c7CgoKCVRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQsJXAsJXAsJXAsJXApXG4iLAoJCWhrZXksaVN1YmtleSxscHN6TmFtZSwqbHBjY2hOYW1lLGxwZHdSZXNlcnZlZCxscHN6Q2xhc3MsbHBjY2hDbGFzcyxmdAoJKTsKCWlmIChscHN6TmFtZSkgewoJCWxwc3pOYW1lVwk9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hOYW1lKjIpOwoJCWxwY2NoTmFtZVcJPSAqbHBjY2hOYW1lKjI7Cgl9IGVsc2UgewoJCWxwc3pOYW1lVwk9IE5VTEw7CgkJbHBjY2hOYW1lVyAJPSAwOwoJfQoJaWYgKGxwc3pDbGFzcykgewoJCWxwc3pDbGFzc1cJCT0gKExQV1NUUil4bWFsbG9jKCpscGNjaENsYXNzKjIpOwoJCWxwY2NoQ2xhc3NXCT0gKmxwY2NoQ2xhc3MqMjsKCX0gZWxzZSB7CgkJbHBzekNsYXNzVwk9MDsKCQlscGNjaENsYXNzVz0wOwoJfQoJcmV0PVJlZ0VudW1LZXlFeDMyVygKCQloa2V5LAoJCWlTdWJrZXksCgkJbHBzek5hbWVXLAoJCSZscGNjaE5hbWVXLAoJCWxwZHdSZXNlcnZlZCwKCQlscHN6Q2xhc3NXLAoJCSZscGNjaENsYXNzVywKCQlmdAoJKTsKCWlmIChyZXQ9PUVSUk9SX1NVQ0NFU1MpIHsKCQlsc3RyY3B5V3RvQShscHN6TmFtZSxscHN6TmFtZVcpOwoJCSpscGNjaE5hbWU9c3RybGVuKGxwc3pOYW1lKTsKCQlpZiAobHBzekNsYXNzVykgewoJCQlsc3RyY3B5V3RvQShscHN6Q2xhc3MsbHBzekNsYXNzVyk7CgkJCSpscGNjaENsYXNzPXN0cmxlbihscHN6Q2xhc3MpOwoJCX0KCX0KCWlmIChscHN6TmFtZVcpCgkJZnJlZShscHN6TmFtZVcpOwoJaWYgKGxwc3pDbGFzc1cpCgkJZnJlZShscHN6Q2xhc3NXKTsKCXJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1LZXkzMkEgW0FEVkFQSTMyLjEzN10KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MzJBKCBIS0VZIGhrZXksIERXT1JEIGlTdWJrZXksIExQU1RSIGxwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbHBjY2hOYW1lICkKewogICAgRklMRVRJTUUJZnQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVsZClcbiIsaGtleSxpU3Via2V5LGxwc3pOYW1lLGxwY2NoTmFtZSk7CiAgICByZXR1cm4gUmVnRW51bUtleUV4MzJBKCBoa2V5LCBpU3Via2V5LCBscHN6TmFtZSwgJmxwY2NoTmFtZSwgTlVMTCwgTlVMTCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAmZnQgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRW51bUtleTE2IFtTSEVMTC43XSBbS0VSTkVMLjIxNl0KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtS2V5MTYoIEhLRVkgaGtleSwgRFdPUkQgaVN1YmtleSwgTFBTVFIgbHBzek5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGxwY2NoTmFtZSApCnsKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcCwlbGQpXG4iLGhrZXksaVN1YmtleSxscHN6TmFtZSxscGNjaE5hbWUpOwogICAgcmV0dXJuIFJlZ0VudW1LZXkzMkEoIGhrZXksIGlTdWJrZXksIGxwc3pOYW1lLCBscGNjaE5hbWUpOwp9CgoKLyogCiAqIEVudW1lcmF0ZSBSZWdpc3RyeSBWYWx1ZXMKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0VudW1WYWx1ZTE2IC0+IFJlZ0VudW1WYWx1ZTMyQSAtPiBSZWdFbnVtVmFsdWUzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUzMlcgW0FEVkFQSTMyLjE0Ml0KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgIFtJXSBIYW5kbGUgdG8ga2V5IHRvIHF1ZXJ5CiAqICAgIGlWYWx1ZSAgICAgIFtJXSBJbmRleCBvZiB2YWx1ZSB0byBxdWVyeQogKiAgICBscHN6VmFsdWUgICBbT10gVmFsdWUgc3RyaW5nCiAqICAgIGxwY2NoVmFsdWUgIFtPXSBTaXplIG9mIHZhbHVlIGJ1ZmZlcgogKiAgICBscGRSZXNlcnZlZCBbSV0gUmVzZXJ2ZWQKICogICAgbHBkd1R5cGUgICAgW09dIFR5cGUgY29kZQogKiAgICBscGJEYXRhICAgICBbT10gVmFsdWUgZGF0YQogKiAgICBscGNiRGF0YSAgICBbT10gU2l6ZSBvZiBkYXRhIGJ1ZmZlcgogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1WYWx1ZTMyVyggSEtFWSBoa2V5LCBEV09SRCBpVmFsdWUsIExQV1NUUiBscHN6VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hWYWx1ZSwgTFBEV09SRCBscGRSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBLRVlTVFJVQ1QJbHBrZXk7CglMUEtFWVZBTFVFCXZhbDsKCiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJXAsJXAsJXAsJXAsJXApXG4iLGhrZXksaVZhbHVlLGRlYnVnc3RyX3cobHBzelZhbHVlKSwKICAgICAgICAgIGxwY2NoVmFsdWUsbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YSk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgaWYgKGxwa2V5LT5ucm9mdmFsdWVzIDw9IGlWYWx1ZSkKICAgICAgICByZXR1cm4gRVJST1JfTk9fTU9SRV9JVEVNUzsKCiAgICAvKiBGSVhNRTogU2hvdWxkIHRoaXMgYmUgbHBrZXktPnZhbHVlcyArIGlWYWx1ZSAqIHNpemVvZihLRVlWQUxVRSk/ICovCiAgICB2YWwgPSBscGtleS0+dmFsdWVzICsgaVZhbHVlOwoKCWlmICh2YWwtPm5hbWUpIHsKCQlpZiAobHN0cmxlbjMyVyh2YWwtPm5hbWUpKjIrMj4qbHBjY2hWYWx1ZSkgewoJCQkqbHBjY2hWYWx1ZSA9IGxzdHJsZW4zMlcodmFsLT5uYW1lKSoyKzI7CgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJfQoJCW1lbWNweShscHN6VmFsdWUsdmFsLT5uYW1lLDIqbHN0cmxlbjMyVyh2YWwtPm5hbWUpKzIpOwoJCSpscGNjaFZhbHVlPWxzdHJsZW4zMlcodmFsLT5uYW1lKSoyKzI7Cgl9IGVsc2UgewoJCSpscHN6VmFsdWUJPSAwOwoJCSpscGNjaFZhbHVlCT0gMDsKCX0KCiAgICAvKiBDYW4gYmUgTlVMTCBpZiB0aGUgdHlwZSBjb2RlIGlzIG5vdCByZXF1aXJlZCAqLwogICAgaWYgKGxwZHdUeXBlKQogICAgICAgICpscGR3VHlwZSA9IHZhbC0+dHlwZTsKCglpZiAobHBiRGF0YSkgewoJCWlmICh2YWwtPmxlbj4qbHBjYkRhdGEpCgkJCXJldHVybiBFUlJPUl9NT1JFX0RBVEE7CgkJbWVtY3B5KGxwYkRhdGEsdmFsLT5kYXRhLHZhbC0+bGVuKTsKCQkqbHBjYkRhdGEgPSB2YWwtPmxlbjsKCX0KCXJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdFbnVtVmFsdWUzMkEgW0FEVkFQSTMyLjE0MV0KICovCkRXT1JEIFdJTkFQSSBSZWdFbnVtVmFsdWUzMkEoIEhLRVkgaGtleSwgRFdPUkQgaVZhbHVlLCBMUFNUUiBscHN6VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjY2hWYWx1ZSwgTFBEV09SRCBscGRSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGR3VHlwZSwgTFBCWVRFIGxwYkRhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewoJTFBXU1RSCWxwc3pWYWx1ZVc7CglMUEJZVEUJbHBiRGF0YVc7CglEV09SRAlyZXQsbHBjYkRhdGFXOwoJRFdPUkQgZHdUeXBlOwoKCVRSQUNFKHJlZywiKCV4LCVsZCwlcCwlcCwlcCwlcCwlcCwlcClcbiIsaGtleSxpVmFsdWUsbHBzelZhbHVlLGxwY2NoVmFsdWUsCgkJbHBkUmVzZXJ2ZWQsbHBkd1R5cGUsbHBiRGF0YSxscGNiRGF0YSk7CgoJbHBzelZhbHVlVyA9IChMUFdTVFIpeG1hbGxvYygqbHBjY2hWYWx1ZSoyKTsKCWlmIChscGJEYXRhKSB7CgkJbHBiRGF0YVcgPSAoTFBCWVRFKXhtYWxsb2MoKmxwY2JEYXRhKjIpOwoJCWxwY2JEYXRhVyA9ICpscGNiRGF0YSoyOwoJfSBlbHNlCgkJbHBiRGF0YVcgPSBOVUxMOwoKCXJldCA9IFJlZ0VudW1WYWx1ZTMyVyggaGtleSwgaVZhbHVlLCBscHN6VmFsdWVXLCBscGNjaFZhbHVlLCAKCQkJCWxwZFJlc2VydmVkLCAmZHdUeXBlLCBscGJEYXRhVywgJmxwY2JEYXRhVyApOwoKCWlmIChscGR3VHlwZSkKCQkqbHBkd1R5cGUgPSBkd1R5cGU7CgoJaWYgKHJldD09RVJST1JfU1VDQ0VTUykgewoJCWxzdHJjcHlXdG9BKGxwc3pWYWx1ZSxscHN6VmFsdWVXKTsKCQlpZiAobHBiRGF0YSkgewoJCQlpZiAoKDE8PGR3VHlwZSkgJiBVTklDT05WTUFTSykgewoJCQkJbHN0cmNweVd0b0EobHBiRGF0YSwoTFBXU1RSKWxwYkRhdGFXKTsKCQkJfSBlbHNlIHsKCQkJCWlmIChscGNiRGF0YVcgPiAqbHBjYkRhdGEpCgkJCQkJcmV0CT0gRVJST1JfTU9SRV9EQVRBOwoJCQkJZWxzZQoJCQkJCW1lbWNweShscGJEYXRhLGxwYkRhdGFXLGxwY2JEYXRhVyk7CgkJCX0KCQkJKmxwY2JEYXRhID0gbHBjYkRhdGFXOwoJCX0KCX0KICAgIGlmIChscGJEYXRhVykgZnJlZShscGJEYXRhVyk7CiAgICBpZiAobHBzelZhbHVlVykgZnJlZShscHN6VmFsdWVXKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0VudW1WYWx1ZTE2IFtLRVJORUwuMjIzXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0VudW1WYWx1ZTE2KCBIS0VZIGhrZXksIERXT1JEIGlWYWx1ZSwgTFBTVFIgbHBzelZhbHVlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoVmFsdWUsIExQRFdPUkQgbHBkUmVzZXJ2ZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBkd1R5cGUsIExQQllURSBscGJEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JEYXRhICkKewogICAgVFJBQ0UocmVnLCIoJXgsJWxkLCVwLCVwLCVwLCVwLCVwLCVwKVxuIixoa2V5LGlWYWx1ZSxscHN6VmFsdWUsbHBjY2hWYWx1ZSwKICAgICAgICAgIGxwZFJlc2VydmVkLGxwZHdUeXBlLGxwYkRhdGEsbHBjYkRhdGEpOwogICAgcmV0dXJuIFJlZ0VudW1WYWx1ZTMyQSggaGtleSwgaVZhbHVlLCBscHN6VmFsdWUsIGxwY2NoVmFsdWUsIGxwZFJlc2VydmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwZHdUeXBlLCBscGJEYXRhLCBscGNiRGF0YSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDbG9zZUtleSBbU0hFTEwuM10gW0tFUk5FTC4yMjBdIFtBRFZBUEkzMi4xMjZdCiAqIFJlbGVhc2VzIHRoZSBoYW5kbGUgb2YgdGhlIHNwZWNpZmllZCBrZXkKICoKICogUEFSQU1TCiAqICAgIGhrZXkgW0ldIEhhbmRsZSBvZiBrZXkgdG8gY2xvc2UKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBFUlJPUl9TVUNDRVNTCiAqICAgIEZhaWx1cmU6IEVycm9yIGNvZGUKICovCkRXT1JEIFdJTkFQSSBSZWdDbG9zZUtleSggSEtFWSBoa2V5ICkKewogICAgVFJBQ0UocmVnLCIoJXgpXG4iLGhrZXkpOwoKICAgIC8qIFRoZSBzdGFuZGFyZCBoYW5kbGVzIGFyZSBhbGxvd2VkIHRvIHN1Y2NlZWQsIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIG5vdAogICAgICAgY2xvc2VkICovCiAgICBpZiAoaXNfc3RhbmRhcmRfaGtleShoa2V5KSkKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKCiAgICByZXR1cm4gcmVtb3ZlX2hhbmRsZShoa2V5KTsKfQoKCi8qIAogKiBEZWxldGUgcmVnaXN0cnkga2V5CiAqCiAqIENhbGxwYXRoOgogKiBSZWdEZWxldGVLZXkxNiAtPiBSZWdEZWxldGVLZXkzMkEgLT4gUmVnRGVsZXRlS2V5MzJXCiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnRGVsZXRlS2V5MzJXIFtBRFZBUEkzMi4xMzRdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgIFtJXSBIYW5kbGUgdG8gb3BlbiBrZXkKICogICAgbHBzelN1YktleSBbSV0gTmFtZSBvZiBzdWJrZXkgdG8gZGVsZXRlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRVJST1JfU1VDQ0VTUwogKiAgICBGYWlsdXJlOiBFcnJvciBjb2RlCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5MzJXKCBIS0VZIGhrZXksIExQV1NUUiBscHN6U3ViS2V5ICkKewoJTFBLRVlTVFJVQ1QJKmxwbHBQcmV2S2V5LGxwTmV4dEtleSxscHhrZXk7CglMUFdTVFIJCSp3cHM7CglpbnQJCXdwYyxpOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelN1YktleSkpOwoKICAgIGxwTmV4dEtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwogICAgaWYgKCFscE5leHRLZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIC8qIFN1YmtleSBwYXJhbSBjYW5ub3QgYmUgTlVMTCAqLwogICAgaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSkKICAgICAgICByZXR1cm4gRVJST1JfQkFES0VZOwoKICAgIC8qIFdlIG5lZWQgdG8ga25vdyB0aGUgcHJldmlvdXMga2V5IGluIHRoZSBoaWVyLiAqLwoJc3BsaXRfa2V5cGF0aChscHN6U3ViS2V5LCZ3cHMsJndwYyk7CglpIAk9IDA7CglscHhrZXkJPSBscE5leHRLZXk7Cgl3aGlsZSAoaTx3cGMtMSkgewoJCWxweGtleT1scE5leHRLZXktPm5leHRzdWI7CgkJd2hpbGUgKGxweGtleSkgewoJCQlUUkFDRShyZWcsICIgIFNjYW5uaW5nIFslc11cbiIsCgkJCQkgICAgIGRlYnVnc3RyX3cobHB4a2V5LT5rZXluYW1lKSk7CgkJCWlmICghbHN0cmNtcGkzMlcod3BzW2ldLGxweGtleS0+a2V5bmFtZSkpCgkJCQlicmVhazsKCQkJbHB4a2V5PWxweGtleS0+bmV4dDsKCQl9CgkJaWYgKCFscHhrZXkpIHsKCQkJRlJFRV9LRVlfUEFUSDsKCQkJVFJBQ0UocmVnLCAiICBOb3QgZm91bmQuXG4iKTsKCQkJLyogbm90IGZvdW5kIGlzIHN1Y2Nlc3MgKi8KCQkJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7CgkJfQoJCWkrKzsKCQlscE5leHRLZXkJPSBscHhrZXk7Cgl9CglscHhrZXkJPSBscE5leHRLZXktPm5leHRzdWI7CglscGxwUHJldktleSA9ICYobHBOZXh0S2V5LT5uZXh0c3ViKTsKCXdoaWxlIChscHhrZXkpIHsKCQlUUkFDRShyZWcsICIgIFNjYW5uaW5nIFslc11cbiIsCgkJCSAgICAgZGVidWdzdHJfdyhscHhrZXktPmtleW5hbWUpKTsKCQlpZiAoIWxzdHJjbXBpMzJXKHdwc1tpXSxscHhrZXktPmtleW5hbWUpKQoJCQlicmVhazsKCQlscGxwUHJldktleQk9ICYobHB4a2V5LT5uZXh0KTsKCQlscHhrZXkJCT0gbHB4a2V5LT5uZXh0OwoJfQoKCWlmICghbHB4a2V5KSB7CgkJRlJFRV9LRVlfUEFUSDsKCQlXQVJOKHJlZyAsICIgIE5vdCBmb3VuZC5cbiIpOwoJCXJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsKCX0KCglpZiAobHB4a2V5LT5uZXh0c3ViKSB7CgkJRlJFRV9LRVlfUEFUSDsKCQlXQVJOKHJlZyAsICIgIE5vdCBlbXB0eS5cbiIpOwoJCXJldHVybiBFUlJPUl9DQU5UV1JJVEU7Cgl9CgkqbHBscFByZXZLZXkJPSBscHhrZXktPm5leHQ7CglmcmVlKGxweGtleS0+a2V5bmFtZSk7CglpZiAobHB4a2V5LT5jbGFzcykKCQlmcmVlKGxweGtleS0+Y2xhc3MpOwoJaWYgKGxweGtleS0+dmFsdWVzKQoJCWZyZWUobHB4a2V5LT52YWx1ZXMpOwoJZnJlZShscHhrZXkpOwoJRlJFRV9LRVlfUEFUSDsKCVRSQUNFKHJlZywgIiAgRG9uZS5cbiIpOwoJcmV0dXJuCUVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZUtleTMyQSBbQURWQVBJMzIuMTMzXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZUtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSApCnsKICAgIExQV1NUUiBscHN6U3ViS2V5VzsKICAgIERXT1JEICByZXQ7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLGhrZXksZGVidWdzdHJfYShscHN6U3ViS2V5KSk7CiAgICBscHN6U3ViS2V5VyA9IGxwc3pTdWJLZXk/c3RyZHVwQTJXKGxwc3pTdWJLZXkpOk5VTEw7CiAgICByZXQgPSBSZWdEZWxldGVLZXkzMlcoIGhrZXksIGxwc3pTdWJLZXlXICk7CiAgICBpZihscHN6U3ViS2V5VykgZnJlZShscHN6U3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVLZXkxNiBbU0hFTEwuNF0gW0tFUk5FTC4yMTldCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlS2V5MTYoIEhLRVkgaGtleSwgTFBDU1RSIGxwc3pTdWJLZXkgKQp7CiAgICBUUkFDRShyZWcsIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pTdWJLZXkpKTsKICAgIHJldHVybiBSZWdEZWxldGVLZXkzMkEoIGhrZXksIGxwc3pTdWJLZXkgKTsKfQoKCi8qIAogKiBEZWxldGUgcmVnaXN0cnkgdmFsdWUKICoKICogQ2FsbHBhdGg6CiAqIFJlZ0RlbGV0ZVZhbHVlMTYgLT4gUmVnRGVsZXRlVmFsdWUzMkEgLT4gUmVnRGVsZXRlVmFsdWUzMlcKICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVWYWx1ZTMyVyBbQURWQVBJMzIuMTM2XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgIFtJXQogKiAgICBscHN6VmFsdWUgW0ldCiAqCiAqIFJFVFVSTlMKICovCkRXT1JEIFdJTkFQSSBSZWdEZWxldGVWYWx1ZTMyVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzelZhbHVlICkKewoJRFdPUkQJCWk7CglMUEtFWVNUUlVDVAlscGtleTsKCUxQS0VZVkFMVUUJdmFsOwoKICAgIFRSQUNFKHJlZywiKCV4LCVzKVxuIixoa2V5LGRlYnVnc3RyX3cobHBzelZhbHVlKSk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgoJaWYgKGxwc3pWYWx1ZSkgewoJCWZvciAoaT0wO2k8bHBrZXktPm5yb2Z2YWx1ZXM7aSsrKQoJCQlpZiAoCWxwa2V5LT52YWx1ZXNbaV0ubmFtZSAmJgoJCQkJIWxzdHJjbXBpMzJXKGxwa2V5LT52YWx1ZXNbaV0ubmFtZSxscHN6VmFsdWUpCgkJCSkKCQkJCWJyZWFrOwoJfSBlbHNlIHsKCQlmb3IgKGk9MDtpPGxwa2V5LT5ucm9mdmFsdWVzO2krKykKCQkJaWYgKGxwa2V5LT52YWx1ZXNbaV0ubmFtZT09TlVMTCkKCQkJCWJyZWFrOwoJfQoKICAgIGlmIChpID09IGxwa2V5LT5ucm9mdmFsdWVzKQogICAgICAgIHJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsKCgl2YWwJPSBscGtleS0+dmFsdWVzK2k7CglpZiAodmFsLT5uYW1lKSBmcmVlKHZhbC0+bmFtZSk7CglpZiAodmFsLT5kYXRhKSBmcmVlKHZhbC0+ZGF0YSk7CgltZW1jcHkoCQoJCWxwa2V5LT52YWx1ZXMraSwKCQlscGtleS0+dmFsdWVzK2krMSwKCQlzaXplb2YoS0VZVkFMVUUpKihscGtleS0+bnJvZnZhbHVlcy1pLTEpCgkpOwoJbHBrZXktPnZhbHVlcwk9IChMUEtFWVZBTFVFKXhyZWFsbG9jKAoJCQkJbHBrZXktPnZhbHVlcywKCQkJCShscGtleS0+bnJvZnZhbHVlcy0xKSpzaXplb2YoS0VZVkFMVUUpCgkJCSk7CglscGtleS0+bnJvZnZhbHVlcy0tOwoJcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ0RlbGV0ZVZhbHVlMzJBIFtBRFZBUEkzMi4xMzVdCiAqLwpEV09SRCBXSU5BUEkgUmVnRGVsZXRlVmFsdWUzMkEoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlICkKewogICAgTFBXU1RSIGxwc3pWYWx1ZVc7CiAgICBEV09SRCAgcmV0OwoKICAgIFRSQUNFKHJlZywgIigleCwlcylcbiIsaGtleSxkZWJ1Z3N0cl9hKGxwc3pWYWx1ZSkpOwogICAgbHBzelZhbHVlVyA9IGxwc3pWYWx1ZT9zdHJkdXBBMlcobHBzelZhbHVlKTpOVUxMOwogICAgcmV0ID0gUmVnRGVsZXRlVmFsdWUzMlcoIGhrZXksIGxwc3pWYWx1ZVcgKTsKICAgIGlmKGxwc3pWYWx1ZVcpIGZyZWUobHBzelZhbHVlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdEZWxldGVWYWx1ZTE2IFtLRVJORUwuMjIyXQogKi8KRFdPUkQgV0lOQVBJIFJlZ0RlbGV0ZVZhbHVlMTYoIEhLRVkgaGtleSwgTFBTVFIgbHBzelZhbHVlICkKewogICAgVFJBQ0UocmVnLCIoJXgsJXMpXG4iLCBoa2V5LGRlYnVnc3RyX2EobHBzelZhbHVlKSk7CiAgICByZXR1cm4gUmVnRGVsZXRlVmFsdWUzMkEoIGhrZXksIGxwc3pWYWx1ZSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdGbHVzaEtleSBbS0VSTkVMLjIyN10gW0FEVkFQSTMyLjE0M10KICogV3JpdGVzIGtleSB0byByZWdpc3RyeQogKgogKiBQQVJBTVMKICogICAgaGtleSBbSV0gSGFuZGxlIG9mIGtleSB0byB3cml0ZQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KRFdPUkQgV0lOQVBJIFJlZ0ZsdXNoS2V5KCBIS0VZIGhrZXkgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKICAgIEJPT0wzMiByZXQ7CgogICAgVFJBQ0UocmVnLCAiKCV4KVxuIiwgaGtleSk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRVJSKHJlZywgIldoYXQgaXMgdGhlIGNvcnJlY3QgZmlsZW5hbWU/XG4iKTsKCiAgICByZXQgPSBfc2F2ZXJlZyggbHBrZXksICJmb28uYmFyIiwgVFJVRSk7CgogICAgaWYoIHJldCApIHsKICAgICAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKICAgIH0gZWxzZQogICAgICAgIHJldHVybiBFUlJPUl9VTktOT1dOOyAgLyogRklYTUUgKi8KfQoKCi8qIEZJWE1FOiBscGNjaFhYWFggLi4uIGlzIHRoaXMgY291bnRpbmcgaW4gV0NIQVJTIG9yIGluIEJZVEVzID8/ICovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdRdWVyeUluZm9LZXkzMlcgW0FEVkFQSTMyLjE1M10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICAgICAgICAgW0ldIEhhbmRsZSB0byBrZXkgdG8gcXVlcnkKICogICAgbHBzekNsYXNzICAgICAgICAgICAgICBbT10gQnVmZmVyIGZvciBjbGFzcyBzdHJpbmcKICogICAgbHBjY2hDbGFzcyAgICAgICAgICAgICBbT10gU2l6ZSBvZiBjbGFzcyBzdHJpbmcgYnVmZmVyCiAqICAgIGxwZHdSZXNlcnZlZCAgICAgICAgICAgW0ldIFJlc2VydmVkCiAqICAgIGxwY1N1YktleXMgICAgICAgICAgICAgW0ldIEJ1ZmZlciBmb3IgbnVtYmVyIG9mIHN1YmtleXMKICogICAgbHBjY2hNYXhTdWJLZXkgICAgICAgICBbT10gQnVmZmVyIGZvciBsb25nZXN0IHN1YmtleSBuYW1lIGxlbmd0aAogKiAgICBscGNjaE1heENsYXNzICAgICAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3QgY2xhc3Mgc3RyaW5nIGxlbmd0aAogKiAgICBscGNWYWx1ZXMgICAgICAgICAgICAgIFtPXSBCdWZmZXIgZm9yIG51bWJlciBvZiB2YWx1ZSBlbnRyaWVzCiAqICAgIGxwY2NoTWF4VmFsdWVOYW1lICAgICAgW09dIEJ1ZmZlciBmb3IgbG9uZ2VzdCB2YWx1ZSBuYW1lIGxlbmd0aAogKiAgICBscGNjYk1heFZhbHVlRGF0YSAgICAgIFtPXSBCdWZmZXIgZm9yIGxvbmdlc3QgdmFsdWUgZGF0YSBsZW5ndGgKICogICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciBbT10gQnVmZmVyIGZvciBzZWN1cml0eSBkZXNjcmlwdG9yIGxlbmd0aAogKiAgICBmdAogKi8KRFdPUkQgV0lOQVBJIFJlZ1F1ZXJ5SW5mb0tleTMyVyggSEtFWSBoa2V5LCBMUFdTVFIgbHBzekNsYXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjaENsYXNzLCBMUERXT1JEIGxwZHdSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNTdWJLZXlzLCBMUERXT1JEIGxwY2NoTWF4U3Via2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTWF4Q2xhc3MsIExQRFdPUkQgbHBjVmFsdWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTWF4VmFsdWVOYW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNjYk1heFZhbHVlRGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciwgRklMRVRJTUUgKmZ0ICkKewoJTFBLRVlTVFJVQ1QJbHBrZXksbHB4a2V5OwoJaW50CQlucm9ma2V5cyxtYXhzdWJrZXksbWF4Y2xhc3MsbWF4dm5hbWUsbWF4dmRhdGE7CglpbnQJCWk7CgoJVFJBQ0UocmVnLCIoJXgsJXAsLi4uKVxuIixoa2V5LGxwc3pDbGFzcyk7CglscGtleSA9IGxvb2t1cF9oa2V5KGhrZXkpOwoJaWYgKCFscGtleSkKCQlyZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CglpZiAobHBzekNsYXNzKSB7CgkJaWYgKGxwa2V5LT5jbGFzcykgewoJCQlpZiAobHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjIrMj4qbHBjY2hDbGFzcykgewoJCQkJKmxwY2NoQ2xhc3M9bHN0cmxlbjMyVyhscGtleS0+Y2xhc3MpKjI7CgkJCQlyZXR1cm4gRVJST1JfTU9SRV9EQVRBOwoJCQl9CgkJCSpscGNjaENsYXNzPWxzdHJsZW4zMlcobHBrZXktPmNsYXNzKSoyOwoJCQltZW1jcHkobHBzekNsYXNzLGxwa2V5LT5jbGFzcyxsc3RybGVuMzJXKGxwa2V5LT5jbGFzcykpOwoJCX0gZWxzZSB7CgkJCSpscHN6Q2xhc3MJPSAwOwoJCQkqbHBjY2hDbGFzcwk9IDA7CgkJfQoJfSBlbHNlIHsKCQlpZiAobHBjY2hDbGFzcykKCQkJKmxwY2NoQ2xhc3MJPSBsc3RybGVuMzJXKGxwa2V5LT5jbGFzcykqMjsKCX0KCWxweGtleT1scGtleS0+bmV4dHN1YjsKCW5yb2ZrZXlzPW1heHN1YmtleT1tYXhjbGFzcz1tYXh2bmFtZT1tYXh2ZGF0YT0wOwoJd2hpbGUgKGxweGtleSkgewoJCW5yb2ZrZXlzKys7CgkJaWYgKGxzdHJsZW4zMlcobHB4a2V5LT5rZXluYW1lKT5tYXhzdWJrZXkpCgkJCW1heHN1YmtleT1sc3RybGVuMzJXKGxweGtleS0+a2V5bmFtZSk7CgkJaWYgKGxweGtleS0+Y2xhc3MgJiYgbHN0cmxlbjMyVyhscHhrZXktPmNsYXNzKT5tYXhjbGFzcykKCQkJbWF4Y2xhc3M9bHN0cmxlbjMyVyhscHhrZXktPmNsYXNzKTsKCQlscHhrZXk9bHB4a2V5LT5uZXh0OwoJfQoJZm9yIChpPTA7aTxscGtleS0+bnJvZnZhbHVlcztpKyspIHsKCQlMUEtFWVZBTFVFCXZhbD1scGtleS0+dmFsdWVzK2k7CgoJCWlmICh2YWwtPm5hbWUgJiYgbHN0cmxlbjMyVyh2YWwtPm5hbWUpPm1heHZuYW1lKQoJCQltYXh2bmFtZT1sc3RybGVuMzJXKHZhbC0+bmFtZSk7CgkJaWYgKHZhbC0+bGVuPm1heHZkYXRhKQoJCQltYXh2ZGF0YT12YWwtPmxlbjsKCX0KCWlmICghbWF4Y2xhc3MpIG1heGNsYXNzCT0gMTsKCWlmICghbWF4dm5hbWUpIG1heHZuYW1lCT0gMTsKCWlmIChscGNWYWx1ZXMpCgkJKmxwY1ZhbHVlcwk9IGxwa2V5LT5ucm9mdmFsdWVzOwoJaWYgKGxwY1N1YktleXMpCgkJKmxwY1N1YktleXMJPSBucm9ma2V5czsKCWlmIChscGNjaE1heFN1YmtleSkKCQkqbHBjY2hNYXhTdWJrZXkJPSBtYXhzdWJrZXkqMjsKCWlmIChscGNjaE1heENsYXNzKQoJCSpscGNjaE1heENsYXNzCT0gbWF4Y2xhc3MqMjsKCWlmIChscGNjaE1heFZhbHVlTmFtZSkKCQkqbHBjY2hNYXhWYWx1ZU5hbWU9IG1heHZuYW1lOwoJaWYgKGxwY2NiTWF4VmFsdWVEYXRhKQoJCSpscGNjYk1heFZhbHVlRGF0YT0gbWF4dmRhdGE7CglyZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUXVlcnlJbmZvS2V5MzJBIFtBRFZBUEkzMi4xNTJdCiAqLwpEV09SRCBXSU5BUEkgUmVnUXVlcnlJbmZvS2V5MzJBKCBIS0VZIGhrZXksIExQU1RSIGxwc3pDbGFzcywgTFBEV09SRCBscGNjaENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwZHdSZXNlcnZlZCwgTFBEV09SRCBscGNTdWJLZXlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NoTWF4U3Via2V5LCBMUERXT1JEIGxwY2NoTWF4Q2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRFdPUkQgbHBjVmFsdWVzLCBMUERXT1JEIGxwY2NoTWF4VmFsdWVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2NiTWF4VmFsdWVEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBscGNiU2VjdXJpdHlEZXNjcmlwdG9yLCBGSUxFVElNRSAqZnQgKQp7CglMUFdTVFIJCWxwc3pDbGFzc1c7CglEV09SRAkJcmV0OwoKCVRSQUNFKHJlZywiKCV4LC4uLi4uLilcbiIsaGtleSk7CglpZiAobHBzekNsYXNzKSB7CgkJKmxwY2NoQ2xhc3MqPSAyOwoJCWxwc3pDbGFzc1cgID0gKExQV1NUUil4bWFsbG9jKCpscGNjaENsYXNzKTsKCgl9IGVsc2UKCQlscHN6Q2xhc3NXICA9IE5VTEw7CglyZXQ9UmVnUXVlcnlJbmZvS2V5MzJXKAoJCWhrZXksCgkJbHBzekNsYXNzVywKCQlscGNjaENsYXNzLAoJCWxwZHdSZXNlcnZlZCwKCQlscGNTdWJLZXlzLAoJCWxwY2NoTWF4U3Via2V5LAoJCWxwY2NoTWF4Q2xhc3MsCgkJbHBjVmFsdWVzLAoJCWxwY2NoTWF4VmFsdWVOYW1lLAoJCWxwY2NiTWF4VmFsdWVEYXRhLAoJCWxwY2JTZWN1cml0eURlc2NyaXB0b3IsCgkJZnQKCSk7CglpZiAocmV0PT1FUlJPUl9TVUNDRVNTICYmIGxwc3pDbGFzcykKCQlsc3RyY3B5V3RvQShscHN6Q2xhc3MsbHBzekNsYXNzVyk7CglpZiAobHBjY2hDbGFzcykKCQkqbHBjY2hDbGFzcy89MjsKCWlmIChscGNjaE1heFN1YmtleSkKCQkqbHBjY2hNYXhTdWJrZXkvPTI7CglpZiAobHBjY2hNYXhDbGFzcykKCQkqbHBjY2hNYXhDbGFzcy89MjsKCWlmIChscGNjaE1heFZhbHVlTmFtZSkKCQkqbHBjY2hNYXhWYWx1ZU5hbWUvPTI7CglpZiAobHBzekNsYXNzVykKCQlmcmVlKGxwc3pDbGFzc1cpOwoJcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnQ29ubmVjdFJlZ2lzdHJ5MzJXIFtBRFZBUEkzMi4xMjhdCiAqCiAqIFBBUkFNUwogKiAgICBscE1hY2hpbmVOYW1lIFtJXSBBZGRyZXNzIG9mIG5hbWUgb2YgcmVtb3RlIGNvbXB1dGVyCiAqICAgIGhIZXkgICAgICAgICAgW0ldIFByZWRlZmluZWQgcmVnaXN0cnkgaGFuZGxlCiAqICAgIHBoa1Jlc3VsdCAgICAgW0ldIEFkZHJlc3Mgb2YgYnVmZmVyIGZvciByZW1vdGUgcmVnaXN0cnkgaGFuZGxlCiAqLwpMT05HIFdJTkFQSSBSZWdDb25uZWN0UmVnaXN0cnkzMlcoIExQQ1dTVFIgbHBNYWNoaW5lTmFtZSwgSEtFWSBoS2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEhLRVkgcGhrUmVzdWx0ICkKewogICAgVFJBQ0UocmVnLCIoJXMsJXgsJXApOiBzdHViXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSksaEtleSxwaGtSZXN1bHQpOwoKICAgIGlmICghbHBNYWNoaW5lTmFtZSB8fCAhKmxwTWFjaGluZU5hbWUpIHsKICAgICAgICAvKiBVc2UgdGhlIGxvY2FsIG1hY2hpbmUgbmFtZSAqLwogICAgICAgIHJldHVybiBSZWdPcGVuS2V5MTYoIGhLZXksICIiLCBwaGtSZXN1bHQgKTsKICAgIH0KCiAgICBGSVhNRShyZWcsIkNhbm5vdCBjb25uZWN0IHRvICVzXG4iLGRlYnVnc3RyX3cobHBNYWNoaW5lTmFtZSkpOwogICAgcmV0dXJuIEVSUk9SX0JBRF9ORVRQQVRIOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdDb25uZWN0UmVnaXN0cnkzMkEgW0FEVkFQSTMyLjEyN10KICovCkxPTkcgV0lOQVBJIFJlZ0Nvbm5lY3RSZWdpc3RyeTMyQSggTFBDU1RSIG1hY2hpbmUsIEhLRVkgaGtleSwgTFBIS0VZIHJlc2tleSApCnsKICAgIERXT1JEIHJldDsKICAgIExQV1NUUiBtYWNoaW5lVyA9IHN0cmR1cEEyVyhtYWNoaW5lKTsKICAgIHJldCA9IFJlZ0Nvbm5lY3RSZWdpc3RyeTMyVyggbWFjaGluZVcsIGhrZXksIHJlc2tleSApOwogICAgZnJlZShtYWNoaW5lVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdHZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTQ0XQogKiBSZXRyaWV2ZXMgYSBjb3B5IG9mIHNlY3VyaXR5IGRlc2NyaXB0b3IgcHJvdGVjdGluZyB0aGUgcmVnaXN0cnkga2V5CiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICAgICAgICAgICAgICAgIFtJXSAgIE9wZW4gaGFuZGxlIG9mIGtleSB0byBzZXQKICogICAgU2VjdXJpdHlJbmZvcm1hdGlvbiAgICBbSV0gICBEZXNjcmlwdG9yIGNvbnRlbnRzCiAqICAgIHBTZWN1cml0eURlc2NyaXB0b3IgICAgW09dICAgQWRkcmVzcyBvZiBkZXNjcmlwdG9yIGZvciBrZXkKICogICAgbHBjYlNlY3VyaXR5RGVzY3JpcHRvciBbSS9PXSBBZGRyZXNzIG9mIHNpemUgb2YgYnVmZmVyIGFuZCBkZXNjcmlwdGlvbgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IEVSUk9SX1NVQ0NFU1MKICogICAgRmFpbHVyZTogRXJyb3IgY29kZQogKi8KTE9ORyBXSU5BUEkgUmVnR2V0S2V5U2VjdXJpdHkoIEhLRVkgaGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRUNVUklUWV9JTkZPUk1BVElPTiBTZWN1cml0eUluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9ERVNDUklQVE9SIHBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIGxwY2JTZWN1cml0eURlc2NyaXB0b3IgKQp7CiAgICBMUEtFWVNUUlVDVAlscGtleTsKCiAgICBUUkFDRShyZWcsIigleCwlbGQsJXAsJWxkKVxuIixoa2V5LFNlY3VyaXR5SW5mb3JtYXRpb24scFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgIGxwY2JTZWN1cml0eURlc2NyaXB0b3I/KmxwY2JTZWN1cml0eURlc2NyaXB0b3I6MCk7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgLyogRklYTUU6IENoZWNrIGZvciB2YWxpZCBTZWN1cml0eUluZm9ybWF0aW9uIHZhbHVlcyAqLwoKICAgIGlmICgqbHBjYlNlY3VyaXR5RGVzY3JpcHRvciA8IHNpemVvZigqcFNlY3VyaXR5RGVzY3JpcHRvcikpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVI7CgogICAgRklYTUUocmVnLCAiKCV4LCVsZCwlcCwlbGQpOiBzdHViXG4iLGhrZXksU2VjdXJpdHlJbmZvcm1hdGlvbiwKICAgICAgICAgIHBTZWN1cml0eURlc2NyaXB0b3IsbHBjYlNlY3VyaXR5RGVzY3JpcHRvcj8qbHBjYlNlY3VyaXR5RGVzY3JpcHRvcjowKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTG9hZEtleTMyVyBbQURWQVBJMzIuPz8/XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwc3pTdWJLZXkgW0ldIEFkZHJlc3Mgb2YgbmFtZSBvZiBzdWJrZXkKICogICAgbHBzekZpbGUgICBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgcmVnaXN0cnkgaW5mb3JtYXRpb24KICovCkxPTkcgV0lOQVBJIFJlZ0xvYWRLZXkzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscHN6U3ViS2V5LCBMUENXU1RSIGxwc3pGaWxlICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CiAgICBUUkFDRShyZWcsIigleCwlcywlcylcbiIsaGtleSxkZWJ1Z3N0cl93KGxwc3pTdWJLZXkpLGRlYnVnc3RyX3cobHBzekZpbGUpKTsKCiAgICAvKiBEbyB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKCFscHN6U3ViS2V5IHx8ICEqbHBzelN1YktleSB8fCAhbHBzekZpbGUgfHwgISpscHN6RmlsZSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9QQVJBTUVURVI7CgogICAgbHBrZXkgPSBsb29rdXBfaGtleSggaGtleSApOwogICAgaWYgKCFscGtleSkKICAgICAgICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CgogICAgRklYTUUocmVnLCIoJXgsJXMsJXMpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSwKICAgICAgICAgIGRlYnVnc3RyX3cobHBzekZpbGUpKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTG9hZEtleTMyQSBbQURWQVBJMzIuPz8/XQogKi8KTE9ORyBXSU5BUEkgUmVnTG9hZEtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBzelN1YktleSwgTFBDU1RSIGxwc3pGaWxlICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBzelN1YktleVcgPSBzdHJkdXBBMlcobHBzelN1YktleSk7CiAgICBMUFdTVFIgbHBzekZpbGVXID0gc3RyZHVwQTJXKGxwc3pGaWxlKTsKICAgIHJldCA9IFJlZ0xvYWRLZXkzMlcoIGhrZXksIGxwc3pTdWJLZXlXLCBscHN6RmlsZVcgKTsKICAgIGlmKGxwc3pGaWxlVykgZnJlZShscHN6RmlsZVcpOwogICAgaWYobHBzelN1YktleVcpIGZyZWUobHBzelN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnTm90aWZ5Q2hhbmdlS2V5VmFsdWUgW0FEVkFQSTMyLj8/P10KICoKICogUEFSQU1TCiAqICAgIGhrZXkgICAgICAgICAgICBbSV0gSGFuZGxlIG9mIGtleSB0byB3YXRjaAogKiAgICBmV2F0Y2hTdWJUcmVlICAgW0ldIEZsYWcgZm9yIHN1YmtleSBub3RpZmljYXRpb24KICogICAgZmR3Tm90aWZ5RmlsdGVyIFtJXSBDaGFuZ2VzIHRvIGJlIHJlcG9ydGVkCiAqICAgIGhFdmVudCAgICAgICAgICBbSV0gSGFuZGxlIG9mIHNpZ25hbGVkIGV2ZW50CiAqICAgIGZBc3luYyAgICAgICAgICBbSV0gRmxhZyBmb3IgYXN5bmNocm9ub3VzIHJlcG9ydGluZwogKi8KTE9ORyBXSU5BUEkgUmVnTm90aWZ5Q2hhbmdlS2V5VmFsdWUoIEhLRVkgaGtleSwgQk9PTDMyIGZXYXRjaFN1YlRyZWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZmR3Tm90aWZ5RmlsdGVyLCBIQU5ETEUzMiBoRXZlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MMzIgZkFzeW5jICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CiAgICBUUkFDRShyZWcsIigleCwlaSwlbGQsJXgsJWkpXG4iLGhrZXksZldhdGNoU3ViVHJlZSxmZHdOb3RpZnlGaWx0ZXIsCiAgICAgICAgICBoRXZlbnQsZkFzeW5jKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsIigleCwlaSwlbGQsJXgsJWkpOiBzdHViXG4iLGhrZXksZldhdGNoU3ViVHJlZSxmZHdOb3RpZnlGaWx0ZXIsCiAgICAgICAgICBoRXZlbnQsZkFzeW5jKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnVW5Mb2FkS2V5MzJXIFtBRFZBUEkzMi4xNzNdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgICBbSV0gSGFuZGxlIG9mIG9wZW4ga2V5CiAqICAgIGxwU3ViS2V5IFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5IHRvIHVubG9hZAogKi8KTE9ORyBXSU5BUEkgUmVnVW5Mb2FkS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBTdWJLZXkgKQp7CiAgICBGSVhNRShyZWcsIigleCwlcyk6IHN0dWJcbiIsaGtleSwgZGVidWdzdHJfdyhscFN1YktleSkpOwogICAgcmV0dXJuIEVSUk9SX1NVQ0NFU1M7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ1VuTG9hZEtleTMyQSBbQURWQVBJMzIuMTcyXQogKi8KTE9ORyBXSU5BUEkgUmVnVW5Mb2FkS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscFN1YktleSApCnsKICAgIExPTkcgcmV0OwogICAgTFBXU1RSIGxwU3ViS2V5VyA9IHN0cmR1cEEyVyhscFN1YktleSk7CiAgICByZXQgPSBSZWdVbkxvYWRLZXkzMlcoIGhrZXksIGxwU3ViS2V5VyApOwogICAgaWYobHBTdWJLZXlXKSBmcmVlKGxwU3ViS2V5Vyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTZXRLZXlTZWN1cml0eSBbQURWQVBJMzIuMTY3XQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgICAgICBbSV0gT3BlbiBoYW5kbGUgb2Yga2V5IHRvIHNldAogKiAgICBTZWN1cml0eUluZm8gIFtJXSBEZXNjcmlwdG9yIGNvbnRlbnRzCiAqICAgIHBTZWN1cml0eURlc2MgW0ldIEFkZHJlc3Mgb2YgZGVzY3JpcHRvciBmb3Iga2V5CiAqLwpMT05HIFdJTkFQSSBSZWdTZXRLZXlTZWN1cml0eSggSEtFWSBoa2V5LCBTRUNVUklUWV9JTkZPUk1BVElPTiBTZWN1cml0eUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0RFU0NSSVBUT1IgcFNlY3VyaXR5RGVzYyApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFKHJlZywiKCV4LCVsZCwlcClcbiIsaGtleSxTZWN1cml0eUluZm8scFNlY3VyaXR5RGVzYyk7CgogICAgLyogSXQgc2VlbXMgdG8gcGVyZm9ybSB0aGlzIGNoZWNrIGJlZm9yZSB0aGUgaGtleSBjaGVjayAqLwogICAgaWYgKChTZWN1cml0eUluZm8gJiBPV05FUl9TRUNVUklUWV9JTkZPUk1BVElPTikgfHwKICAgICAgICAoU2VjdXJpdHlJbmZvICYgR1JPVVBfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIERBQ0xfU0VDVVJJVFlfSU5GT1JNQVRJT04pIHx8CiAgICAgICAgKFNlY3VyaXR5SW5mbyAmIFNBQ0xfU0VDVVJJVFlfSU5GT1JNQVRJT04pKSB7CiAgICAgICAgLyogUGFyYW0gT0sgKi8KICAgIH0gZWxzZQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBpZiAoIXBTZWN1cml0eURlc2MpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOwoKICAgIGxwa2V5ID0gbG9va3VwX2hrZXkoIGhrZXkgKTsKICAgIGlmICghbHBrZXkpCiAgICAgICAgcmV0dXJuIEVSUk9SX0lOVkFMSURfSEFORExFOwoKICAgIEZJWE1FKHJlZywiOigleCwlbGQsJXApOiBzdHViXG4iLGhrZXksU2VjdXJpdHlJbmZvLHBTZWN1cml0eURlc2MpOwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdTYXZlS2V5MzJXIFtBRFZBUEkzMi4xNjZdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgW0ldIEhhbmRsZSBvZiBrZXkgd2hlcmUgc2F2ZSBiZWdpbnMKICogICAgbHBGaWxlIFtJXSBBZGRyZXNzIG9mIGZpbGVuYW1lIHRvIHNhdmUgdG8KICogICAgc2EgICAgIFtJXSBBZGRyZXNzIG9mIHNlY3VyaXR5IHN0cnVjdHVyZQogKi8KTE9ORyBXSU5BUEkgUmVnU2F2ZUtleTMyVyggSEtFWSBoa2V5LCBMUENXU1RSIGxwRmlsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBzYSApCnsKICAgIExQS0VZU1RSVUNUCWxwa2V5OwoKICAgIFRSQUNFKHJlZywgIigleCwlcywlcClcbiIsIGhrZXksIGRlYnVnc3RyX3cobHBGaWxlKSwgc2EpOwoKICAgIC8qIEl0IGFwcGVhcnMgdG8gZG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBGaWxlIHx8ICEqbHBGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsICIoJXgsJXMsJXApOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwRmlsZSksIHNhKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnU2F2ZUtleTMyQSBbQURWQVBJMzIuMTY1XQogKi8KTE9ORyBXSU5BUEkgUmVnU2F2ZUtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBGaWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIHNhICkKewogICAgTE9ORyByZXQ7CiAgICBMUFdTVFIgbHBGaWxlVyA9IHN0cmR1cEEyVyhscEZpbGUpOwogICAgcmV0ID0gUmVnU2F2ZUtleTMyVyggaGtleSwgbHBGaWxlVywgc2EgKTsKICAgIGZyZWUobHBGaWxlVyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5MzJXIFtBRFZBUEkzMi4xNjRdCiAqCiAqIFBBUkFNUwogKiAgICBoa2V5ICAgIFtJXSBIYW5kbGUgb2Yga2V5IHdoZXJlIHJlc3RvcmUgYmVnaW5zCiAqICAgIGxwRmlsZSAgW0ldIEFkZHJlc3Mgb2YgZmlsZW5hbWUgY29udGFpbmluZyBzYXZlZCB0cmVlCiAqICAgIGR3RmxhZ3MgW0ldIE9wdGlvbmFsIGZsYWdzCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5MzJXKCBIS0VZIGhrZXksIExQQ1dTVFIgbHBGaWxlLCBEV09SRCBkd0ZsYWdzICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCAiKCV4LCVzLCVsZClcbiIsaGtleSxkZWJ1Z3N0cl93KGxwRmlsZSksZHdGbGFncyk7CgogICAgLyogSXQgc2VlbXMgdG8gZG8gdGhpcyBjaGVjayBiZWZvcmUgdGhlIGhrZXkgY2hlY2sgKi8KICAgIGlmICghbHBGaWxlIHx8ICEqbHBGaWxlKQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsIigleCwlcywlbGQpOiBzdHViXG4iLGhrZXksZGVidWdzdHJfdyhscEZpbGUpLGR3RmxhZ3MpOwoKICAgIC8qIENoZWNrIGZvciBmaWxlIGV4aXN0ZW5jZSAqLwoKICAgIHJldHVybiBFUlJPUl9TVUNDRVNTOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWdSZXN0b3JlS2V5MzJBIFtBRFZBUEkzMi4xNjNdCiAqLwpMT05HIFdJTkFQSSBSZWdSZXN0b3JlS2V5MzJBKCBIS0VZIGhrZXksIExQQ1NUUiBscEZpbGUsIERXT1JEIGR3RmxhZ3MgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscEZpbGVXID0gc3RyZHVwQTJXKGxwRmlsZSk7CiAgICByZXQgPSBSZWdSZXN0b3JlS2V5MzJXKCBoa2V5LCBscEZpbGVXLCBkd0ZsYWdzICk7CiAgICBpZihscEZpbGVXKSBmcmVlKGxwRmlsZVcpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleTMyVyBbQURWQVBJMzIuMTYyXQogKgogKiBQQVJBTVMKICogICAgaGtleSAgICAgIFtJXSBIYW5kbGUgb2Ygb3BlbiBrZXkKICogICAgbHBTdWJLZXkgIFtJXSBBZGRyZXNzIG9mIG5hbWUgb2Ygc3Via2V5CiAqICAgIGxwTmV3RmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgZmlsZSB3aXRoIG5ldyBkYXRhCiAqICAgIGxwT2xkRmlsZSBbSV0gQWRkcmVzcyBvZiBmaWxlbmFtZSBmb3IgYmFja3VwIGZpbGUKICovCkxPTkcgV0lOQVBJIFJlZ1JlcGxhY2VLZXkzMlcoIEhLRVkgaGtleSwgTFBDV1NUUiBscFN1YktleSwgTFBDV1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbHBPbGRGaWxlICkKewogICAgTFBLRVlTVFJVQ1QJbHBrZXk7CgogICAgVFJBQ0UocmVnLCIoJXgsJXMsJXMsJXMpXG4iLGhrZXksZGVidWdzdHJfdyhscFN1YktleSksCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKCiAgICBscGtleSA9IGxvb2t1cF9oa2V5KCBoa2V5ICk7CiAgICBpZiAoIWxwa2V5KQogICAgICAgIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKCiAgICBGSVhNRShyZWcsICIoJXgsJXMsJXMsJXMpOiBzdHViXG4iLCBoa2V5LCBkZWJ1Z3N0cl93KGxwU3ViS2V5KSwgCiAgICAgICAgICBkZWJ1Z3N0cl93KGxwTmV3RmlsZSksZGVidWdzdHJfdyhscE9sZEZpbGUpKTsKCiAgICByZXR1cm4gRVJST1JfU1VDQ0VTUzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnUmVwbGFjZUtleTMyQSBbQURWQVBJMzIuMTYxXQogKi8KTE9ORyBXSU5BUEkgUmVnUmVwbGFjZUtleTMyQSggSEtFWSBoa2V5LCBMUENTVFIgbHBTdWJLZXksIExQQ1NUUiBscE5ld0ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBscE9sZEZpbGUgKQp7CiAgICBMT05HIHJldDsKICAgIExQV1NUUiBscFN1YktleVcgPSBzdHJkdXBBMlcobHBTdWJLZXkpOwogICAgTFBXU1RSIGxwTmV3RmlsZVcgPSBzdHJkdXBBMlcobHBOZXdGaWxlKTsKICAgIExQV1NUUiBscE9sZEZpbGVXID0gc3RyZHVwQTJXKGxwT2xkRmlsZSk7CiAgICByZXQgPSBSZWdSZXBsYWNlS2V5MzJXKCBoa2V5LCBscFN1YktleVcsIGxwTmV3RmlsZVcsIGxwT2xkRmlsZVcgKTsKICAgIGZyZWUobHBPbGRGaWxlVyk7CiAgICBmcmVlKGxwTmV3RmlsZVcpOwogICAgZnJlZShscFN1YktleVcpOwogICAgcmV0dXJuIHJldDsKfQoK