{"action":"created","comment":{"url":"https://api.github.com/repos/jenkinsci/jenkins/pulls/comments/29112893","id":29112893,"diff_hunk":"@@ -0,0 +1,88 @@\n+package jenkins.security;\n+\n+import org.apache.commons.codec.binary.Base64;\n+\n+import java.io.IOException;\n+import java.security.GeneralSecurityException;\n+import java.security.KeyFactory;\n+import java.security.KeyPair;\n+import java.security.KeyPairGenerator;\n+import java.security.PrivateKey;\n+import java.security.SecureRandom;\n+import java.security.interfaces.RSAPrivateCrtKey;\n+import java.security.interfaces.RSAPrivateKey;\n+import java.security.interfaces.RSAPublicKey;\n+import java.security.spec.PKCS8EncodedKeySpec;\n+import java.security.spec.RSAPublicKeySpec;\n+\n+/**\n+ * RSA public/private key pair as {@link ConfidentialKey}.\n+ *\n+ * <p>\n+ * As per the design principle of {@link ConfidentialKey}, not exposing {@link PrivateKey} directly.\n+ * Define subtypes for different use cases.\n+ *\n+ * @author Kohsuke Kawaguchi\n+ */\n+public abstract class RSAConfidentialKey extends ConfidentialKey {\n+    private volatile RSAPrivateKey priv;\n+    private volatile RSAPublicKey pub;\n+    public RSAConfidentialKey(String id) {\n+        super(id);\n+    }\n+\n+    public RSAConfidentialKey(Class owner, String shortName) {\n+        this(owner.getName() + '.' + shortName);\n+    }\n+\n+    private RSAPrivateKey getKey() {","path":"core/src/main/java/jenkins/security/RSAConfidentialKey.java","position":38,"original_position":38,"commit_id":"0d41a2c3eb9274c1452b0644cc6cf96789fae031","original_commit_id":"43a2f43a9f4b85aa17c80a3d9a0d51be3150452e","user":{"login":"stephenc","id":209336,"avatar_url":"https://avatars.githubusercontent.com/u/209336?v=3","gravatar_id":"","url":"https://api.github.com/users/stephenc","html_url":"https://github.com/stephenc","followers_url":"https://api.github.com/users/stephenc/followers","following_url":"https://api.github.com/users/stephenc/following{/other_user}","gists_url":"https://api.github.com/users/stephenc/gists{/gist_id}","starred_url":"https://api.github.com/users/stephenc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephenc/subscriptions","organizations_url":"https://api.github.com/users/stephenc/orgs","repos_url":"https://api.github.com/users/stephenc/repos","events_url":"https://api.github.com/users/stephenc/events{/privacy}","received_events_url":"https://api.github.com/users/stephenc/received_events","type":"User","site_admin":false},"body":"@kohsuke can I ask you to recall exactly what code pattern of yours offends me most?\r\n\r\nSo let me see, you use a volatile to avoid locking on read, which incurs a memory barrier, and then use a synchronised to guard the write (which costs the same memory barrier except now you have additional memory barriers on each access of the volatile field)\r\n\r\nUnless you can prove the need for this (incorrect in my view) complexity, please just use a lock to guard read and write.\r\n\r\n(I have yet to review the actual code, but you called out my number 1 alarm bell of threading issues in Jenkins, and I am not yet - from my phone - seeing any comment where you claim the need to use this pattern)\r\n\r\nActually scratch that. I've looked at the code. Please use a lock as the volatile incurs the same memory barrier cost for all reads as a simple lock and incurs far more memory barriers for a write and this is a relatively simple class. Use an internal lock if you want to avoid using the objects intrinsic lock (which is normally a good idea, don't want others enticing deadlocks by accidentally locking on the intrinsic lock)","created_at":"2015-04-26T19:26:17Z","updated_at":"2015-04-26T19:26:17Z","html_url":"https://github.com/jenkinsci/jenkins/pull/1671#discussion_r29112893","pull_request_url":"https://api.github.com/repos/jenkinsci/jenkins/pulls/1671","_links":{"self":{"href":"https://api.github.com/repos/jenkinsci/jenkins/pulls/comments/29112893"},"html":{"href":"https://github.com/jenkinsci/jenkins/pull/1671#discussion_r29112893"},"pull_request":{"href":"https://api.github.com/repos/jenkinsci/jenkins/pulls/1671"}}},"pull_request":{"url":"https://api.github.com/repos/jenkinsci/jenkins/pulls/1671","id":34082024,"html_url":"https://github.com/jenkinsci/jenkins/pull/1671","diff_url":"https://github.com/jenkinsci/jenkins/pull/1671.diff","patch_url":"https://github.com/jenkinsci/jenkins/pull/1671.patch","issue_url":"https://api.github.com/repos/jenkinsci/jenkins/issues/1671","number":1671,"state":"open","locked":false,"title":"Define additional ConfidentialStore around RSA key pair","user":{"login":"kohsuke","id":50003,"avatar_url":"https://avatars.githubusercontent.com/u/50003?v=3","gravatar_id":"","url":"https://api.github.com/users/kohsuke","html_url":"https://github.com/kohsuke","followers_url":"https://api.github.com/users/kohsuke/followers","following_url":"https://api.github.com/users/kohsuke/following{/other_user}","gists_url":"https://api.github.com/users/kohsuke/gists{/gist_id}","starred_url":"https://api.github.com/users/kohsuke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kohsuke/subscriptions","organizations_url":"https://api.github.com/users/kohsuke/orgs","repos_url":"https://api.github.com/users/kohsuke/repos","events_url":"https://api.github.com/users/kohsuke/events{/privacy}","received_events_url":"https://api.github.com/users/kohsuke/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-04-24T20:11:58Z","updated_at":"2015-04-26T19:26:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":"86be5188701a06cdbdfaff803b960f5d7bf62de9","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/jenkinsci/jenkins/pulls/1671/commits","review_comments_url":"https://api.github.com/repos/jenkinsci/jenkins/pulls/1671/comments","review_comment_url":"https://api.github.com/repos/jenkinsci/jenkins/pulls/comments{/number}","comments_url":"https://api.github.com/repos/jenkinsci/jenkins/issues/1671/comments","statuses_url":"https://api.github.com/repos/jenkinsci/jenkins/statuses/0d41a2c3eb9274c1452b0644cc6cf96789fae031","head":{"label":"jenkinsci:rsa-credential-store","ref":"rsa-credential-store","sha":"0d41a2c3eb9274c1452b0644cc6cf96789fae031","user":{"login":"jenkinsci","id":107424,"avatar_url":"https://avatars.githubusercontent.com/u/107424?v=3","gravatar_id":"","url":"https://api.github.com/users/jenkinsci","html_url":"https://github.com/jenkinsci","followers_url":"https://api.github.com/users/jenkinsci/followers","following_url":"https://api.github.com/users/jenkinsci/following{/other_user}","gists_url":"https://api.github.com/users/jenkinsci/gists{/gist_id}","starred_url":"https://api.github.com/users/jenkinsci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jenkinsci/subscriptions","organizations_url":"https://api.github.com/users/jenkinsci/orgs","repos_url":"https://api.github.com/users/jenkinsci/repos","events_url":"https://api.github.com/users/jenkinsci/events{/privacy}","received_events_url":"https://api.github.com/users/jenkinsci/received_events","type":"Organization","site_admin":false},"repo":{"id":1103607,"name":"jenkins","full_name":"jenkinsci/jenkins","owner":{"login":"jenkinsci","id":107424,"avatar_url":"https://avatars.githubusercontent.com/u/107424?v=3","gravatar_id":"","url":"https://api.github.com/users/jenkinsci","html_url":"https://github.com/jenkinsci","followers_url":"https://api.github.com/users/jenkinsci/followers","following_url":"https://api.github.com/users/jenkinsci/following{/other_user}","gists_url":"https://api.github.com/users/jenkinsci/gists{/gist_id}","starred_url":"https://api.github.com/users/jenkinsci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jenkinsci/subscriptions","organizations_url":"https://api.github.com/users/jenkinsci/orgs","repos_url":"https://api.github.com/users/jenkinsci/repos","events_url":"https://api.github.com/users/jenkinsci/events{/privacy}","received_events_url":"https://api.github.com/users/jenkinsci/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/jenkinsci/jenkins","description":"Jenkins Continuous Integration Server","fork":true,"url":"https://api.github.com/repos/jenkinsci/jenkins","forks_url":"https://api.github.com/repos/jenkinsci/jenkins/forks","keys_url":"https://api.github.com/repos/jenkinsci/jenkins/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jenkinsci/jenkins/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jenkinsci/jenkins/teams","hooks_url":"https://api.github.com/repos/jenkinsci/jenkins/hooks","issue_events_url":"https://api.github.com/repos/jenkinsci/jenkins/issues/events{/number}","events_url":"https://api.github.com/repos/jenkinsci/jenkins/events","assignees_url":"https://api.github.com/repos/jenkinsci/jenkins/assignees{/user}","branches_url":"https://api.github.com/repos/jenkinsci/jenkins/branches{/branch}","tags_url":"https://api.github.com/repos/jenkinsci/jenkins/tags","blobs_url":"https://api.github.com/repos/jenkinsci/jenkins/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jenkinsci/jenkins/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jenkinsci/jenkins/git/refs{/sha}","trees_url":"https://api.github.com/repos/jenkinsci/jenkins/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jenkinsci/jenkins/statuses/{sha}","languages_url":"https://api.github.com/repos/jenkinsci/jenkins/languages","stargazers_url":"https://api.github.com/repos/jenkinsci/jenkins/stargazers","contributors_url":"https://api.github.com/repos/jenkinsci/jenkins/contributors","subscribers_url":"https://api.github.com/repos/jenkinsci/jenkins/subscribers","subscription_url":"https://api.github.com/repos/jenkinsci/jenkins/subscription","commits_url":"https://api.github.com/repos/jenkinsci/jenkins/commits{/sha}","git_commits_url":"https://api.github.com/repos/jenkinsci/jenkins/git/commits{/sha}","comments_url":"https://api.github.com/repos/jenkinsci/jenkins/comments{/number}","issue_comment_url":"https://api.github.com/repos/jenkinsci/jenkins/issues/comments{/number}","contents_url":"https://api.github.com/repos/jenkinsci/jenkins/contents/{+path}","compare_url":"https://api.github.com/repos/jenkinsci/jenkins/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jenkinsci/jenkins/merges","archive_url":"https://api.github.com/repos/jenkinsci/jenkins/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jenkinsci/jenkins/downloads","issues_url":"https://api.github.com/repos/jenkinsci/jenkins/issues{/number}","pulls_url":"https://api.github.com/repos/jenkinsci/jenkins/pulls{/number}","milestones_url":"https://api.github.com/repos/jenkinsci/jenkins/milestones{/number}","notifications_url":"https://api.github.com/repos/jenkinsci/jenkins/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jenkinsci/jenkins/labels{/name}","releases_url":"https://api.github.com/repos/jenkinsci/jenkins/releases{/id}","created_at":"2010-11-22T21:21:23Z","updated_at":"2015-04-26T19:06:35Z","pushed_at":"2015-04-26T19:21:50Z","git_url":"git://github.com/jenkinsci/jenkins.git","ssh_url":"git@github.com:jenkinsci/jenkins.git","clone_url":"https://github.com/jenkinsci/jenkins.git","svn_url":"https://github.com/jenkinsci/jenkins","homepage":"http://jenkins-ci.org/","size":420464,"stargazers_count":3987,"watchers_count":3987,"language":"Java","has_issues":false,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":1790,"mirror_url":null,"open_issues_count":113,"forks":1790,"open_issues":113,"watchers":3987,"default_branch":"master"}},"base":{"label":"jenkinsci:master","ref":"master","sha":"6a138b59b4eee42f65d620730802d3a97a0f6c4a","user":{"login":"jenkinsci","id":107424,"avatar_url":"https://avatars.githubusercontent.com/u/107424?v=3","gravatar_id":"","url":"https://api.github.com/users/jenkinsci","html_url":"https://github.com/jenkinsci","followers_url":"https://api.github.com/users/jenkinsci/followers","following_url":"https://api.github.com/users/jenkinsci/following{/other_user}","gists_url":"https://api.github.com/users/jenkinsci/gists{/gist_id}","starred_url":"https://api.github.com/users/jenkinsci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jenkinsci/subscriptions","organizations_url":"https://api.github.com/users/jenkinsci/orgs","repos_url":"https://api.github.com/users/jenkinsci/repos","events_url":"https://api.github.com/users/jenkinsci/events{/privacy}","received_events_url":"https://api.github.com/users/jenkinsci/received_events","type":"Organization","site_admin":false},"repo":{"id":1103607,"name":"jenkins","full_name":"jenkinsci/jenkins","owner":{"login":"jenkinsci","id":107424,"avatar_url":"https://avatars.githubusercontent.com/u/107424?v=3","gravatar_id":"","url":"https://api.github.com/users/jenkinsci","html_url":"https://github.com/jenkinsci","followers_url":"https://api.github.com/users/jenkinsci/followers","following_url":"https://api.github.com/users/jenkinsci/following{/other_user}","gists_url":"https://api.github.com/users/jenkinsci/gists{/gist_id}","starred_url":"https://api.github.com/users/jenkinsci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jenkinsci/subscriptions","organizations_url":"https://api.github.com/users/jenkinsci/orgs","repos_url":"https://api.github.com/users/jenkinsci/repos","events_url":"https://api.github.com/users/jenkinsci/events{/privacy}","received_events_url":"https://api.github.com/users/jenkinsci/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/jenkinsci/jenkins","description":"Jenkins Continuous Integration Server","fork":true,"url":"https://api.github.com/repos/jenkinsci/jenkins","forks_url":"https://api.github.com/repos/jenkinsci/jenkins/forks","keys_url":"https://api.github.com/repos/jenkinsci/jenkins/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jenkinsci/jenkins/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jenkinsci/jenkins/teams","hooks_url":"https://api.github.com/repos/jenkinsci/jenkins/hooks","issue_events_url":"https://api.github.com/repos/jenkinsci/jenkins/issues/events{/number}","events_url":"https://api.github.com/repos/jenkinsci/jenkins/events","assignees_url":"https://api.github.com/repos/jenkinsci/jenkins/assignees{/user}","branches_url":"https://api.github.com/repos/jenkinsci/jenkins/branches{/branch}","tags_url":"https://api.github.com/repos/jenkinsci/jenkins/tags","blobs_url":"https://api.github.com/repos/jenkinsci/jenkins/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jenkinsci/jenkins/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jenkinsci/jenkins/git/refs{/sha}","trees_url":"https://api.github.com/repos/jenkinsci/jenkins/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jenkinsci/jenkins/statuses/{sha}","languages_url":"https://api.github.com/repos/jenkinsci/jenkins/languages","stargazers_url":"https://api.github.com/repos/jenkinsci/jenkins/stargazers","contributors_url":"https://api.github.com/repos/jenkinsci/jenkins/contributors","subscribers_url":"https://api.github.com/repos/jenkinsci/jenkins/subscribers","subscription_url":"https://api.github.com/repos/jenkinsci/jenkins/subscription","commits_url":"https://api.github.com/repos/jenkinsci/jenkins/commits{/sha}","git_commits_url":"https://api.github.com/repos/jenkinsci/jenkins/git/commits{/sha}","comments_url":"https://api.github.com/repos/jenkinsci/jenkins/comments{/number}","issue_comment_url":"https://api.github.com/repos/jenkinsci/jenkins/issues/comments{/number}","contents_url":"https://api.github.com/repos/jenkinsci/jenkins/contents/{+path}","compare_url":"https://api.github.com/repos/jenkinsci/jenkins/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jenkinsci/jenkins/merges","archive_url":"https://api.github.com/repos/jenkinsci/jenkins/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jenkinsci/jenkins/downloads","issues_url":"https://api.github.com/repos/jenkinsci/jenkins/issues{/number}","pulls_url":"https://api.github.com/repos/jenkinsci/jenkins/pulls{/number}","milestones_url":"https://api.github.com/repos/jenkinsci/jenkins/milestones{/number}","notifications_url":"https://api.github.com/repos/jenkinsci/jenkins/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jenkinsci/jenkins/labels{/name}","releases_url":"https://api.github.com/repos/jenkinsci/jenkins/releases{/id}","created_at":"2010-11-22T21:21:23Z","updated_at":"2015-04-26T19:06:35Z","pushed_at":"2015-04-26T19:21:50Z","git_url":"git://github.com/jenkinsci/jenkins.git","ssh_url":"git@github.com:jenkinsci/jenkins.git","clone_url":"https://github.com/jenkinsci/jenkins.git","svn_url":"https://github.com/jenkinsci/jenkins","homepage":"http://jenkins-ci.org/","size":420464,"stargazers_count":3987,"watchers_count":3987,"language":"Java","has_issues":false,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":1790,"mirror_url":null,"open_issues_count":113,"forks":1790,"open_issues":113,"watchers":3987,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/jenkinsci/jenkins/pulls/1671"},"html":{"href":"https://github.com/jenkinsci/jenkins/pull/1671"},"issue":{"href":"https://api.github.com/repos/jenkinsci/jenkins/issues/1671"},"comments":{"href":"https://api.github.com/repos/jenkinsci/jenkins/issues/1671/comments"},"review_comments":{"href":"https://api.github.com/repos/jenkinsci/jenkins/pulls/1671/comments"},"review_comment":{"href":"https://api.github.com/repos/jenkinsci/jenkins/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/jenkinsci/jenkins/pulls/1671/commits"},"statuses":{"href":"https://api.github.com/repos/jenkinsci/jenkins/statuses/0d41a2c3eb9274c1452b0644cc6cf96789fae031"}}}}