LyoKICogQ29weXJpZ2h0IChDKSAyMDAzIE1pY2hhZWwgR/xubmV3aWcKICogQ29weXJpZ2h0IChDKSAyMDAzIENvZGVXZWF2ZXJzIEluYy4gKFVscmljaCBDemVrYWxsYSkKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJpbml0Z3VpZC5oIgojaW5jbHVkZSAiZG1vLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChtc2Rtbyk7CgojZGVmaW5lIE1TRE1PX01BSk9SX1ZFUlNJT04gNgoKc3RhdGljIGNvbnN0IFdDSEFSIHN6RE1PUm9vdEtleVtdID0gCnsKICAgICdEJywnaScsJ3InLCdlJywnYycsJ3QnLCdTJywnaCcsJ28nLCd3JywnXFwnLAogICAgJ00nLCdlJywnZCcsJ2knLCdhJywnTycsJ2InLCdqJywnZScsJ2MnLCd0JywncycsMAp9OyAKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT0lucHV0VHlwZVtdID0KewogICAgJ0knLCduJywncCcsJ3UnLCd0JywnVCcsJ3knLCdwJywnZScsJ3MnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRNT091dHB1dFR5cGVbXSA9CnsKICAgICdPJywndScsJ3QnLCdwJywndScsJ3QnLCdUJywneScsJ3AnLCdlJywncycsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6RE1PS2V5ZWRbXSA9CnsKICAgICdLJywnZScsJ3knLCdlJywnZCcsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6RE1PQ2F0ZWdvcmllc1tdID0KewogICAgJ0MnLCdhJywndCcsJ2UnLCdnJywnbycsJ3InLCdpJywnZScsJ3MnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzekdVSURGbXRbXSA9CnsKICAgICclJywnMCcsJzgnLCdYJywnLScsJyUnLCcwJywnNCcsJ1gnLCctJywnJScsJzAnLCc0JywnWCcsJy0nLCclJywnMCcsCiAgICAnMicsJ1gnLCclJywnMCcsJzInLCdYJywnLScsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywKICAgICdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywwCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pDYXQzRm10W10gPQp7CiAgICAnJScsJ3MnLCdcXCcsJyUnLCdzJywnXFwnLCclJywncycsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6Q2F0MkZtdFtdID0KewogICAgJyUnLCdzJywnXFwnLCclJywncycsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6VG9HdWlkRm10W10gPQp7CiAgICAneycsJyUnLCdzJywnfScsMAp9OwoKCnR5cGVkZWYgc3RydWN0CnsKICAgIGNvbnN0IElFbnVtRE1PVnRibCAgICAgICAgICpscFZ0Ymw7CiAgICBMT05HCQkJcmVmOwogICAgRFdPUkQJCQlpbmRleDsKICAgIGNvbnN0IEdVSUQqICAgICAgICAgICAgICAgICBndWlkQ2F0ZWdvcnk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgZHdGbGFnczsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICBjSW5UeXBlczsKICAgIERNT19QQVJUSUFMX01FRElBVFlQRSAgICAgICAqcEluVHlwZXM7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgY091dFR5cGVzOwogICAgRE1PX1BBUlRJQUxfTUVESUFUWVBFICAgICAgICpwT3V0VHlwZXM7CiAgICBIS0VZICAgICAgICAgICAgICAgICAgICAgICAgaGtleTsKfSBJRW51bURNT0ltcGw7CgpzdGF0aWMgSFJFU1VMVCByZWFkX3R5cGVzKEhLRVkgcm9vdCwgTFBDV1NUUiBrZXksIFVMT05HICpzdXBwbGllZCwgVUxPTkcgcmVxdWVzdGVkLCBETU9fUEFSVElBTF9NRURJQVRZUEUqIHR5cGVzKTsKCnN0YXRpYyBjb25zdCBJRW51bURNT1Z0YmwgZWRtb3Z0OwoKc3RhdGljIExQV1NUUiBHVUlEVG9TdHJpbmcoTFBXU1RSIGxwd3N0ciwgUkVGR1VJRCBscGNndWlkKQp7CiAgICB3c3ByaW50ZlcobHB3c3RyLCBzekdVSURGbXQsIGxwY2d1aWQtPkRhdGExLCBscGNndWlkLT5EYXRhMiwKICAgICAgICBscGNndWlkLT5EYXRhMywgbHBjZ3VpZC0+RGF0YTRbMF0sIGxwY2d1aWQtPkRhdGE0WzFdLAogICAgICAgIGxwY2d1aWQtPkRhdGE0WzJdLCBscGNndWlkLT5EYXRhNFszXSwgbHBjZ3VpZC0+RGF0YTRbNF0sCiAgICAgICAgbHBjZ3VpZC0+RGF0YTRbNV0sIGxwY2d1aWQtPkRhdGE0WzZdLCBscGNndWlkLT5EYXRhNFs3XSk7CgogICAgcmV0dXJuIGxwd3N0cjsKfQoKc3RhdGljIEJPT0wgSXNNZWRpYVR5cGVFcXVhbChjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUqIG10MSwgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiBtdDIpCnsKCiAgICByZXR1cm4gKElzRXF1YWxDTFNJRCgmbXQxLT50eXBlLCAmbXQyLT50eXBlKSB8fAogICAgICAgICAgICBJc0VxdWFsQ0xTSUQoJm10Mi0+dHlwZSwgJkdVSURfTlVMTCkgfHwKICAgICAgICAgICAgSXNFcXVhbENMU0lEKCZtdDEtPnR5cGUsICZHVUlEX05VTEwpKSAmJgogICAgICAgICAgICAoSXNFcXVhbENMU0lEKCZtdDEtPnN1YnR5cGUsICZtdDItPnN1YnR5cGUpIHx8CiAgICAgICAgICAgIElzRXF1YWxDTFNJRCgmbXQyLT5zdWJ0eXBlLCAmR1VJRF9OVUxMKSB8fAogICAgICAgICAgICBJc0VxdWFsQ0xTSUQoJm10MS0+c3VidHlwZSwgJkdVSURfTlVMTCkpOwp9CgpzdGF0aWMgSFJFU1VMVCB3cml0ZV90eXBlcyhIS0VZIGhrZXksIExQQ1dTVFIgbmFtZSwgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFKiB0eXBlcywgRFdPUkQgY291bnQpCnsKICAgIEhSRVNVTFQgaHJlcyA9IFNfT0s7CiAgICBpZiAoTVNETU9fTUFKT1JfVkVSU0lPTiA+IDUpCiAgICB7CiAgICAgICAgaHJlcyA9IFJlZ1NldFZhbHVlRXhXKGhrZXksIG5hbWUsIDAsIFJFR19CSU5BUlksIChjb25zdCBCWVRFKikgdHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnQqIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBIS0VZIHNrZXkxLHNrZXkyLHNrZXkzOwogICAgICAgIERXT1JEIGluZGV4ID0gMDsKICAgICAgICBXQ0hBUiBzekd1aWRLZXlbNjRdOwoKICAgICAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKGhrZXksIG5hbWUsIDAsIE5VTEwsIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS0VZX1dSSVRFLCBOVUxMLCAmc2tleTEsIE5VTEwpOwogICAgICAgIHdoaWxlIChpbmRleCA8IGNvdW50KQogICAgICAgIHsKICAgICAgICAgICAgR1VJRFRvU3RyaW5nKHN6R3VpZEtleSwmdHlwZXNbaW5kZXhdLnR5cGUpOwogICAgICAgICAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKHNrZXkxLCBzekd1aWRLZXksIDAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfV1JJVEUsIE5VTEwsICZza2V5MiwgTlVMTCk7CiAgICAgICAgICAgIEdVSURUb1N0cmluZyhzekd1aWRLZXksJnR5cGVzW2luZGV4XS5zdWJ0eXBlKTsKICAgICAgICAgICAgaHJlcyA9IFJlZ0NyZWF0ZUtleUV4Vyhza2V5Miwgc3pHdWlkS2V5LCAwLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX1dSSVRFLCBOVUxMLCAmc2tleTMsIE5VTEwpOwogICAgICAgICAgICBSZWdDbG9zZUtleShza2V5Myk7CiAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KHNrZXkyKTsKICAgICAgICAgICAgaW5kZXggKys7CiAgICAgICAgfQogICAgICAgIFJlZ0Nsb3NlS2V5KHNrZXkxKTsKICAgIH0KCiAgICByZXR1cm4gaHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBETU9SZWdpc3RlciAoTVNETU8uQCkKICoKICogUmVnaXN0ZXIgYSBEaXJlY3RYIE1lZGlhIE9iamVjdC4KICovCkhSRVNVTFQgV0lOQVBJIERNT1JlZ2lzdGVyKAogICBMUENXU1RSIHN6TmFtZSwKICAgUkVGQ0xTSUQgY2xzaWRETU8sCiAgIFJFRkdVSUQgZ3VpZENhdGVnb3J5LAogICBEV09SRCBkd0ZsYWdzLAogICBEV09SRCBjSW5UeXBlcywKICAgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFICpwSW5UeXBlcywKICAgRFdPUkQgY091dFR5cGVzLAogICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBPdXRUeXBlcwopCnsKICAgIFdDSEFSIHN6Z3VpZFs2NF07CiAgICBIUkVTVUxUIGhyZXM7CiAgICBIS0VZIGhya2V5ID0gMDsKICAgIEhLRVkgaGtleSA9IDA7CiAgICBIS0VZIGhja2V5ID0gMDsKICAgIEhLRVkgaGNsc2tleSA9IDA7CgogICAgVFJBQ0UoIiVzXG4iLCBkZWJ1Z3N0cl93KHN6TmFtZSkpOwoKICAgIGhyZXMgPSBSZWdDcmVhdGVLZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6RE1PUm9vdEtleSwgMCwgTlVMTCwKICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX1dSSVRFLCBOVUxMLCAmaHJrZXksIE5VTEwpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgLyogQ3JlYXRlIGNsc2lkRE1PIGtleSB1bmRlciBNZWRpYU9iamVjdHMgKi8gCiAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKGhya2V5LCBHVUlEVG9TdHJpbmcoc3pndWlkLCBjbHNpZERNTyksIDAsIE5VTEwsCiAgICAgICAgUkVHX09QVElPTl9OT05fVk9MQVRJTEUsIEtFWV9XUklURSwgTlVMTCwgJmhrZXksIE5VTEwpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgLyogU2V0IGRlZmF1bHQgTmFtZSB2YWx1ZSAqLwogICAgaHJlcyA9IFJlZ1NldFZhbHVlRXhXKGhrZXksIE5VTEwsIDAsIFJFR19TWiwgKGNvbnN0IEJZVEUqKSBzek5hbWUsIAogICAgICAgIChzdHJsZW5XKHN6TmFtZSkgKyAxKSAqIHNpemVvZihXQ0hBUikpOwoKICAgIC8qIFNldCBJbnB1dFR5cGVzICovCiAgICBocmVzID0gd3JpdGVfdHlwZXMoaGtleSwgc3pETU9JbnB1dFR5cGUsIHBJblR5cGVzLCBjSW5UeXBlcyk7CgogICAgLyogU2V0IE91dHB1dFR5cGVzICovCiAgICBocmVzID0gd3JpdGVfdHlwZXMoaGtleSwgc3pETU9PdXRwdXRUeXBlLCBwT3V0VHlwZXMsIGNPdXRUeXBlcyk7CgogICAgaWYgKGR3RmxhZ3MgJiBETU9fUkVHSVNURVJGX0lTX0tFWUVEKQogICAgewogICAgICAgIC8qIENyZWF0ZSBLZXllZCBrZXkgKi8gCiAgICAgICAgaHJlcyA9IFJlZ0NyZWF0ZUtleUV4Vyhoa2V5LCBzekRNT0tleWVkLCAwLCBOVUxMLAogICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX1dSSVRFLCBOVUxMLCAmaGNrZXksIE5VTEwpOwogICAgICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgICAgIGdvdG8gbGVuZDsKICAgICAgICBSZWdDbG9zZUtleShoY2tleSk7CiAgICB9CgogICAgLyogUmVnaXN0ZXIgdGhlIGNhdGVnb3J5ICovCiAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKGhya2V5LCBzekRNT0NhdGVnb3JpZXMsIDAsIE5VTEwsCiAgICAgICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfV1JJVEUsIE5VTEwsICZoY2tleSwgTlVMTCk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCiAgICBSZWdDbG9zZUtleShoa2V5KTsKCiAgICBocmVzID0gUmVnQ3JlYXRlS2V5RXhXKGhja2V5LCBHVUlEVG9TdHJpbmcoc3pndWlkLCBndWlkQ2F0ZWdvcnkpLCAwLCBOVUxMLAogICAgICAgICAgICBSRUdfT1BUSU9OX05PTl9WT0xBVElMRSwgS0VZX1dSSVRFLCBOVUxMLCAmaGtleSwgTlVMTCk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKICAgIGhyZXMgPSBSZWdDcmVhdGVLZXlFeFcoaGtleSwgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pLCAwLCBOVUxMLAogICAgICAgIFJFR19PUFRJT05fTk9OX1ZPTEFUSUxFLCBLRVlfV1JJVEUsIE5VTEwsICZoY2xza2V5LCBOVUxMKTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKbGVuZDoKICAgIGlmIChoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgaWYgKGhja2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhja2V5KTsKICAgIGlmIChoY2xza2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhjbHNrZXkpOwogICAgaWYgKGhya2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhya2V5KTsKCiAgICBUUkFDRSgiIGhyZXN1bHQ9MHglMDh4XG4iLCBocmVzKTsKICAgIHJldHVybiBocmVzOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBETU9VbnJlZ2lzdGVyIChNU0RNTy5AKQogKgogKiBVbnJlZ2lzdGVyIGEgRGlyZWN0WCBNZWRpYSBPYmplY3QuCiAqLwpIUkVTVUxUIFdJTkFQSSBETU9VbnJlZ2lzdGVyKFJFRkNMU0lEIGNsc2lkRE1PLCBSRUZHVUlEIGd1aWRDYXRlZ29yeSkKewogICAgSFJFU1VMVCBocmVzOwogICAgV0NIQVIgc3pndWlkWzY0XTsKICAgIEhLRVkgaHJrZXkgPSAwOwogICAgSEtFWSBoY2tleSA9IDA7CgogICAgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pOwoKICAgIFRSQUNFKCIlcyAlcFxuIiwgZGVidWdzdHJfdyhzemd1aWQpLCBndWlkQ2F0ZWdvcnkpOwoKICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhXKEhLRVlfQ0xBU1NFU19ST09ULCBzekRNT1Jvb3RLZXksIDAsIEtFWV9XUklURSwgJmhya2V5KTsKICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgZ290byBsZW5kOwoKICAgIGhyZXMgPSBSZWdEZWxldGVLZXlXKGhya2V5LCBzemd1aWQpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoaHJrZXksIHN6RE1PQ2F0ZWdvcmllcywgMCwgS0VZX1dSSVRFLCAmaGNrZXkpOwogICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICBnb3RvIGxlbmQ7CgogICAgaHJlcyA9IFJlZ0RlbGV0ZUtleVcoaGNrZXksIHN6Z3VpZCk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCmxlbmQ6CiAgICBpZiAoaGNrZXkpCiAgICAgICAgUmVnQ2xvc2VLZXkoaGNrZXkpOwogICAgaWYgKGhya2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhya2V5KTsKCiAgICByZXR1cm4gaHJlczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRE1PR2V0TmFtZSAoTVNETU8uQCkKICoKICogR2V0IERNUCBOYW1lIGZyb20gdGhlIHJlZ2lzdHJ5CiAqLwpIUkVTVUxUIFdJTkFQSSBETU9HZXROYW1lKFJFRkNMU0lEIGNsc2lkRE1PLCBXQ0hBUiBzek5hbWVbODBdKQp7CiAgICBXQ0hBUiBzemd1aWRbNjRdOwogICAgSFJFU1VMVCBocmVzOwogICAgSEtFWSBocmtleSA9IDA7CiAgICBIS0VZIGhrZXkgPSAwOwogICAgRFdPUkQgY291bnQ7CgogICAgVFJBQ0UoIiVzXG4iLCBkZWJ1Z3N0cl9ndWlkKGNsc2lkRE1PKSk7CgogICAgaHJlcyA9IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6RE1PUm9vdEtleSwgCiAgICAgICAgMCwgS0VZX1JFQUQsICZocmtleSk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCiAgICBocmVzID0gUmVnT3BlbktleUV4VyhocmtleSwgR1VJRFRvU3RyaW5nKHN6Z3VpZCwgY2xzaWRETU8pLAogICAgICAgIDAsIEtFWV9SRUFELCAmaGtleSk7CiAgICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBocmVzKQogICAgICAgIGdvdG8gbGVuZDsKCiAgICBjb3VudCA9IHNpemVvZihzek5hbWUpOwogICAgaHJlcyA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgTlVMTCwgTlVMTCwgTlVMTCwgCiAgICAgICAgKExQQllURSkgc3pOYW1lLCAmY291bnQpOyAKCiAgICBUUkFDRSgiIHN6TmFtZT0lc1xuIiwgZGVidWdzdHJfdyhzek5hbWUpKTsKbGVuZDoKICAgIGlmIChoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhya2V5KTsKICAgIGlmIChoa2V5KQogICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwoKICAgIHJldHVybiBocmVzOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBJRW51bURNT19EZXN0cnVjdG9yCiovCnN0YXRpYyBCT09MIElFbnVtRE1PX0Rlc3RydWN0b3IoSUVudW1ETU8qIGlmYWNlKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiVwXG4iLCBUaGlzKTsKCiAgICBpZiAoVGhpcy0+aGtleSkKICAgICAgICBSZWdDbG9zZUtleShUaGlzLT5oa2V5KTsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5wSW5UeXBlcyk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5wT3V0VHlwZXMpOwoKICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJRW51bURNT19Db25zdHJ1Y3RvcgogKi8Kc3RhdGljIElFbnVtRE1PICogSUVudW1ETU9fQ29uc3RydWN0b3IoCiAgICBSRUZHVUlEIGd1aWRDYXRlZ29yeSwKICAgIERXT1JEIGR3RmxhZ3MsCiAgICBEV09SRCBjSW5UeXBlcywKICAgIGNvbnN0IERNT19QQVJUSUFMX01FRElBVFlQRSAqcEluVHlwZXMsCiAgICBEV09SRCBjT3V0VHlwZXMsCiAgICBjb25zdCBETU9fUEFSVElBTF9NRURJQVRZUEUgKnBPdXRUeXBlcykKewogICAgVUlOVCBzaXplOwogICAgSUVudW1ETU9JbXBsKiBscGVkbW87CiAgICBCT09MIHJldCA9IEZBTFNFOwoKICAgIGxwZWRtbyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSUVudW1ETU9JbXBsKSk7CgogICAgaWYgKGxwZWRtbykKICAgIHsKICAgICAgICBscGVkbW8tPnJlZiA9IDE7CiAgICAgICAgbHBlZG1vLT5scFZ0YmwgPSAmZWRtb3Z0OwogICAgICAgIGxwZWRtby0+aW5kZXggPSAtMTsKCWxwZWRtby0+Z3VpZENhdGVnb3J5ID0gZ3VpZENhdGVnb3J5OwoJbHBlZG1vLT5kd0ZsYWdzID0gZHdGbGFnczsKCiAgICAgICAgaWYgKGNJblR5cGVzID4gMCkKICAgICAgICB7CiAgICAgICAgICAgIHNpemUgPSBjSW5UeXBlcyAqIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpOwogICAgICAgICAgICBscGVkbW8tPnBJblR5cGVzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgICAgICAgICBpZiAoIWxwZWRtby0+cEluVHlwZXMpCiAgICAgICAgICAgICAgICBnb3RvIGxlcnI7CiAgICAgICAgICAgIG1lbWNweShscGVkbW8tPnBJblR5cGVzLCBwSW5UeXBlcywgc2l6ZSk7CiAgICAgICAgICAgIGxwZWRtby0+Y0luVHlwZXMgPSBjSW5UeXBlczsKICAgICAgICB9CgogICAgICAgIGlmIChjT3V0VHlwZXMgPiAwKQogICAgICAgIHsKICAgICAgICAgICAgc2l6ZSA9IGNPdXRUeXBlcyAqIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpOwogICAgICAgICAgICBscGVkbW8tPnBPdXRUeXBlcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgICAgICAgICAgaWYgKCFscGVkbW8tPnBPdXRUeXBlcykKICAgICAgICAgICAgICAgIGdvdG8gbGVycjsKICAgICAgICAgICAgbWVtY3B5KGxwZWRtby0+cE91dFR5cGVzLCBwT3V0VHlwZXMsIHNpemUpOwogICAgICAgICAgICBscGVkbW8tPmNPdXRUeXBlcyA9IGNPdXRUeXBlczsKICAgICAgICB9CgogICAgICAgIC8qIElmIG5vdCBmaWx0ZXJpbmcgYnkgY2F0ZWdvcnkgZW51bSBmcm9tIG1lZGlhIG9iamVjdHMgcm9vdCAqLwogICAgICAgIGlmIChJc0VxdWFsR1VJRChndWlkQ2F0ZWdvcnksICZHVUlEX05VTEwpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKEVSUk9SX1NVQ0NFU1MgPT0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pETU9Sb290S2V5LCAKICAgICAgICAgICAgICAgIDAsIEtFWV9SRUFELCAmbHBlZG1vLT5oa2V5KSkKICAgICAgICAgICAgICAgIHJldCA9IFRSVUU7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIHN6Z3VpZFs2NF07CiAgICAgICAgICAgIFdDSEFSIHN6S2V5W01BWF9QQVRIXTsKCiAgICAgICAgICAgIHdzcHJpbnRmVyhzektleSwgc3pDYXQzRm10LCBzekRNT1Jvb3RLZXksIHN6RE1PQ2F0ZWdvcmllcywgCiAgICAgICAgICAgICAgICBHVUlEVG9TdHJpbmcoc3pndWlkLCBndWlkQ2F0ZWdvcnkpKTsKICAgICAgICAgICAgaWYgKEVSUk9SX1NVQ0NFU1MgPT0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pLZXksIAogICAgICAgICAgICAgICAgMCwgS0VZX1JFQUQsICZscGVkbW8tPmhrZXkpKQogICAgICAgICAgICAgICAgcmV0ID0gVFJVRTsKICAgICAgICB9CgpsZXJyOgogICAgICAgIGlmKCFyZXQpCiAgICAgICAgewogICAgICAgICAgICBJRW51bURNT19EZXN0cnVjdG9yKChJRW51bURNTyopbHBlZG1vKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLGxwZWRtbyk7CiAgICAgICAgICAgIGxwZWRtbyA9IE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIFRSQUNFKCJyZXR1cm5pbmcgJXBcbiIsIGxwZWRtbyk7CgogICAgcmV0dXJuIChJRW51bURNTyopbHBlZG1vOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mbkFkZFJlZgogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJRW51bURNT19mbkFkZFJlZihJRW51bURNTyAqIGlmYWNlKQp7CiAgICBJRW51bURNT0ltcGwgKlRoaXMgPSAoSUVudW1ETU9JbXBsICopaWZhY2U7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIEVudW1ETU9fUXVlcnlJbnRlcmZhY2UKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRW51bURNT19mblF1ZXJ5SW50ZXJmYWNlKAogICAgSUVudW1ETU8qIGlmYWNlLAogICAgUkVGSUlEIHJpaWQsCiAgICBMUFZPSUQgKnBwdk9iaikKewogICAgSUVudW1ETU9JbXBsICpUaGlzID0gKElFbnVtRE1PSW1wbCAqKWlmYWNlOwoKICAgICpwcHZPYmogPSBOVUxMOwoKICAgIGlmKElzRXF1YWxJSUQocmlpZCwgJklJRF9JVW5rbm93bikpCiAgICAgICAgKnBwdk9iaiA9IFRoaXM7CiAgICBlbHNlIGlmKElzRXF1YWxJSUQocmlpZCwgJklJRF9JRW51bURNTykpCiAgICAgICAgKnBwdk9iaiA9IChJRW51bURNTyopVGhpczsKCiAgICBpZigqcHB2T2JqKQogICAgewogICAgICAgIElFbnVtRE1PX2ZuQWRkUmVmKChJRW51bURNTyopKnBwdk9iaik7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CgogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElFbnVtRE1PX2ZuUmVsZWFzZQogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJRW51bURNT19mblJlbGVhc2UoSUVudW1ETU8gKiBpZmFjZSkKewogICAgSUVudW1ETU9JbXBsICpUaGlzID0gKElFbnVtRE1PSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmQ291bnQgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBpZiAoIXJlZkNvdW50KQogICAgewogICAgICAgIElFbnVtRE1PX0Rlc3RydWN0b3IoKElFbnVtRE1PKilUaGlzKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CiAgICB9CiAgICByZXR1cm4gcmVmQ291bnQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElFbnVtRE1PX2ZuTmV4dAogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFbnVtRE1PX2ZuTmV4dCgKICAgIElFbnVtRE1PICogaWZhY2UsIAogICAgRFdPUkQgY0l0ZW1zVG9GZXRjaCwKICAgIENMU0lEICogcENMU0lELAogICAgV0NIQVIgKiogTmFtZXMsCiAgICBEV09SRCAqIHBjSXRlbXNGZXRjaGVkKQp7CiAgICBGSUxFVElNRSBmdDsKICAgIEhLRVkgaGtleTsKICAgIFdDSEFSIHN6TmV4dEtleVtNQVhfUEFUSF07CiAgICBXQ0hBUiBzekd1aWRLZXlbNjRdOwogICAgV0NIQVIgc3pLZXlbTUFYX1BBVEhdOwogICAgV0NIQVIgc3pWYWx1ZVtNQVhfUEFUSF07CiAgICBEV09SRCBsZW47CiAgICBVSU5UIGNvdW50ID0gMDsKICAgIEhSRVNVTFQgaHJlcyA9IFNfT0s7CgogICAgSUVudW1ETU9JbXBsICpUaGlzID0gKElFbnVtRE1PSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCItLT4gKCVwKSAlZCAlcCAlcCAlcFxuIiwgaWZhY2UsIGNJdGVtc1RvRmV0Y2gsIHBDTFNJRCwgTmFtZXMsIHBjSXRlbXNGZXRjaGVkKTsKCiAgICBpZiAoIXBDTFNJRCB8fCAhTmFtZXMgfHwgIXBjSXRlbXNGZXRjaGVkKQogICAgICAgIHJldHVybiBFX1BPSU5URVI7CgogICAgd2hpbGUgKGNvdW50IDwgY0l0ZW1zVG9GZXRjaCkKICAgIHsKICAgICAgICBUaGlzLT5pbmRleCsrOwoKICAgICAgICBsZW4gPSBNQVhfUEFUSDsKICAgICAgICBocmVzID0gUmVnRW51bUtleUV4VyhUaGlzLT5oa2V5LCBUaGlzLT5pbmRleCwgc3pOZXh0S2V5LCAmbGVuLCBOVUxMLCBOVUxMLCBOVUxMLCAmZnQpOwogICAgICAgIGlmIChocmVzICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBUUkFDRSgiZm91bmQgJXNcbiIsIGRlYnVnc3RyX3coc3pOZXh0S2V5KSk7CgogICAgICAgIGlmICghKFRoaXMtPmR3RmxhZ3MgJiBETU9fRU5VTUZfSU5DTFVERV9LRVlFRCkpCiAgICAgICAgewogICAgICAgICAgICB3c3ByaW50Zlcoc3pLZXksIHN6Q2F0M0ZtdCwgc3pETU9Sb290S2V5LCBzek5leHRLZXksIHN6RE1PS2V5ZWQpOwogICAgICAgICAgICBocmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pLZXksIDAsIEtFWV9SRUFELCAmaGtleSk7CiAgICAgICAgICAgIGlmIChFUlJPUl9TVUNDRVNTID09IGhyZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICAgICAgLyogU2tpcCBLZXllZCBlbnRyaWVzICovCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgd3NwcmludGZXKHN6S2V5LCBzekNhdDJGbXQsIHN6RE1PUm9vdEtleSwgc3pOZXh0S2V5KTsKICAgICAgICBocmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pLZXksIDAsIEtFWV9SRUFELCAmaGtleSk7CgogICAgICAgIGlmIChUaGlzLT5wSW5UeXBlcykKICAgICAgICB7CiAgICAgICAgICAgIFVJTlQgaSwgajsKICAgICAgICAgICAgRFdPUkQgY0luVHlwZXM7CiAgICAgICAgICAgIERNT19QQVJUSUFMX01FRElBVFlQRSogcEluVHlwZXM7CgogICAgICAgICAgICBocmVzID0gcmVhZF90eXBlcyhoa2V5LCBzekRNT0lucHV0VHlwZSwgJmNJblR5cGVzLAogICAgICAgICAgICAgICAgICAgIHNpemVvZihzelZhbHVlKS9zaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKSwKICAgICAgICAgICAgICAgICAgICAoRE1PX1BBUlRJQUxfTUVESUFUWVBFKilzelZhbHVlKTsKCiAgICAgICAgICAgIGlmIChFUlJPUl9TVUNDRVNTICE9IGhyZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KGhrZXkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCgkgICAgcEluVHlwZXMgPSAoRE1PX1BBUlRJQUxfTUVESUFUWVBFKikgc3pWYWx1ZTsKCiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5jSW5UeXBlczsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgY0luVHlwZXM7IGorKykgCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKElzTWVkaWFUeXBlRXF1YWwoJnBJblR5cGVzW2pdLCAmVGhpcy0+cEluVHlwZXNbaV0pKQoJCSAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CgoJCWlmIChqID49IGNJblR5cGVzKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaSA8IFRoaXMtPmNJblR5cGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoVGhpcy0+cE91dFR5cGVzKQogICAgICAgIHsKICAgICAgICAgICAgVUlOVCBpLCBqOwogICAgICAgICAgICBEV09SRCBjT3V0VHlwZXM7CiAgICAgICAgICAgIERNT19QQVJUSUFMX01FRElBVFlQRSogcE91dFR5cGVzOwoKICAgICAgICAgICAgaHJlcyA9IHJlYWRfdHlwZXMoaGtleSwgc3pETU9PdXRwdXRUeXBlLCAmY091dFR5cGVzLAogICAgICAgICAgICAgICAgICAgIHNpemVvZihzelZhbHVlKS9zaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKSwKICAgICAgICAgICAgICAgICAgICAoRE1PX1BBUlRJQUxfTUVESUFUWVBFKilzelZhbHVlKTsKCgkgICAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gaHJlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKCSAgICBwT3V0VHlwZXMgPSAoRE1PX1BBUlRJQUxfTUVESUFUWVBFKikgc3pWYWx1ZTsKCiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5jT3V0VHlwZXM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGNPdXRUeXBlczsgaisrKSAKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoSXNNZWRpYVR5cGVFcXVhbCgmcE91dFR5cGVzW2pdLCAmVGhpcy0+cE91dFR5cGVzW2ldKSkKCQkgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQoKCQlpZiAoaiA+PSBjT3V0VHlwZXMpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpIDwgVGhpcy0+Y091dFR5cGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKCS8qIE1lZGlhIG9iamVjdCB3YXNuJ3QgZmlsdGVyZWQgc28gYWRkIGl0IHRvIHJldHVybiBsaXN0ICovCiAgICAgICAgTmFtZXNbY291bnRdID0gTlVMTDsKCWxlbiA9IE1BWF9QQVRIICogc2l6ZW9mKFdDSEFSKTsKICAgICAgICBocmVzID0gUmVnUXVlcnlWYWx1ZUV4Vyhoa2V5LCBOVUxMLCBOVUxMLCBOVUxMLCAoTFBCWVRFKSBzelZhbHVlLCAmbGVuKTsgCiAgICAgICAgaWYgKEVSUk9SX1NVQ0NFU1MgPT0gaHJlcykKCXsKICAgICAgICAgICAgTmFtZXNbY291bnRdID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlblcoc3pWYWx1ZSkgKyAxKTsKCSAgICBpZiAoTmFtZXNbY291bnRdKQogICAgICAgICAgICAgICAgc3RyY21wVyhOYW1lc1tjb3VudF0sIHN6VmFsdWUpOwoJfQogICAgICAgIHdzcHJpbnRmVyhzekd1aWRLZXksc3pUb0d1aWRGbXQsc3pOZXh0S2V5KTsKICAgICAgICBDTFNJREZyb21TdHJpbmcoc3pHdWlkS2V5LCAmcENMU0lEW2NvdW50XSk7CgogICAgICAgIFRSQUNFKCJmb3VuZCBtYXRjaCAlcyAlc1xuIiwgZGVidWdzdHJfdyhzelZhbHVlKSwgZGVidWdzdHJfdyhzek5leHRLZXkpKTsKICAgICAgICBSZWdDbG9zZUtleShoa2V5KTsKCWNvdW50Kys7CiAgICB9CgogICAgKnBjSXRlbXNGZXRjaGVkID0gY291bnQ7CiAgICBpZiAoKnBjSXRlbXNGZXRjaGVkIDwgY0l0ZW1zVG9GZXRjaCkKICAgICAgICBocmVzID0gU19GQUxTRTsKCiAgICBUUkFDRSgiPC0tICVpIGZvdW5kXG4iLGNvdW50KTsKICAgIHJldHVybiBocmVzOwp9CiAKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUVudW1ETU9fZm5Ta2lwCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVudW1ETU9fZm5Ta2lwKElFbnVtRE1PICogaWZhY2UsIERXT1JEIGNJdGVtc1RvU2tpcCkKewogICAgSUVudW1ETU9JbXBsICpUaGlzID0gKElFbnVtRE1PSW1wbCAqKWlmYWNlOwoKICAgIFRoaXMtPmluZGV4ICs9IGNJdGVtc1RvU2tpcDsKCiAgICByZXR1cm4gU19PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUVudW1ETU9fZm5SZXNldAogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElFbnVtRE1PX2ZuUmVzZXQoSUVudW1ETU8gKiBpZmFjZSkKewogICAgSUVudW1ETU9JbXBsICpUaGlzID0gKElFbnVtRE1PSW1wbCAqKWlmYWNlOwoKICAgIFRoaXMtPmluZGV4ID0gLTE7CgogICAgcmV0dXJuIFNfT0s7Cn0KIAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRW51bURNT19mbkNsb25lCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUVudW1ETU9fZm5DbG9uZShJRW51bURNTyAqIGlmYWNlLCBJRW51bURNTyAqKnBwRW51bSkKewogICAgSUVudW1ETU9JbXBsICpUaGlzID0gKElFbnVtRE1PSW1wbCAqKWlmYWNlOwoKICAgIEZJWE1FKCIoJXApLT4oKSB0byAoJXApLT4oKSBFX05PVElNUExcbiIsIFRoaXMsIHBwRW51bSk7CgogIHJldHVybiBFX05PVElNUEw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERNT0VudW0gKE1TRE1PLkApCiAqCiAqIEVudW1lcmF0ZSBEaXJlY3RYIE1lZGlhIE9iamVjdHMgaW4gdGhlIHJlZ2lzdHJ5LgogKi8KSFJFU1VMVCBXSU5BUEkgRE1PRW51bSgKICAgIFJFRkdVSUQgZ3VpZENhdGVnb3J5LAogICAgRFdPUkQgZHdGbGFncywKICAgIERXT1JEIGNJblR5cGVzLAogICAgY29uc3QgRE1PX1BBUlRJQUxfTUVESUFUWVBFICpwSW5UeXBlcywKICAgIERXT1JEIGNPdXRUeXBlcywKICAgIGNvbnN0IERNT19QQVJUSUFMX01FRElBVFlQRSAqcE91dFR5cGVzLAogICAgSUVudW1ETU8gKipwcEVudW0pCnsKICAgIEhSRVNVTFQgaHJlcyA9IEVfRkFJTDsKCiAgICBUUkFDRSgiZ3VpZENhdGVnb3J5PSVwIGR3RmxhZ3M9MHglMDh4IGNJblR5cGVzPSVkIGNPdXRUeXBlcz0lZFxuIiwKICAgICAgICBndWlkQ2F0ZWdvcnksIGR3RmxhZ3MsIGNJblR5cGVzLCBjT3V0VHlwZXMpOwoKICAgICpwcEVudW0gPSBJRW51bURNT19Db25zdHJ1Y3RvcihndWlkQ2F0ZWdvcnksIGR3RmxhZ3MsIGNJblR5cGVzLAogICAgICAgIHBJblR5cGVzLCBjT3V0VHlwZXMsIHBPdXRUeXBlcyk7CiAgICBpZiAoKnBwRW51bSkKICAgICAgICBocmVzID0gU19PSzsKCiAgICByZXR1cm4gaHJlczsKfQoKCnN0YXRpYyBjb25zdCBJRW51bURNT1Z0YmwgZWRtb3Z0ID0KewoJSUVudW1ETU9fZm5RdWVyeUludGVyZmFjZSwKCUlFbnVtRE1PX2ZuQWRkUmVmLAoJSUVudW1ETU9fZm5SZWxlYXNlLAoJSUVudW1ETU9fZm5OZXh0LAoJSUVudW1ETU9fZm5Ta2lwLAoJSUVudW1ETU9fZm5SZXNldCwKCUlFbnVtRE1PX2ZuQ2xvbmUsCn07CgoKSFJFU1VMVCByZWFkX3R5cGVzKEhLRVkgcm9vdCwgTFBDV1NUUiBrZXksIFVMT05HICpzdXBwbGllZCwgVUxPTkcgcmVxdWVzdGVkLCBETU9fUEFSVElBTF9NRURJQVRZUEUqIHR5cGVzICkKewogICAgSFJFU1VMVCByZXQgPSBTX09LOwogICAgaWYgKE1TRE1PX01BSk9SX1ZFUlNJT04gPiA1KQogICAgewogICAgICAgIERXT1JEIGxlbjsKICAgICAgICBsZW4gPSByZXF1ZXN0ZWQgKiBzaXplb2YoRE1PX1BBUlRJQUxfTUVESUFUWVBFKTsKICAgICAgICByZXQgPSBSZWdRdWVyeVZhbHVlRXhXKHJvb3QsIGtleSwgTlVMTCwgTlVMTCwgKExQQllURSkgdHlwZXMsICZsZW4pOwogICAgICAgICpzdXBwbGllZCA9IGxlbiAvIHNpemVvZihETU9fUEFSVElBTF9NRURJQVRZUEUpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIEhLRVkgaGtleTsKICAgICAgICBXQ0hBUiBzekd1aWRLZXlbNjRdOwoKICAgICAgICAqc3VwcGxpZWQgPSAwOwogICAgICAgIGlmIChFUlJPUl9TVUNDRVNTID09IFJlZ09wZW5LZXlFeFcocm9vdCwga2V5LCAwLCBLRVlfUkVBRCwgJmhrZXkpKQogICAgICAgIHsKICAgICAgICAgIGludCBpbmRleCA9IDA7CiAgICAgICAgICBXQ0hBUiBzek5leHRLZXlbTUFYX1BBVEhdOwogICAgICAgICAgRFdPUkQgbGVuOwogICAgICAgICAgTE9ORyByYyA9IEVSUk9SX1NVQ0NFU1M7CgogICAgICAgICAgd2hpbGUgKHJjID09IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgICB7CiAgICAgICAgICAgIGxlbiA9IE1BWF9QQVRIICogc2l6ZW9mKFdDSEFSKTsKICAgICAgICAgICAgcmMgPSBSZWdFbnVtS2V5RXhXKGhrZXksIGluZGV4LCBzek5leHRLZXksICZsZW4sIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgICAgICBpZiAocmMgPT0gRVJST1JfU1VDQ0VTUykKICAgICAgICAgICAgewogICAgICAgICAgICAgIEhLRVkgc3ViazsKICAgICAgICAgICAgICBpbnQgc3ViX2luZGV4ID0gMDsKICAgICAgICAgICAgICBMT05HIHJjcyA9IEVSUk9SX1NVQ0NFU1M7CiAgICAgICAgICAgICAgV0NIQVIgc3pTdWJLZXlbTUFYX1BBVEhdOwoKICAgICAgICAgICAgICBSZWdPcGVuS2V5RXhXKGhrZXksIHN6TmV4dEtleSwgMCwgS0VZX1JFQUQsICZzdWJrKTsKICAgICAgICAgICAgICB3aGlsZSAocmNzID09IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbGVuID0gTUFYX1BBVEggKiBzaXplb2YoV0NIQVIpOwogICAgICAgICAgICAgICAgcmNzID0gUmVnRW51bUtleUV4VyhzdWJrLCBzdWJfaW5kZXgsIHN6U3ViS2V5LCAmbGVuLCBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgICAgIGlmIChyY3MgPT0gRVJST1JfU1VDQ0VTUykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgaWYgKCpzdXBwbGllZCA+PSByZXF1ZXN0ZWQpCiAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBCYWlsaW5nICovCiAgICAgICAgICAgICAgICAgICAgcmV0ID0gU19GQUxTRTsKICAgICAgICAgICAgICAgICAgICByYyA9IEVSUk9SX01PUkVfREFUQTsKICAgICAgICAgICAgICAgICAgICByY3MgPSBFUlJPUl9NT1JFX0RBVEE7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgIHdzcHJpbnRmVyhzekd1aWRLZXksc3pUb0d1aWRGbXQsc3pOZXh0S2V5KTsKICAgICAgICAgICAgICAgICAgQ0xTSURGcm9tU3RyaW5nKHN6R3VpZEtleSwgJnR5cGVzWypzdXBwbGllZF0udHlwZSk7CiAgICAgICAgICAgICAgICAgIHdzcHJpbnRmVyhzekd1aWRLZXksc3pUb0d1aWRGbXQsc3pTdWJLZXkpOwogICAgICAgICAgICAgICAgICBDTFNJREZyb21TdHJpbmcoc3pHdWlkS2V5LCAmdHlwZXNbKnN1cHBsaWVkXS5zdWJ0eXBlKTsKICAgICAgICAgICAgICAgICAgVFJBQ0UoIkFkZGluZyB0eXBlICVzIHN1YnR5cGUgJXMgYXQgaW5kZXggJWlcbiIsCiAgICAgICAgICAgICAgICAgICAgZGVidWdzdHJfZ3VpZCgmdHlwZXNbKnN1cHBsaWVkXS50eXBlKSwKICAgICAgICAgICAgICAgICAgICBkZWJ1Z3N0cl9ndWlkKCZ0eXBlc1sqc3VwcGxpZWRdLnN1YnR5cGUpLAogICAgICAgICAgICAgICAgICAgICpzdXBwbGllZCk7CiAgICAgICAgICAgICAgICAgICgqc3VwcGxpZWQpKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdWJfaW5kZXgrKzsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaW5kZXgrKzsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBETU9HZXRUeXBlcyAoTVNETU8uQCkKICovCkhSRVNVTFQgV0lOQVBJIERNT0dldFR5cGVzKFJFRkNMU0lEIGNsc2lkRE1PLAogICAgICAgICAgICAgICBVTE9ORyB1bElucHV0VHlwZXNSZXF1ZXN0ZWQsCiAgICAgICAgICAgICAgIFVMT05HKiBwdWxJbnB1dFR5cGVzU3VwcGxpZWQsCiAgICAgICAgICAgICAgIERNT19QQVJUSUFMX01FRElBVFlQRSogcElucHV0VHlwZXMsCiAgICAgICAgICAgICAgIFVMT05HIHVsT3V0cHV0VHlwZXNSZXF1ZXN0ZWQsCiAgICAgICAgICAgICAgIFVMT05HKiBwdWxPdXRwdXRUeXBlc1N1cHBsaWVkLAogICAgICAgICAgICAgICBETU9fUEFSVElBTF9NRURJQVRZUEUqIHBPdXRwdXRUeXBlcykKewogIEhLRVkgcm9vdCxoa2V5OwogIEhSRVNVTFQgcmV0ID0gU19PSzsKICBXQ0hBUiBzemd1aWRbNjRdOwoKICBUUkFDRSAoIiglcywldSwlcCwlcCwldSwlcCwlcCksc3R1YiFcbiIsIGRlYnVnc3RyX2d1aWQoY2xzaWRETU8pLAogICAgICAgIHVsSW5wdXRUeXBlc1JlcXVlc3RlZCwgcHVsSW5wdXRUeXBlc1N1cHBsaWVkLCBwSW5wdXRUeXBlcywKICAgICAgICB1bE91dHB1dFR5cGVzUmVxdWVzdGVkLCBwdWxPdXRwdXRUeXBlc1N1cHBsaWVkLCBwT3V0cHV0VHlwZXMpOwoKICBpZiAoRVJST1JfU1VDQ0VTUyAhPSBSZWdPcGVuS2V5RXhXKEhLRVlfQ0xBU1NFU19ST09ULCBzekRNT1Jvb3RLZXksIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfUkVBRCwgJnJvb3QpKQogICAgcmV0dXJuIEVfRkFJTDsKCiAgaWYgKEVSUk9SX1NVQ0NFU1MgIT0gUmVnT3BlbktleUV4Vyhyb290LEdVSURUb1N0cmluZyhzemd1aWQsY2xzaWRETU8pICwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9SRUFELCAmaGtleSkpCiAgewogICAgUmVnQ2xvc2VLZXkocm9vdCk7CiAgICByZXR1cm4gRV9GQUlMOwogIH0KCiAgaWYgKHVsSW5wdXRUeXBlc1JlcXVlc3RlZCA+IDApCiAgewogICAgcmV0ID0gcmVhZF90eXBlcyhoa2V5LCBzekRNT0lucHV0VHlwZSwgcHVsSW5wdXRUeXBlc1N1cHBsaWVkLCB1bElucHV0VHlwZXNSZXF1ZXN0ZWQsIHBJbnB1dFR5cGVzICk7CiAgfQogIGVsc2UKICAgICpwdWxJbnB1dFR5cGVzU3VwcGxpZWQgPSAwOwoKICBpZiAodWxPdXRwdXRUeXBlc1JlcXVlc3RlZCA+IDApCiAgewogICAgSFJFU1VMVCByZXQyOwogICAgcmV0MiA9IHJlYWRfdHlwZXMoaGtleSwgc3pETU9PdXRwdXRUeXBlLCBwdWxPdXRwdXRUeXBlc1N1cHBsaWVkLCB1bE91dHB1dFR5cGVzUmVxdWVzdGVkLCBwT3V0cHV0VHlwZXMgKTsKCiAgICBpZiAocmV0ID09IFNfT0spCiAgICAgICAgcmV0ID0gcmV0MjsKICB9CiAgZWxzZQogICAgKnB1bE91dHB1dFR5cGVzU3VwcGxpZWQgPSAwOwoKICByZXR1cm4gcmV0Owp9Cg==