diff options
author | Fraser Tweedale <ftweedal@redhat.com> | 2015-01-28 02:41:10 -0500 |
---|---|---|
committer | Fraser Tweedale <ftweedal@redhat.com> | 2015-09-26 14:11:51 +1000 |
commit | 2a9f56d02b4a284cda6f8b61b250e1494f19a83e (patch) | |
tree | 9b12125932ed41a5dbe06f8dafb66656e78c7ad8 /base/server/cms/src/com/netscape/cms/servlet | |
parent | a5a50e95a691587e22335018538b4f578dfee6d1 (diff) | |
download | pki-2a9f56d02b4a284cda6f8b61b250e1494f19a83e.tar.gz pki-2a9f56d02b4a284cda6f8b61b250e1494f19a83e.tar.xz pki-2a9f56d02b4a284cda6f8b61b250e1494f19a83e.zip |
Lightweight CAs: initial support
This commit adds initial support for "lightweight CAs" - CAs that
inhabit an existing CA instance and share the request queue and
certificate database of the "top-level CA".
We initially support only sub-CAs under the top-level CA - either
direct sub-CAs or nested. The general design will support hosting
unrelated CAs but creation or import of unrelated CAs is not yet
implemented.
Part of: https://fedorahosted.org/pki/ticket/1213
Diffstat (limited to 'base/server/cms/src/com/netscape/cms/servlet')
5 files changed, 81 insertions, 15 deletions
diff --git a/base/server/cms/src/com/netscape/cms/servlet/base/PKIService.java b/base/server/cms/src/com/netscape/cms/servlet/base/PKIService.java index 4ebf075cb..fe77fd567 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/base/PKIService.java +++ b/base/server/cms/src/com/netscape/cms/servlet/base/PKIService.java @@ -56,7 +56,10 @@ public class PKIService { public static List<MediaType> MESSAGE_FORMATS = Arrays.asList( MediaType.APPLICATION_XML_TYPE, MediaType.APPLICATION_JSON_TYPE, - MediaType.APPLICATION_FORM_URLENCODED_TYPE + MediaType.APPLICATION_FORM_URLENCODED_TYPE, + MediaType.valueOf("application/pkix-cert"), + MediaType.valueOf("application/pkcs7-mime"), + MediaType.valueOf("application/x-pem-file") ); public final static int MIN_FILTER_LENGTH = 3; diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestDAO.java b/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestDAO.java index c94ee1496..27d8b8262 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestDAO.java +++ b/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestDAO.java @@ -175,7 +175,7 @@ public class CertRequestDAO extends CMSRequestDAO { results = processor.processRenewal(data, request); } else { EnrollmentProcessor processor = new EnrollmentProcessor("caProfileSubmit", locale); - results = processor.processEnrollment(data, request); + results = processor.processEnrollment(data, request, null); } IRequest reqs[] = (IRequest[]) results.get(CAProcessor.ARG_REQUESTS); diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java index 960f997cd..e5b9a14df 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java +++ b/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java @@ -30,6 +30,8 @@ import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.EPropertyNotFound; import com.netscape.certsrv.base.SessionContext; import com.netscape.certsrv.cert.CertEnrollmentRequest; +import com.netscape.certsrv.ca.AuthorityID; +import com.netscape.certsrv.profile.IEnrollProfile; import com.netscape.certsrv.profile.IProfile; import com.netscape.certsrv.profile.IProfileAuthenticator; import com.netscape.certsrv.profile.IProfileContext; @@ -98,7 +100,7 @@ public class EnrollmentProcessor extends CertProcessor { } CertEnrollmentRequest data = CertEnrollmentRequestFactory.create(cmsReq, profile, locale); - return processEnrollment(data, cmsReq.getHttpReq()); + return processEnrollment(data, cmsReq.getHttpReq(), null); } /** @@ -118,8 +120,11 @@ public class EnrollmentProcessor extends CertProcessor { * @param cmsReq the object holding the request and response information * @exception EBaseException an error has occurred */ - public HashMap<String, Object> processEnrollment(CertEnrollmentRequest data, HttpServletRequest request) - throws EBaseException { + public HashMap<String, Object> processEnrollment( + CertEnrollmentRequest data, + HttpServletRequest request, + AuthorityID aid) + throws EBaseException { try { if (CMS.debugOn()) { @@ -146,6 +151,10 @@ public class EnrollmentProcessor extends CertProcessor { } IProfileContext ctx = profile.createContext(); + + if (aid != null) + ctx.set(IEnrollProfile.REQUEST_AUTHORITY_ID, aid.toString()); + CMS.debug("EnrollmentProcessor: set Inputs into profile Context"); setInputsIntoContext(data, profile, ctx); diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java index 2826f477e..8558ec23f 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java +++ b/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java @@ -36,6 +36,10 @@ import com.netscape.certsrv.base.BadRequestException; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.EPropertyNotFound; import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.ca.AuthorityID; +import com.netscape.certsrv.ca.CADisabledException; +import com.netscape.certsrv.ca.CANotFoundException; +import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.cert.CertReviewResponse; import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.profile.EDeferException; @@ -327,6 +331,31 @@ public class RequestProcessor extends CertProcessor { } /** + * Ensure validity of AuthorityID and that CA exists and is enabled. + */ + private void ensureCAEnabled(String aidString) throws EBaseException { + AuthorityID aid = null; + try { + aid = new AuthorityID(aidString); + } catch (IllegalArgumentException e) { + // this shouldn't happen because request was already accepted + throw new BadRequestDataException("Invalid AuthorityID in request data"); + } + ICertificateAuthority ca = (ICertificateAuthority) + CMS.getSubsystem("ca"); + if (ca == null) + // this shouldn't happen + throw new CANotFoundException("Could not get host authority"); // shouldn't happen + ca = ca.getCA(aid); + if (ca == null) + // this shouldn't happen because request was already accepted + throw new CANotFoundException("Unknown CA: " + aidString); + if (!ca.getAuthorityEnabled()) + // authority was disabled after request was accepted + throw new CADisabledException("CA '" + aidString + "' is disabled"); + } + + /** * Approve request * <P> * @@ -346,11 +375,16 @@ public class RequestProcessor extends CertProcessor { * occurred */ private void approveRequest(IRequest req, CertReviewResponse data, IProfile profile, Locale locale) - throws EProfileException { + throws EBaseException { String auditMessage = null; String auditSubjectID = auditSubjectID(); String auditRequesterID = auditRequesterID(req); + // ensure target CA is enabled + String aidString = req.getExtDataInString(IEnrollProfile.REQUEST_AUTHORITY_ID); + if (aidString != null) + ensureCAEnabled(aidString); + try { profile.execute(req); req.setRequestStatus(RequestStatus.COMPLETE); 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 36b0e4d0d..c0729d881 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 @@ -434,8 +434,19 @@ public class CertUtil { (signingKeyType.equals("dsa") && algorithm.contains("DSA"))); } + public static X509CertImpl createLocalCertWithCA(IConfigStore config, X509Key x509key, + String prefix, String certTag, String type, ICertificateAuthority ca) throws IOException { + return createLocalCert(config, x509key, prefix, certTag, type, ca, null); + } + public static X509CertImpl createLocalCert(IConfigStore config, X509Key x509key, String prefix, String certTag, String type, Context context) throws IOException { + return createLocalCert(config, x509key, prefix, certTag, type, null, context); + } + + public static X509CertImpl createLocalCert(IConfigStore config, X509Key x509key, + String prefix, String certTag, String type, + ICertificateAuthority ca, Context context) throws IOException { CMS.debug("Creating local certificate... certTag=" + certTag); String profile = null; @@ -446,13 +457,14 @@ public class CertUtil { } X509CertImpl cert = null; - ICertificateAuthority ca = null; ICertificateRepository cr = null; RequestId reqId = null; String profileId = null; IRequestQueue queue = null; IRequest req = null; + boolean caProvided = ca != null; + try { Boolean injectSAN = config.getBoolean( "service.injectSAN", false); @@ -468,7 +480,8 @@ public class CertUtil { } else { keyAlgorithm = config.getString(prefix + certTag + ".keyalgorithm"); } - ca = (ICertificateAuthority) CMS.getSubsystem( + if (!caProvided) + ca = (ICertificateAuthority) CMS.getSubsystem( ICertificateAuthority.ID); cr = ca.getCertificateRepository(); BigInteger serialNo = cr.getNextSerialNumber(); @@ -496,9 +509,9 @@ public class CertUtil { } CMS.debug("Cert Template: " + info.toString()); - String instanceRoot = config.getString("instanceRoot"); + String instanceRoot = CMS.getConfigStore().getString("instanceRoot"); - String configurationRoot = config.getString("configurationRoot"); + String configurationRoot = CMS.getConfigStore().getString("configurationRoot"); CertInfoProfile processor = new CertInfoProfile( instanceRoot + configurationRoot + profile); @@ -541,11 +554,18 @@ public class CertUtil { processor.populate(req, info); - String caPriKeyID = config.getString( - prefix + "signing" + ".privkey.id"); - byte[] keyIDb = CryptoUtil.string2byte(caPriKeyID); - PrivateKey caPrik = CryptoUtil.findPrivateKeyFromID( - keyIDb); + PrivateKey caPrik = null; + if (caProvided) { + java.security.PrivateKey pk = ca.getSigningUnit().getPrivateKey(); + if (!(pk instanceof PrivateKey)) + throw new IOException("CA Private key must be a JSS PrivateKey"); + caPrik = (PrivateKey) pk; + } else { + String caPriKeyID = config.getString( + prefix + "signing" + ".privkey.id"); + byte[] keyIDb = CryptoUtil.string2byte(caPriKeyID); + caPrik = CryptoUtil.findPrivateKeyFromID(keyIDb); + } if (caPrik == null) { CMS.debug("CertUtil::createSelfSignedCert() - " |