IyAtKi0gY29kaW5nOiBsYXRpbi0xIC0qLQojCiMgQ29weXJpZ2h0IChDKSBNYXJ0aW4gU2r2Z3JlbiBhbmQgQUIgU3RyYWt0IDIwMDEsIEFsbCByaWdodHMgcmVzZXJ2ZWQKIyBDb3B5cmlnaHQgKEMpIEplYW4tUGF1bCBDYWxkZXJvbmUgMjAwOCwgQWxsIHJpZ2h0cyByZXNlcnZlZAoKIiIiCkNlcnRpZmljYXRlIGdlbmVyYXRpb24gbW9kdWxlLgoiIiIKCmZyb20gT3BlblNTTCBpbXBvcnQgY3J5cHRvCgpUWVBFX1JTQSA9IGNyeXB0by5UWVBFX1JTQQpUWVBFX0RTQSA9IGNyeXB0by5UWVBFX0RTQQoKZGVmIGNyZWF0ZUtleVBhaXIodHlwZSwgYml0cyk6CiAgICAiIiIKICAgIENyZWF0ZSBhIHB1YmxpYy9wcml2YXRlIGtleSBwYWlyLgoKICAgIEFyZ3VtZW50czogdHlwZSAtIEtleSB0eXBlLCBtdXN0IGJlIG9uZSBvZiBUWVBFX1JTQSBhbmQgVFlQRV9EU0EKICAgICAgICAgICAgICAgYml0cyAtIE51bWJlciBvZiBiaXRzIHRvIHVzZSBpbiB0aGUga2V5CiAgICBSZXR1cm5zOiAgIFRoZSBwdWJsaWMvcHJpdmF0ZSBrZXkgcGFpciBpbiBhIFBLZXkgb2JqZWN0CiAgICAiIiIKICAgIHBrZXkgPSBjcnlwdG8uUEtleSgpCiAgICBwa2V5LmdlbmVyYXRlX2tleSh0eXBlLCBiaXRzKQogICAgcmV0dXJuIHBrZXkKCmRlZiBjcmVhdGVDZXJ0UmVxdWVzdChwa2V5LCBkaWdlc3Q9Im1kNSIsICoqbmFtZSk6CiAgICAiIiIKICAgIENyZWF0ZSBhIGNlcnRpZmljYXRlIHJlcXVlc3QuCgogICAgQXJndW1lbnRzOiBwa2V5ICAgLSBUaGUga2V5IHRvIGFzc29jaWF0ZSB3aXRoIHRoZSByZXF1ZXN0CiAgICAgICAgICAgICAgIGRpZ2VzdCAtIERpZ2VzdGlvbiBtZXRob2QgdG8gdXNlIGZvciBzaWduaW5nLCBkZWZhdWx0IGlzIG1kNQogICAgICAgICAgICAgICAqKm5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgc3ViamVjdCBvZiB0aGUgcmVxdWVzdCwgcG9zc2libGUKICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzIGFyZToKICAgICAgICAgICAgICAgICAgICAgICAgICBDICAgICAtIENvdW50cnkgbmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgIFNUICAgIC0gU3RhdGUgb3IgcHJvdmluY2UgbmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgIEwgICAgIC0gTG9jYWxpdHkgbmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgIE8gICAgIC0gT3JnYW5pemF0aW9uIG5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgICBPVSAgICAtIE9yZ2FuaXphdGlvbmFsIHVuaXQgbmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgIENOICAgIC0gQ29tbW9uIG5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgICBlbWFpbEFkZHJlc3MgLSBFLW1haWwgYWRkcmVzcwogICAgUmV0dXJuczogICBUaGUgY2VydGlmaWNhdGUgcmVxdWVzdCBpbiBhbiBYNTA5UmVxIG9iamVjdAogICAgIiIiCiAgICByZXEgPSBjcnlwdG8uWDUwOVJlcSgpCiAgICBzdWJqID0gcmVxLmdldF9zdWJqZWN0KCkKCiAgICBmb3IgKGtleSx2YWx1ZSkgaW4gbmFtZS5pdGVtcygpOgogICAgICAgIHNldGF0dHIoc3Viaiwga2V5LCB2YWx1ZSkKCiAgICByZXEuc2V0X3B1YmtleShwa2V5KQogICAgcmVxLnNpZ24ocGtleSwgZGlnZXN0KQogICAgcmV0dXJuIHJlcQoKZGVmIGNyZWF0ZUNlcnRpZmljYXRlKHJlcSwgKGlzc3VlckNlcnQsIGlzc3VlcktleSksIHNlcmlhbCwgKG5vdEJlZm9yZSwgbm90QWZ0ZXIpLCBkaWdlc3Q9Im1kNSIpOgogICAgIiIiCiAgICBHZW5lcmF0ZSBhIGNlcnRpZmljYXRlIGdpdmVuIGEgY2VydGlmaWNhdGUgcmVxdWVzdC4KCiAgICBBcmd1bWVudHM6IHJlcSAgICAgICAgLSBDZXJ0aWZpY2F0ZSByZXFldXN0IHRvIHVzZQogICAgICAgICAgICAgICBpc3N1ZXJDZXJ0IC0gVGhlIGNlcnRpZmljYXRlIG9mIHRoZSBpc3N1ZXIKICAgICAgICAgICAgICAgaXNzdWVyS2V5ICAtIFRoZSBwcml2YXRlIGtleSBvZiB0aGUgaXNzdWVyCiAgICAgICAgICAgICAgIHNlcmlhbCAgICAgLSBTZXJpYWwgbnVtYmVyIGZvciB0aGUgY2VydGlmaWNhdGUKICAgICAgICAgICAgICAgbm90QmVmb3JlICAtIFRpbWVzdGFtcCAocmVsYXRpdmUgdG8gbm93KSB3aGVuIHRoZSBjZXJ0aWZpY2F0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRzIGJlaW5nIHZhbGlkCiAgICAgICAgICAgICAgIG5vdEFmdGVyICAgLSBUaW1lc3RhbXAgKHJlbGF0aXZlIHRvIG5vdykgd2hlbiB0aGUgY2VydGlmaWNhdGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3BzIGJlaW5nIHZhbGlkCiAgICAgICAgICAgICAgIGRpZ2VzdCAgICAgLSBEaWdlc3QgbWV0aG9kIHRvIHVzZSBmb3Igc2lnbmluZywgZGVmYXVsdCBpcyBtZDUKICAgIFJldHVybnM6ICAgVGhlIHNpZ25lZCBjZXJ0aWZpY2F0ZSBpbiBhbiBYNTA5IG9iamVjdAogICAgIiIiCiAgICBjZXJ0ID0gY3J5cHRvLlg1MDkoKQogICAgY2VydC5zZXRfc2VyaWFsX251bWJlcihzZXJpYWwpCiAgICBjZXJ0LmdtdGltZV9hZGpfbm90QmVmb3JlKG5vdEJlZm9yZSkKICAgIGNlcnQuZ210aW1lX2Fkal9ub3RBZnRlcihub3RBZnRlcikKICAgIGNlcnQuc2V0X2lzc3Vlcihpc3N1ZXJDZXJ0LmdldF9zdWJqZWN0KCkpCiAgICBjZXJ0LnNldF9zdWJqZWN0KHJlcS5nZXRfc3ViamVjdCgpKQogICAgY2VydC5zZXRfcHVia2V5KHJlcS5nZXRfcHVia2V5KCkpCiAgICBjZXJ0LnNpZ24oaXNzdWVyS2V5LCBkaWdlc3QpCiAgICByZXR1cm4gY2VydAoK