LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIENvcHlyaWdodCAyMDA2IFR1bmdzdGVuIEdyYXBoaWNzLCBJbmMuLCBCaXNtYXJjaywgTkQuIFVTQS4KICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEKICogY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZQogKiAiU29mdHdhcmUiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nCiAqIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwKICogZGlzdHJpYnV0ZSwgc3ViIGxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0bwogKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8KICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSAoaW5jbHVkaW5nIHRoZQogKiBuZXh0IHBhcmFncmFwaCkgc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucwogKiBvZiB0aGUgU29mdHdhcmUuCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwKICogVEhFIENPUFlSSUdIVCBIT0xERVJTLCBBVVRIT1JTIEFORC9PUiBJVFMgU1VQUExJRVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLAogKiBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IKICogT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRQogKiBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgogKgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qCiAqIFNpbXBsZSBvcGVuIGhhc2ggdGFiIGltcGxlbWVudGF0aW9uLgogKgogKiBBdXRob3JzOgogKiBUaG9tYXMgSGVsbHN0cvZtIDx0aG9tYXMtYXQtdHVuZ3N0ZW5ncmFwaGljcy1kb3QtY29tPgogKi8KCiNpbmNsdWRlICJkcm1QLmgiCiNpbmNsdWRlICJkcm1faGFzaHRhYi5oIgojaW5jbHVkZSA8bGludXgvaGFzaC5oPgoKaW50IGRybV9odF9jcmVhdGUoZHJtX29wZW5faGFzaF90ICpodCwgdW5zaWduZWQgaW50IG9yZGVyKQp7Cgl1bnNpZ25lZCBpbnQgaTsKCglodC0+c2l6ZSA9IDEgPDwgb3JkZXI7CglodC0+b3JkZXIgPSBvcmRlcjsKCWh0LT5maWxsID0gMDsKCWh0LT50YWJsZSA9IHZtYWxsb2MoaHQtPnNpemUqc2l6ZW9mKCpodC0+dGFibGUpKTsKCWlmICghaHQtPnRhYmxlKSB7CgkJRFJNX0VSUk9SKCJPdXQgb2YgbWVtb3J5IGZvciBoYXNoIHRhYmxlXG4iKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCWZvciAoaT0wOyBpPCBodC0+c2l6ZTsgKytpKSB7CgkJSU5JVF9ITElTVF9IRUFEKCZodC0+dGFibGVbaV0pOwoJfQoJcmV0dXJuIDA7Cn0KCnZvaWQgZHJtX2h0X3ZlcmJvc2VfbGlzdChkcm1fb3Blbl9oYXNoX3QgKmh0LCB1bnNpZ25lZCBsb25nIGtleSkKewoJZHJtX2hhc2hfaXRlbV90ICplbnRyeTsKCXN0cnVjdCBobGlzdF9oZWFkICpoX2xpc3Q7CglzdHJ1Y3QgaGxpc3Rfbm9kZSAqbGlzdDsKCXVuc2lnbmVkIGludCBoYXNoZWRfa2V5OwoJaW50IGNvdW50ID0gMDsKCgloYXNoZWRfa2V5ID0gaGFzaF9sb25nKGtleSwgaHQtPm9yZGVyKTsKCURSTV9ERUJVRygiS2V5IGlzIDB4JTA4bHgsIEhhc2hlZCBrZXkgaXMgMHglMDh4XG4iLCBrZXksIGhhc2hlZF9rZXkpOwoJaF9saXN0ID0gJmh0LT50YWJsZVtoYXNoZWRfa2V5XTsKCWhsaXN0X2Zvcl9lYWNoKGxpc3QsIGhfbGlzdCkgewoJCWVudHJ5ID0gaGxpc3RfZW50cnkobGlzdCwgZHJtX2hhc2hfaXRlbV90LCBoZWFkKTsKCQlEUk1fREVCVUcoImNvdW50ICVkLCBrZXk6IDB4JTA4bHhcbiIsIGNvdW50KyssIGVudHJ5LT5rZXkpOwoJfQp9CgpzdGF0aWMgc3RydWN0IGhsaXN0X25vZGUgKmRybV9odF9maW5kX2tleShkcm1fb3Blbl9oYXNoX3QgKmh0LCAKCQkJCQkgIHVuc2lnbmVkIGxvbmcga2V5KQp7Cglkcm1faGFzaF9pdGVtX3QgKmVudHJ5OwoJc3RydWN0IGhsaXN0X2hlYWQgKmhfbGlzdDsKCXN0cnVjdCBobGlzdF9ub2RlICpsaXN0OwoJdW5zaWduZWQgaW50IGhhc2hlZF9rZXk7CgoJaGFzaGVkX2tleSA9IGhhc2hfbG9uZyhrZXksIGh0LT5vcmRlcik7CgloX2xpc3QgPSAmaHQtPnRhYmxlW2hhc2hlZF9rZXldOwoJaGxpc3RfZm9yX2VhY2gobGlzdCwgaF9saXN0KSB7CgkJZW50cnkgPSBobGlzdF9lbnRyeShsaXN0LCBkcm1faGFzaF9pdGVtX3QsIGhlYWQpOwoJCWlmIChlbnRyeS0+a2V5ID09IGtleSkKCQkJcmV0dXJuIGxpc3Q7CgkJaWYgKGVudHJ5LT5rZXkgPiBrZXkpCgkJCWJyZWFrOwoJfQoJcmV0dXJuIE5VTEw7Cn0KCgppbnQgZHJtX2h0X2luc2VydF9pdGVtKGRybV9vcGVuX2hhc2hfdCAqaHQsIGRybV9oYXNoX2l0ZW1fdCAqaXRlbSkKewoJZHJtX2hhc2hfaXRlbV90ICplbnRyeTsKCXN0cnVjdCBobGlzdF9oZWFkICpoX2xpc3Q7CglzdHJ1Y3QgaGxpc3Rfbm9kZSAqbGlzdCwgKnBhcmVudDsKCXVuc2lnbmVkIGludCBoYXNoZWRfa2V5OwoJdW5zaWduZWQgbG9uZyBrZXkgPSBpdGVtLT5rZXk7CgoJaGFzaGVkX2tleSA9IGhhc2hfbG9uZyhrZXksIGh0LT5vcmRlcik7CgloX2xpc3QgPSAmaHQtPnRhYmxlW2hhc2hlZF9rZXldOwoJcGFyZW50ID0gTlVMTDsKCWhsaXN0X2Zvcl9lYWNoKGxpc3QsIGhfbGlzdCkgewoJCWVudHJ5ID0gaGxpc3RfZW50cnkobGlzdCwgZHJtX2hhc2hfaXRlbV90LCBoZWFkKTsKCQlpZiAoZW50cnktPmtleSA9PSBrZXkpCgkJCXJldHVybiAtRUlOVkFMOwoJCWlmIChlbnRyeS0+a2V5ID4ga2V5KQoJCQlicmVhazsKCQlwYXJlbnQgPSBsaXN0OwoJfQoJaWYgKHBhcmVudCkgewoJCWhsaXN0X2FkZF9hZnRlcihwYXJlbnQsICZpdGVtLT5oZWFkKTsKCX0gZWxzZSB7CgkJaGxpc3RfYWRkX2hlYWQoJml0ZW0tPmhlYWQsIGhfbGlzdCk7Cgl9CglyZXR1cm4gMDsKfQoKLyoKICogSnVzdCBpbnNlcnQgYW4gaXRlbSBhbmQgcmV0dXJuIGFueSAiYml0cyIgYml0IGtleSB0aGF0IGhhc24ndCBiZWVuIAogKiB1c2VkIGJlZm9yZS4KICovCmludCBkcm1faHRfanVzdF9pbnNlcnRfcGxlYXNlKGRybV9vcGVuX2hhc2hfdCAqaHQsIGRybV9oYXNoX2l0ZW1fdCAqaXRlbSwKCQkJICAgICAgdW5zaWduZWQgbG9uZyBzZWVkLCBpbnQgYml0cywgaW50IHNoaWZ0LAoJCQkgICAgICB1bnNpZ25lZCBsb25nIGFkZCkKewoJaW50IHJldDsKCXVuc2lnbmVkIGxvbmcgbWFzayA9ICgxIDw8IGJpdHMpIC0gMTsKCXVuc2lnbmVkIGxvbmcgZmlyc3QsIHVuc2hpZnRlZF9rZXk7CgoJdW5zaGlmdGVkX2tleSA9IGhhc2hfbG9uZyhzZWVkLCBiaXRzKTsKCWZpcnN0ID0gdW5zaGlmdGVkX2tleTsKCWRvIHsKCQlpdGVtLT5rZXkgPSAodW5zaGlmdGVkX2tleSA8PCBzaGlmdCkgKyBhZGQ7CgkJcmV0ID0gZHJtX2h0X2luc2VydF9pdGVtKGh0LCBpdGVtKTsKCQlpZiAocmV0KQoJCQl1bnNoaWZ0ZWRfa2V5ID0gKHVuc2hpZnRlZF9rZXkgKyAxKSAmIG1hc2s7Cgl9IHdoaWxlKHJldCAmJiAodW5zaGlmdGVkX2tleSAhPSBmaXJzdCkpOwoKCWlmIChyZXQpIHsKCQlEUk1fRVJST1IoIkF2YWlsYWJsZSBrZXkgYml0IHNwYWNlIGV4aGF1c3RlZFxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CglyZXR1cm4gMDsKfQoKaW50IGRybV9odF9maW5kX2l0ZW0oZHJtX29wZW5faGFzaF90ICpodCwgdW5zaWduZWQgbG9uZyBrZXksCgkJICAgICBkcm1faGFzaF9pdGVtX3QgKippdGVtKQp7CglzdHJ1Y3QgaGxpc3Rfbm9kZSAqbGlzdDsKCglsaXN0ID0gZHJtX2h0X2ZpbmRfa2V5KGh0LCBrZXkpOwoJaWYgKCFsaXN0KQoJCXJldHVybiAtRUlOVkFMOwoKCSppdGVtID0gaGxpc3RfZW50cnkobGlzdCwgZHJtX2hhc2hfaXRlbV90LCBoZWFkKTsKCXJldHVybiAwOwp9CgppbnQgZHJtX2h0X3JlbW92ZV9rZXkoZHJtX29wZW5faGFzaF90ICpodCwgdW5zaWduZWQgbG9uZyBrZXkpCnsKCXN0cnVjdCBobGlzdF9ub2RlICpsaXN0OwoKCWxpc3QgPSBkcm1faHRfZmluZF9rZXkoaHQsIGtleSk7CglpZiAobGlzdCkgewoJCWhsaXN0X2RlbF9pbml0KGxpc3QpOwoJCWh0LT5maWxsLS07CgkJcmV0dXJuIDA7Cgl9CglyZXR1cm4gLUVJTlZBTDsKfQoKaW50IGRybV9odF9yZW1vdmVfaXRlbShkcm1fb3Blbl9oYXNoX3QgKmh0LCBkcm1faGFzaF9pdGVtX3QgKml0ZW0pCnsKCWhsaXN0X2RlbF9pbml0KCZpdGVtLT5oZWFkKTsKCWh0LT5maWxsLS07CglyZXR1cm4gMDsKfQoKdm9pZCBkcm1faHRfcmVtb3ZlKGRybV9vcGVuX2hhc2hfdCAqaHQpCnsKCWlmIChodC0+dGFibGUpIHsKCQl2ZnJlZShodC0+dGFibGUpOwoJCWh0LT50YWJsZSA9IE5VTEw7Cgl9Cn0KCg==