{"action":"created","comment":{"url":"https://api.github.com/repos/codice/ddf/pulls/comments/37000717","id":37000717,"diff_hunk":"@@ -0,0 +1,267 @@\n+/**\n+ * Copyright (c) Codice Foundation\n+ * <p/>\n+ * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser\n+ * General Public License as published by the Free Software Foundation, either version 3 of the\n+ * License, or any later version.\n+ * <p/>\n+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details. A copy of the GNU Lesser General Public License\n+ * is distributed along with this program and can be found at\n+ * <http://www.gnu.org/licenses/lgpl.html>.\n+ */\n+package org.codice.ddf.certificate;\n+\n+import java.io.ByteArrayInputStream;\n+import java.io.ByteArrayOutputStream;\n+import java.io.IOException;\n+import java.io.OutputStream;\n+import java.math.BigInteger;\n+import java.net.InetAddress;\n+import java.net.UnknownHostException;\n+import java.security.GeneralSecurityException;\n+import java.security.PrivateKey;\n+import java.security.PublicKey;\n+import java.security.Security;\n+import java.security.Signature;\n+import java.security.cert.CertificateException;\n+import java.security.cert.CertificateFactory;\n+import java.security.cert.X509Certificate;\n+import java.util.Date;\n+\n+import org.bouncycastle.asn1.ASN1ObjectIdentifier;\n+import org.bouncycastle.asn1.x500.X500Name;\n+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;\n+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;\n+import org.bouncycastle.cert.X509v3CertificateBuilder;\n+import org.bouncycastle.jce.provider.BouncyCastleProvider;\n+import org.bouncycastle.operator.ContentSigner;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+\n+    /*+----------------------------------------------------------------------\n+     ||\n+     ||  Class: CertificateManager\n+     ||\n+     ||        Purpose:  Collection of static methods that manages X509Certificate creation and signing.\n+     ||\n+     ||  Inherits From:  None\n+     ||\n+     ||     Interfaces:  None\n+     ||\n+     |+-----------------------------------------------------------------------\n+     ||\n+     ||      Constants:  MILLIS_IN_DAY - Number of milliseconds in a day\n+     ||                  MILLIS_IN_YEAR - Number of milliseconds in a year\n+     ||\n+     |+-----------------------------------------------------------------------\n+     ||\n+     ||  Class Methods:     X509v3CertificateBuilder    createDefaultX509SigningRequest(PublicKey)\n+     ||                     X509v3CertificateBuilder    createCustomX509SigningRequest(String, String, int, PublicKey)\n+     ||                     X509v3CertificateBuilder    createCustomX509SigningRequest(String, String, String, String, String, String, String, String, String, String, int, PublicKey)\n+     ||                     X509Certificate             signX509CertificateSHA256RSA(X509v3CertificateBuilder, PrivateKey)\n+     ||                     void                        registerBCSecurityProvider()\n+     ||                     String                      getHostName()\n+     ||\n+     ||\n+     ++-----------------------------------------------------------------------*/\n+\n+public class CertificateManager {\n+    private static final long MILLIS_IN_DAY = 86400000;\n+\n+    private static final long MILLIS_IN_YEAR = 31536000000L;\n+\n+    private static final Logger LOGGER = LoggerFactory.getLogger(CertificateManager.class);\n+\n+    /**\n+     * ---------------------------------------------------------------------\n+     * Method: createDefaultX509SigningRequest\n+     * <p/>\n+     * Purpose:  Creates a signing request with default issuer and subject information\n+     * <p/>\n+     * Pre-condition: None\n+     * <p/>\n+     * Post-condition: Issuer information, subject information, and the encoded public key have been added to the returned signing request. Valid for 3 years.\n+     *\n+     * @param pubKey the PublicKey to be associated with the certificate signing request\n+     * @return X509v3CertificateBuilder with the issuer, subject, and encoded public key set.\n+     * -------------------------------------------------------------------\n+     */\n+\n+    public static X509v3CertificateBuilder createDefaultX509SigningRequest(PublicKey pubKey) {\n+        X509v3CertificateBuilder certBuilder;\n+        Long currentTimeMillis = System.currentTimeMillis();\n+        X500Name theIssuer = new X500Name(\n+                \"C=US,ST=AZ,O=DDF,OU=Dev,CN=DDF Demo Root CA,E=ddfrootca@example.org\");\n+        X500Name theSubject = new X500Name(\n+                \"CN=\" + getHostName() + \", OU=Conn, OU=Dev, OU=DevT, O=U.S., C=US\");\n+        certBuilder = new X509v3CertificateBuilder(theIssuer,\n+                new BigInteger(currentTimeMillis.toString()),\n+                (new Date(currentTimeMillis - MILLIS_IN_DAY)),\n+                (new Date(currentTimeMillis + (MILLIS_IN_YEAR * 3))), theSubject,","path":"platform/security/certificate/src/main/java/org/codice/ddf/certificate/CertificateManager.java","position":102,"original_position":102,"commit_id":"977e5c41ddcfd00df8336ec291f9e64be4d48fa9","original_commit_id":"977e5c41ddcfd00df8336ec291f9e64be4d48fa9","user":{"login":"lessarderic","id":11377558,"avatar_url":"https://avatars.githubusercontent.com/u/11377558?v=3","gravatar_id":"","url":"https://api.github.com/users/lessarderic","html_url":"https://github.com/lessarderic","followers_url":"https://api.github.com/users/lessarderic/followers","following_url":"https://api.github.com/users/lessarderic/following{/other_user}","gists_url":"https://api.github.com/users/lessarderic/gists{/gist_id}","starred_url":"https://api.github.com/users/lessarderic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lessarderic/subscriptions","organizations_url":"https://api.github.com/users/lessarderic/orgs","repos_url":"https://api.github.com/users/lessarderic/repos","events_url":"https://api.github.com/users/lessarderic/events{/privacy}","received_events_url":"https://api.github.com/users/lessarderic/received_events","type":"User","site_admin":false},"body":":+1: ","created_at":"2015-08-13T17:24:52Z","updated_at":"2015-08-13T17:24:52Z","html_url":"https://github.com/codice/ddf/pull/118#discussion_r37000717","pull_request_url":"https://api.github.com/repos/codice/ddf/pulls/118","_links":{"self":{"href":"https://api.github.com/repos/codice/ddf/pulls/comments/37000717"},"html":{"href":"https://github.com/codice/ddf/pull/118#discussion_r37000717"},"pull_request":{"href":"https://api.github.com/repos/codice/ddf/pulls/118"}}},"pull_request":{"url":"https://api.github.com/repos/codice/ddf/pulls/118","id":42300389,"html_url":"https://github.com/codice/ddf/pull/118","diff_url":"https://github.com/codice/ddf/pull/118.diff","patch_url":"https://github.com/codice/ddf/pull/118.patch","issue_url":"https://api.github.com/repos/codice/ddf/issues/118","number":118,"state":"open","locked":false,"title":"DDF-1363: Implement programmatic certificate generation, keystores, a…","user":{"login":"brianfelix","id":12402520,"avatar_url":"https://avatars.githubusercontent.com/u/12402520?v=3","gravatar_id":"","url":"https://api.github.com/users/brianfelix","html_url":"https://github.com/brianfelix","followers_url":"https://api.github.com/users/brianfelix/followers","following_url":"https://api.github.com/users/brianfelix/following{/other_user}","gists_url":"https://api.github.com/users/brianfelix/gists{/gist_id}","starred_url":"https://api.github.com/users/brianfelix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brianfelix/subscriptions","organizations_url":"https://api.github.com/users/brianfelix/orgs","repos_url":"https://api.github.com/users/brianfelix/repos","events_url":"https://api.github.com/users/brianfelix/events{/privacy}","received_events_url":"https://api.github.com/users/brianfelix/received_events","type":"User","site_admin":false},"body":"…nd management\r\n\r\nAdded the ability to generate x509 certificates, create/add to keystores,\r\nand extract objects from PEM files. This allows for easier generation of\r\nself-signed certificates.\n\n<!-- Reviewable:start -->\n[<img src=\"https://reviewable.io/review_button.png\" height=40 alt=\"Review on Reviewable\"/>](https://reviewable.io/reviews/codice/ddf/118)\n<!-- Reviewable:end -->\n","created_at":"2015-08-12T23:20:04Z","updated_at":"2015-08-13T17:24:52Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a4d44b77a6369a0a3aae4199b57333819accc53f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/codice/ddf/pulls/118/commits","review_comments_url":"https://api.github.com/repos/codice/ddf/pulls/118/comments","review_comment_url":"https://api.github.com/repos/codice/ddf/pulls/comments{/number}","comments_url":"https://api.github.com/repos/codice/ddf/issues/118/comments","statuses_url":"https://api.github.com/repos/codice/ddf/statuses/977e5c41ddcfd00df8336ec291f9e64be4d48fa9","head":{"label":"brianfelix:DDF-1363","ref":"DDF-1363","sha":"977e5c41ddcfd00df8336ec291f9e64be4d48fa9","user":{"login":"brianfelix","id":12402520,"avatar_url":"https://avatars.githubusercontent.com/u/12402520?v=3","gravatar_id":"","url":"https://api.github.com/users/brianfelix","html_url":"https://github.com/brianfelix","followers_url":"https://api.github.com/users/brianfelix/followers","following_url":"https://api.github.com/users/brianfelix/following{/other_user}","gists_url":"https://api.github.com/users/brianfelix/gists{/gist_id}","starred_url":"https://api.github.com/users/brianfelix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brianfelix/subscriptions","organizations_url":"https://api.github.com/users/brianfelix/orgs","repos_url":"https://api.github.com/users/brianfelix/repos","events_url":"https://api.github.com/users/brianfelix/events{/privacy}","received_events_url":"https://api.github.com/users/brianfelix/received_events","type":"User","site_admin":false},"repo":{"id":36394348,"name":"ddf","full_name":"brianfelix/ddf","owner":{"login":"brianfelix","id":12402520,"avatar_url":"https://avatars.githubusercontent.com/u/12402520?v=3","gravatar_id":"","url":"https://api.github.com/users/brianfelix","html_url":"https://github.com/brianfelix","followers_url":"https://api.github.com/users/brianfelix/followers","following_url":"https://api.github.com/users/brianfelix/following{/other_user}","gists_url":"https://api.github.com/users/brianfelix/gists{/gist_id}","starred_url":"https://api.github.com/users/brianfelix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brianfelix/subscriptions","organizations_url":"https://api.github.com/users/brianfelix/orgs","repos_url":"https://api.github.com/users/brianfelix/repos","events_url":"https://api.github.com/users/brianfelix/events{/privacy}","received_events_url":"https://api.github.com/users/brianfelix/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/brianfelix/ddf","description":"The Distributed Data Framework - Distribution, SDK, and Test","fork":true,"url":"https://api.github.com/repos/brianfelix/ddf","forks_url":"https://api.github.com/repos/brianfelix/ddf/forks","keys_url":"https://api.github.com/repos/brianfelix/ddf/keys{/key_id}","collaborators_url":"https://api.github.com/repos/brianfelix/ddf/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/brianfelix/ddf/teams","hooks_url":"https://api.github.com/repos/brianfelix/ddf/hooks","issue_events_url":"https://api.github.com/repos/brianfelix/ddf/issues/events{/number}","events_url":"https://api.github.com/repos/brianfelix/ddf/events","assignees_url":"https://api.github.com/repos/brianfelix/ddf/assignees{/user}","branches_url":"https://api.github.com/repos/brianfelix/ddf/branches{/branch}","tags_url":"https://api.github.com/repos/brianfelix/ddf/tags","blobs_url":"https://api.github.com/repos/brianfelix/ddf/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/brianfelix/ddf/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/brianfelix/ddf/git/refs{/sha}","trees_url":"https://api.github.com/repos/brianfelix/ddf/git/trees{/sha}","statuses_url":"https://api.github.com/repos/brianfelix/ddf/statuses/{sha}","languages_url":"https://api.github.com/repos/brianfelix/ddf/languages","stargazers_url":"https://api.github.com/repos/brianfelix/ddf/stargazers","contributors_url":"https://api.github.com/repos/brianfelix/ddf/contributors","subscribers_url":"https://api.github.com/repos/brianfelix/ddf/subscribers","subscription_url":"https://api.github.com/repos/brianfelix/ddf/subscription","commits_url":"https://api.github.com/repos/brianfelix/ddf/commits{/sha}","git_commits_url":"https://api.github.com/repos/brianfelix/ddf/git/commits{/sha}","comments_url":"https://api.github.com/repos/brianfelix/ddf/comments{/number}","issue_comment_url":"https://api.github.com/repos/brianfelix/ddf/issues/comments{/number}","contents_url":"https://api.github.com/repos/brianfelix/ddf/contents/{+path}","compare_url":"https://api.github.com/repos/brianfelix/ddf/compare/{base}...{head}","merges_url":"https://api.github.com/repos/brianfelix/ddf/merges","archive_url":"https://api.github.com/repos/brianfelix/ddf/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/brianfelix/ddf/downloads","issues_url":"https://api.github.com/repos/brianfelix/ddf/issues{/number}","pulls_url":"https://api.github.com/repos/brianfelix/ddf/pulls{/number}","milestones_url":"https://api.github.com/repos/brianfelix/ddf/milestones{/number}","notifications_url":"https://api.github.com/repos/brianfelix/ddf/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/brianfelix/ddf/labels{/name}","releases_url":"https://api.github.com/repos/brianfelix/ddf/releases{/id}","created_at":"2015-05-27T20:37:45Z","updated_at":"2015-05-27T20:37:46Z","pushed_at":"2015-08-12T23:45:34Z","git_url":"git://github.com/brianfelix/ddf.git","ssh_url":"git@github.com:brianfelix/ddf.git","clone_url":"https://github.com/brianfelix/ddf.git","svn_url":"https://github.com/brianfelix/ddf","homepage":"","size":52526,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"codice:master","ref":"master","sha":"9dde877405235d899c9fab6109283fb2a030866c","user":{"login":"codice","id":2386734,"avatar_url":"https://avatars.githubusercontent.com/u/2386734?v=3","gravatar_id":"","url":"https://api.github.com/users/codice","html_url":"https://github.com/codice","followers_url":"https://api.github.com/users/codice/followers","following_url":"https://api.github.com/users/codice/following{/other_user}","gists_url":"https://api.github.com/users/codice/gists{/gist_id}","starred_url":"https://api.github.com/users/codice/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codice/subscriptions","organizations_url":"https://api.github.com/users/codice/orgs","repos_url":"https://api.github.com/users/codice/repos","events_url":"https://api.github.com/users/codice/events{/privacy}","received_events_url":"https://api.github.com/users/codice/received_events","type":"Organization","site_admin":false},"repo":{"id":15173563,"name":"ddf","full_name":"codice/ddf","owner":{"login":"codice","id":2386734,"avatar_url":"https://avatars.githubusercontent.com/u/2386734?v=3","gravatar_id":"","url":"https://api.github.com/users/codice","html_url":"https://github.com/codice","followers_url":"https://api.github.com/users/codice/followers","following_url":"https://api.github.com/users/codice/following{/other_user}","gists_url":"https://api.github.com/users/codice/gists{/gist_id}","starred_url":"https://api.github.com/users/codice/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codice/subscriptions","organizations_url":"https://api.github.com/users/codice/orgs","repos_url":"https://api.github.com/users/codice/repos","events_url":"https://api.github.com/users/codice/events{/privacy}","received_events_url":"https://api.github.com/users/codice/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codice/ddf","description":"The Distributed Data Framework - Distribution, SDK, and Test","fork":false,"url":"https://api.github.com/repos/codice/ddf","forks_url":"https://api.github.com/repos/codice/ddf/forks","keys_url":"https://api.github.com/repos/codice/ddf/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codice/ddf/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codice/ddf/teams","hooks_url":"https://api.github.com/repos/codice/ddf/hooks","issue_events_url":"https://api.github.com/repos/codice/ddf/issues/events{/number}","events_url":"https://api.github.com/repos/codice/ddf/events","assignees_url":"https://api.github.com/repos/codice/ddf/assignees{/user}","branches_url":"https://api.github.com/repos/codice/ddf/branches{/branch}","tags_url":"https://api.github.com/repos/codice/ddf/tags","blobs_url":"https://api.github.com/repos/codice/ddf/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codice/ddf/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codice/ddf/git/refs{/sha}","trees_url":"https://api.github.com/repos/codice/ddf/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codice/ddf/statuses/{sha}","languages_url":"https://api.github.com/repos/codice/ddf/languages","stargazers_url":"https://api.github.com/repos/codice/ddf/stargazers","contributors_url":"https://api.github.com/repos/codice/ddf/contributors","subscribers_url":"https://api.github.com/repos/codice/ddf/subscribers","subscription_url":"https://api.github.com/repos/codice/ddf/subscription","commits_url":"https://api.github.com/repos/codice/ddf/commits{/sha}","git_commits_url":"https://api.github.com/repos/codice/ddf/git/commits{/sha}","comments_url":"https://api.github.com/repos/codice/ddf/comments{/number}","issue_comment_url":"https://api.github.com/repos/codice/ddf/issues/comments{/number}","contents_url":"https://api.github.com/repos/codice/ddf/contents/{+path}","compare_url":"https://api.github.com/repos/codice/ddf/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codice/ddf/merges","archive_url":"https://api.github.com/repos/codice/ddf/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codice/ddf/downloads","issues_url":"https://api.github.com/repos/codice/ddf/issues{/number}","pulls_url":"https://api.github.com/repos/codice/ddf/pulls{/number}","milestones_url":"https://api.github.com/repos/codice/ddf/milestones{/number}","notifications_url":"https://api.github.com/repos/codice/ddf/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codice/ddf/labels{/name}","releases_url":"https://api.github.com/repos/codice/ddf/releases{/id}","created_at":"2013-12-13T20:38:28Z","updated_at":"2015-08-09T12:08:48Z","pushed_at":"2015-08-13T16:55:05Z","git_url":"git://github.com/codice/ddf.git","ssh_url":"git@github.com:codice/ddf.git","clone_url":"https://github.com/codice/ddf.git","svn_url":"https://github.com/codice/ddf","homepage":"","size":133472,"stargazers_count":19,"watchers_count":19,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":52,"mirror_url":null,"open_issues_count":9,"forks":52,"open_issues":9,"watchers":19,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/codice/ddf/pulls/118"},"html":{"href":"https://github.com/codice/ddf/pull/118"},"issue":{"href":"https://api.github.com/repos/codice/ddf/issues/118"},"comments":{"href":"https://api.github.com/repos/codice/ddf/issues/118/comments"},"review_comments":{"href":"https://api.github.com/repos/codice/ddf/pulls/118/comments"},"review_comment":{"href":"https://api.github.com/repos/codice/ddf/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/codice/ddf/pulls/118/commits"},"statuses":{"href":"https://api.github.com/repos/codice/ddf/statuses/977e5c41ddcfd00df8336ec291f9e64be4d48fa9"}}}}