From d04f2d292d57bd50cef0d229ef5ab60cdc8492a9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Felix=20D=C3=B6rre?= Date: Sat, 2 Aug 2014 15:00:37 +0200 Subject: [PATCH] Implement certificate profiles in java code. --- doc/tableStructure.sql | 11 ++-- src/org/cacert/gigi/Certificate.java | 15 ++++- src/org/cacert/gigi/CertificateProfile.java | 63 +++++++++++++++++++ .../pages/account/CertificateIssueForm.java | 3 +- .../pages/account/CertificateIssueForm.templ | 30 +++------ tests/org/cacert/gigi/TestCertificate.java | 6 +- .../cacert/gigi/TestSeparateSessionScope.java | 2 +- 7 files changed, 98 insertions(+), 32 deletions(-) create mode 100644 src/org/cacert/gigi/CertificateProfile.java diff --git a/doc/tableStructure.sql b/doc/tableStructure.sql index 76babce8..69f85347 100644 --- a/doc/tableStructure.sql +++ b/doc/tableStructure.sql @@ -144,14 +144,17 @@ CREATE TABLE `clientcerts` ( DROP TABLE IF EXISTS `profiles`; CREATE TABLE `profiles` ( `id` int(3) NOT NULL AUTO_INCREMENT, + `keyname` varchar(10) NOT NULL, `keyUsage` varchar(100) NOT NULL, `extendedKeyUsage` varchar(100) NOT NULL, `rootcert` int(2) NOT NULL DEFAULT '1', - PRIMARY KEY (`id`) + `name` varchar(100) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE (`keyname`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; -INSERT INTO `profiles` SET keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='clientAuth'; -INSERT INTO `profiles` SET keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='serverAuth'; -INSERT INTO `profiles` SET keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='emailProtection'; +INSERT INTO `profiles` SET keyname='client', name='ssl-client', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='clientAuth'; +INSERT INTO `profiles` SET keyname='server', name='ssl-server', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='serverAuth'; +INSERT INTO `profiles` SET keyname='mail', name='mail', keyUsage='digitalSignature, keyEncipherment, keyAgreement', extendedKeyUsage='emailProtection'; DROP TABLE IF EXISTS `subjectAlternativeNames`; CREATE TABLE `subjectAlternativeNames` ( diff --git a/src/org/cacert/gigi/Certificate.java b/src/org/cacert/gigi/Certificate.java index a2645c62..6b06926f 100644 --- a/src/org/cacert/gigi/Certificate.java +++ b/src/org/cacert/gigi/Certificate.java @@ -83,18 +83,21 @@ public class Certificate { private List sans; - public Certificate(int ownerId, String dn, String md, String csr, CSRType csrType, SubjectAlternateName... sans) { + private CertificateProfile profile; + + public Certificate(int ownerId, String dn, String md, String csr, CSRType csrType, CertificateProfile profile, SubjectAlternateName... sans) { this.ownerId = ownerId; this.dn = dn; this.md = md; this.csr = csr; this.csrType = csrType; + this.profile = profile; this.sans = Arrays.asList(sans); } private Certificate(String serial) { try { - PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT id,subject, md, csr_name, crt_name,memid FROM `certs` WHERE serial=?"); + PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT id,subject, md, csr_name, crt_name,memid, profile FROM `certs` WHERE serial=?"); ps.setString(1, serial); ResultSet rs = ps.executeQuery(); if ( !rs.next()) { @@ -106,6 +109,7 @@ public class Certificate { csrName = rs.getString(4); crtName = rs.getString(5); ownerId = rs.getInt(6); + profile = CertificateProfile.getById(rs.getInt(7)); this.serial = serial; PreparedStatement ps2 = DatabaseConnection.getInstance().prepare("SELECT contents, type FROM `subjectAlternativeNames` WHERE certId=?"); @@ -178,11 +182,12 @@ public class Certificate { } Notary.writeUserAgreement(ownerId, "CCA", "issue certificate", "", true, 0); - PreparedStatement inserter = DatabaseConnection.getInstance().prepare("INSERT INTO certs SET md=?, subject=?, csr_type=?, crt_name='', memid=?, profile=1"); + PreparedStatement inserter = DatabaseConnection.getInstance().prepare("INSERT INTO certs SET md=?, subject=?, csr_type=?, crt_name='', memid=?, profile=?"); inserter.setString(1, md); inserter.setString(2, dn); inserter.setString(3, csrType.toString()); inserter.setInt(4, ownerId); + inserter.setInt(5, profile.getId()); inserter.execute(); id = DatabaseConnection.lastInsertId(inserter); File csrFile = KeyStorage.locateCsr(id); @@ -268,6 +273,10 @@ public class Certificate { return Collections.unmodifiableList(sans); } + public CertificateProfile getProfile() { + return profile; + } + public static Certificate getBySerial(String serial) { // TODO caching? try { diff --git a/src/org/cacert/gigi/CertificateProfile.java b/src/org/cacert/gigi/CertificateProfile.java new file mode 100644 index 00000000..d2e6b277 --- /dev/null +++ b/src/org/cacert/gigi/CertificateProfile.java @@ -0,0 +1,63 @@ +package org.cacert.gigi; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; + +import org.cacert.gigi.database.DatabaseConnection; + +public class CertificateProfile { + + final int id; + + final String keyName; + + final String visibleName; + + static HashMap byName = new HashMap<>(); + + static HashMap byId = new HashMap<>(); + + private CertificateProfile(int id, String keyName, String visibleName) { + this.id = id; + this.keyName = keyName; + this.visibleName = visibleName; + } + + public int getId() { + return id; + } + + public String getKeyName() { + return keyName; + } + + public String getVisibleName() { + return visibleName; + } + + static { + try { + PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT id, keyname, name FROM `profiles`"); + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + CertificateProfile cp = new CertificateProfile(rs.getInt("id"), rs.getString("keyName"), rs.getString("name")); + byId.put(cp.getId(), cp); + byName.put(cp.getKeyName(), cp); + } + } catch (SQLException e) { + e.printStackTrace(); + } + + } + + public static CertificateProfile getById(int id) { + return byId.get(id); + } + + public static CertificateProfile getByName(String name) { + return byName.get(name); + } + +} diff --git a/src/org/cacert/gigi/pages/account/CertificateIssueForm.java b/src/org/cacert/gigi/pages/account/CertificateIssueForm.java index 225f24de..922f9efb 100644 --- a/src/org/cacert/gigi/pages/account/CertificateIssueForm.java +++ b/src/org/cacert/gigi/pages/account/CertificateIssueForm.java @@ -16,6 +16,7 @@ import javax.servlet.http.HttpServletRequest; import org.cacert.gigi.Certificate; import org.cacert.gigi.Certificate.CSRType; +import org.cacert.gigi.CertificateProfile; import org.cacert.gigi.Digest; import org.cacert.gigi.EmailAddress; import org.cacert.gigi.GigiApiException; @@ -116,7 +117,7 @@ public class CertificateIssueForm extends Form { return false; } System.out.println("issuing " + selectedDigest); - result = new Certificate(LoginPage.getUser(req).getId(), "/commonName=CAcert WoT User", selectedDigest.toString(), this.csr, this.csrType); + result = new Certificate(LoginPage.getUser(req).getId(), "/commonName=CAcert WoT User", selectedDigest.toString(), this.csr, this.csrType, CertificateProfile.getById(1)); result.issue().waitFor(60000); return true; } diff --git a/src/org/cacert/gigi/pages/account/CertificateIssueForm.templ b/src/org/cacert/gigi/pages/account/CertificateIssueForm.templ index 9d94937c..5fc7b836 100644 --- a/src/org/cacert/gigi/pages/account/CertificateIssueForm.templ +++ b/src/org/cacert/gigi/pages/account/CertificateIssueForm.templ @@ -60,16 +60,18 @@ - - - - -
-
- + + + + + - + @@ -81,18 +83,6 @@ - - - - - - - - - - - diff --git a/tests/org/cacert/gigi/TestCertificate.java b/tests/org/cacert/gigi/TestCertificate.java index c2f47473..2e8426d2 100644 --- a/tests/org/cacert/gigi/TestCertificate.java +++ b/tests/org/cacert/gigi/TestCertificate.java @@ -24,7 +24,7 @@ public class TestCertificate extends ManagedTest { public void testClientCertLoginStates() throws IOException, GeneralSecurityException, SQLException, InterruptedException { KeyPair kp = generateKeypair(); String key1 = generatePEMCSR(kp, "CN=testmail@example.com"); - Certificate c = new Certificate(1, "/CN=testmail@example.com", "sha256", key1, CSRType.CSR); + Certificate c = new Certificate(1, "/CN=testmail@example.com", "sha256", key1, CSRType.CSR, CertificateProfile.getById(1)); final PrivateKey pk = kp.getPrivate(); c.issue().waitFor(60000); final X509Certificate ce = c.cert(); @@ -35,7 +35,7 @@ public class TestCertificate extends ManagedTest { public void testSans() throws IOException, GeneralSecurityException, SQLException, InterruptedException { KeyPair kp = generateKeypair(); String key = generatePEMCSR(kp, "CN=testmail@example.com"); - Certificate c = new Certificate(1, "/CN=testmail@example.com", "sha256", key, CSRType.CSR, // + Certificate c = new Certificate(1, "/CN=testmail@example.com", "sha256", key, CSRType.CSR, CertificateProfile.getById(1),// new SubjectAlternateName(SANType.EMAIL, "testmail@example.com"), new SubjectAlternateName(SANType.DNS, "testmail.example.com")); testFails(CertificateStatus.DRAFT, c); @@ -82,7 +82,7 @@ public class TestCertificate extends ManagedTest { public void testCertLifeCycle() throws IOException, GeneralSecurityException, SQLException, InterruptedException { KeyPair kp = generateKeypair(); String key = generatePEMCSR(kp, "CN=testmail@example.com"); - Certificate c = new Certificate(1, "/CN=testmail@example.com", "sha256", key, CSRType.CSR); + Certificate c = new Certificate(1, "/CN=testmail@example.com", "sha256", key, CSRType.CSR, CertificateProfile.getById(1)); final PrivateKey pk = kp.getPrivate(); testFails(CertificateStatus.DRAFT, c); diff --git a/tests/org/cacert/gigi/TestSeparateSessionScope.java b/tests/org/cacert/gigi/TestSeparateSessionScope.java index 6f78dbac..840249f4 100644 --- a/tests/org/cacert/gigi/TestSeparateSessionScope.java +++ b/tests/org/cacert/gigi/TestSeparateSessionScope.java @@ -24,7 +24,7 @@ public class TestSeparateSessionScope extends ManagedTest { String cookie = login(mail, TEST_PASSWORD); KeyPair kp = generateKeypair(); String csr = generatePEMCSR(kp, "CN=felix@dogcraft.de"); - Certificate c = new Certificate(user, "/CN=testmail@example.com", "sha256", csr, CSRType.CSR); + Certificate c = new Certificate(user, "/CN=testmail@example.com", "sha256", csr, CSRType.CSR, CertificateProfile.getById(1)); final PrivateKey pk = kp.getPrivate(); c.issue().waitFor(60000); final X509Certificate ce = c.cert(); -- 2.39.2