{"action":"created","comment":{"url":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls/comments/34332378","id":34332378,"diff_hunk":"@@ -157,19 +159,33 @@ def get_cert_file(self, achall):\n         return os.path.join(\n             self.configurator.config.work_dir, achall.nonce_domain + \".crt\")\n \n+    def get_key_path(self, achall):\n+        \"\"\"Get standardized path to challenge key.\"\"\"\n+        return os.path.join(\n+            self.configurator.config.work_dir, achall.nonce_domain + '.pem')\n+\n     def _setup_challenge_cert(self, achall, s=None):\n         # pylint: disable=invalid-name\n         \"\"\"Generate and write out challenge certificate.\"\"\"\n-        cert_path = self.get_cert_file(achall)\n+        cert_path = self.get_cert_path(achall)\n         # Register the path before you write out the file\n         self.configurator.reverter.register_file_creation(True, cert_path)\n \n         cert_pem, response = achall.gen_cert_and_response(s)\n \n         # Write out challenge cert\n-        with open(cert_path, \"w\") as cert_chall_fd:\n+        with open(cert_path, \"wb\") as cert_chall_fd:\n             cert_chall_fd.write(cert_pem)\n \n+        key_path = self.get_key_path(achall)\n+        key_pem = achall.key.key.private_bytes(\n+            encoding=serialization.Encoding.PEM,\n+            format=serialization.PrivateFormat.TraditionalOpenSSL,\n+            encryption_algorithm=serialization.NoEncryption())\n+        with le_util.safe_open(key_path, 'wb', chmod=0o400) as key_file:\n+            key_file.write(key_pem)\n+        self.configurator.reverter.register_file_creation(True, key_path)","path":"letsencrypt/plugins/common.py","position":55,"original_position":55,"commit_id":"1d35946b4e3c7c165bde39010e88bebb46871ddc","original_commit_id":"30a02d448792758281451e029d3b9046449515fa","user":{"login":"jdkasten","id":1581662,"avatar_url":"https://avatars.githubusercontent.com/u/1581662?v=3","gravatar_id":"","url":"https://api.github.com/users/jdkasten","html_url":"https://github.com/jdkasten","followers_url":"https://api.github.com/users/jdkasten/followers","following_url":"https://api.github.com/users/jdkasten/following{/other_user}","gists_url":"https://api.github.com/users/jdkasten/gists{/gist_id}","starred_url":"https://api.github.com/users/jdkasten/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jdkasten/subscriptions","organizations_url":"https://api.github.com/users/jdkasten/orgs","repos_url":"https://api.github.com/users/jdkasten/repos","events_url":"https://api.github.com/users/jdkasten/events{/privacy}","received_events_url":"https://api.github.com/users/jdkasten/received_events","type":"User","site_admin":false},"body":"In case of a crash... it doesn't hurt if the reference has been created in the reverter... but it does hurt if the file was created and there is no reference to clean it up.","created_at":"2015-07-10T07:18:28Z","updated_at":"2015-07-10T07:18:28Z","html_url":"https://github.com/letsencrypt/letsencrypt/pull/593#discussion_r34332378","pull_request_url":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls/593","_links":{"self":{"href":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls/comments/34332378"},"html":{"href":"https://github.com/letsencrypt/letsencrypt/pull/593#discussion_r34332378"},"pull_request":{"href":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls/593"}}},"pull_request":{"url":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls/593","id":39574047,"html_url":"https://github.com/letsencrypt/letsencrypt/pull/593","diff_url":"https://github.com/letsencrypt/letsencrypt/pull/593.diff","patch_url":"https://github.com/letsencrypt/letsencrypt/pull/593.patch","issue_url":"https://api.github.com/repos/letsencrypt/letsencrypt/issues/593","number":593,"state":"open","locked":false,"title":"Rewrite accounts and registration","user":{"login":"kuba","id":106176,"avatar_url":"https://avatars.githubusercontent.com/u/106176?v=3","gravatar_id":"","url":"https://api.github.com/users/kuba","html_url":"https://github.com/kuba","followers_url":"https://api.github.com/users/kuba/followers","following_url":"https://api.github.com/users/kuba/following{/other_user}","gists_url":"https://api.github.com/users/kuba/gists{/gist_id}","starred_url":"https://api.github.com/users/kuba/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kuba/subscriptions","organizations_url":"https://api.github.com/users/kuba/orgs","repos_url":"https://api.github.com/users/kuba/repos","events_url":"https://api.github.com/users/kuba/events{/privacy}","received_events_url":"https://api.github.com/users/kuba/received_events","type":"User","site_admin":false},"body":"Save accounts to:\r\n\r\n    /etc/letsencrypt/accounts/www.letsencrypt-dmeo.org/acme/new-reg/ \\\r\n    my.local.hostname@2015-07-04T14:04:10Z/ \\\r\n    {regr.json,meta.json,private_key.json}\r\n\r\nAccount now represents a combination of private key, Registration Resource and client account metadata. `Account.id` based on the account metadata (creation host and datetime). UI interface (`cli._determine_account`) based on the `id`, and not on email as previously.\r\n\r\nAdd `AccountStorage` interface and `AccountFileStorage`, `AccountMemoryStorage` implementations (latter, in-memory, useful for testing).\r\n\r\nCreate Account only after Registration Resource is received (`register()` returns `Account`).\r\n\r\nAllow `client.Client(..., acme=acme, ...)`: API client might reuse `acme.client.Client` as returned by `register()`.\r\n\r\nMove `report_new_account` to `letsencrypt.account`, `client.Client.register` into `client.register`.\r\n\r\nUse `Registration.from_data` acme API.\r\n\r\n`achallenges.AChallenge.key` is now the `acme.jose.JWK`, not `le_util.Key`. Plugins have to export PEM/DER as necessary (c.f. `letsencrypt.plugins.common.Dvsni.get_key_path`)\r\n\r\nAdd `--agree-tos`, save `--agree-eula` to `args.eula`. Prompt for EULA as soon as client is launched, add prompt for TOS.\r\n\r\nRemove unnecessary `letsencrypt.network`. Remove, now irrelevant, `IConfig.account_keys_dir`.\r\n\r\nBased on the draft from https://github.com/letsencrypt/letsencrypt/pull/362#issuecomment-97946817.\r\n\r\nAlso, expose `le_util.safe_open`.\r\n\r\nSorry about the size, @jdkasten!","created_at":"2015-07-09T11:43:08Z","updated_at":"2015-07-10T07:18:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"098cc3bd5b7c496f6e9900fa36a0639fdadf2a10","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls/593/commits","review_comments_url":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls/593/comments","review_comment_url":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls/comments{/number}","comments_url":"https://api.github.com/repos/letsencrypt/letsencrypt/issues/593/comments","statuses_url":"https://api.github.com/repos/letsencrypt/letsencrypt/statuses/1d35946b4e3c7c165bde39010e88bebb46871ddc","head":{"label":"kuba:account-resource-json","ref":"account-resource-json","sha":"1d35946b4e3c7c165bde39010e88bebb46871ddc","user":{"login":"kuba","id":106176,"avatar_url":"https://avatars.githubusercontent.com/u/106176?v=3","gravatar_id":"","url":"https://api.github.com/users/kuba","html_url":"https://github.com/kuba","followers_url":"https://api.github.com/users/kuba/followers","following_url":"https://api.github.com/users/kuba/following{/other_user}","gists_url":"https://api.github.com/users/kuba/gists{/gist_id}","starred_url":"https://api.github.com/users/kuba/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kuba/subscriptions","organizations_url":"https://api.github.com/users/kuba/orgs","repos_url":"https://api.github.com/users/kuba/repos","events_url":"https://api.github.com/users/kuba/events{/privacy}","received_events_url":"https://api.github.com/users/kuba/received_events","type":"User","site_admin":false},"repo":{"id":26831060,"name":"letsencrypt","full_name":"kuba/letsencrypt","owner":{"login":"kuba","id":106176,"avatar_url":"https://avatars.githubusercontent.com/u/106176?v=3","gravatar_id":"","url":"https://api.github.com/users/kuba","html_url":"https://github.com/kuba","followers_url":"https://api.github.com/users/kuba/followers","following_url":"https://api.github.com/users/kuba/following{/other_user}","gists_url":"https://api.github.com/users/kuba/gists{/gist_id}","starred_url":"https://api.github.com/users/kuba/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kuba/subscriptions","organizations_url":"https://api.github.com/users/kuba/orgs","repos_url":"https://api.github.com/users/kuba/repos","events_url":"https://api.github.com/users/kuba/events{/privacy}","received_events_url":"https://api.github.com/users/kuba/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/kuba/letsencrypt","description":"Let's Encrypt client","fork":true,"url":"https://api.github.com/repos/kuba/letsencrypt","forks_url":"https://api.github.com/repos/kuba/letsencrypt/forks","keys_url":"https://api.github.com/repos/kuba/letsencrypt/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kuba/letsencrypt/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kuba/letsencrypt/teams","hooks_url":"https://api.github.com/repos/kuba/letsencrypt/hooks","issue_events_url":"https://api.github.com/repos/kuba/letsencrypt/issues/events{/number}","events_url":"https://api.github.com/repos/kuba/letsencrypt/events","assignees_url":"https://api.github.com/repos/kuba/letsencrypt/assignees{/user}","branches_url":"https://api.github.com/repos/kuba/letsencrypt/branches{/branch}","tags_url":"https://api.github.com/repos/kuba/letsencrypt/tags","blobs_url":"https://api.github.com/repos/kuba/letsencrypt/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kuba/letsencrypt/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kuba/letsencrypt/git/refs{/sha}","trees_url":"https://api.github.com/repos/kuba/letsencrypt/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kuba/letsencrypt/statuses/{sha}","languages_url":"https://api.github.com/repos/kuba/letsencrypt/languages","stargazers_url":"https://api.github.com/repos/kuba/letsencrypt/stargazers","contributors_url":"https://api.github.com/repos/kuba/letsencrypt/contributors","subscribers_url":"https://api.github.com/repos/kuba/letsencrypt/subscribers","subscription_url":"https://api.github.com/repos/kuba/letsencrypt/subscription","commits_url":"https://api.github.com/repos/kuba/letsencrypt/commits{/sha}","git_commits_url":"https://api.github.com/repos/kuba/letsencrypt/git/commits{/sha}","comments_url":"https://api.github.com/repos/kuba/letsencrypt/comments{/number}","issue_comment_url":"https://api.github.com/repos/kuba/letsencrypt/issues/comments{/number}","contents_url":"https://api.github.com/repos/kuba/letsencrypt/contents/{+path}","compare_url":"https://api.github.com/repos/kuba/letsencrypt/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kuba/letsencrypt/merges","archive_url":"https://api.github.com/repos/kuba/letsencrypt/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kuba/letsencrypt/downloads","issues_url":"https://api.github.com/repos/kuba/letsencrypt/issues{/number}","pulls_url":"https://api.github.com/repos/kuba/letsencrypt/pulls{/number}","milestones_url":"https://api.github.com/repos/kuba/letsencrypt/milestones{/number}","notifications_url":"https://api.github.com/repos/kuba/letsencrypt/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kuba/letsencrypt/labels{/name}","releases_url":"https://api.github.com/repos/kuba/letsencrypt/releases{/id}","created_at":"2014-11-18T21:34:04Z","updated_at":"2015-06-25T08:21:53Z","pushed_at":"2015-07-10T06:53:55Z","git_url":"git://github.com/kuba/letsencrypt.git","ssh_url":"git@github.com:kuba/letsencrypt.git","clone_url":"https://github.com/kuba/letsencrypt.git","svn_url":"https://github.com/kuba/letsencrypt","homepage":"","size":5707,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"letsencrypt:master","ref":"master","sha":"d850be2d73ca75d0c5f94737ac7acff595644183","user":{"login":"letsencrypt","id":9289019,"avatar_url":"https://avatars.githubusercontent.com/u/9289019?v=3","gravatar_id":"","url":"https://api.github.com/users/letsencrypt","html_url":"https://github.com/letsencrypt","followers_url":"https://api.github.com/users/letsencrypt/followers","following_url":"https://api.github.com/users/letsencrypt/following{/other_user}","gists_url":"https://api.github.com/users/letsencrypt/gists{/gist_id}","starred_url":"https://api.github.com/users/letsencrypt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/letsencrypt/subscriptions","organizations_url":"https://api.github.com/users/letsencrypt/orgs","repos_url":"https://api.github.com/users/letsencrypt/repos","events_url":"https://api.github.com/users/letsencrypt/events{/privacy}","received_events_url":"https://api.github.com/users/letsencrypt/received_events","type":"Organization","site_admin":false},"repo":{"id":26516210,"name":"letsencrypt","full_name":"letsencrypt/letsencrypt","owner":{"login":"letsencrypt","id":9289019,"avatar_url":"https://avatars.githubusercontent.com/u/9289019?v=3","gravatar_id":"","url":"https://api.github.com/users/letsencrypt","html_url":"https://github.com/letsencrypt","followers_url":"https://api.github.com/users/letsencrypt/followers","following_url":"https://api.github.com/users/letsencrypt/following{/other_user}","gists_url":"https://api.github.com/users/letsencrypt/gists{/gist_id}","starred_url":"https://api.github.com/users/letsencrypt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/letsencrypt/subscriptions","organizations_url":"https://api.github.com/users/letsencrypt/orgs","repos_url":"https://api.github.com/users/letsencrypt/repos","events_url":"https://api.github.com/users/letsencrypt/events{/privacy}","received_events_url":"https://api.github.com/users/letsencrypt/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/letsencrypt/letsencrypt","description":"An ACME client that can update Apache/Nginx configurations","fork":false,"url":"https://api.github.com/repos/letsencrypt/letsencrypt","forks_url":"https://api.github.com/repos/letsencrypt/letsencrypt/forks","keys_url":"https://api.github.com/repos/letsencrypt/letsencrypt/keys{/key_id}","collaborators_url":"https://api.github.com/repos/letsencrypt/letsencrypt/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/letsencrypt/letsencrypt/teams","hooks_url":"https://api.github.com/repos/letsencrypt/letsencrypt/hooks","issue_events_url":"https://api.github.com/repos/letsencrypt/letsencrypt/issues/events{/number}","events_url":"https://api.github.com/repos/letsencrypt/letsencrypt/events","assignees_url":"https://api.github.com/repos/letsencrypt/letsencrypt/assignees{/user}","branches_url":"https://api.github.com/repos/letsencrypt/letsencrypt/branches{/branch}","tags_url":"https://api.github.com/repos/letsencrypt/letsencrypt/tags","blobs_url":"https://api.github.com/repos/letsencrypt/letsencrypt/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/letsencrypt/letsencrypt/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/letsencrypt/letsencrypt/git/refs{/sha}","trees_url":"https://api.github.com/repos/letsencrypt/letsencrypt/git/trees{/sha}","statuses_url":"https://api.github.com/repos/letsencrypt/letsencrypt/statuses/{sha}","languages_url":"https://api.github.com/repos/letsencrypt/letsencrypt/languages","stargazers_url":"https://api.github.com/repos/letsencrypt/letsencrypt/stargazers","contributors_url":"https://api.github.com/repos/letsencrypt/letsencrypt/contributors","subscribers_url":"https://api.github.com/repos/letsencrypt/letsencrypt/subscribers","subscription_url":"https://api.github.com/repos/letsencrypt/letsencrypt/subscription","commits_url":"https://api.github.com/repos/letsencrypt/letsencrypt/commits{/sha}","git_commits_url":"https://api.github.com/repos/letsencrypt/letsencrypt/git/commits{/sha}","comments_url":"https://api.github.com/repos/letsencrypt/letsencrypt/comments{/number}","issue_comment_url":"https://api.github.com/repos/letsencrypt/letsencrypt/issues/comments{/number}","contents_url":"https://api.github.com/repos/letsencrypt/letsencrypt/contents/{+path}","compare_url":"https://api.github.com/repos/letsencrypt/letsencrypt/compare/{base}...{head}","merges_url":"https://api.github.com/repos/letsencrypt/letsencrypt/merges","archive_url":"https://api.github.com/repos/letsencrypt/letsencrypt/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/letsencrypt/letsencrypt/downloads","issues_url":"https://api.github.com/repos/letsencrypt/letsencrypt/issues{/number}","pulls_url":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls{/number}","milestones_url":"https://api.github.com/repos/letsencrypt/letsencrypt/milestones{/number}","notifications_url":"https://api.github.com/repos/letsencrypt/letsencrypt/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/letsencrypt/letsencrypt/labels{/name}","releases_url":"https://api.github.com/repos/letsencrypt/letsencrypt/releases{/id}","created_at":"2014-11-12T02:52:20Z","updated_at":"2015-07-10T07:13:15Z","pushed_at":"2015-07-10T06:53:55Z","git_url":"git://github.com/letsencrypt/letsencrypt.git","ssh_url":"git@github.com:letsencrypt/letsencrypt.git","clone_url":"https://github.com/letsencrypt/letsencrypt.git","svn_url":"https://github.com/letsencrypt/letsencrypt","homepage":"","size":8131,"stargazers_count":2615,"watchers_count":2615,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":194,"mirror_url":null,"open_issues_count":112,"forks":194,"open_issues":112,"watchers":2615,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls/593"},"html":{"href":"https://github.com/letsencrypt/letsencrypt/pull/593"},"issue":{"href":"https://api.github.com/repos/letsencrypt/letsencrypt/issues/593"},"comments":{"href":"https://api.github.com/repos/letsencrypt/letsencrypt/issues/593/comments"},"review_comments":{"href":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls/593/comments"},"review_comment":{"href":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/letsencrypt/letsencrypt/pulls/593/commits"},"statuses":{"href":"https://api.github.com/repos/letsencrypt/letsencrypt/statuses/1d35946b4e3c7c165bde39010e88bebb46871ddc"}}}}