summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorChristina Fu <cfu@redhat.com>2015-04-15 10:58:08 -0700
committerChristina Fu <cfu@redhat.com>2015-04-21 18:24:32 -0700
commite2683d6a8f6211ac58a5674aaa626814f26ebbf2 (patch)
treecb6e9fae0990b334ee1acd6333f8ef46594994e8 /base
parent79c5627ae28840756d99928fd33701552cc93322 (diff)
downloadpki-e2683d6a8f6211ac58a5674aaa626814f26ebbf2.tar.gz
pki-e2683d6a8f6211ac58a5674aaa626814f26ebbf2.tar.xz
pki-e2683d6a8f6211ac58a5674aaa626814f26ebbf2.zip
Ticket 1316 Allow adding SAN to server cert during the install process
Usage: * under /usr/share/pki/ca/conf, you will find a new file called serverCert.profile.exampleWithSANpattern * copy existing serverCert.profile away and replace with serverCert.profile.exampleWithSANpattern * edit serverCert.profile.exampleWithSANpattern - follow the instruction right above 8.default. - save and quit * cd /usr/share/pki/ca/profiles/ca , edit caInternalAuthServerCert.cfg - follow the instruction right above policyset.serverCertSet.9 - save and quit * save away and edit the ca config file for pkispawn: (note: you can add multiple SAN's delimited by ',' for pki_san_server_cert - add the following lines, e.g. pki_san_inject=True pki_san_server_cert=host1.Example.com - do the same pkispawn cfg changes for kra or any other instances that you plan on creating * create your instance(s) check the sl sever cert, it should contain something like the following: Identifier: Subject Alternative Name - 2.5.29.17 Critical: no Value: DNSName: host1.Example.com
Diffstat (limited to 'base')
-rw-r--r--base/ca/shared/conf/serverCert.profile.exampleWithSANpattern68
-rw-r--r--base/ca/shared/profiles/ca/caInternalAuthServerCert.cfg23
-rw-r--r--base/common/src/com/netscape/certsrv/system/SystemCertData.java13
-rw-r--r--base/server/cms/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java11
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/csadmin/CertUtil.java96
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java13
-rw-r--r--base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java10
-rw-r--r--base/server/etc/default.cfg3
-rw-r--r--base/server/python/pki/server/deployment/pkihelper.py9
-rw-r--r--base/server/python/pki/server/deployment/pkiparser.py3
10 files changed, 239 insertions, 10 deletions
diff --git a/base/ca/shared/conf/serverCert.profile.exampleWithSANpattern b/base/ca/shared/conf/serverCert.profile.exampleWithSANpattern
new file mode 100644
index 000000000..5ca44270e
--- /dev/null
+++ b/base/ca/shared/conf/serverCert.profile.exampleWithSANpattern
@@ -0,0 +1,68 @@
+#
+# Server Certificate
+#
+id=serverCert.profile
+name=All Purpose SSL server cert Profile
+description=This profile creates an SSL server certificate that is valid for SSL servers
+profileIDMapping=caServerCert
+profileSetIDMapping=serverCertSet
+list=2,4,5,6,7,8
+2.default.class=com.netscape.cms.profile.def.ValidityDefault
+2.default.name=Validity Default
+2.default.params.range=720
+2.default.params.startTime=0
+4.default.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
+4.default.name=Authority Key Identifier Default
+5.default.class=com.netscape.cms.profile.def.AuthInfoAccessExtDefault
+5.default.name=AIA Extension Default
+5.default.params.authInfoAccessADEnable_0=true
+5.default.params.authInfoAccessADLocationType_0=URIName
+5.default.params.authInfoAccessADLocation_0=
+5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+5.default.params.authInfoAccessCritical=false
+5.default.params.authInfoAccessNumADs=1
+6.default.class=com.netscape.cms.profile.def.KeyUsageExtDefault
+6.default.name=Key Usage Default
+6.default.params.keyUsageCritical=true
+6.default.params.keyUsageDigitalSignature=true
+6.default.params.keyUsageNonRepudiation=true
+6.default.params.keyUsageDataEncipherment=true
+6.default.params.keyUsageKeyEncipherment=true
+6.default.params.keyUsageKeyAgreement=false
+6.default.params.keyUsageKeyCertSign=false
+6.default.params.keyUsageCrlSign=false
+6.default.params.keyUsageEncipherOnly=false
+6.default.params.keyUsageDecipherOnly=false
+7.default.class=com.netscape.cms.profile.def.ExtendedKeyUsageExtDefault
+7.default.name=Extended Key Usage Extension Default
+7.default.params.exKeyUsageCritical=false
+7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1
+# allows SAN to be specified from client side
+# need to:
+# 1. add 8 to list above
+# 2. change below to reflect the number of general names, and
+# turn each corresponding subjAltExtPattern_<num> to true
+# 8.default.params.subjAltNameNumGNs
+8.default.class=com.netscape.cms.profile.def.SubjectAltNameExtDefault
+8.default.name=Subject Alternative Name Extension Default
+8.default.params.subjAltExtGNEnable_0=true
+8.default.params.subjAltExtPattern_0=$request.req_san_pattern_0$
+8.default.params.subjAltExtType_0=DNSName
+8.default.params.subjAltExtGNEnable_1=true
+8.default.params.subjAltExtPattern_1=$request.req_san_pattern_1$
+8.default.params.subjAltExtType_1=DNSName
+8.default.params.subjAltExtGNEnable_2=true
+8.default.params.subjAltExtPattern_2=$request.req_san_pattern_2$
+8.default.params.subjAltExtType_2=DNSName
+8.default.params.subjAltExtGNEnable_3=true
+8.default.params.subjAltExtPattern_3=$request.req_san_pattern_3$
+8.default.params.subjAltExtType_3=DNSName
+8.default.params.subjAltExtType_4=OtherName
+8.default.params.subjAltExtSource_4=UUID4
+8.default.params.subjAltExtPattern_4=(IA5String)1.2.3.4,$server.source$
+8.default.params.subjAltExtGNEnable_4=true
+8.default.params.subjAltExtType_5=DNSName
+8.default.params.subjAltExtPattern_5=myhost.example.com
+8.default.params.subjAltExtGNEnable_5=true
+8.default.params.subjAltNameExtCritical=false
+8.default.params.subjAltNameNumGNs=6
diff --git a/base/ca/shared/profiles/ca/caInternalAuthServerCert.cfg b/base/ca/shared/profiles/ca/caInternalAuthServerCert.cfg
index 719351080..f145325f0 100644
--- a/base/ca/shared/profiles/ca/caInternalAuthServerCert.cfg
+++ b/base/ca/shared/profiles/ca/caInternalAuthServerCert.cfg
@@ -8,6 +8,7 @@ name=Security Domain Server Certificate Enrollment
input.list=i1,i2
input.i1.class_id=certReqInputImpl
input.i2.class_id=submitterInfoInputImpl
+input.i3.class_id=subjectAltNameExtInputImpl
output.list=o1
output.o1.class_id=certOutputImpl
policyset.list=serverCertSet
@@ -84,3 +85,25 @@ policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA25
policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
policyset.serverCertSet.8.default.name=Signing Alg
policyset.serverCertSet.8.default.params.signingAlg=-
+# allows SAN to be specified from client side
+# need to:
+# 1. add i3 to input.list above
+# 2. add 9 to policyset.serverCertSet.list above
+# 3. change below to reflect the number of general names, and
+# turn each corresponding subjAltExtPattern_<num> to true
+# policyset.serverCertSet.9.default.params.subjAltNameNumGNs
+policyset.serverCertSet.9.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.9.constraint.name=No Constraint
+policyset.serverCertSet.9.default.class_id=subjectAltNameExtDefaultImpl
+policyset.serverCertSet.9.default.name=Subject Alternative Name Extension Default
+policyset.serverCertSet.9.default.params.subjAltExtGNEnable_0=true
+policyset.serverCertSet.9.default.params.subjAltExtPattern_0=$request.req_san_pattern_0$
+policyset.serverCertSet.9.default.params.subjAltExtType_0=DNSName
+policyset.serverCertSet.9.default.params.subjAltExtGNEnable_1=false
+policyset.serverCertSet.9.default.params.subjAltExtPattern_1=$request.req_san_pattern_1$
+policyset.serverCertSet.9.default.params.subjAltExtType_1=DNSName
+policyset.serverCertSet.9.default.params.subjAltExtGNEnable_2=false
+policyset.serverCertSet.9.default.params.subjAltExtPattern_2=$request.req_san_pattern_2$
+policyset.serverCertSet.9.default.params.subjAltExtType_2=DNSName
+policyset.serverCertSet.9.default.params.subjAltNameExtCritical=false
+policyset.serverCertSet.9.default.params.subjAltNameNumGNs=1
diff --git a/base/common/src/com/netscape/certsrv/system/SystemCertData.java b/base/common/src/com/netscape/certsrv/system/SystemCertData.java
index 064d8e190..89fb8cb8f 100644
--- a/base/common/src/com/netscape/certsrv/system/SystemCertData.java
+++ b/base/common/src/com/netscape/certsrv/system/SystemCertData.java
@@ -46,6 +46,7 @@ public class SystemCertData {
public static final String REQUEST_EXT_OID = "req_ext_oid";
public static final String REQUEST_EXT_CRITICAL = "req_ext_critial";
public static final String REQUEST_EXT_DATA = "req_ext_data";
+ public static final String SERVER_CERT_SAN = "san_for_server_cert";
@XmlElement
protected String tag;
@@ -92,6 +93,9 @@ public class SystemCertData {
@XmlElement
protected String req_ext_data;
+ @XmlElement
+ protected String san_for_server_cert;
+
public SystemCertData() {
// required for JAXB
}
@@ -113,6 +117,8 @@ public class SystemCertData {
req_ext_oid = form.getFirst(REQUEST_EXT_OID);
req_ext_critical = form.getFirst(REQUEST_EXT_CRITICAL);
req_ext_data = form.getFirst(REQUEST_EXT_DATA);
+ //support SAN in server cert
+ san_for_server_cert = form.getFirst(SERVER_CERT_SAN);
}
/**
@@ -307,4 +313,11 @@ public class SystemCertData {
return false;
}
+ /**
+ * @return the server cert SAN
+ */
+ public String getServerCertSAN() {
+ return san_for_server_cert;
+ }
+
}
diff --git a/base/server/cms/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java
index 240f86a13..ca3d05f25 100644
--- a/base/server/cms/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java
+++ b/base/server/cms/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java
@@ -450,6 +450,7 @@ public class SubjectAltNameExtDefault extends EnrollExtDefault {
if (!pattern.equals("")) {
CMS.debug("SubjectAltNameExtDefault: createExtension() pattern="+ pattern);
String gname = "";
+ String gtype = "";
// cfu - see if this is server-generated (e.g. UUID4)
// to use this feature, use $server.source$ in pattern
@@ -479,16 +480,18 @@ public class SubjectAltNameExtDefault extends EnrollExtDefault {
} else {
if (request != null) {
gname = mapPattern(request, pattern);
+ gtype = mapPattern(request, type);
}
}
- if (gname.equals("") || gname.contains("$")) {
- CMS.debug("ubjectAltNameExtDefault: mapPattern()failed. Not added. gname="+ gname);
+ if (gname.equals("") ||
+ gname.startsWith(CONFIG_SAN_REQ_PATTERN_PREFIX)) {
+ CMS.debug("SubjectAltNameExtDefault: gname is empty,not added.");
continue;
}
- CMS.debug("SubjectAltNameExtDefault: createExtension got gname=" + gname);
+ CMS.debug("SubjectAltNameExtDefault: createExtension got gname=" +gname + " with type=" + gtype);
- GeneralNameInterface n = parseGeneralName(type + ":" + gname);
+ GeneralNameInterface n = parseGeneralName(gtype + ":" + gname);
CMS.debug("adding gname: " + gname);
if (n != null) {
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/CertUtil.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/CertUtil.java
index 22f092973..36b0e4d0d 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/CertUtil.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/CertUtil.java
@@ -206,6 +206,85 @@ public class CertUtil {
}
}
+
+ // Dynamically inject the SubjectAlternativeName extension to a
+ // local/self-signed master CA's request for its SSL Server Certificate.
+ //
+ // Since this information may vary from instance to
+ // instance, obtain the necessary information from the
+ // 'service.sslserver.san' value(s) in the instance's
+ // CS.cfg, process these values converting each item into
+ // its individual SubjectAlternativeName components, and
+ // inject these values into the local request.
+ //
+ public static void injectSANextensionIntoRequest(IConfigStore config,
+ IRequest req) throws Exception {
+ CMS.debug("CertUtil::injectSANextensionIntoRequest() - injecting SAN " +
+ "entries into request . . .");
+ int i = 0;
+ if (config == null || req == null) {
+ throw new EBaseException("injectSANextensionIntoRequest: parameters config and req cannot be null");
+ }
+ String sanHostnames = config.getString("service.sslserver.san");
+ String sans[] = StringUtils.split(sanHostnames, ",");
+ for (String san : sans) {
+ CMS.debug("CertUtil: injectSANextensionIntoRequest() injecting " +
+ "SAN hostname: " + san);
+ req.setExtData("req_san_pattern_" + i, san);
+ i++;
+ }
+ CMS.debug("CertUtil: injectSANextensionIntoRequest() " + "injected " +
+ i + " SAN entries into request.");
+ }
+
+ // Dynamically apply the SubjectAlternativeName extension to a
+ // remote PKI instance's request for its SSL Server Certificate.
+ //
+ // Since this information may vary from instance to
+ // instance, obtain the necessary information from the
+ // 'service.sslserver.san' value(s) in the instance's
+ // CS.cfg, process these values converting each item into
+ // its individual SubjectAlternativeName components, and
+ // build an SSL Server Certificate URL extension consisting
+ // of this information.
+ //
+ // 03/27/2013 - Should consider removing this
+ // "buildSANSSLserverURLExtension()"
+ // method if it becomes possible to
+ // embed a certificate extension into
+ // a PKCS #10 certificate request.
+ //
+ public static String buildSANSSLserverURLExtension(IConfigStore config)
+ throws Exception {
+ String url = "";
+ String entries = "";
+
+ CMS.debug("CertUtil: buildSANSSLserverURLExtension() " +
+ "building SAN SSL Server Certificate URL extension . . .");
+ int i = 0;
+ if (config == null) {
+ throw new EBaseException("injectSANextensionIntoRequest: parameter config cannot be null");
+ }
+ String sanHostnames = config.getString("service.sslserver.san");
+ String sans[] = StringUtils.split(sanHostnames, ",");
+ for (String san : sans) {
+ CMS.debug("CertUtil: buildSANSSLserverURLExtension() processing " +
+ "SAN hostname: " + san);
+ // Add the DNSName for all SANs
+ entries = entries +
+ "&req_san_pattern_" + i + "=" + san;
+ i++;
+ }
+
+ url = "&req_san_entries=" + i + entries;
+
+ CMS.debug("CertUtil: buildSANSSLserverURLExtension() " + "placed " +
+ i + " SAN entries into SSL Server Certificate URL.");
+
+ return url;
+ }
+
+
/*
* create requests so renewal can work on these initial certs
*/
@@ -375,6 +454,9 @@ public class CertUtil {
IRequest req = null;
try {
+ Boolean injectSAN = config.getBoolean(
+ "service.injectSAN", false);
+ CMS.debug("createLocalCert: injectSAN=" + injectSAN);
String dn = config.getString(prefix + certTag + ".dn");
String keyAlgorithm = null;
Date date = new Date();
@@ -426,6 +508,10 @@ public class CertUtil {
queue = ca.getRequestQueue();
if (queue != null) {
req = createLocalRequest(queue, serialNo.toString(), info);
+ if (certTag.equals("sslserver") &&
+ injectSAN == true) {
+ injectSANextensionIntoRequest(config, req);
+ }
CMS.debug("CertUtil profile name= " + profile);
req.setExtData("req_key", x509key.toString());
@@ -498,7 +584,7 @@ public class CertUtil {
}
} catch (Exception e) {
CMS.debug(e);
- CMS.debug("NamePanel configCert() exception caught:" + e.toString());
+ CMS.debug("CertUtil createLocalCert() exception caught:" + e.toString());
}
if (cr == null) {
@@ -520,22 +606,22 @@ public class CertUtil {
cert.getSerialNumber(), cert, meta);
} catch (Exception e) {
CMS.debug(
- "NamePanel configCert: failed to add metainfo. Exception: " + e.toString());
+ "CertUtil createLocalCert: failed to add metainfo. Exception: " + e.toString());
}
try {
cr.addCertificateRecord(record);
CMS.debug(
- "NamePanel configCert: finished adding certificate record.");
+ "CertUtil createLocalCert: finished adding certificate record.");
} catch (Exception e) {
CMS.debug(
- "NamePanel configCert: failed to add certificate record. Exception: "
+ "CertUtil createLocalCert: failed to add certificate record. Exception: "
+ e.toString());
try {
cr.deleteCertificateRecord(record.getSerialNumber());
cr.addCertificateRecord(record);
} catch (Exception ee) {
- CMS.debug("NamePanel update: Exception: " + ee.toString());
+ CMS.debug("CertUtil createLocalCert: Exception: " + ee.toString());
}
}
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
index 21aaf203b..1765ba7a6 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
@@ -2492,11 +2492,22 @@ public class ConfigurationUtils {
} catch (Exception ee) {
}
+ String sslserver_extension = "";
+ Boolean injectSAN = config.getBoolean(
+ "service.injectSAN", false);
+ CMS.debug("ConfigurationUtils: injectSAN="+injectSAN);
+ if (certTag.equals("sslserver") &&
+ injectSAN == true) {
+ sslserver_extension =
+ CertUtil.buildSANSSLserverURLExtension(config);
+ }
+
String content =
"requestor_name="
+ sysType + "-" + machineName + "-" + securePort + "&profileId=" + profileId
+ "&cert_request_type=pkcs10&cert_request=" + URLEncoder.encode(pkcs10, "UTF-8")
- + "&xmlOutput=true&sessionID=" + session_id;
+ + "&xmlOutput=true&sessionID=" + session_id
+ + sslserver_extension;
cert = CertUtil.createRemoteCert(ca_hostname, ca_port,
content, response, panel);
if (cert == null) {
diff --git a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
index 7067c24ec..12dd54dac 100644
--- a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
+++ b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
@@ -410,6 +410,16 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
cs.putString("preop.cert." + tag + ".signingalgorithm", signingalgorithm);
cs.putString("preop.cert." + tag + ".nickname", nickname);
cs.putString("preop.cert." + tag + ".dn", dn);
+
+ // support injecting SAN into server cert
+ if ( tag.equals("sslserver") && certData.getServerCertSAN() != null) {
+ CMS.debug("updateConfiguration(): san_server_cert found");
+ cs.putString("service.injectSAN", "true");
+ cs.putString("service.sslserver.san", certData.getServerCertSAN());
+ } else {
+ if ( tag.equals("sslserver"))
+ CMS.debug("SystemConfigService:processCerts(): san_server_cert not found for tag sslserver");
+ }
cs.commit(false);
if (!request.getStepTwo()) {
diff --git a/base/server/etc/default.cfg b/base/server/etc/default.cfg
index 50117a20e..3f7af5ebd 100644
--- a/base/server/etc/default.cfg
+++ b/base/server/etc/default.cfg
@@ -104,6 +104,9 @@ pki_security_domain_https_port=8443
pki_security_domain_name=%(pki_dns_domainname)s Security Domain
pki_security_domain_password=
pki_security_domain_user=caadmin
+#for supporting server cert SAN injection
+pki_san_inject=False
+pki_san_for_server_cert=
pki_skip_configuration=False
pki_skip_installation=False
pki_ssl_server_key_algorithm=SHA256withRSA
diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py
index 7f46c1f8b..884215e85 100644
--- a/base/server/python/pki/server/deployment/pkihelper.py
+++ b/base/server/python/pki/server/deployment/pkihelper.py
@@ -463,6 +463,11 @@ class ConfigurationFile:
self.mdict['pki_skip_configuration'])
self.standalone = config.str2bool(self.mdict['pki_standalone'])
self.subordinate = config.str2bool(self.mdict['pki_subordinate'])
+ # server cert san injection support
+ self.san_inject = config.str2bool(self.mdict['pki_san_inject'])
+ if self.san_inject:
+ self.confirm_data_exists('pki_san_for_server_cert')
+ self.san_for_server_cert = self.mdict['pki_san_for_server_cert']
# set useful 'string' object variables for this class
self.subsystem = self.mdict['pki_subsystem']
@@ -3637,6 +3642,7 @@ class ConfigClient:
self.add_req_ext = config.str2bool(
self.mdict['pki_req_ext_add'])
self.security_domain_type = self.mdict['pki_security_domain_type']
+ self.san_inject = config.str2bool(self.mdict['pki_san_inject'])
def configure_pki_data(self, data):
config.pki_log.info(
@@ -4335,6 +4341,9 @@ class ConfigClient:
cert.nickname = self.mdict["pki_%s_nickname" % tag]
cert.subjectDN = self.mdict["pki_%s_subject_dn" % tag]
cert.token = self.mdict["pki_%s_token" % tag]
+ if tag == 'ssl_server' and self.san_inject:
+ cert.san_for_server_cert = \
+ self.mdict['pki_san_for_server_cert']
return cert
def retrieve_existing_server_cert(self, cfg_file):
diff --git a/base/server/python/pki/server/deployment/pkiparser.py b/base/server/python/pki/server/deployment/pkiparser.py
index e37b0e4a5..e93f1717e 100644
--- a/base/server/python/pki/server/deployment/pkiparser.py
+++ b/base/server/python/pki/server/deployment/pkiparser.py
@@ -588,6 +588,9 @@ class PKIConfigParser:
if not 'pki_subordinate' in self.mdict or\
not len(self.mdict['pki_subordinate']):
self.mdict['pki_subordinate'] = "false"
+ if not 'pki_san_inject' in self.mdict or\
+ not len(self.mdict['pki_san_inject']):
+ self.mdict['pki_san_inject'] = "false"
# PKI Target (slot substitution) name/value pairs
self.mdict['pki_target_cs_cfg'] = \