LyoKICogc25tcHVzbS5jIC0gc2VuZCBzbm1wIFNFVCByZXF1ZXN0cyB0byBhIG5ldHdvcmsgZW50aXR5IHRvIGNoYW5nZSB0aGUKICogICAgICAgICAgICAgdXNtIHVzZXIgZGF0YWJhc2UKICoKICogWFhYIGdldCBlbmdpbmVJRCBkeW5hbWljYWxseS4KICogWFhYIHJlYWQgcGFzc3dvcmRzIGZyb20gcHJvbXB0cwogKiBYWFggY3VzdG9taXplIHJlc3BvbnNlcyB3aXRoIHVzZXIgbmFtZXMsIGV0Yy4KICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaWYgVElNRV9XSVRIX1NZU19USU1FCiMgaWZkZWYgV0lOMzIKIyAgaW5jbHVkZSA8c3lzL3RpbWViLmg+CiMgZWxzZQojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVuZGlmCiMgaW5jbHVkZSA8dGltZS5oPgojZWxzZQojIGlmIEhBVkVfU1lTX1RJTUVfSAojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVsc2UKIyAgaW5jbHVkZSA8dGltZS5oPgojIGVuZGlmCiNlbmRpZgojaWYgSEFWRV9TWVNfU0VMRUNUX0gKI2luY2x1ZGUgPHN5cy9zZWxlY3QuaD4KI2VuZGlmCiNpZiBIQVZFX1dJTlNPQ0tfSAojaW5jbHVkZSA8d2luc29jay5oPgojZW5kaWYKI2lmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCiNpZiBIQVZFX0FSUEFfSU5FVF9ICiNpbmNsdWRlIDxhcnBhL2luZXQuaD4KI2VuZGlmCgojaWYgZGVmaW5lZChIQVZFX09QRU5TU0xfREhfSCkgJiYgZGVmaW5lZChIQVZFX0xJQkNSWVBUTykKI2luY2x1ZGUgPG9wZW5zc2wvZGguaD4KI2VuZGlmIC8qIEhBVkVfT1BFTlNTTF9ESF9IICYmIEhBVkVfTElCQ1JZUFRPICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KCmludCAgICAgICAgICAgICBtYWluKGludCwgY2hhciAqKik7CgojZGVmaW5lIENNRF9QQVNTV0RfTkFNRSAgICAicGFzc3dkIgojZGVmaW5lIENNRF9QQVNTV0QgICAgICAgICAxCiNkZWZpbmUgQ01EX0NSRUFURV9OQU1FICAgICJjcmVhdGUiCiNkZWZpbmUgQ01EX0NSRUFURSAgICAgICAgIDIKI2RlZmluZSBDTURfREVMRVRFX05BTUUgICAgImRlbGV0ZSIKI2RlZmluZSBDTURfREVMRVRFICAgICAgICAgMwojZGVmaW5lIENNRF9DTE9ORUZST01fTkFNRSAiY2xvbmVGcm9tIgojZGVmaW5lIENNRF9DTE9ORUZST00gICAgICA0CiNkZWZpbmUgQ01EX0FDVElWQVRFX05BTUUgICJhY3RpdmF0ZSIKI2RlZmluZSBDTURfQUNUSVZBVEUgICAgICAgNQojZGVmaW5lIENNRF9ERUFDVElWQVRFX05BTUUgImRlYWN0aXZhdGUiCiNkZWZpbmUgQ01EX0RFQUNUSVZBVEUgICAgIDYKI2RlZmluZSBDTURfQ0hBTkdFS0VZX05BTUUgICJjaGFuZ2VrZXkiCiNkZWZpbmUgQ01EX0NIQU5HRUtFWSAgICAgIDcKCiNkZWZpbmUgQ01EX05VTSAgICA3CgpzdGF0aWMgY29uc3QgY2hhciAqc3VjY2Vzc05vdGVzW0NNRF9OVU1dID0gewogICAgIlNOTVB2MyBLZXkocykgc3VjY2Vzc2Z1bGx5IGNoYW5nZWQuIiwKICAgICJVc2VyIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLiIsCiAgICAiVXNlciBzdWNjZXNzZnVsbHkgZGVsZXRlZC4iLAogICAgIlVzZXIgc3VjY2Vzc2Z1bGx5IGNsb25lZC4iLAogICAgIlVzZXIgc3VjY2Vzc2Z1bGx5IGFjdGl2YXRlZC4iLAogICAgIlVzZXIgc3VjY2Vzc2Z1bGx5IGRlYWN0aXZhdGVkLiIsCiAgICAiU05NUHYzIEtleShzKSBzdWNjZXNzZnVsbHkgY2hhbmdlZC4iCn07CgojZGVmaW5lICAgICAgICAgICAgICAgICAgIFVTTV9PSURfTEVOICAgIDEyCiNkZWZpbmUgICAgICAgICAgICAgICAgREhfVVNNX09JRF9MRU4gICAgMTEKCnN0YXRpYyBvaWQKCmF1dGhLZXlPaWRbTUFYX09JRF9MRU5dID0geyAxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMiwgMiwgMSwgNiB9LApvd25BdXRoS2V5T2lkW01BWF9PSURfTEVOXSA9IHsxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMiwgMiwgMSwgN30sCnByaXZLZXlPaWRbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAyLCAyLCAxLCA5fSwKb3duUHJpdktleU9pZFtNQVhfT0lEX0xFTl0gPSB7MSwgMywgNiwgMSwgNiwgMywgMTUsIDEsIDIsIDIsIDEsIDEwfSwKdXNtVXNlckNsb25lRnJvbVtNQVhfT0lEX0xFTl0gPSB7MSwgMywgNiwgMSwgNiwgMywgMTUsIDEsIDIsIDIsIDEsIDR9LAp1c21Vc2VyU2VjdXJpdHlOYW1lW01BWF9PSURfTEVOXSA9IHsxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMiwgMiwgMSwgM30sCnVzbVVzZXJQdWJsaWNbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAyLCAyLCAxLCAxMX0sCnVzbVVzZXJTdGF0dXNbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAyLCAyLCAxLCAxM30sCi8qIGRpZmZpZSBoZWxtYW4gY2hhbmdlIGtleSBvYmplY3RzICovCnVzbURIVXNlckF1dGhLZXlDaGFuZ2VbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDMsIDEwMSwgMSwgMSwgMiwgMSwgMSB9LAp1c21ESFVzZXJQcml2S2V5Q2hhbmdlW01BWF9PSURfTEVOXSA9IHsxLCAzLCA2LCAxLCAzLCAxMDEsIDEsIDEsIDIsIDEsIDMgfSwKI2lmIGRlZmluZWQoSEFWRV9PUEVOU1NMX0RIX0gpICYmIGRlZmluZWQoSEFWRV9MSUJDUllQVE8pCnVzbURIVXNlck93bkF1dGhLZXlDaGFuZ2VbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDMsIDEwMSwgMSwgMSwgMiwgMSwgMiB9LAp1c21ESFVzZXJPd25Qcml2S2V5Q2hhbmdlW01BWF9PSURfTEVOXSA9IHsxLCAzLCA2LCAxLCAzLCAxMDEsIDEsIDEsIDIsIDEsIDQgfSwKI2VuZGlmIC8qIEhBVkVfT1BFTlNTTF9ESF9IICYmIEhBVkVfTElCQ1JZUFRPICovCnVzbURIUGFyYW1ldGVyc1tdID0geyAxLDMsNiwxLDMsMTAxLDEsMSwxLDAgfQo7CnNpemVfdCB1c21ESFBhcmFtZXRlcnNfbGVuID0gT0lEX0xFTkdUSCh1c21ESFBhcmFtZXRlcnMpOwoKc3RhdGljCm9pZCAgICAgICAgICAgICphdXRoS2V5Q2hhbmdlID0gYXV0aEtleU9pZCwgKnByaXZLZXlDaGFuZ2UgPSBwcml2S2V5T2lkOwpvaWQgICAgICAgICAgICAqZGhhdXRoS2V5Q2hhbmdlID0gdXNtREhVc2VyQXV0aEtleUNoYW5nZSwKICAgICAgICAgICAgICAgKmRocHJpdktleUNoYW5nZSA9IHVzbURIVXNlclByaXZLZXlDaGFuZ2U7CmludCAgICAgICAgICAgICBkb2F1dGhrZXkgPSAwLCBkb3ByaXZrZXkgPSAwLCB1c2Vsb2NhbGl6ZWRrZXkgPSAwOwpzaXplX3QgICAgICAgICAgdXNtVXNlckVuZ2luZUlETGVuID0gMDsKdV9jaGFyICAgICAgICAgKnVzbVVzZXJFbmdpbmVJRCA9IE5VTEw7CmNoYXIgICAgICAgICAgICp1c21Vc2VyUHVibGljX3ZhbCA9IE5VTEw7CgoKdm9pZAp1c2FnZSh2b2lkKQp7CiAgICBmcHJpbnRmKHN0ZGVyciwgIlVzYWdlOiBzbm1wdXNtICIpOwogICAgc25tcF9wYXJzZV9hcmdzX3VzYWdlKHN0ZGVycik7CiAgICBmcHJpbnRmKHN0ZGVyciwgIiBDT01NQU5EXG5cbiIpOwogICAgc25tcF9wYXJzZV9hcmdzX2Rlc2NyaXB0aW9ucyhzdGRlcnIpOwogICAgZnByaW50ZihzdGRlcnIsICJcbnNubXB1c20gY29tbWFuZHM6XG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiICBbb3B0aW9uc10gY3JlYXRlICAgICBVU0VSIFtDTE9ORUZST00tVVNFUl1cbiIpOwogICAgZnByaW50ZihzdGRlcnIsICIgIFtvcHRpb25zXSBkZWxldGUgICAgIFVTRVJcbiIpOwogICAgZnByaW50ZihzdGRlcnIsICIgIFtvcHRpb25zXSBjbG9uZUZyb20gIFVTRVIgQ0xPTkVGUk9NLVVTRVJcbiIpOwogICAgZnByaW50ZihzdGRlcnIsICIgIFtvcHRpb25zXSBhY3RpdmF0ZSAgIFVTRVJcbiIpOwogICAgZnByaW50ZihzdGRlcnIsICIgIFtvcHRpb25zXSBkZWFjdGl2YXRlIFVTRVJcbiIpOwogICAgZnByaW50ZihzdGRlcnIsICIgIFtvcHRpb25zXSBbLUNhXSBbLUN4XSBjaGFuZ2VrZXkgW1VTRVJdXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAiICBbb3B0aW9uc10gWy1DYV0gWy1DeF0gcGFzc3dkIE9MRC1QQVNTUEhSQVNFIE5FVy1QQVNTUEhSQVNFIFtVU0VSXVxuIik7CiAgICBmcHJpbnRmKHN0ZGVyciwKICAgICAgICAgICAgIiAgW29wdGlvbnNdICgtQ2F8LUN4KSAtQ2sgcGFzc3dkIE9MRC1LRVktT1ItUEFTU1BIUkFTRSBORVctS0VZLU9SLVBBU1NQSFJBU0UgW1VTRVJdXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXG5zbm1wdXNtIG9wdGlvbnM6XG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXHQtQ0UgRU5HSU5FLUlEXHRTZXQgdXNtVXNlckVuZ2luZUlEIChlLmcuIDgwMDAwMDAyMDEwOTg0MDMwMSkuXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXHQtQ3AgU1RSSU5HXHRTZXQgdXNtVXNlclB1YmxpYyB2YWx1ZSB0byBTVFJJTkcuXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXHQtQ3hcdFx0Q2hhbmdlIHRoZSBwcml2YWN5IGtleS5cbiIpOwogICAgZnByaW50ZihzdGRlcnIsICJcdC1DYVx0XHRDaGFuZ2UgdGhlIGF1dGhlbnRpY2F0aW9uIGtleS5cbiIpOwogICAgZnByaW50ZihzdGRlcnIsICJcdC1Da1x0XHRBbGxvd3MgdG8gdXNlIGxvY2FsaXplZCBrZXkgKG11c3Qgc3RhcnQgd2l0aCAweClcbiIpOwogICAgZnByaW50ZihzdGRlcnIsICJcdFx0XHRpbnN0ZWFkIG9mIHBhc3NwaHJhc2UuXG4iKTsKfQoKLyoKICogc2V0dXBfb2lkIGFwcGVuZHMgdG8gdGhlIG9pZCB0aGUgaW5kZXggZm9yIHRoZSBlbmdpbmVpZC91c2VyIAogKi8Kdm9pZApzZXR1cF9vaWQob2lkICogaXQsIHNpemVfdCAqIGxlbiwgdV9jaGFyICogaWQsIHNpemVfdCBpZGxlbiwKICAgICAgICAgIGNvbnN0IGNoYXIgKnVzZXIpCnsKICAgIGludCAgICAgICAgICAgICBpLCBpdEluZGV4ID0gKmxlbjsKCiAgICAqbGVuID0gaXRJbmRleCArIDEgKyBpZGxlbiArIDEgKyBzdHJsZW4odXNlcik7CgogICAgaXRbaXRJbmRleCsrXSA9IGlkbGVuOwogICAgZm9yIChpID0gMDsgaSA8IChpbnQpIGlkbGVuOyBpKyspIHsKICAgICAgICBpdFtpdEluZGV4KytdID0gaWRbaV07CiAgICB9CgogICAgaXRbaXRJbmRleCsrXSA9IHN0cmxlbih1c2VyKTsKICAgIGZvciAoaSA9IDA7IGkgPCAoaW50KSBzdHJsZW4odXNlcik7IGkrKykgewogICAgICAgIGl0W2l0SW5kZXgrK10gPSB1c2VyW2ldOwogICAgfQoKI2lmZGVmIE5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERQogICAgZnByaW50ZihzdGRvdXQsICJzZXR1cF9vaWQ6ICIpOyAgCiAgICBmcHJpbnRfb2JqaWQoc3Rkb3V0LCBpdCwgKmxlbik7ICAKICAgIGZwcmludGYoc3Rkb3V0LCAiXG4iKTsgIAojZW5kaWYKfQoKI2lmIGRlZmluZWQoSEFWRV9PUEVOU1NMX0RIX0gpICYmIGRlZmluZWQoSEFWRV9MSUJDUllQVE8pCmludApnZXRfVVNNX0RIX2tleShuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnMsIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqZGh2YXIsCiAgICAgICAgICAgICAgIHNpemVfdCBvdXRrZXlfbGVuLAogICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqcGR1LCBjb25zdCBjaGFyICprZXluYW1lLAogICAgICAgICAgICAgICBvaWQgKmtleW9pZCwgc2l6ZV90IGtleW9pZF9sZW4pIHsKICAgIHVfY2hhciAqZGhrZXljaGFuZ2U7CiAgICBESCAqZGg7CiAgICBCSUdOVU0gKm90aGVyX3B1YjsKICAgIHVfY2hhciAqa2V5OwogICAgc2l6ZV90IGtleV9sZW47CiAgICB1bnNpZ25lZCBjaGFyICpjcDsKICAgICAgICAgICAgCiAgICBkaGtleWNoYW5nZSA9ICh1X2NoYXIgKikgbWFsbG9jKDIgKiB2YXJzLT52YWxfbGVuICogc2l6ZW9mKGNoYXIpKTsKICAgIGlmICghZGhrZXljaGFuZ2UpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgCiAgICBtZW1jcHkoZGhrZXljaGFuZ2UsIHZhcnMtPnZhbC5zdHJpbmcsIHZhcnMtPnZhbF9sZW4pOwoKICAgIGNwID0gZGh2YXItPnZhbC5zdHJpbmc7CiAgICBkaCA9IGQyaV9ESHBhcmFtcyhOVUxMLCAoY29uc3QgdW5zaWduZWQgY2hhciAqKikgJmNwLAogICAgICAgICAgICAgICAgICAgICAgZGh2YXItPnZhbF9sZW4pOwoKICAgIGlmICghZGggfHwgIWRoLT5nIHx8ICFkaC0+cCkgewogICAgICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIERIX2dlbmVyYXRlX2tleShkaCk7CiAgICBpZiAoIWRoLT5wdWJfa2V5KSB7CiAgICAgICAgU05NUF9GUkVFKGRoa2V5Y2hhbmdlKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CiAgICAgICAgICAgIAogICAgaWYgKHZhcnMtPnZhbF9sZW4gIT0gQk5fbnVtX2J5dGVzKGRoLT5wdWJfa2V5KSkgewogICAgICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICAgICAgZnByaW50ZihzdGRlcnIsImluY29ycmVjdCBkaWZmaWUtaGVsbWFuIGxlbmd0aHMgKCVsdSAhPSAlZClcbiIsCiAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZyl2YXJzLT52YWxfbGVuLCBCTl9udW1fYnl0ZXMoZGgtPnB1Yl9rZXkpKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgQk5fYm4yYmluKGRoLT5wdWJfa2V5LCBkaGtleWNoYW5nZSArIHZhcnMtPnZhbF9sZW4pOwoKICAgIGtleV9sZW4gPSBESF9zaXplKGRoKTsKICAgIGlmICgha2V5X2xlbikgewogICAgICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQogICAga2V5ID0gKHVfY2hhciAqKSBtYWxsb2Moa2V5X2xlbiAqIHNpemVvZih1X2NoYXIpKTsKCiAgICBpZiAoIWtleSkgewogICAgICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIG90aGVyX3B1YiA9IEJOX2JpbjJibih2YXJzLT52YWwuc3RyaW5nLCB2YXJzLT52YWxfbGVuLCBOVUxMKTsKICAgIGlmICghb3RoZXJfcHViKSB7CiAgICAgICAgU05NUF9GUkVFKGRoa2V5Y2hhbmdlKTsKICAgICAgICBTTk1QX0ZSRUUoa2V5KTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgaWYgKERIX2NvbXB1dGVfa2V5KGtleSwgb3RoZXJfcHViLCBkaCkpIHsKICAgICAgICB1X2NoYXIgKmtwOwoKICAgICAgICBwcmludGYoIm5ldyAlcyBrZXk6IDB4Iiwga2V5bmFtZSk7CiAgICAgICAgZm9yKGtwID0ga2V5ICsga2V5X2xlbiAtIG91dGtleV9sZW47CiAgICAgICAgICAgIGtwIC0ga2V5IDwga2V5X2xlbjsgIGtwKyspIHsKICAgICAgICAgICAgcHJpbnRmKCIlMDJ4IiwgKHVuc2lnbmVkIGNoYXIpICprcCk7CiAgICAgICAgfQogICAgICAgIHByaW50ZigiXG4iKTsKICAgIH0KCiAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBrZXlvaWQsIGtleW9pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX09DVEVUX1NUUiwgZGhrZXljaGFuZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgMiAqIHZhcnMtPnZhbF9sZW4pOwoKICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICBTTk1QX0ZSRUUob3RoZXJfcHViKTsKICAgIFNOTVBfRlJFRShrZXkpOwoKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KI2VuZGlmIC8qIEhBVkVfT1BFTlNTTF9ESF9IICovCgpzdGF0aWMgdm9pZApvcHRQcm9jKGludCBhcmdjLCBjaGFyICpjb25zdCAqYXJndiwgaW50IG9wdCkKewogICAgc3dpdGNoIChvcHQpIHsKICAgIGNhc2UgJ0MnOgogICAgICAgIHdoaWxlICgqb3B0YXJnKSB7CiAgICAgICAgICAgIHN3aXRjaCAoKm9wdGFyZysrKSB7CiAgICAgICAgICAgIGNhc2UgJ2EnOgogICAgICAgICAgICAgICAgZG9hdXRoa2V5ID0gMTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAneCc6CiAgICAgICAgICAgICAgICBkb3ByaXZrZXkgPSAxOwogICAgICAgICAgICAgICAgYnJlYWs7CgoJICAgIGNhc2UgJ2snOgoJICAgICAgICB1c2Vsb2NhbGl6ZWRrZXkgPSAxOwoJCWJyZWFrOwoKCSAgICBjYXNlICdwJzoKICAgICAgICAgICAgICAgIGlmIChvcHRpbmQgPCBhcmdjKSB7CgkJICAgIHVzbVVzZXJQdWJsaWNfdmFsID0gIGFyZ3Zbb3B0aW5kXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJCYWQgLUNwIG9wdGlvbjogbm8gYXJndW1lbnQgZ2l2ZW5cbiIpOwogICAgICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBvcHRpbmQrKzsKICAgICAgICAgICAgICAgIGJyZWFrOwoKCSAgICBjYXNlICdFJzogewoJICAgICAgICBzaXplX3QgZWJ1Zl9sZW4gPSAzMjsgLyogWFhYOiBNQVhfRU5HSU5FSURfTEVOR1RIICovCiAgICAgICAgICAgICAgICB1X2NoYXIgKmVidWY7CiAgICAgICAgICAgICAgICBpZiAob3B0aW5kIDwgYXJnYykgewogICAgICAgICAgICAgICAgICAgIGlmIChhcmd2W29wdGluZF0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgZWJ1ZiA9ICh1X2NoYXIgKiltYWxsb2MoZWJ1Zl9sZW4pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWJ1ZiA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtYWxsb2MgZmFpbHVyZSBwcm9jZXNzaW5nIC1DRSBvcHRpb24uXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCQkgICAgICAgIGlmICghc25tcF9oZXhfdG9fYmluYXJ5KCZlYnVmLCAmZWJ1Zl9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ1c21Vc2VyRW5naW5lSURMZW4sIDEsIGFyZ3Zbb3B0aW5kXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJhZCB1c21Vc2VyRW5naW5lSUQgdmFsdWUgYWZ0ZXIgLUNFIG9wdGlvbi5cbiIpOwoJCSAgICAgICAgICAgIGZyZWUoZWJ1Zik7CgkJICAgICAgICAgICAgZXhpdCgxKTsKCQkgICAgICAgIH0KCQkgICAgICAgIHVzbVVzZXJFbmdpbmVJRCA9IGVidWY7CgkJICAgICAgICBERUJVR01TR1RMKCgic25tcHVzbSIsICJ1c21Vc2VyRW5naW5lSUQgc2V0IHRvOiAiKSk7CgkJICAgICAgICBERUJVR01TR0hFWCgoInNubXB1c20iLCB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbikpOwoJCSAgICAgICAgREVCVUdNU0coKCJzbm1wdXNtIiwgIlxuIikpOwoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiQmFkIC1DRSBvcHRpb246IG5vIGFyZ3VtZW50IGdpdmVuXG4iKTsKICAgICAgICAgICAgICAgICAgICBleGl0KDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgb3B0aW5kKys7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5rbm93biBmbGFnIHBhc3NlZCB0byAtQzogJWNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGFyZ1stMV0pOwogICAgICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KfQoKaW50Cm1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkKewogICAgbmV0c25tcF9zZXNzaW9uIHNlc3Npb24sICpzczsKICAgIG5ldHNubXBfcGR1ICAgICpwZHUgPSBOVUxMLCAqcmVzcG9uc2UgPSBOVUxMOwoKICAgIGludCAgICAgICAgICAgICBhcmc7CiAgICBzaXplX3QgICAgICAgICAgbmFtZV9sZW5ndGggPSBVU01fT0lEX0xFTjsKICAgIHNpemVfdCAgICAgICAgICBuYW1lX2xlbmd0aDIgPSBVU01fT0lEX0xFTjsKICAgIGludCAgICAgICAgICAgICBzdGF0dXM7CiAgICBpbnQgICAgICAgICAgICAgZXhpdHZhbCA9IDA7CiAgICBpbnQgICAgICAgICAgICAgcnZhbDsKICAgIGludCAgICAgICAgICAgICBjb21tYW5kID0gMDsKICAgIGxvbmcgICAgICAgICAgICBsb25ndmFyOwoKICAgIHNpemVfdCAgICAgICAgICBvbGRLdV9sZW4gPSBTTk1QX01BWEJVRl9TTUFMTCwKICAgICAgICBuZXdLdV9sZW4gPSBTTk1QX01BWEJVRl9TTUFMTCwKICAgICAgICBvbGRrdWxfbGVuID0gU05NUF9NQVhCVUZfU01BTEwsCiAgICAgICAgb2xka3VscHJpdl9sZW4gPSBTTk1QX01BWEJVRl9TTUFMTCwKICAgICAgICBuZXdrdWxwcml2X2xlbiA9IFNOTVBfTUFYQlVGX1NNQUxMLAogICAgICAgIG5ld2t1bF9sZW4gPSBTTk1QX01BWEJVRl9TTUFMTCwKICAgICAgICBrZXljaGFuZ2VfbGVuID0gU05NUF9NQVhCVUZfU01BTEwsCiAgICAgICAga2V5Y2hhbmdlcHJpdl9sZW4gPSBTTk1QX01BWEJVRl9TTUFMTDsKCiAgICBjaGFyICAgICAgICAgICAqbmV3cGFzcyA9IE5VTEwsICpvbGRwYXNzID0gTlVMTDsKICAgIHVfY2hhciAgICAgICAgICBvbGRLdVtTTk1QX01BWEJVRl9TTUFMTF0sCiAgICAgICAgbmV3S3VbU05NUF9NQVhCVUZfU01BTExdLAogICAgICAgIG9sZGt1bFtTTk1QX01BWEJVRl9TTUFMTF0sCiAgICAgICAgb2xka3VscHJpdltTTk1QX01BWEJVRl9TTUFMTF0sCiAgICAgICAgbmV3a3VscHJpdltTTk1QX01BWEJVRl9TTUFMTF0sCiAgICAgICAgbmV3a3VsW1NOTVBfTUFYQlVGX1NNQUxMXSwga2V5Y2hhbmdlW1NOTVBfTUFYQlVGX1NNQUxMXSwKICAgICAgICBrZXljaGFuZ2Vwcml2W1NOTVBfTUFYQlVGX1NNQUxMXTsKCiAgICBhdXRoS2V5Q2hhbmdlID0gYXV0aEtleU9pZDsKICAgIHByaXZLZXlDaGFuZ2UgPSBwcml2S2V5T2lkOwoKICAgIC8qCiAgICAgKiBnZXQgdGhlIGNvbW1vbiBjb21tYW5kIGxpbmUgYXJndW1lbnRzIAogICAgICovCiAgICBzd2l0Y2ggKGFyZyA9IHNubXBfcGFyc2VfYXJncyhhcmdjLCBhcmd2LCAmc2Vzc2lvbiwgIkM6Iiwgb3B0UHJvYykpIHsKICAgIGNhc2UgLTI6CiAgICAgICAgZXhpdCgwKTsKICAgIGNhc2UgLTE6CiAgICAgICAgdXNhZ2UoKTsKICAgICAgICBleGl0KDEpOwogICAgZGVmYXVsdDoKICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoYXJnID49IGFyZ2MpIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlBsZWFzZSBzcGVjaWZ5IGFuIG9wZXJhdGlvbiB0byBwZXJmb3JtLlxuIik7CiAgICAgICAgdXNhZ2UoKTsKICAgICAgICBleGl0KDEpOwogICAgfQoKICAgIFNPQ0tfU1RBUlRVUDsKCiAgICAvKgogICAgICogb3BlbiBhbiBTTk1QIHNlc3Npb24gCiAgICAgKi8KICAgIC8qCiAgICAgKiBOb3RlOiAgdGhpcyBuZWVkcyB0byBvYnRhaW4gdGhlIGVuZ2luZUlEIHVzZWQgYmVsb3cgCiAgICAgKi8KICAgIHNlc3Npb24uZmxhZ3MgJj0gflNOTVBfRkxBR1NfRE9OVF9QUk9CRTsKICAgIHNzID0gc25tcF9vcGVuKCZzZXNzaW9uKTsKICAgIGlmIChzcyA9PSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkaWFnbm9zZSBzbm1wX29wZW4gZXJyb3JzIHdpdGggdGhlIGlucHV0IG5ldHNubXBfc2Vzc2lvbiBwb2ludGVyIAogICAgICAgICAqLwogICAgICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXB1c20iLCAmc2Vzc2lvbik7CiAgICAgICAgZXhpdCgxKTsKICAgIH0KCiAgICAvKgogICAgICogc2V0IHVzbVVzZXJFbmdpbmVJRCBmcm9tIHNzLT5jb250ZXh0RW5naW5lSUQKICAgICAqICAgaWYgbm90IGFscmVhZHkgc2V0ICh2aWEgLUNFKQogICAgICovCiAgICBpZiAodXNtVXNlckVuZ2luZUlEID09IE5VTEwpIHsKICAgICAgdXNtVXNlckVuZ2luZUlEICAgID0gc3MtPmNvbnRleHRFbmdpbmVJRDsKICAgICAgdXNtVXNlckVuZ2luZUlETGVuID0gc3MtPmNvbnRleHRFbmdpbmVJRExlbjsKICAgIH0KCiAgICAvKgogICAgICogY3JlYXRlIFBEVSBmb3IgU0VUIHJlcXVlc3QgYW5kIGFkZCBvYmplY3QgbmFtZXMgYW5kIHZhbHVlcyB0byByZXF1ZXN0IAogICAgICovCiAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoU05NUF9NU0dfU0VUKTsKICAgIGlmICghcGR1KSB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsICJGYWlsZWQgdG8gY3JlYXRlIHJlcXVlc3RcbiIpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CgoKICAgIGlmIChzdHJjbXAoYXJndlthcmddLCBDTURfUEFTU1dEX05BTUUpID09IDApIHsKCiAgICAgICAgLyoKICAgICAgICAgKiBwYXNzd2Q6IGNoYW5nZSBhIHVzZXJzIHBhc3N3b3JkLgogICAgICAgICAqCiAgICAgICAgICogWFhYOiAgVXNlcyB0aGUgYXV0aCB0eXBlIG9mIHRoZSBjYWxsaW5nIHVzZXIsIGEgTUQ1IHVzZXIgY2FuJ3QKICAgICAgICAgKiAgICAgICBjaGFuZ2UgYSBTSEEgdXNlcidzIGtleS4KICAgICAgICAgKi8KICAgICAgICBjaGFyICpwYXNzd2RfdXNlcjsKCiAgICAgICAgY29tbWFuZCA9IENNRF9QQVNTV0Q7CiAgICAgICAgb2xkcGFzcyA9IGFyZ3ZbKythcmddOwogICAgICAgIG5ld3Bhc3MgPSBhcmd2WysrYXJnXTsKICAgICAgICBwYXNzd2RfdXNlciA9IGFyZ3ZbKythcmddOwoKICAgICAgICBpZiAoZG9wcml2a2V5ID09IDAgJiYgZG9hdXRoa2V5ID09IDApCiAgICAgICAgICAgIGRvcHJpdmtleSA9IGRvYXV0aGtleSA9IDE7CgogICAgICAgIGlmIChuZXdwYXNzID09IE5VTEwgfHwgc3RybGVuKG5ld3Bhc3MpIDwgVVNNX0xFTkdUSF9QX01JTikgewogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwKICAgICAgICAgICAgICAgICAgICAiTmV3IHBhc3NwaHJhc2UgbXVzdCBiZSBncmVhdGVyIHRoYW4gJWQgY2hhcmFjdGVycyBpbiBsZW5ndGguXG4iLAogICAgICAgICAgICAgICAgICAgIFVTTV9MRU5HVEhfUF9NSU4pOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG9sZHBhc3MgPT0gTlVMTCB8fCBzdHJsZW4ob2xkcGFzcykgPCBVU01fTEVOR1RIX1BfTUlOKSB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAgICAgICAgICJPbGQgcGFzc3BocmFzZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlZCBjaGFyYWN0ZXJzIGluIGxlbmd0aC5cbiIsCiAgICAgICAgICAgICAgICAgICAgVVNNX0xFTkdUSF9QX01JTik7CiAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgfQoKICAgICAgICAvKiAKICAgICAgICAgKiBDaGFuZ2UgdGhlIHVzZXIgc3VwcGxpZWQgb24gY29tbWFuZCBsaW5lLgogICAgICAgICAqLwogICAgICAgIGlmICgocGFzc3dkX3VzZXIgIT0gTlVMTCkgJiYgKHN0cmxlbihwYXNzd2RfdXNlcikgPiAwKSkgewogICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5TmFtZSA9IHBhc3N3ZF91c2VyOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFVzZSBvd24ga2V5IG9iamVjdCBpZiBubyB1c2VyIHdhcyBzdXBwbGllZC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGF1dGhLZXlDaGFuZ2UgPSBvd25BdXRoS2V5T2lkOwogICAgICAgICAgICBwcml2S2V5Q2hhbmdlID0gb3duUHJpdktleU9pZDsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogZG8gd2UgaGF2ZSBhIHNlY3VyaXR5TmFtZT8gIElmIG5vdCwgY29weSB0aGUgZGVmYXVsdCAKICAgICAgICAgKi8KICAgICAgICBpZiAoc2Vzc2lvbi5zZWN1cml0eU5hbWUgPT0gTlVMTCkgewogICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5TmFtZSA9IAoJICAgICAgc3RyZHVwKG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJCSAgIE5FVFNOTVBfRFNfTElCX1NFQ05BTUUpKTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogdGhlIG9sZCBLdSBpcyBpbiB0aGUgc2Vzc2lvbiwgYnV0IHdlIG5lZWQgdGhlIG5ldyBvbmUgCiAgICAgICAgICovCiAgICAgICAgaWYgKHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8gPT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBnZXQgLmNvbmYgc2V0IGRlZmF1bHQgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjb25zdCBvaWQgICAgICAqZGVmID0KICAgICAgICAgICAgICAgIGdldF9kZWZhdWx0X2F1dGh0eXBlKCZzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvTGVuKTsKICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90byA9CiAgICAgICAgICAgICAgICBzbm1wX2R1cGxpY2F0ZV9vYmppZChkZWYsIHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG9MZW4pOwogICAgICAgIH0KICAgICAgICBpZiAoc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90byA9PSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGFzc3VtZSBNRDUgCiAgICAgICAgICAgICAqLwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NRDUKICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90b0xlbiA9CiAgICAgICAgICAgICAgICBzaXplb2YodXNtSE1BQ01ENUF1dGhQcm90b2NvbCkgLyBzaXplb2Yob2lkKTsKICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90byA9CiAgICAgICAgICAgICAgICBzbm1wX2R1cGxpY2F0ZV9vYmppZCh1c21ITUFDTUQ1QXV0aFByb3RvY29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90b0xlbik7CiNlbHNlCiAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG9MZW4gPQogICAgICAgICAgICAgICAgc2l6ZW9mKHVzbUhNQUNTSEExQXV0aFByb3RvY29sKSAvIHNpemVvZihvaWQpOwogICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvID0KICAgICAgICAgICAgICAgIHNubXBfZHVwbGljYXRlX29iamlkKHVzbUhNQUNTSEExQXV0aFByb3RvY29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90b0xlbik7CiNlbmRpZgoKICAgICAgICB9CgoJaWYgKHVzZWxvY2FsaXplZGtleSAmJiAoc3RybmNtcChvbGRwYXNzLCAiMHgiLCAyKSA9PSAwKSkgewoJICAgIC8qCgkgICAgICogdXNlIHRoZSBsb2NhbGl6ZWQga2V5IGZyb20gdGhlIGNvbW1hbmQgbGluZQoJICAgICAqLwoJICAgIHVfY2hhciAqYnVmOwoJICAgIHNpemVfdCBidWZfbGVuID0gU05NUF9NQVhCVUZfU01BTEw7CgkgICAgYnVmID0gKHVfY2hhciAqKSBtYWxsb2MgKGJ1Zl9sZW4gKiBzaXplb2YodV9jaGFyKSk7CgoJICAgIG9sZGt1bF9sZW4gPSAwOyAvKiBpbml0aWFsaXplIHRoZSBvZmZzZXQgKi8KCSAgICBpZiAoIXNubXBfaGV4X3RvX2JpbmFyeSgodV9jaGFyICoqKSAoJmJ1ZiksICZidWZfbGVuLCAmb2xka3VsX2xlbiwgMCwgb2xkcGFzcykpIHsKCSAgICAgIHNubXBfcGVycm9yKGFyZ3ZbMF0pOwoJICAgICAgZnByaW50ZihzdGRlcnIsICJnZW5lcmF0aW5nIHRoZSBvbGQgS3VsIGZyb20gbG9jYWxpemVkIGtleSBmYWlsZWRcbiIpOwoJICAgICAgZXhpdCgxKTsKCSAgICB9CgkgICAgCgkgICAgbWVtY3B5KG9sZGt1bCwgYnVmLCBvbGRrdWxfbGVuKTsKCSAgICBTTk1QX0ZSRUUoYnVmKTsKCX0KCWVsc2UgewoJICAgIC8qCgkgICAgICogdGhlIG9sZCBLdSBpcyBpbiB0aGUgc2Vzc2lvbiwgYnV0IHdlIG5lZWQgdGhlIG5ldyBvbmUgCgkgICAgICovCgkgICAgcnZhbCA9IGdlbmVyYXRlX0t1KHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8sCgkJCSAgICAgICBzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvTGVuLAoJCQkgICAgICAgKHVfY2hhciAqKSBvbGRwYXNzLCBzdHJsZW4ob2xkcGFzcyksCgkJCSAgICAgICBvbGRLdSwgJm9sZEt1X2xlbik7CgkgICAgCgkgICAgaWYgKHJ2YWwgIT0gU05NUEVSUl9TVUNDRVNTKSB7CgkgICAgICAgIHNubXBfcGVycm9yKGFyZ3ZbMF0pOwoJICAgICAgICBmcHJpbnRmKHN0ZGVyciwgImdlbmVyYXRpbmcgdGhlIG9sZCBLdSBmYWlsZWRcbiIpOwoJICAgICAgICBleGl0KDEpOwoJICAgIH0KCgkgICAgLyoKCSAgICAgKiBnZW5lcmF0ZSB0aGUgdHdvIEt1bCdzIAoJICAgICAqLwoJICAgIHJ2YWwgPSBnZW5lcmF0ZV9rdWwoc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90bywKCQkJCXNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG9MZW4sCgkJCQl1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwKCQkJCW9sZEt1LCBvbGRLdV9sZW4sIG9sZGt1bCwgJm9sZGt1bF9sZW4pOwoJICAgIAoJICAgIGlmIChydmFsICE9IFNOTVBFUlJfU1VDQ0VTUykgewoJICAgICAgICBzbm1wX3BlcnJvcihhcmd2WzBdKTsKCQlmcHJpbnRmKHN0ZGVyciwgImdlbmVyYXRpbmcgdGhlIG9sZCBLdWwgZmFpbGVkXG4iKTsKCQlleGl0KDEpOwoJICAgIH0KCX0KCWlmICh1c2Vsb2NhbGl6ZWRrZXkgJiYgKHN0cm5jbXAobmV3cGFzcywgIjB4IiwgMikgPT0gMCkpIHsKCSAgICAvKgoJICAgICAqIHVzZSB0aGUgbG9jYWxpemVkIGtleSBmcm9tIHRoZSBjb21tYW5kIGxpbmUKCSAgICAgKi8KCSAgICB1X2NoYXIgKmJ1ZjsKCSAgICBzaXplX3QgYnVmX2xlbiA9IFNOTVBfTUFYQlVGX1NNQUxMOwoJICAgIGJ1ZiA9ICh1X2NoYXIgKikgbWFsbG9jIChidWZfbGVuICogc2l6ZW9mKHVfY2hhcikpOwoKCSAgICBuZXdrdWxfbGVuID0gMDsgLyogaW5pdGlhbGl6ZSB0aGUgb2Zmc2V0ICovCgkgICAgaWYgKCFzbm1wX2hleF90b19iaW5hcnkoKHVfY2hhciAqKikgKCZidWYpLCAmYnVmX2xlbiwgJm5ld2t1bF9sZW4sIDAsIG5ld3Bhc3MpKSB7CgkgICAgICBzbm1wX3BlcnJvcihhcmd2WzBdKTsKCSAgICAgIGZwcmludGYoc3RkZXJyLCAiZ2VuZXJhdGluZyB0aGUgbmV3IEt1bCBmcm9tIGxvY2FsaXplZCBrZXkgZmFpbGVkXG4iKTsKCSAgICAgIGV4aXQoMSk7CgkgICAgfQoJICAgIAoJICAgIG1lbWNweShuZXdrdWwsIGJ1ZiwgbmV3a3VsX2xlbik7CgkgICAgU05NUF9GUkVFKGJ1Zik7Cgl9IGVsc2UgewogICAgICAgICAgICBydmFsID0gZ2VuZXJhdGVfS3Uoc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90bywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG9MZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIG5ld3Bhc3MsIHN0cmxlbihuZXdwYXNzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0t1LCAmbmV3S3VfbGVuKTsKCiAgICAgICAgICAgIGlmIChydmFsICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgICAgICAgICAgc25tcF9wZXJyb3IoYXJndlswXSk7CiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgImdlbmVyYXRpbmcgdGhlIG5ldyBLdSBmYWlsZWRcbiIpOwogICAgICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICAgICAgfQoKCSAgICBydmFsID0gZ2VuZXJhdGVfa3VsKHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8sCgkJCQlzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvTGVuLAoJCQkJdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sCgkJCQluZXdLdSwgbmV3S3VfbGVuLCBuZXdrdWwsICZuZXdrdWxfbGVuKTsKCgkgICAgaWYgKHJ2YWwgIT0gU05NUEVSUl9TVUNDRVNTKSB7CgkgICAgICAgIHNubXBfcGVycm9yKGFyZ3ZbMF0pOwoJCWZwcmludGYoc3RkZXJyLCAiZ2VuZXJhdGluZyB0aGUgbmV3IEt1bCBmYWlsZWRcbiIpOwoJCWV4aXQoMSk7CgkgICAgfQoJfQoKICAgICAgICAvKgogICAgICAgICAqIGZvciBlbmNyeXB0aW9uLCB3ZSBtYXkgbmVlZCB0byB0cnVuY2F0ZSB0aGUga2V5IHRvIHRoZSBwcm9wZXIgbGVuZ3RoCiAgICAgICAgICogc28gd2UgbmVlZCB0d28gY29waWVzLiAgRm9yIHNpbXBsaWNpdHksIHdlIGFsd2F5cyBqdXN0IGNvcHkgZXZlbiBpZgogICAgICAgICAqIHRoZXkncmUgdGhlIHNhbWUgbGVuZ3Rocy4KICAgICAgICAgKi8KICAgICAgICBpZiAoZG9wcml2a2V5KSB7CiAgICAgICAgICAgIGlmICghc2Vzc2lvbi5zZWN1cml0eVByaXZQcm90bykgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5vIGVuY3J5cHRpb24gdHlwZSBzcGVjaWZpZWQsIHdoaWNoIEkgbmVlZCBpbiBvcmRlciB0byBrbm93IHRvIGNoYW5nZSB0aGUga2V5XG4iKTsKICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9ERVMKICAgICAgICAgICAgaWYgKElTVFJBTlNGT1JNKHNlc3Npb24uc2VjdXJpdHlQcml2UHJvdG8sIERFU1ByaXYpKSB7CiAgICAgICAgICAgICAgICAvKiBERVMgdXNlcyBhIDEyOCBiaXQga2V5LCA2NCBiaXRzIG9mIHdoaWNoIGlzIGEgc2FsdCAqLwogICAgICAgICAgICAgICAgb2xka3VscHJpdl9sZW4gPSBuZXdrdWxwcml2X2xlbiA9IDE2OwogICAgICAgICAgICB9CiNlbmRpZgojaWZkZWYgSEFWRV9BRVMKICAgICAgICAgICAgaWYgKElTVFJBTlNGT1JNKHNlc3Npb24uc2VjdXJpdHlQcml2UHJvdG8sIEFFU1ByaXYpKSB7CiAgICAgICAgICAgICAgICBvbGRrdWxwcml2X2xlbiA9IG5ld2t1bHByaXZfbGVuID0gMTY7CiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIG1lbWNweShvbGRrdWxwcml2LCBvbGRrdWwsIG9sZGt1bHByaXZfbGVuKTsKICAgICAgICAgICAgbWVtY3B5KG5ld2t1bHByaXYsIG5ld2t1bCwgbmV3a3VscHJpdl9sZW4pOwogICAgICAgIH0KICAgICAgICAgICAgCgogICAgICAgIC8qCiAgICAgICAgICogY3JlYXRlIHRoZSBrZXljaGFuZ2Ugc3RyaW5nIAogICAgICAgICAqLwoJaWYgKGRvYXV0aGtleSkgewoJICBydmFsID0gZW5jb2RlX2tleWNoYW5nZShzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvLAoJCQkJICBzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvTGVuLAoJCQkJICBvbGRrdWwsIG9sZGt1bF9sZW4sCgkJCQkgIG5ld2t1bCwgbmV3a3VsX2xlbiwKCQkJCSAga2V5Y2hhbmdlLCAma2V5Y2hhbmdlX2xlbik7CgoJICBpZiAocnZhbCAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKCSAgICBzbm1wX3BlcnJvcihhcmd2WzBdKTsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJlbmNvZGluZyB0aGUga2V5Y2hhbmdlIGZhaWxlZFxuIik7CiAgICAgICAgICAgIHVzYWdlKCk7CiAgICAgICAgICAgIGV4aXQoMSk7CgkgIH0KCX0KCiAgICAgICAgLyogd2hpY2ggaXMgc2xpZ2h0bHkgZGlmZmVyZW50IGZvciBlbmNyeXB0aW9uIGlmIGxlbmd0aHMgYXJlCiAgICAgICAgICAgZGlmZmVyZW50ICovCglpZiAoZG9wcml2a2V5KSB7CgkgIHJ2YWwgPSBlbmNvZGVfa2V5Y2hhbmdlKHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90b0xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRrdWxwcml2LCBvbGRrdWxwcml2X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdrdWxwcml2LCBuZXdrdWxwcml2X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXljaGFuZ2Vwcml2LCAma2V5Y2hhbmdlcHJpdl9sZW4pOwoKCSAgaWYgKHJ2YWwgIT0gU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIHNubXBfcGVycm9yKGFyZ3ZbMF0pOwogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgImVuY29kaW5nIHRoZSBrZXljaGFuZ2UgZmFpbGVkXG4iKTsKICAgICAgICAgICAgdXNhZ2UoKTsKICAgICAgICAgICAgZXhpdCgxKTsKCSAgfQoJfQoKICAgICAgICAvKgogICAgICAgICAqIGFkZCB0aGUga2V5Y2hhbmdlIHN0cmluZyB0byB0aGUgb3V0Z29pbmcgcGFja2V0IAogICAgICAgICAqLwogICAgICAgIGlmIChkb2F1dGhrZXkpIHsKICAgICAgICAgICAgc2V0dXBfb2lkKGF1dGhLZXlDaGFuZ2UsICZuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLAogICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eU5hbWUpOwogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBhdXRoS2V5Q2hhbmdlLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9PQ1RFVF9TVFIsIGtleWNoYW5nZSwga2V5Y2hhbmdlX2xlbik7CiAgICAgICAgfQogICAgICAgIGlmIChkb3ByaXZrZXkpIHsKICAgICAgICAgICAgc2V0dXBfb2lkKHByaXZLZXlDaGFuZ2UsICZuYW1lX2xlbmd0aDIsCiAgICAgICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwKICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlOYW1lKTsKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgcHJpdktleUNoYW5nZSwgbmFtZV9sZW5ndGgyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX09DVEVUX1NUUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleWNoYW5nZXByaXYsIGtleWNoYW5nZXByaXZfbGVuKTsKICAgICAgICB9CgogICAgfSBlbHNlIGlmIChzdHJjbXAoYXJndlthcmddLCBDTURfQ1JFQVRFX05BTUUpID09IDApIHsKICAgICAgICAvKgogICAgICAgICAqIGNyZWF0ZTogIGNyZWF0ZSBhIHVzZXIKICAgICAgICAgKgogICAgICAgICAqIGNyZWF0ZSBVU0VSIFtDTE9ORUZST01dCiAgICAgICAgICovCiAgICAgICAgaWYgKCsrYXJnID49IGFyZ2MpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJZb3UgbXVzdCBzcGVjaWZ5IHRoZSB1c2VyIG5hbWUgdG8gY3JlYXRlXG4iKTsKICAgICAgICAgICAgdXNhZ2UoKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIGNvbW1hbmQgPSBDTURfQ1JFQVRFOwoKICAgICAgICBpZiAoKythcmcgPCBhcmdjKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNsb25lIHRoZSBuZXcgdXNlciBmcm9tIGFuIGV4aXN0aW5nIHVzZXIKICAgICAgICAgICAgICogICAoYW5kIG1ha2UgdGhlbSBhY3RpdmUgaW1tZWRpYXRlbHkpCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzZXR1cF9vaWQodXNtVXNlclN0YXR1cywgJm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sIGFyZ3ZbYXJnLTFdKTsKICAgICAgICAgICAgbG9uZ3ZhciA9IFJTX0NSRUFURUFOREdPOwogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCB1c21Vc2VyU3RhdHVzLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JTlRFR0VSLCAodV9jaGFyICopICYgbG9uZ3ZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihsb25ndmFyKSk7CgogICAgICAgICAgICBuYW1lX2xlbmd0aCA9IFVTTV9PSURfTEVOOwogICAgICAgICAgICBzZXR1cF9vaWQodXNtVXNlckNsb25lRnJvbSwgJm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICBhcmd2W2FyZyAtIDFdKTsKICAgICAgICAgICAgc2V0dXBfb2lkKHVzbVVzZXJTZWN1cml0eU5hbWUsICZuYW1lX2xlbmd0aDIsCiAgICAgICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwKICAgICAgICAgICAgICAgICAgICAgIGFyZ3ZbYXJnXSk7CiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIHVzbVVzZXJDbG9uZUZyb20sIG5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX09CSkVDVF9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgdXNtVXNlclNlY3VyaXR5TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihvaWQpICogbmFtZV9sZW5ndGgyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBjcmVhdGUgYSBuZXcgKHVuYXV0aGVudGljYXRlZCkgdXNlciBmcm9tIHNjcmF0Y2gKICAgICAgICAgICAgICogVGhlIE5ldC1TTk1QIGFnZW50IHdvbid0IGFsbG93IHN1Y2ggYSB1c2VyIHRvIGJlIG1hZGUgYWN0aXZlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2V0dXBfb2lkKHVzbVVzZXJTdGF0dXMsICZuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLCBhcmd2W2FyZy0xXSk7CiAgICAgICAgICAgIGxvbmd2YXIgPSBSU19DUkVBVEVBTkRXQUlUOwogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCB1c21Vc2VyU3RhdHVzLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JTlRFR0VSLCAodV9jaGFyICopICYgbG9uZ3ZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihsb25ndmFyKSk7CiAgICAgICAgfQoKICAgIH0gZWxzZSBpZiAoc3RyY21wKGFyZ3ZbYXJnXSwgQ01EX0NMT05FRlJPTV9OQU1FKSA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBjcmVhdGU6ICBjbG9uZSBhIHVzZXIgZnJvbSBhbm90aGVyCiAgICAgICAgICoKICAgICAgICAgKiBjbG9uZUZyb20gVVNFUiBGUk9NCiAgICAgICAgICovCiAgICAgICAgaWYgKCsrYXJnID49IGFyZ2MpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICAgICAgICAgIllvdSBtdXN0IHNwZWNpZnkgdGhlIHVzZXIgbmFtZSB0byBvcGVyYXRlIG9uXG4iKTsKICAgICAgICAgICAgdXNhZ2UoKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIGNvbW1hbmQgPSBDTURfQ0xPTkVGUk9NOwogICAgICAgIHNldHVwX29pZCh1c21Vc2VyU3RhdHVzLCAmbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLCBhcmd2W2FyZ10pOwogICAgICAgIGxvbmd2YXIgPSBSU19BQ1RJVkU7CiAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgdXNtVXNlclN0YXR1cywgbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JTlRFR0VSLCAodV9jaGFyICopICYgbG9uZ3ZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGxvbmd2YXIpKTsKICAgICAgICBuYW1lX2xlbmd0aCA9IFVTTV9PSURfTEVOOwogICAgICAgIHNldHVwX29pZCh1c21Vc2VyQ2xvbmVGcm9tLCAmbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLCBhcmd2W2FyZ10pOwoKICAgICAgICBpZiAoKythcmcgPj0gYXJnYykgewogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwKICAgICAgICAgICAgICAgICAgICAiWW91IG11c3Qgc3BlY2lmeSB0aGUgdXNlciBuYW1lIHRvIGNsb25lIGZyb21cbiIpOwogICAgICAgICAgICB1c2FnZSgpOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KCiAgICAgICAgc2V0dXBfb2lkKHVzbVVzZXJTZWN1cml0eU5hbWUsICZuYW1lX2xlbmd0aDIsCiAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLCBhcmd2W2FyZ10pOwogICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIHVzbVVzZXJDbG9uZUZyb20sIG5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fT0JKRUNUX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIHVzbVVzZXJTZWN1cml0eU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihvaWQpICogbmFtZV9sZW5ndGgyKTsKCiAgICB9IGVsc2UgaWYgKHN0cmNtcChhcmd2W2FyZ10sIENNRF9ERUxFVEVfTkFNRSkgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogZGVsZXRlOiAgZGVsZXRlIGEgdXNlcgogICAgICAgICAqCiAgICAgICAgICogZGVsZXRlIFVTRVIKICAgICAgICAgKi8KICAgICAgICBpZiAoKythcmcgPj0gYXJnYykgewogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIllvdSBtdXN0IHNwZWNpZnkgdGhlIHVzZXIgbmFtZSB0byBkZWxldGVcbiIpOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KCiAgICAgICAgY29tbWFuZCA9IENNRF9ERUxFVEU7CiAgICAgICAgc2V0dXBfb2lkKHVzbVVzZXJTdGF0dXMsICZuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sIGFyZ3ZbYXJnXSk7CiAgICAgICAgbG9uZ3ZhciA9IFJTX0RFU1RST1k7CiAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgdXNtVXNlclN0YXR1cywgbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JTlRFR0VSLCAodV9jaGFyICopICYgbG9uZ3ZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGxvbmd2YXIpKTsKICAgIH0gZWxzZSBpZiAoc3RyY21wKGFyZ3ZbYXJnXSwgQ01EX0FDVElWQVRFX05BTUUpID09IDApIHsKICAgICAgICAvKgogICAgICAgICAqIGFjdGl2YXRlOiAgYWN0aXZhdGUgYSB1c2VyCiAgICAgICAgICoKICAgICAgICAgKiBhY3RpdmF0ZSBVU0VSCiAgICAgICAgICovCiAgICAgICAgaWYgKCsrYXJnID49IGFyZ2MpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJZb3UgbXVzdCBzcGVjaWZ5IHRoZSB1c2VyIG5hbWUgdG8gYWN0aXZhdGVcbiIpOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KCiAgICAgICAgY29tbWFuZCA9IENNRF9BQ1RJVkFURTsKICAgICAgICBzZXR1cF9vaWQodXNtVXNlclN0YXR1cywgJm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwgYXJndlthcmddKTsKICAgICAgICBsb25ndmFyID0gUlNfQUNUSVZFOwogICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIHVzbVVzZXJTdGF0dXMsIG5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiwgKHVfY2hhciAqKSAmIGxvbmd2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihsb25ndmFyKSk7CiAgICB9IGVsc2UgaWYgKHN0cmNtcChhcmd2W2FyZ10sIENNRF9ERUFDVElWQVRFX05BTUUpID09IDApIHsKICAgICAgICAvKgogICAgICAgICAqIGRlYWN0aXZhdGU6ICBkZWFjdGl2YXRlIGEgdXNlcgogICAgICAgICAqCiAgICAgICAgICogZGVhY3RpdmF0ZSBVU0VSCiAgICAgICAgICovCiAgICAgICAgaWYgKCsrYXJnID49IGFyZ2MpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJZb3UgbXVzdCBzcGVjaWZ5IHRoZSB1c2VyIG5hbWUgdG8gZGVhY3RpdmF0ZVxuIik7CiAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgfQoKICAgICAgICBjb21tYW5kID0gQ01EX0RFQUNUSVZBVEU7CiAgICAgICAgc2V0dXBfb2lkKHVzbVVzZXJTdGF0dXMsICZuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sIGFyZ3ZbYXJnXSk7CiAgICAgICAgbG9uZ3ZhciA9IFJTX05PVElOU0VSVklDRTsKICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCB1c21Vc2VyU3RhdHVzLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0lOVEVHRVIsICh1X2NoYXIgKikgJiBsb25ndmFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobG9uZ3ZhcikpOwojaWYgZGVmaW5lZChIQVZFX09QRU5TU0xfREhfSCkgJiYgZGVmaW5lZChIQVZFX0xJQkNSWVBUTykKICAgIH0gZWxzZSBpZiAoc3RyY21wKGFyZ3ZbYXJnXSwgQ01EX0NIQU5HRUtFWV9OQU1FKSA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBjaGFuZ2UgdGhlIGtleSBvZiBhIHVzZXIgaWYgREggaXMgYXZhaWxhYmxlCiAgICAgICAgICovCgogICAgICAgIGNoYXIgKnBhc3N3ZF91c2VyOwogICAgICAgIG5ldHNubXBfcGR1ICpkaHBkdSwgKmRocmVzcG9uc2UgPSBOVUxMOwogICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFycywgKmRodmFyOwogICAgICAgIAogICAgICAgIGNvbW1hbmQgPSBDTURfQ0hBTkdFS0VZOwogICAgICAgIG5hbWVfbGVuZ3RoID0gREhfVVNNX09JRF9MRU47CiAgICAgICAgbmFtZV9sZW5ndGgyID0gREhfVVNNX09JRF9MRU47CgogICAgICAgIHBhc3N3ZF91c2VyID0gYXJndlsrK2FyZ107CgogICAgICAgIGlmIChkb3ByaXZrZXkgPT0gMCAmJiBkb2F1dGhrZXkgPT0gMCkKICAgICAgICAgICAgZG9wcml2a2V5ID0gZG9hdXRoa2V5ID0gMTsKCiAgICAgICAgLyogCiAgICAgICAgICogQ2hhbmdlIHRoZSB1c2VyIHN1cHBsaWVkIG9uIGNvbW1hbmQgbGluZS4KICAgICAgICAgKi8KICAgICAgICBpZiAoKHBhc3N3ZF91c2VyICE9IE5VTEwpICYmIChzdHJsZW4ocGFzc3dkX3VzZXIpID4gMCkpIHsKICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eU5hbWUgPSBwYXNzd2RfdXNlcjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBVc2Ugb3duIGtleSBvYmplY3QgaWYgbm8gdXNlciB3YXMgc3VwcGxpZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBkaGF1dGhLZXlDaGFuZ2UgPSB1c21ESFVzZXJPd25BdXRoS2V5Q2hhbmdlOwogICAgICAgICAgICBkaHByaXZLZXlDaGFuZ2UgPSB1c21ESFVzZXJPd25Qcml2S2V5Q2hhbmdlOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBkbyB3ZSBoYXZlIGEgc2VjdXJpdHlOYW1lPyAgSWYgbm90LCBjb3B5IHRoZSBkZWZhdWx0IAogICAgICAgICAqLwogICAgICAgIGlmIChzZXNzaW9uLnNlY3VyaXR5TmFtZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlOYW1lID0gCgkgICAgICBzdHJkdXAobmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkJICAgTkVUU05NUF9EU19MSUJfU0VDTkFNRSkpOwogICAgICAgIH0KCiAgICAgICAgLyogZmV0Y2ggdGhlIG5lZWRlZCBkaWZmaWUgaGVsbWFuIHBhcmFtZXRlcnMgKi8KICAgICAgICBkaHBkdSA9IHNubXBfcGR1X2NyZWF0ZShTTk1QX01TR19HRVQpOwogICAgICAgIGlmICghZGhwZHUpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJGYWlsZWQgdG8gY3JlYXRlIERIIHJlcXVlc3RcbiIpOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KCiAgICAgICAgLyogZ2V0IHRoZSBjdXJyZW50IERIIHBhcmFtZXRlcnMgKi8KICAgICAgICBzbm1wX2FkZF9udWxsX3ZhcihkaHBkdSwgdXNtREhQYXJhbWV0ZXJzLCB1c21ESFBhcmFtZXRlcnNfbGVuKTsKICAgICAgICAKICAgICAgICAvKiBtYXliZSB0aGUgYXV0aCBrZXkgcHVibGljIHZhbHVlICovCiAgICAgICAgaWYgKGRvYXV0aGtleSkgewogICAgICAgICAgICBzZXR1cF9vaWQoZGhhdXRoS2V5Q2hhbmdlLCAmbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwKICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlOYW1lKTsKICAgICAgICAgICAgc25tcF9hZGRfbnVsbF92YXIoZGhwZHUsIGRoYXV0aEtleUNoYW5nZSwgbmFtZV9sZW5ndGgpOwogICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgLyogbWF5YmUgdGhlIHByaXYga2V5IHB1YmxpYyB2YWx1ZSAqLwogICAgICAgIGlmIChkb3ByaXZrZXkpIHsKICAgICAgICAgICAgc2V0dXBfb2lkKGRocHJpdktleUNoYW5nZSwgJm5hbWVfbGVuZ3RoMiwKICAgICAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLAogICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eU5hbWUpOwogICAgICAgICAgICBzbm1wX2FkZF9udWxsX3ZhcihkaHBkdSwgZGhwcml2S2V5Q2hhbmdlLCBuYW1lX2xlbmd0aDIpOwogICAgICAgIH0KCiAgICAgICAgLyogZmV0Y2ggdGhlIHZhbHVlcyAqLwogICAgICAgIHN0YXR1cyA9IHNubXBfc3luY2hfcmVzcG9uc2Uoc3MsIGRocGR1LCAmZGhyZXNwb25zZSk7CgogICAgICAgIGlmIChzdGF0dXMgIT0gU05NUEVSUl9TVUNDRVNTIHx8IGRocmVzcG9uc2UgPT0gTlVMTCB8fAogICAgICAgICAgICBkaHJlc3BvbnNlLT5lcnJzdGF0ICE9IFNOTVBfRVJSX05PRVJST1IgfHwKICAgICAgICAgICAgZGhyZXNwb25zZS0+dmFyaWFibGVzLT50eXBlICE9IEFTTl9PQ1RFVF9TVFIpIHsKICAgICAgICAgICAgc25tcF9zZXNzX3BlcnJvcigic25tcHVzbSIsIHNzKTsKICAgICAgICAgICAgaWYgKGRocmVzcG9uc2UgJiYgZGhyZXNwb25zZS0+dmFyaWFibGVzICYmCiAgICAgICAgICAgICAgICBkaHJlc3BvbnNlLT52YXJpYWJsZXMtPnR5cGUgIT0gQVNOX09DVEVUX1NUUikgewogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICAgICAgICAgICAgICJDYW4ndCBnZXQgZGlmZmllLWhlbG1hbiBleGNoYW5nZSBmcm9tIHRoZSBhZ2VudFxuIik7CiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgIiAgKG1heWJlIGl0IGRvZXNuJ3Qgc3VwcG9ydCB0aGUgU05NUC1VU00tREgtT0JKRUNUUy1NSUIgTUlCKVxuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZXhpdHZhbCA9IDE7CiAgICAgICAgICAgIGdvdG8gYmVnb25lOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBkaHZhciA9IGRocmVzcG9uc2UtPnZhcmlhYmxlczsKICAgICAgICB2YXJzID0gZGh2YXItPm5leHRfdmFyaWFibGU7CiAgICAgICAgLyogY29tcGxldGUgdGhlIERIIGVxdWF0aW9uICYgcHJpbnQgcmVzdWx0aW5nIGtleXMgKi8KICAgICAgICBpZiAoZG9hdXRoa2V5KSB7CiAgICAgICAgICAgIGlmIChnZXRfVVNNX0RIX2tleSh2YXJzLCBkaHZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjX2dldF9wcm9wZXJsZW5ndGgoc3MtPnNlY3VyaXR5QXV0aFByb3RvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcy0+c2VjdXJpdHlBdXRoUHJvdG9MZW4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGR1LCAiYXV0aCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaGF1dGhLZXlDaGFuZ2UsIG5hbWVfbGVuZ3RoKSAhPSBTTk1QRVJSX1NVQ0NFU1MpCiAgICAgICAgICAgICAgICBnb3RvIGJlZ29uZTsKICAgICAgICAgICAgdmFycyA9IHZhcnMtPm5leHRfdmFyaWFibGU7CiAgICAgICAgfQogICAgICAgIGlmIChkb3ByaXZrZXkpIHsKCSAgICBzaXplX3QgZGhwcml2S2V5TGVuID0gMDsKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfREVTCgkgICAgaWYgKElTVFJBTlNGT1JNKHNzLT5zZWN1cml0eVByaXZQcm90bywgREVTUHJpdikpIHsKICAgICAgICAgICAgICAgIC8qIERFUyB1c2VzIGEgMTI4IGJpdCBrZXksIDY0IGJpdHMgb2Ygd2hpY2ggaXMgYSBzYWx0ICovCgkgICAgICAgIGRocHJpdktleUxlbiA9IDE2OwoJICAgIH0KI2VuZGlmCiNpZmRlZiBIQVZFX0FFUwoJICAgIGlmIChJU1RSQU5TRk9STShzcy0+c2VjdXJpdHlQcml2UHJvdG8sIEFFU1ByaXYpKSB7CgkgICAgICAgIGRocHJpdktleUxlbiA9IDE2OwoJICAgIH0KI2VuZGlmCiAgICAgICAgICAgIGlmIChnZXRfVVNNX0RIX2tleSh2YXJzLCBkaHZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRocHJpdktleUxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBkdSwgInByaXYiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGhwcml2S2V5Q2hhbmdlLCBuYW1lX2xlbmd0aDIpCiAgICAgICAgICAgICAgICAhPSBTTk1QRVJSX1NVQ0NFU1MpCiAgICAgICAgICAgICAgICBnb3RvIGJlZ29uZTsKICAgICAgICAgICAgdmFycyA9IHZhcnMtPm5leHRfdmFyaWFibGU7CiAgICAgICAgfQogICAgICAgIC8qIHNubXBfZnJlZV9wZHUoZGhyZXNwb25zZSk7ICovIC8qIHBhcnRzIHN0aWxsIGluIHVzZSBzb21ld2hlcmUgKi8KI2VuZGlmIC8qIEhBVkVfT1BFTlNTTF9ESF9IICYmIEhBVkVfTElCQ1JZUFRPICovCiAgICB9IGVsc2UgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5rbm93biBjb21tYW5kXG4iKTsKICAgICAgICB1c2FnZSgpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CgogICAgLyoKICAgICAqIGFkZCB1c21Vc2VyUHVibGljIGlmIHNwZWNpZmllZCAodmlhIC1DcCkKICAgICAqLwogICAgaWYgKHVzbVVzZXJQdWJsaWNfdmFsKSB7CiAgICAgICAgbmFtZV9sZW5ndGggPSBVU01fT0lEX0xFTjsKCXNldHVwX29pZCh1c21Vc2VyUHVibGljLCAmbmFtZV9sZW5ndGgsCgkJICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwKCQkgIHNlc3Npb24uc2VjdXJpdHlOYW1lKTsKCXNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIHVzbVVzZXJQdWJsaWMsIG5hbWVfbGVuZ3RoLAoJCQkgICAgICBBU05fT0NURVRfU1RSLCB1c21Vc2VyUHVibGljX3ZhbCwgCgkJCSAgICAgIHN0cmxlbih1c21Vc2VyUHVibGljX3ZhbCkpOwkgIAogICAgfQoKICAgIC8qCiAgICAgKiBkbyB0aGUgcmVxdWVzdCAKICAgICAqLwogICAgc3RhdHVzID0gc25tcF9zeW5jaF9yZXNwb25zZShzcywgcGR1LCAmcmVzcG9uc2UpOwogICAgaWYgKHN0YXR1cyA9PSBTVEFUX1NVQ0NFU1MpIHsKICAgICAgICBpZiAocmVzcG9uc2UpIHsKICAgICAgICAgICAgaWYgKHJlc3BvbnNlLT5lcnJzdGF0ID09IFNOTVBfRVJSX05PRVJST1IpIHsKICAgICAgICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCAiJXNcbiIsIHN1Y2Nlc3NOb3Rlc1tjb21tYW5kIC0gMV0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJFcnJvciBpbiBwYWNrZXQuXG5SZWFzb246ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2VycnN0cmluZyhyZXNwb25zZS0+ZXJyc3RhdCkpOwogICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLT5lcnJpbmRleCAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgIGNvdW50OwogICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyczsKICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIkZhaWxlZCBvYmplY3Q6ICIpOwogICAgICAgICAgICAgICAgICAgIGZvciAoY291bnQgPSAxLCB2YXJzID0gcmVzcG9uc2UtPnZhcmlhYmxlczsKICAgICAgICAgICAgICAgICAgICAgICAgIHZhcnMgJiYgY291bnQgIT0gcmVzcG9uc2UtPmVycmluZGV4OwogICAgICAgICAgICAgICAgICAgICAgICAgdmFycyA9IHZhcnMtPm5leHRfdmFyaWFibGUsIGNvdW50KyspCiAgICAgICAgICAgICAgICAgICAgICAgIC8qRU1QVFkqLzsKICAgICAgICAgICAgICAgICAgICBpZiAodmFycykKICAgICAgICAgICAgICAgICAgICAgICAgZnByaW50X29iamlkKHN0ZGVyciwgdmFycy0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcnMtPm5hbWVfbGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlxuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBleGl0dmFsID0gMjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoc3RhdHVzID09IFNUQVRfVElNRU9VVCkgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiVGltZW91dDogTm8gUmVzcG9uc2UgZnJvbSAlc1xuIiwKICAgICAgICAgICAgICAgIHNlc3Npb24ucGVlcm5hbWUpOwogICAgICAgIGV4aXR2YWwgPSAxOwogICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgIC8qIHN0YXR1cyA9PSBTVEFUX0VSUk9SICovCiAgICAgICAgc25tcF9zZXNzX3BlcnJvcigic25tcHNldCIsIHNzKTsKICAgICAgICBleGl0dmFsID0gMTsKICAgIH0KCiNpZiBkZWZpbmVkKEhBVkVfT1BFTlNTTF9ESF9IKSAmJiBkZWZpbmVkKEhBVkVfTElCQ1JZUFRPKQogIGJlZ29uZToKI2VuZGlmIC8qIEhBVkVfT1BFTlNTTF9ESF9IICYmIEhBVkVfTElCQ1JZUFRPICovCiAgICBpZiAocmVzcG9uc2UpCiAgICAgICAgc25tcF9mcmVlX3BkdShyZXNwb25zZSk7CiAgICBzbm1wX2Nsb3NlKHNzKTsKICAgIFNPQ0tfQ0xFQU5VUDsKICAgIHJldHVybiBleGl0dmFsOwp9Cg==