PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFsLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw0L2xvb3NlLmR0ZCI+CjxodG1sPjxoZWFkPjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PUlTTy04ODU5LTEiPjx0aXRsZT5DLqBDb2RlIGZvciBBZGQgS2V5d29yZCBFeGFtcGxlPC90aXRsZT48bWV0YSBuYW1lPSJnZW5lcmF0b3IiIGNvbnRlbnQ9IkRvY0Jvb2sgWFNMIFN0eWxlc2hlZXRzIFYxLjYwLjEiPjxsaW5rIHJlbD0iaG9tZSIgaHJlZj0iaW5kZXguaHRtbCIgdGl0bGU9IkxpYnhtbCBUdXRvcmlhbCI+PGxpbmsgcmVsPSJ1cCIgaHJlZj0iaW5kZXguaHRtbCIgdGl0bGU9IkxpYnhtbCBUdXRvcmlhbCI+PGxpbmsgcmVsPSJwcmV2aW91cyIgaHJlZj0iYXBiLmh0bWwiIHRpdGxlPSJCLqBDb2RlIGZvciBLZXl3b3JkIEV4YW1wbGUiPjxsaW5rIHJlbD0ibmV4dCIgaHJlZj0iYXBkLmh0bWwiIHRpdGxlPSJELqBDb2RlIGZvciBBZGQgQXR0cmlidXRlIEV4YW1wbGUiPjwvaGVhZD48Ym9keSBiZ2NvbG9yPSJ3aGl0ZSIgdGV4dD0iYmxhY2siIGxpbms9IiMwMDAwRkYiIHZsaW5rPSIjODQwMDg0IiBhbGluaz0iIzAwMDBGRiI+PGRpdiBjbGFzcz0ibmF2aGVhZGVyIj48dGFibGUgd2lkdGg9IjEwMCUiIHN1bW1hcnk9Ik5hdmlnYXRpb24gaGVhZGVyIj48dHI+PHRoIGNvbHNwYW49IjMiIGFsaWduPSJjZW50ZXIiPkMuoENvZGUgZm9yIEFkZCBLZXl3b3JkIEV4YW1wbGU8L3RoPjwvdHI+PHRyPjx0ZCB3aWR0aD0iMjAlIiBhbGlnbj0ibGVmdCI+PGEgYWNjZXNza2V5PSJwIiBocmVmPSJhcGIuaHRtbCI+UHJldjwvYT6gPC90ZD48dGggd2lkdGg9IjYwJSIgYWxpZ249ImNlbnRlciI+oDwvdGg+PHRkIHdpZHRoPSIyMCUiIGFsaWduPSJyaWdodCI+oDxhIGFjY2Vzc2tleT0ibiIgaHJlZj0iYXBkLmh0bWwiPk5leHQ8L2E+PC90ZD48L3RyPjwvdGFibGU+PGhyPjwvZGl2PjxkaXYgY2xhc3M9ImFwcGVuZGl4IiBsYW5nPSJlbiI+PGRpdiBjbGFzcz0idGl0bGVwYWdlIj48ZGl2PjxkaXY+PGgyIGNsYXNzPSJ0aXRsZSI+PGEgbmFtZT0iYWRka2V5d29yZGFwcGVuZGl4Ij48L2E+Qy6gQ29kZSBmb3IgQWRkIEtleXdvcmQgRXhhbXBsZTwvaDI+PC9kaXY+PC9kaXY+PGRpdj48L2Rpdj48L2Rpdj48cD4KICAgICAgPC9wPjxwcmUgY2xhc3M9InByb2dyYW1saXN0aW5nIj4KI2luY2x1ZGUgJmx0O3N0ZGlvLmgmZ3Q7CiNpbmNsdWRlICZsdDtzdHJpbmcuaCZndDsKI2luY2x1ZGUgJmx0O3N0ZGxpYi5oJmd0OwojaW5jbHVkZSAmbHQ7bGlieG1sL3htbG1lbW9yeS5oJmd0OwojaW5jbHVkZSAmbHQ7bGlieG1sL3BhcnNlci5oJmd0OwoKdm9pZApwYXJzZVN0b3J5ICh4bWxEb2NQdHIgZG9jLCB4bWxOb2RlUHRyIGN1ciwgY2hhciAqa2V5d29yZCkgewoKCXhtbE5ld1RleHRDaGlsZCAoY3VyLCBOVUxMLCAmcXVvdDtrZXl3b3JkJnF1b3Q7LCBrZXl3b3JkKTsKICAgIHJldHVybjsKfQoKeG1sRG9jUHRyCnBhcnNlRG9jKGNoYXIgKmRvY25hbWUsIGNoYXIgKmtleXdvcmQpIHsKCgl4bWxEb2NQdHIgZG9jOwoJeG1sTm9kZVB0ciBjdXI7CgoJZG9jID0geG1sUGFyc2VGaWxlKGRvY25hbWUpOwoJCglpZiAoZG9jID09IE5VTEwgKSB7CgkJZnByaW50ZihzdGRlcnIsJnF1b3Q7RG9jdW1lbnQgbm90IHBhcnNlZCBzdWNjZXNzZnVsbHkuIFxuJnF1b3Q7KTsKCQlyZXR1cm4gKE5VTEwpOwoJfQoJCgljdXIgPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwoJCglpZiAoY3VyID09IE5VTEwpIHsKCQlmcHJpbnRmKHN0ZGVyciwmcXVvdDtlbXB0eSBkb2N1bWVudFxuJnF1b3Q7KTsKCQl4bWxGcmVlRG9jKGRvYyk7CgkJcmV0dXJuIChOVUxMKTsKCX0KCQoJaWYgKHhtbFN0cmNtcChjdXItJmd0O25hbWUsIChjb25zdCB4bWxDaGFyICopICZxdW90O3N0b3J5JnF1b3Q7KSkgewoJCWZwcmludGYoc3RkZXJyLCZxdW90O2RvY3VtZW50IG9mIHRoZSB3cm9uZyB0eXBlLCByb290IG5vZGUgIT0gc3RvcnkmcXVvdDspOwoJCXhtbEZyZWVEb2MoZG9jKTsKCQlyZXR1cm4gKE5VTEwpOwoJfQoJCgljdXIgPSBjdXItJmd0O3htbENoaWxkcmVuTm9kZTsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJCWlmICgoIXhtbFN0cmNtcChjdXItJmd0O25hbWUsIChjb25zdCB4bWxDaGFyICopJnF1b3Q7c3RvcnlpbmZvJnF1b3Q7KSkpewoJCQlwYXJzZVN0b3J5IChkb2MsIGN1ciwga2V5d29yZCk7CgkJfQoJCSAKCWN1ciA9IGN1ci0mZ3Q7bmV4dDsKCX0KCXJldHVybihkb2MpOwp9CgppbnQKbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpIHsKCgljaGFyICpkb2NuYW1lOwoJY2hhciAqa2V5d29yZDsKCXhtbERvY1B0ciBkb2M7CgoJaWYgKGFyZ2MgJmx0Oz0gMikgewoJCXByaW50ZigmcXVvdDtVc2FnZTogJXMgZG9jbmFtZSwga2V5d29yZFxuJnF1b3Q7LCBhcmd2WzBdKTsKCQlyZXR1cm4oMCk7Cgl9CgoJZG9jbmFtZSA9IGFyZ3ZbMV07CglrZXl3b3JkID0gYXJndlsyXTsKCWRvYyA9IHBhcnNlRG9jIChkb2NuYW1lLCBrZXl3b3JkKTsKCWlmIChkb2MgIT0gTlVMTCkgewoJCXhtbFNhdmVGb3JtYXRGaWxlIChkb2NuYW1lLCBkb2MsIDApOwoJCXhtbEZyZWVEb2MoZG9jKTsKCX0KCQoJcmV0dXJuICgxKTsKfQoKPC9wcmU+PHA+CiAgICA8L3A+PC9kaXY+PGRpdiBjbGFzcz0ibmF2Zm9vdGVyIj48aHI+PHRhYmxlIHdpZHRoPSIxMDAlIiBzdW1tYXJ5PSJOYXZpZ2F0aW9uIGZvb3RlciI+PHRyPjx0ZCB3aWR0aD0iNDAlIiBhbGlnbj0ibGVmdCI+PGEgYWNjZXNza2V5PSJwIiBocmVmPSJhcGIuaHRtbCI+UHJldjwvYT6gPC90ZD48dGQgd2lkdGg9IjIwJSIgYWxpZ249ImNlbnRlciI+PGEgYWNjZXNza2V5PSJ1IiBocmVmPSJpbmRleC5odG1sIj5VcDwvYT48L3RkPjx0ZCB3aWR0aD0iNDAlIiBhbGlnbj0icmlnaHQiPqA8YSBhY2Nlc3NrZXk9Im4iIGhyZWY9ImFwZC5odG1sIj5OZXh0PC9hPjwvdGQ+PC90cj48dHI+PHRkIHdpZHRoPSI0MCUiIGFsaWduPSJsZWZ0IiB2YWxpZ249InRvcCI+Qi6gQ29kZSBmb3IgS2V5d29yZCBFeGFtcGxloDwvdGQ+PHRkIHdpZHRoPSIyMCUiIGFsaWduPSJjZW50ZXIiPjxhIGFjY2Vzc2tleT0iaCIgaHJlZj0iaW5kZXguaHRtbCI+SG9tZTwvYT48L3RkPjx0ZCB3aWR0aD0iNDAlIiBhbGlnbj0icmlnaHQiIHZhbGlnbj0idG9wIj6gRC6gQ29kZSBmb3IgQWRkIEF0dHJpYnV0ZSBFeGFtcGxlPC90ZD48L3RyPjwvdGFibGU+PC9kaXY+PC9ib2R5PjwvaHRtbD4K