LyoKICogQ29weXJpZ2h0IChDKSAyMDAzIE1pY2hhZWwgR/xubmV3aWcKICogQ29weXJpZ2h0IChDKSAyMDAzIENvZGVXZWF2ZXJzIEluYy4gKFVscmljaCBDemVrYWxsYSkKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJpbml0Z3VpZC5oIgojaW5jbHVkZSAiZG1vLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChtc2Rtbyk7CgojZGVmaW5lIE1TRE1PX01BSk9SX1ZFUlNJT04gNgoKc3RhdGljIGNvbnN0IFdDSEFSIHN6RE1PUm9vdEtleVtdID0gCnsKICAgICdEJywnaScsJ3InLCdlJywnYycsJ3QnLCdTJywnaCcsJ28nLCd3JywnXFwnLAogICAgJ00nLCdlJywnZCcsJ2knLCdhJywnTycsJ2InLCdqJywnZScsJ2MnLCd0JywncycsMAp9OyAKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT0lucHV0VHlwZVtdID0KewogICAgJ0knLCduJywncCcsJ3UnLCd0JywnVCcsJ3knLCdwJywnZScsJ3MnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT091dHB1dFR5cGVbXSA9CnsKICAgICdPJywndScsJ3QnLCdwJywndScsJ3QnLCdUJywneScsJ3AnLCdlJywncycsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6RE1PS2V5ZWRbXSA9CnsKICAgICdLJywnZScsJ3knLCdlJywnZCcsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6RE1PQ2F0ZWdvcmllc1tdID0KewogICAgJ0MnLCdhJywndCcsJ2UnLCdnJywnbycsJ3InLCdpJywnZScsJ3MnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekdVSURGbXRbXSA9CnsKICAgICclJywnMCcsJzgnLCdYJywnLScsJyUnLCcwJywnNCcsJ1gnLCctJywnJScsJzAnLCc0JywnWCcsJy0nLCclJywnMCcsCiAgICAnMicsJ1gnLCclJywnMCcsJzInLCdYJywnLScsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywKICAgICdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywwCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pDYXQzRm10W10gPQp7CiAgICAnJScsJ3MnLCdcXCcsJyUnLCdzJywnXFwnLCclJywncycsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6Q2F0MkZtdFtdID0KewogICAgJyUnLCdzJywnXFwnLCclJywncycsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6VG9HdWlkRm10W10gPQp7CiAgICAneycsJyUnLCdzJywnfScsMAp9OwoKCnR5cGVkZWYgc3RydWN0CnsKICAgIGNvbnN0IElFbnVtRE1PVnRibCAgICAgICAgICpscFZ0Ymw7CiAgICBMT05HCQkJcmVmOwogICAgRFdPUkQJCQlpbmRleDsKICAgIGNvbnN0IEdVSUQqICAgICAgICAgICAgICAgICBndWlkQ2F0ZWdvcnk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgZHdGbGFnczsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICBjSW5UeXBlczsKICAgIERNT19QQVJUSUFMX01FRElBVFlQRSAgICAgICAqcEluVHlwZXM7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgY091dFR5cGVzOwogICAgRE1PX1BBUlRJQUxfTUVESUFUWVBFICAgICAgICpwT3V0VHlwZXM7CiAgICBIS0VZICAgICAgICAgICAgICAgICAgICAgICAgaGtleTsKfSBJRW51bURNT0ltcGw7CgpzdGF0aWMgSFJFU1VMVCByZWFkX3R5cGVzKEhLRVkgcm9vdCwgTFBDV1NUUiBrZXksIFVMT05HICpzdXBwbGllZCwgVUxPTkcgcmVxdWVzdGVkLCBETU9fUEFSVElBTF9NRURJQVRZUEUqIHR5cGVzKTsKCnN0YXRpYyBjb25zdCBJRW51bURNT1Z0YmwgZWRtb3Z0OwoKc3RhdGljIExQV1NUUiBHVUlEVG9TdHJpbmcoTFBXU1RSIGxwd3N0ciwgUkVGR1VJRCBscGNndWlkKQp7CiAgICB3c3ByaW50ZlcobHB3c3RyLCBzekdVSURGbXQsIGxwY2d1aWQtPkRhdGExLCBscGNndWlkLT5EYXRhMiwKICAgICAgICBscGNndWlkLT5EYXRhMywgbHBjZ3VpZC0+RGF0YTRbMF0sIGxwY2d1aWQtPkRhdGE0WzFdLAogICAgICAgIGxwY2d1aWQtPkRhdGE0WzJdLCBscGNndWlkLT5EYXRhNFszXSwgbHBjZ3VpZC0+RGF0YTRbNF0sCiAgICAgICAgbHBjZ3VpZC0+RGF0YTRbNV0sIGxwY2d1aWQtPkRhdGE0WzZdLCBscGNndWlkLT5EYXRhNFs3XSk7CgogICAgcmV0dXJuIGxwd3N0cjsKfQoKc3RhdGljIEJPT0wgSXNNZWRpYVR5cGVFcXVhbChjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUqIG10MSwgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBtdDIpCnsKCiAgICByZXR1cm4gKElzRXF1YWxDTFNJRCgmbXQxLT50eXBlLCAmbXQyLT50eXBlKSB8fAogICAgICAgICAgICBJc0VxdWFsQ0xTSUQoJm10Mi0+dHlwZSwgJkdVSURfTlVMTCkgfHwKICAgICAgICAgICAgSXNFcXVhbENMU0lEKCZtdDEtPnR5cGUsICZHVUlEX05VTEwpKSAmJgogICAgICAgICAgICAoSXNFcXVhbENMU0lEKCZtdDEtPnN1YnR5cGUsICZtdDItPnN1YnR5cGUpIHx8CiAgICAgICAgICAgIElzRXF1YWxDTFNJRCgmbXQyLT5zdWJ0eXBlLCAmR1VJRF9OVUxMKSB8fAogICAgICAgICAgICBJc0VxdWFsQ0xTSUQoJm10MS0+c3VidHlwZSwgJkdVSURfTlVMTCkpOwp9CgpzdGF0aWMgSFJFU1VMVCB3cml0ZV90eXBlcyhIS0VZIGhrZXksIExQQ1dTVFIgbmFtZSwgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiB0eXBlcywgRFdPUkQgY291bnQpCnsKICAgIEhSRVNVTFQgaHJlcyA9IFNfT0s7CiAgICBpZiAoTVNETU9fTUFKT1JfVkVSU0lPTiA+IDUpCiAgICB7CiAgICAgICAgaHJlcyA9IFJlZ1NldFZhbHVlRXhXKGhrZXksIG5hbWUsIDAsIFJFR19CSU5BUlksIChjb25zdCBCWVRFKikgdHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnQqIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBIS0VZIHNrZXkxLHNrZXkyLHNrZXkzOwogICAgICAgIERXT1JEIGluZGV4ID0gMDsKICAgICAgICBXQ0hBUiBzekd1aWRLZXlbNjRdOwoKICAgICAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKGhrZXksIG5hbWUsIDAsIE5VTEwsIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX1dSSVRFLCBOVUxMLCAmc2tleTEsIE5VTEwpOwogICAgICAgIHdoaWxlIChpbmRleCA8IGNvdW50KQogICAgICAgIHsKICAgICAgICAgICAgR1VJRFRvU3RyaW5nKHN6R3VpZEtleSwmdHlwZXNbaW5kZXhdLnR5cGUpOwogICAgICAgICAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKHNrZXkxLCBzekd1aWRLZXksIDAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfV1JJVEUsIE5VTEwsICZza2V5MiwgTlVMTCk7CiAgICAgICAgICAgIEdVSURUb1N0cmluZyhzekd1aWRLZXksJnR5cGVzW2luZGV4XS5zdWJ0eXBlKTsKICAgICAgICAgICAgaHJlcyA9IFJlZ0NyZWF0ZUtleUV4Vyhza2V5Miwgc3pHdWlkS2V5LCAwLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX1dSSVRFLCBOVUxMLCAmc2tleTMsIE5VTEwpOwogICAgICAgICAgICBSZWdDbG9zZUtleShza2V5Myk7CiAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KHNrZXkyKTsKICAgICAgICAgICAgaW5kZXggKys7CiAgICAgICAgfQogICAgICAgIFJlZ0Nsb3NlS2V5KHNrZXkxKTsKICAgIH0KCiAgICByZXR1cm4gaHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBETU9SZWdpc3RlciAoTVNETU8uQCkKICoKICogUmVnaXN0ZXIgYSBEaXJlY3RYIE1lZGlhIE9iamVjdC4KICovCkhSRVNVTFQgV0lOQVBJIERNT1JlZ2lzdGVyKAogICBMUENXU1RSIHN6TmFtZSwKICAgUkVGQ0xTSUQgY2xzaWRETU8sCiAgIFJFRkdVSUQgZ3VpZENhdGVnb3J5LAogICBEV09SRCBkd0ZsYWdzLAogICBEV09SRCBjSW5UeXBlcywKICAgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFICpwSW5UeXBlcywKICAgRFdPUkQgY091dFR5cGVzLAogICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBPdXRUeXBlcwopCnsKICAgIFdDSEFSIHN6Z3VpZFs2NF07CiAgICBIUkVTVUxUIGhyZXM7CiAgICBIS0VZIGhya2V5ID0gMDsKICAgIEhLRVkgaGtleSA9IDA7CiAgICBIS0VZIGhja2V5ID0gMDsKICAgIEhLRVkgaGNsc2tleSA9IDA7CgogICAgVFJBQ0UoIiVzXG4iLCBkZWJ1Z3N0cl93KHN6TmFtZSkpOwoKICAgIGhyZXMgPSBSZWdDcmVhdGVLZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6RE1PUm9vdEtleSwgMCwgTlVMTCwKICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX1dSSVRFLCBOVUxMLCAmaHJrZXksIE5VTEwpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgLyogQ3JlYXRlIGNsc2lkRE1PIGtleSB1bmRlciBNZWRpYU9iamVjdHMgKi8gCiAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKGhya2V5LCBHVUlEVG9TdHJpbmcoc3pndWlkLCBjbHNpZERNTyksIDAsIE5VTEwsCiAgICAgICAgUkVHX09QVElPTl9OT05fVk9MQVRJTEUsIEtFWV9XUklURSwgTlVMTCwgJmhrZXksIE5VTEwpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgLyogU2V0IGRlZmF1bHQgTmFtZSB2YWx1ZSAqLwogICAgaHJlcyA9IFJlZ1NldFZhbHVlRXhXKGhrZXksIE5VTEwsIDAsIFJFR19TWiwgKGNvbnN0IEJZVEUqKSBzek5hbWUsIAogICAgICAgIChzdHJsZW5XKHN6TmFtZSkgKyAxKSAqIHNpemVvZihXQ0hBUikpOwoKICAgIC8qIFNldCBJbnB1dFR5cGVzICovCiAgICBocmVzID0gd3JpdGVfdHlwZXMoaGtleSwgc3pETU9JbnB1dFR5cGUsIHBJblR5cGVzLCBjSW5UeXBlcyk7CgogICAgLyogU2V0IE91dHB1dFR5cGVzICovCiAgICBocmVzID0gd3JpdGVfdHlwZXMoaGtleSwgc3pETU9PdXRwdXRUeXBlLCBwT3V0VHlwZXMsIGNPdXRUeXBlcyk7CgogICAgaWYgKGR3RmxhZ3MgJiBETU9fUkVHSVNURVJGX0lTX0tFWUVEKQogICAgewogICAgICAgIC8qIENyZWF0ZSBLZXllZCBrZXkgKi8gCiAgICAgICAgaHJlcyA9IFJlZ0NyZWF0ZUtleUV4Vyhoa2V5LCBzekRNT0tleWVkLCAwLCBOVUxMLAogICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX1dSSVRFLCBOVUxMLCAmaGNrZXksIE5VTEwpOwogICAgICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgICAgIGdvdG8gbGVuZDsKICAgICAgICBSZWdDbG9zZUtleShoY2tleSk7CiAgICB9CgogICAgLyogUmVnaXN0ZXIgdGhlIGNhdGVnb3J5ICovCiAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKGhya2V5LCBzekRNT0NhdGVnb3JpZXMsIDAsIE5VTEwsCiAgICAgICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfV1JJVEUsIE5VTEwsICZoY2tleSwgTlVMTCk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCiAgICBSZWdDbG9zZUtleShoa2V5KTsKCiAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKGhja2V5LCBHVUlEVG9TdHJpbmcoc3pndWlkLCBndWlkQ2F0ZWdvcnkpLCAwLCBOVUxMLAogICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX1dSSVRFLCBOVUxMLCAmaGtleSwgTlVMTCk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKICAgIGhyZXMgPSBSZWdDcmVhdGVLZXlFeFcoaGtleSwgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pLCAwLCBOVUxMLAogICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfV1JJVEUsIE5VTEwsICZoY2xza2V5LCBOVUxMKTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKbGVuZDoKICAgIGlmIChoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgaWYgKGhja2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhja2V5KTsKICAgIGlmIChoY2xza2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhjbHNrZXkpOwogICAgaWYgKGhya2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhya2V5KTsKCiAgICBUUkFDRSgiIGhyZXN1bHQ9MHglMDh4XG4iLCBocmVzKTsKICAgIHJldHVybiBocmVzOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBETU9VbnJlZ2lzdGVyIChNU0RNTy5AKQogKgogKiBVbnJlZ2lzdGVyIGEgRGlyZWN0WCBNZWRpYSBPYmplY3QuCiAqLwpIUkVTVUxUIFdJTkFQSSBETU9VbnJlZ2lzdGVyKFJFRkNMU0lEIGNsc2lkRE1PLCBSRUZHVUlEIGd1aWRDYXRlZ29yeSkKewogICAgSFJFU1VMVCBocmVzOwogICAgV0NIQVIgc3pndWlkWzY0XTsKICAgIEhLRVkgaHJrZXkgPSAwOwogICAgSEtFWSBoY2tleSA9IDA7CgogICAgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pOwoKICAgIFRSQUNFKCIlcyAlcFxuIiwgZGVidWdzdHJfdyhzemd1aWQpLCBndWlkQ2F0ZWdvcnkpOwoKICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKEhLRVlfQ0xBU1NFU19ST09ULCBzekRNT1Jvb3RLZXksIDAsIEtFWV9XUklURSwgJmhya2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGhyZXMgPSBSZWdEZWxldGVLZXlXKGhya2V5LCBzemd1aWQpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoaHJrZXksIHN6RE1PQ2F0ZWdvcmllcywgMCwgS0VZX1dSSVRFLCAmaGNrZXkpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgaHJlcyA9IFJlZ0RlbGV0ZUtleVcoaGNrZXksIHN6Z3VpZCk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCmxlbmQ6CiAgICBpZiAoaGNrZXkpCiAgICAgICAgUmVnQ2xvc2VLZXkoaGNrZXkpOwogICAgaWYgKGhya2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhya2V5KTsKCiAgICByZXR1cm4gaHJlczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRE1PR2V0TmFtZSAoTVNETU8uQCkKICoKICogR2V0IERNUCBOYW1lIGZyb20gdGhlIHJlZ2lzdHJ5CiAqLwpIUkVTVUxUIFdJTkFQSSBETU9HZXROYW1lKFJFRkNMU0lEIGNsc2lkRE1PLCBXQ0hBUiBzek5hbWVbXSkKewogICAgV0NIQVIgc3pndWlkWzY0XTsKICAgIEhSRVNVTFQgaHJlczsKICAgIEhLRVkgaHJrZXkgPSAwOwogICAgSEtFWSBoa2V5ID0gMDsKICAgIHN0YXRpYyBjb25zdCBJTlQgbWF4X25hbWVfbGVuID0gODA7CiAgICBEV09SRCBjb3VudDsKCiAgICBUUkFDRSgiJXNcbiIsIGRlYnVnc3RyX2d1aWQoY2xzaWRETU8pKTsKCiAgICBocmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pETU9Sb290S2V5LCAKICAgICAgICAwLCBLRVlfUkVBRCwgJmhya2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKGhya2V5LCBHVUlEVG9TdHJpbmcoc3pndWlkLCBjbHNpZERNTyksCiAgICAgICAgMCwgS0VZX1JFQUQsICZoa2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGNvdW50ID0gbWF4X25hbWVfbGVuICogc2l6ZW9mKFdDSEFSKTsKICAgIGhyZXMgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIE5VTEwsIE5VTEwsIE5VTEwsIAogICAgICAgIChMUEJZVEUpIHN6TmFtZSwgJmNvdW50KTsgCgogICAgVFJBQ0UoIiBzek5hbWU9JXNcbiIsIGRlYnVnc3RyX3coc3pOYW1lKSk7CmxlbmQ6CiAgICBpZiAoaGtleSkKICAgICAgICBSZWdDbG9zZUtleShocmtleSk7CiAgICBpZiAoaGtleSkKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKCiAgICByZXR1cm4gaHJlczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgSUVudW1ETU9fRGVzdHJ1Y3RvcgoqLwpzdGF0aWMgQk9PTCBJRW51bURNT19EZXN0cnVjdG9yKElFbnVtRE1PKiBpZmFjZSkKewogICAgSUVudW1ETU9JbXBsICpUaGlzID0gKElFbnVtRE1PSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIlcFxuIiwgVGhpcyk7CgogICAgaWYgKFRoaXMtPmhrZXkpCiAgICAgICAgUmVnQ2xvc2VLZXkoVGhpcy0+aGtleSk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cEluVHlwZXMpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cE91dFR5cGVzKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSUVudW1ETU9fQ29uc3RydWN0b3IKICovCnN0YXRpYyBJRW51bURNTyAqIElFbnVtRE1PX0NvbnN0cnVjdG9yKAogICAgUkVGR1VJRCBndWlkQ2F0ZWdvcnksCiAgICBEV09SRCBkd0ZsYWdzLAogICAgRFdPUkQgY0luVHlwZXMsCiAgICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBJblR5cGVzLAogICAgRFdPUkQgY091dFR5cGVzLAogICAgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFICpwT3V0VHlwZXMpCnsKICAgIFVJTlQgc2l6ZTsKICAgIElFbnVtRE1PSW1wbCogbHBlZG1vOwogICAgQk9PTCByZXQgPSBGQUxTRTsKCiAgICBscGVkbW8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElFbnVtRE1PSW1wbCkpOwoKICAgIGlmIChscGVkbW8pCiAgICB7CiAgICAgICAgbHBlZG1vLT5yZWYgPSAxOwogICAgICAgIGxwZWRtby0+bHBWdGJsID0gJmVkbW92dDsKICAgICAgICBscGVkbW8tPmluZGV4ID0gLTE7CglscGVkbW8tPmd1aWRDYXRlZ29yeSA9IGd1aWRDYXRlZ29yeTsKCWxwZWRtby0+ZHdGbGFncyA9IGR3RmxhZ3M7CgogICAgICAgIGlmIChjSW5UeXBlcyA+IDApCiAgICAgICAgewogICAgICAgICAgICBzaXplID0gY0luVHlwZXMgKiBzaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKTsKICAgICAgICAgICAgbHBlZG1vLT5wSW5UeXBlcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgICAgICAgICAgaWYgKCFscGVkbW8tPnBJblR5cGVzKQogICAgICAgICAgICAgICAgZ290byBsZXJyOwogICAgICAgICAgICBtZW1jcHkobHBlZG1vLT5wSW5UeXBlcywgcEluVHlwZXMsIHNpemUpOwogICAgICAgICAgICBscGVkbW8tPmNJblR5cGVzID0gY0luVHlwZXM7CiAgICAgICAgfQoKICAgICAgICBpZiAoY091dFR5cGVzID4gMCkKICAgICAgICB7CiAgICAgICAgICAgIHNpemUgPSBjT3V0VHlwZXMgKiBzaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKTsKICAgICAgICAgICAgbHBlZG1vLT5wT3V0VHlwZXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CiAgICAgICAgICAgIGlmICghbHBlZG1vLT5wT3V0VHlwZXMpCiAgICAgICAgICAgICAgICBnb3RvIGxlcnI7CiAgICAgICAgICAgIG1lbWNweShscGVkbW8tPnBPdXRUeXBlcywgcE91dFR5cGVzLCBzaXplKTsKICAgICAgICAgICAgbHBlZG1vLT5jT3V0VHlwZXMgPSBjT3V0VHlwZXM7CiAgICAgICAgfQoKICAgICAgICAvKiBJZiBub3QgZmlsdGVyaW5nIGJ5IGNhdGVnb3J5IGVudW0gZnJvbSBtZWRpYSBvYmplY3RzIHJvb3QgKi8KICAgICAgICBpZiAoSXNFcXVhbEdVSUQoZ3VpZENhdGVnb3J5LCAmR1VJRF9OVUxMKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChFUlJPUl9TVUNDRVNTID09IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6RE1PUm9vdEtleSwgCiAgICAgICAgICAgICAgICAwLCBLRVlfUkVBRCwgJmxwZWRtby0+aGtleSkpCiAgICAgICAgICAgICAgICByZXQgPSBUUlVFOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiBzemd1aWRbNjRdOwogICAgICAgICAgICBXQ0hBUiBzektleVtNQVhfUEFUSF07CgogICAgICAgICAgICB3c3ByaW50Zlcoc3pLZXksIHN6Q2F0M0ZtdCwgc3pETU9Sb290S2V5LCBzekRNT0NhdGVnb3JpZXMsIAogICAgICAgICAgICAgICAgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgZ3VpZENhdGVnb3J5KSk7CiAgICAgICAgICAgIGlmIChFUlJPUl9TVUNDRVNTID09IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6S2V5LCAKICAgICAgICAgICAgICAgIDAsIEtFWV9SRUFELCAmbHBlZG1vLT5oa2V5KSkKICAgICAgICAgICAgICAgIHJldCA9IFRSVUU7CiAgICAgICAgfQoKbGVycjoKICAgICAgICBpZighcmV0KQogICAgICAgIHsKICAgICAgICAgICAgSUVudW1ETU9fRGVzdHJ1Y3RvcigoSUVudW1ETU8qKWxwZWRtbyk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxscGVkbW8pOwogICAgICAgICAgICBscGVkbW8gPSBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBUUkFDRSgicmV0dXJuaW5nICVwXG4iLCBscGVkbW8pOwoKICAgIHJldHVybiAoSUVudW1ETU8qKWxwZWRtbzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUVudW1ETU9fZm5BZGRSZWYKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUVudW1ETU9fZm5BZGRSZWYoSUVudW1ETU8gKiBpZmFjZSkKewogICAgSUVudW1ETU9JbXBsICpUaGlzID0gKElFbnVtRE1PSW1wbCAqKWlmYWNlOwogICAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBFbnVtRE1PX1F1ZXJ5SW50ZXJmYWNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVudW1ETU9fZm5RdWVyeUludGVyZmFjZSgKICAgIElFbnVtRE1PKiBpZmFjZSwKICAgIFJFRklJRCByaWlkLAogICAgTFBWT0lEICpwcHZPYmopCnsKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKCiAgICAqcHB2T2JqID0gTlVMTDsKCiAgICBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKQogICAgICAgICpwcHZPYmogPSBUaGlzOwogICAgZWxzZSBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSUVudW1ETU8pKQogICAgICAgICpwcHZPYmogPSAoSUVudW1ETU8qKVRoaXM7CgogICAgaWYoKnBwdk9iaikKICAgIHsKICAgICAgICBJRW51bURNT19mbkFkZFJlZigoSUVudW1ETU8qKSpwcHZPYmopOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQoKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mblJlbGVhc2UKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUVudW1ETU9fZm5SZWxlYXNlKElFbnVtRE1PICogaWZhY2UpCnsKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKICAgIFVMT05HIHJlZkNvdW50ID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgaWYgKCFyZWZDb3VudCkKICAgIHsKICAgICAgICBJRW51bURNT19EZXN0cnVjdG9yKChJRW51bURNTyopVGhpcyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogICAgfQogICAgcmV0dXJuIHJlZkNvdW50Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mbk5leHQKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRW51bURNT19mbk5leHQoCiAgICBJRW51bURNTyAqIGlmYWNlLCAKICAgIERXT1JEIGNJdGVtc1RvRmV0Y2gsCiAgICBDTFNJRCAqIHBDTFNJRCwKICAgIFdDSEFSICoqIE5hbWVzLAogICAgRFdPUkQgKiBwY0l0ZW1zRmV0Y2hlZCkKewogICAgRklMRVRJTUUgZnQ7CiAgICBIS0VZIGhrZXk7CiAgICBXQ0hBUiBzek5leHRLZXlbTUFYX1BBVEhdOwogICAgV0NIQVIgc3pHdWlkS2V5WzY0XTsKICAgIFdDSEFSIHN6S2V5W01BWF9QQVRIXTsKICAgIFdDSEFSIHN6VmFsdWVbTUFYX1BBVEhdOwogICAgRFdPUkQgbGVuOwogICAgVUlOVCBjb3VudCA9IDA7CiAgICBIUkVTVUxUIGhyZXMgPSBTX09LOwoKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiLS0+ICglcCkgJWQgJXAgJXAgJXBcbiIsIGlmYWNlLCBjSXRlbXNUb0ZldGNoLCBwQ0xTSUQsIE5hbWVzLCBwY0l0ZW1zRmV0Y2hlZCk7CgogICAgaWYgKCFwQ0xTSUQgfHwgIU5hbWVzIHx8ICFwY0l0ZW1zRmV0Y2hlZCkKICAgICAgICByZXR1cm4gRV9QT0lOVEVSOwoKICAgIHdoaWxlIChjb3VudCA8IGNJdGVtc1RvRmV0Y2gpCiAgICB7CiAgICAgICAgVGhpcy0+aW5kZXgrKzsKCiAgICAgICAgbGVuID0gTUFYX1BBVEg7CiAgICAgICAgaHJlcyA9IFJlZ0VudW1LZXlFeFcoVGhpcy0+aGtleSwgVGhpcy0+aW5kZXgsIHN6TmV4dEtleSwgJmxlbiwgTlVMTCwgTlVMTCwgTlVMTCwgJmZ0KTsKICAgICAgICBpZiAoaHJlcyAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgVFJBQ0UoImZvdW5kICVzXG4iLCBkZWJ1Z3N0cl93KHN6TmV4dEtleSkpOwoKICAgICAgICBpZiAoIShUaGlzLT5kd0ZsYWdzICYgRE1PX0VOVU1GX0lOQ0xVREVfS0VZRUQpKQogICAgICAgIHsKICAgICAgICAgICAgd3NwcmludGZXKHN6S2V5LCBzekNhdDNGbXQsIHN6RE1PUm9vdEtleSwgc3pOZXh0S2V5LCBzekRNT0tleWVkKTsKICAgICAgICAgICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6S2V5LCAwLCBLRVlfUkVBRCwgJmhrZXkpOwogICAgICAgICAgICBpZiAoRVJST1JfU1VDQ0VTUyA9PSBocmVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgICAgIC8qIFNraXAgS2V5ZWQgZW50cmllcyAqLwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHdzcHJpbnRmVyhzektleSwgc3pDYXQyRm10LCBzekRNT1Jvb3RLZXksIHN6TmV4dEtleSk7CiAgICAgICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6S2V5LCAwLCBLRVlfUkVBRCwgJmhrZXkpOwoKICAgICAgICBpZiAoVGhpcy0+cEluVHlwZXMpCiAgICAgICAgewogICAgICAgICAgICBVSU5UIGksIGo7CiAgICAgICAgICAgIERXT1JEIGNJblR5cGVzOwogICAgICAgICAgICBETU9fUEFSVElBTF9NRURJQVRZUEUqIHBJblR5cGVzOwoKICAgICAgICAgICAgaHJlcyA9IHJlYWRfdHlwZXMoaGtleSwgc3pETU9JbnB1dFR5cGUsICZjSW5UeXBlcywKICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3pWYWx1ZSkvc2l6ZW9mKERNT19QQVJUSUFMX01FRElBVFlQRSksCiAgICAgICAgICAgICAgICAgICAgKERNT19QQVJUSUFMX01FRElBVFlQRSopc3pWYWx1ZSk7CgogICAgICAgICAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgoJICAgIHBJblR5cGVzID0gKERNT19QQVJUSUFMX01FRElBVFlQRSopIHN6VmFsdWU7CgogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+Y0luVHlwZXM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGNJblR5cGVzOyBqKyspIAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChJc01lZGlhVHlwZUVxdWFsKCZwSW5UeXBlc1tqXSwgJlRoaXMtPnBJblR5cGVzW2ldKSkKCQkgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQoKCQlpZiAoaiA+PSBjSW5UeXBlcykKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGkgPCBUaGlzLT5jSW5UeXBlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKFRoaXMtPnBPdXRUeXBlcykKICAgICAgICB7CiAgICAgICAgICAgIFVJTlQgaSwgajsKICAgICAgICAgICAgRFdPUkQgY091dFR5cGVzOwogICAgICAgICAgICBETU9fUEFSVElBTF9NRURJQVRZUEUqIHBPdXRUeXBlczsKCiAgICAgICAgICAgIGhyZXMgPSByZWFkX3R5cGVzKGhrZXksIHN6RE1PT3V0cHV0VHlwZSwgJmNPdXRUeXBlcywKICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3pWYWx1ZSkvc2l6ZW9mKERNT19QQVJUSUFMX01FRElBVFlQRSksCiAgICAgICAgICAgICAgICAgICAgKERNT19QQVJUSUFMX01FRElBVFlQRSopc3pWYWx1ZSk7CgoJICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCgkgICAgcE91dFR5cGVzID0gKERNT19QQVJUSUFMX01FRElBVFlQRSopIHN6VmFsdWU7CgogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+Y091dFR5cGVzOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBjT3V0VHlwZXM7IGorKykgCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKElzTWVkaWFUeXBlRXF1YWwoJnBPdXRUeXBlc1tqXSwgJlRoaXMtPnBPdXRUeXBlc1tpXSkpCgkJICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCgkJaWYgKGogPj0gY091dFR5cGVzKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaSA8IFRoaXMtPmNPdXRUeXBlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCgkvKiBNZWRpYSBvYmplY3Qgd2Fzbid0IGZpbHRlcmVkIHNvIGFkZCBpdCB0byByZXR1cm4gbGlzdCAqLwogICAgICAgIE5hbWVzW2NvdW50XSA9IE5VTEw7CglsZW4gPSBNQVhfUEFUSCAqIHNpemVvZihXQ0hBUik7CiAgICAgICAgaHJlcyA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgTlVMTCwgTlVMTCwgTlVMTCwgKExQQllURSkgc3pWYWx1ZSwgJmxlbik7IAogICAgICAgIGlmIChFUlJPUl9TVUNDRVNTID09IGhyZXMpCgl7CiAgICAgICAgICAgIE5hbWVzW2NvdW50XSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW5XKHN6VmFsdWUpICsgMSk7CgkgICAgaWYgKE5hbWVzW2NvdW50XSkKICAgICAgICAgICAgICAgIHN0cmNtcFcoTmFtZXNbY291bnRdLCBzelZhbHVlKTsKCX0KICAgICAgICB3c3ByaW50Zlcoc3pHdWlkS2V5LHN6VG9HdWlkRm10LHN6TmV4dEtleSk7CiAgICAgICAgQ0xTSURGcm9tU3RyaW5nKHN6R3VpZEtleSwgJnBDTFNJRFtjb3VudF0pOwoKICAgICAgICBUUkFDRSgiZm91bmQgbWF0Y2ggJXMgJXNcbiIsIGRlYnVnc3RyX3coc3pWYWx1ZSksIGRlYnVnc3RyX3coc3pOZXh0S2V5KSk7CiAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7Cgljb3VudCsrOwogICAgfQoKICAgICpwY0l0ZW1zRmV0Y2hlZCA9IGNvdW50OwogICAgaWYgKCpwY0l0ZW1zRmV0Y2hlZCA8IGNJdGVtc1RvRmV0Y2gpCiAgICAgICAgaHJlcyA9IFNfRkFMU0U7CgogICAgVFJBQ0UoIjwtLSAlaSBmb3VuZFxuIixjb3VudCk7CiAgICByZXR1cm4gaHJlczsKfQogCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElFbnVtRE1PX2ZuU2tpcAogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFbnVtRE1PX2ZuU2tpcChJRW51bURNTyAqIGlmYWNlLCBEV09SRCBjSXRlbXNUb1NraXApCnsKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKCiAgICBUaGlzLT5pbmRleCArPSBjSXRlbXNUb1NraXA7CgogICAgcmV0dXJuIFNfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElFbnVtRE1PX2ZuUmVzZXQKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRW51bURNT19mblJlc2V0KElFbnVtRE1PICogaWZhY2UpCnsKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKCiAgICBUaGlzLT5pbmRleCA9IC0xOwoKICAgIHJldHVybiBTX09LOwp9CiAKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUVudW1ETU9fZm5DbG9uZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFbnVtRE1PX2ZuQ2xvbmUoSUVudW1ETU8gKiBpZmFjZSwgSUVudW1ETU8gKipwcEVudW0pCnsKICAgIElFbnVtRE1PSW1wbCAqVGhpcyA9IChJRW51bURNT0ltcGwgKilpZmFjZTsKCiAgICBGSVhNRSgiKCVwKS0+KCkgdG8gKCVwKS0+KCkgRV9OT1RJTVBMXG4iLCBUaGlzLCBwcEVudW0pOwoKICByZXR1cm4gRV9OT1RJTVBMOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBETU9FbnVtIChNU0RNTy5AKQogKgogKiBFbnVtZXJhdGUgRGlyZWN0WCBNZWRpYSBPYmplY3RzIGluIHRoZSByZWdpc3RyeS4KICovCkhSRVNVTFQgV0lOQVBJIERNT0VudW0oCiAgICBSRUZHVUlEIGd1aWRDYXRlZ29yeSwKICAgIERXT1JEIGR3RmxhZ3MsCiAgICBEV09SRCBjSW5UeXBlcywKICAgIGNvbnN0IERNT19QQVJUSUFMX01FRElBVFlQRSAqcEluVHlwZXMsCiAgICBEV09SRCBjT3V0VHlwZXMsCiAgICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBPdXRUeXBlcywKICAgIElFbnVtRE1PICoqcHBFbnVtKQp7CiAgICBIUkVTVUxUIGhyZXMgPSBFX0ZBSUw7CgogICAgVFJBQ0UoImd1aWRDYXRlZ29yeT0lcCBkd0ZsYWdzPTB4JTA4eCBjSW5UeXBlcz0lZCBjT3V0VHlwZXM9JWRcbiIsCiAgICAgICAgZ3VpZENhdGVnb3J5LCBkd0ZsYWdzLCBjSW5UeXBlcywgY091dFR5cGVzKTsKCiAgICAqcHBFbnVtID0gSUVudW1ETU9fQ29uc3RydWN0b3IoZ3VpZENhdGVnb3J5LCBkd0ZsYWdzLCBjSW5UeXBlcywKICAgICAgICBwSW5UeXBlcywgY091dFR5cGVzLCBwT3V0VHlwZXMpOwogICAgaWYgKCpwcEVudW0pCiAgICAgICAgaHJlcyA9IFNfT0s7CgogICAgcmV0dXJuIGhyZXM7Cn0KCgpzdGF0aWMgY29uc3QgSUVudW1ETU9WdGJsIGVkbW92dCA9CnsKCUlFbnVtRE1PX2ZuUXVlcnlJbnRlcmZhY2UsCglJRW51bURNT19mbkFkZFJlZiwKCUlFbnVtRE1PX2ZuUmVsZWFzZSwKCUlFbnVtRE1PX2ZuTmV4dCwKCUlFbnVtRE1PX2ZuU2tpcCwKCUlFbnVtRE1PX2ZuUmVzZXQsCglJRW51bURNT19mbkNsb25lLAp9OwoKCkhSRVNVTFQgcmVhZF90eXBlcyhIS0VZIHJvb3QsIExQQ1dTVFIga2V5LCBVTE9ORyAqc3VwcGxpZWQsIFVMT05HIHJlcXVlc3RlZCwgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiB0eXBlcyApCnsKICAgIEhSRVNVTFQgcmV0ID0gU19PSzsKICAgIGlmIChNU0RNT19NQUpPUl9WRVJTSU9OID4gNSkKICAgIHsKICAgICAgICBEV09SRCBsZW47CiAgICAgICAgbGVuID0gcmVxdWVzdGVkICogc2l6ZW9mKERNT19QQVJUSUFMX01FRElBVFlQRSk7CiAgICAgICAgcmV0ID0gUmVnUXVlcnlWYWx1ZUV4Vyhyb290LCBrZXksIE5VTEwsIE5VTEwsIChMUEJZVEUpIHR5cGVzLCAmbGVuKTsKICAgICAgICAqc3VwcGxpZWQgPSBsZW4gLyBzaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBIS0VZIGhrZXk7CiAgICAgICAgV0NIQVIgc3pHdWlkS2V5WzY0XTsKCiAgICAgICAgKnN1cHBsaWVkID0gMDsKICAgICAgICBpZiAoRVJST1JfU1VDQ0VTUyA9PSBSZWdPcGVuS2V5RXhXKHJvb3QsIGtleSwgMCwgS0VZX1JFQUQsICZoa2V5KSkKICAgICAgICB7CiAgICAgICAgICBpbnQgaW5kZXggPSAwOwogICAgICAgICAgV0NIQVIgc3pOZXh0S2V5W01BWF9QQVRIXTsKICAgICAgICAgIERXT1JEIGxlbjsKICAgICAgICAgIExPTkcgcmMgPSBFUlJPUl9TVUNDRVNTOwoKICAgICAgICAgIHdoaWxlIChyYyA9PSBFUlJPUl9TVUNDRVNTKQogICAgICAgICAgewogICAgICAgICAgICBsZW4gPSBNQVhfUEFUSCAqIHNpemVvZihXQ0hBUik7CiAgICAgICAgICAgIHJjID0gUmVnRW51bUtleUV4Vyhoa2V5LCBpbmRleCwgc3pOZXh0S2V5LCAmbGVuLCBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgaWYgKHJjID09IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICBIS0VZIHN1Yms7CiAgICAgICAgICAgICAgaW50IHN1Yl9pbmRleCA9IDA7CiAgICAgICAgICAgICAgTE9ORyByY3MgPSBFUlJPUl9TVUNDRVNTOwogICAgICAgICAgICAgIFdDSEFSIHN6U3ViS2V5W01BWF9QQVRIXTsKCiAgICAgICAgICAgICAgUmVnT3BlbktleUV4Vyhoa2V5LCBzek5leHRLZXksIDAsIEtFWV9SRUFELCAmc3Viayk7CiAgICAgICAgICAgICAgd2hpbGUgKHJjcyA9PSBFUlJPUl9TVUNDRVNTKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxlbiA9IE1BWF9QQVRIICogc2l6ZW9mKFdDSEFSKTsKICAgICAgICAgICAgICAgIHJjcyA9IFJlZ0VudW1LZXlFeFcoc3Viaywgc3ViX2luZGV4LCBzelN1YktleSwgJmxlbiwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgICAgICBpZiAocmNzID09IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIGlmICgqc3VwcGxpZWQgPj0gcmVxdWVzdGVkKQogICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogQmFpbGluZyAqLwogICAgICAgICAgICAgICAgICAgIHJldCA9IFNfRkFMU0U7CiAgICAgICAgICAgICAgICAgICAgcmMgPSBFUlJPUl9NT1JFX0RBVEE7CiAgICAgICAgICAgICAgICAgICAgcmNzID0gRVJST1JfTU9SRV9EQVRBOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICB3c3ByaW50Zlcoc3pHdWlkS2V5LHN6VG9HdWlkRm10LHN6TmV4dEtleSk7CiAgICAgICAgICAgICAgICAgIENMU0lERnJvbVN0cmluZyhzekd1aWRLZXksICZ0eXBlc1sqc3VwcGxpZWRdLnR5cGUpOwogICAgICAgICAgICAgICAgICB3c3ByaW50Zlcoc3pHdWlkS2V5LHN6VG9HdWlkRm10LHN6U3ViS2V5KTsKICAgICAgICAgICAgICAgICAgQ0xTSURGcm9tU3RyaW5nKHN6R3VpZEtleSwgJnR5cGVzWypzdXBwbGllZF0uc3VidHlwZSk7CiAgICAgICAgICAgICAgICAgIFRSQUNFKCJBZGRpbmcgdHlwZSAlcyBzdWJ0eXBlICVzIGF0IGluZGV4ICVpXG4iLAogICAgICAgICAgICAgICAgICAgIGRlYnVnc3RyX2d1aWQoJnR5cGVzWypzdXBwbGllZF0udHlwZSksCiAgICAgICAgICAgICAgICAgICAgZGVidWdzdHJfZ3VpZCgmdHlwZXNbKnN1cHBsaWVkXS5zdWJ0eXBlKSwKICAgICAgICAgICAgICAgICAgICAqc3VwcGxpZWQpOwogICAgICAgICAgICAgICAgICAoKnN1cHBsaWVkKSsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3ViX2luZGV4Kys7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGluZGV4Kys7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRE1PR2V0VHlwZXMgKE1TRE1PLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBETU9HZXRUeXBlcyhSRUZDTFNJRCBjbHNpZERNTywKICAgICAgICAgICAgICAgVUxPTkcgdWxJbnB1dFR5cGVzUmVxdWVzdGVkLAogICAgICAgICAgICAgICBVTE9ORyogcHVsSW5wdXRUeXBlc1N1cHBsaWVkLAogICAgICAgICAgICAgICBETU9fUEFSVElBTF9NRURJQVRZUEUqIHBJbnB1dFR5cGVzLAogICAgICAgICAgICAgICBVTE9ORyB1bE91dHB1dFR5cGVzUmVxdWVzdGVkLAogICAgICAgICAgICAgICBVTE9ORyogcHVsT3V0cHV0VHlwZXNTdXBwbGllZCwKICAgICAgICAgICAgICAgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBwT3V0cHV0VHlwZXMpCnsKICBIS0VZIHJvb3QsaGtleTsKICBIUkVTVUxUIHJldCA9IFNfT0s7CiAgV0NIQVIgc3pndWlkWzY0XTsKCiAgVFJBQ0UgKCIoJXMsJXUsJXAsJXAsJXUsJXAsJXApLHN0dWIhXG4iLCBkZWJ1Z3N0cl9ndWlkKGNsc2lkRE1PKSwKICAgICAgICB1bElucHV0VHlwZXNSZXF1ZXN0ZWQsIHB1bElucHV0VHlwZXNTdXBwbGllZCwgcElucHV0VHlwZXMsCiAgICAgICAgdWxPdXRwdXRUeXBlc1JlcXVlc3RlZCwgcHVsT3V0cHV0VHlwZXNTdXBwbGllZCwgcE91dHB1dFR5cGVzKTsKCiAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pETU9Sb290S2V5LCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX1JFQUQsICZyb290KSkKICAgIHJldHVybiBFX0ZBSUw7CgogIGlmIChFUlJPUl9TVUNDRVNTICE9IFJlZ09wZW5LZXlFeFcocm9vdCxHVUlEVG9TdHJpbmcoc3pndWlkLGNsc2lkRE1PKSAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfUkVBRCwgJmhrZXkpKQogIHsKICAgIFJlZ0Nsb3NlS2V5KHJvb3QpOwogICAgcmV0dXJuIEVfRkFJTDsKICB9CgogIGlmICh1bElucHV0VHlwZXNSZXF1ZXN0ZWQgPiAwKQogIHsKICAgIHJldCA9IHJlYWRfdHlwZXMoaGtleSwgc3pETU9JbnB1dFR5cGUsIHB1bElucHV0VHlwZXNTdXBwbGllZCwgdWxJbnB1dFR5cGVzUmVxdWVzdGVkLCBwSW5wdXRUeXBlcyApOwogIH0KICBlbHNlCiAgICAqcHVsSW5wdXRUeXBlc1N1cHBsaWVkID0gMDsKCiAgaWYgKHVsT3V0cHV0VHlwZXNSZXF1ZXN0ZWQgPiAwKQogIHsKICAgIEhSRVNVTFQgcmV0MjsKICAgIHJldDIgPSByZWFkX3R5cGVzKGhrZXksIHN6RE1PT3V0cHV0VHlwZSwgcHVsT3V0cHV0VHlwZXNTdXBwbGllZCwgdWxPdXRwdXRUeXBlc1JlcXVlc3RlZCwgcE91dHB1dFR5cGVzICk7CgogICAgaWYgKHJldCA9PSBTX09LKQogICAgICAgIHJldCA9IHJldDI7CiAgfQogIGVsc2UKICAgICpwdWxPdXRwdXRUeXBlc1N1cHBsaWVkID0gMDsKCiAgcmV0dXJuIHJldDsKfQo=