summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFraser Tweedale <ftweedal@redhat.com>2015-10-08 01:09:22 -0400
committerFraser Tweedale <ftweedal@redhat.com>2016-02-22 16:48:34 -0500
commitda4ca36ef5e378f55259438b4f72491d0966e5e7 (patch)
tree598d0ae41123b7d31f8f4eb9356a0c75125b5424
parent754b15db85c22903b3f9b18742ab2649fc556ad3 (diff)
downloadpki-da4ca36ef5e378f55259438b4f72491d0966e5e7.tar.gz
pki-da4ca36ef5e378f55259438b4f72491d0966e5e7.tar.xz
pki-da4ca36ef5e378f55259438b4f72491d0966e5e7.zip
Lightweight CAs: enrol cert via profile subsystem
Enrol new CA certs via the profile subsystem to ensure that the usual audit events are logged and to avoid the nasty ConfigStore hack used to generate the cert via CertUtil. This commit also fixes an issue where the new CA certificate does not have the correct Authority Key Identifier extension. Fixes: https://fedorahosted.org/pki/ticket/1624 Fixes: https://fedorahosted.org/pki/ticket/1632
-rw-r--r--base/ca/src/com/netscape/ca/CertificateAuthority.java66
-rw-r--r--base/ca/src/org/dogtagpki/server/ca/rest/AuthorityService.java5
-rw-r--r--base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java3
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/cert/CertEnrollmentRequestFactory.java15
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java15
5 files changed, 88 insertions, 16 deletions
diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java
index d2afa64f8..889e7e3f7 100644
--- a/base/ca/src/com/netscape/ca/CertificateAuthority.java
+++ b/base/ca/src/com/netscape/ca/CertificateAuthority.java
@@ -18,15 +18,18 @@
package com.netscape.ca;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.PrintStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
+import java.security.Signature;
import java.security.cert.CRLException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateParsingException;
@@ -36,6 +39,7 @@ import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import java.util.Vector;
@@ -51,6 +55,7 @@ import netscape.ldap.LDAPException;
import netscape.ldap.LDAPModification;
import netscape.ldap.LDAPModificationSet;
import netscape.ldap.LDAPSearchResults;
+import netscape.security.pkcs.PKCS10;
import netscape.security.util.DerOutputStream;
import netscape.security.util.DerValue;
import netscape.security.x509.AlgorithmId;
@@ -59,6 +64,7 @@ import netscape.security.x509.CertificateIssuerName;
import netscape.security.x509.CertificateSubjectName;
import netscape.security.x509.CertificateVersion;
import netscape.security.x509.X500Name;
+import netscape.security.x509.X500Signer;
import netscape.security.x509.X509CRLImpl;
import netscape.security.x509.X509CertImpl;
import netscape.security.x509.X509CertInfo;
@@ -83,6 +89,7 @@ import org.mozilla.jss.pkix.cert.Extension;
import org.mozilla.jss.pkix.primitive.Name;
import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
import com.netscape.certsrv.authority.ICertAuthority;
import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.EPropertyNotFound;
@@ -100,6 +107,7 @@ import com.netscape.certsrv.ca.ECAException;
import com.netscape.certsrv.ca.ICRLIssuingPoint;
import com.netscape.certsrv.ca.ICertificateAuthority;
import com.netscape.certsrv.ca.IssuerUnavailableException;
+import com.netscape.certsrv.cert.CertEnrollmentRequest;
import com.netscape.certsrv.dbs.IDBSubsystem;
import com.netscape.certsrv.dbs.certdb.ICertRecord;
import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
@@ -110,19 +118,26 @@ import com.netscape.certsrv.ldap.ILdapConnFactory;
import com.netscape.certsrv.logging.ILogger;
import com.netscape.certsrv.ocsp.IOCSPService;
import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.profile.IProfile;
import com.netscape.certsrv.publish.ICRLPublisher;
import com.netscape.certsrv.publish.IPublisherProcessor;
import com.netscape.certsrv.request.ARequestNotifier;
import com.netscape.certsrv.request.IPolicy;
+import com.netscape.certsrv.request.IRequest;
import com.netscape.certsrv.request.IRequestListener;
import com.netscape.certsrv.request.IRequestNotifier;
import com.netscape.certsrv.request.IRequestQueue;
import com.netscape.certsrv.request.IRequestScheduler;
import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.request.RequestStatus;
import com.netscape.certsrv.security.ISigningUnit;
import com.netscape.certsrv.util.IStatsSubsystem;
-import com.netscape.cms.servlet.csadmin.CertUtil;
-import com.netscape.cmscore.base.PropConfigStore;
+import com.netscape.cms.servlet.cert.EnrollmentProcessor;
+import com.netscape.cms.servlet.cert.CertEnrollmentRequestFactory;
+import com.netscape.cms.servlet.processors.CAProcessor;
+import com.netscape.cmscore.base.ArgBlock;
import com.netscape.cmscore.dbs.CRLRepository;
import com.netscape.cmscore.dbs.CertRecord;
import com.netscape.cmscore.dbs.CertificateRepository;
@@ -2376,6 +2391,7 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori
* @param description Optional string description of CA
*/
public ICertificateAuthority createCA(
+ IAuthToken authToken,
String subjectDN, AuthorityID parentAID,
String description)
throws EBaseException {
@@ -2385,7 +2401,7 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori
"Parent CA \"" + parentAID + "\" does not exist");
ICertificateAuthority ca = parentCA.createSubCA(
- subjectDN, description);
+ authToken, subjectDN, description);
caMap.put(ca.getAuthorityID(), ca);
return ca;
}
@@ -2406,6 +2422,7 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori
* caller's responsibility.
*/
public ICertificateAuthority createSubCA(
+ IAuthToken authToken,
String subjectDN, String description)
throws EBaseException {
@@ -2476,20 +2493,49 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori
PublicKey pub = keypair.getPublic();
X509Key x509key = CryptoUtil.convertPublicKeyToX509Key(pub);
+ // Create pkcs10 request
+ CMS.debug("createSubCA: creating pkcs10 request");
+ PKCS10 pkcs10 = new PKCS10(x509key);
+ Signature signature = Signature.getInstance("SHA256withRSA");
+ signature.initSign(keypair.getPrivate());
+ pkcs10.encodeAndSign(
+ new X500Signer(signature, subjectX500Name));
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ pkcs10.print(new PrintStream(out));
+ String pkcs10String = out.toString();
+
// Sign certificate
- String algName = mSigningUnit.getDefaultAlgorithm();
- IConfigStore cs = new PropConfigStore("cs");
- cs.put(".profile", "caCert.profile");
- cs.put(".dn", subjectDN);
- cs.put(".keyalgorithm", algName);
- X509CertImpl cert =
- CertUtil.createLocalCertWithCA(cs, x509key, "", "", "local", this);
+ Locale locale = Locale.getDefault();
+ String profileId = "caCACert";
+ IProfileSubsystem ps = (IProfileSubsystem)
+ CMS.getSubsystem(IProfileSubsystem.ID);
+ IProfile profile = ps.getProfile(profileId);
+ ArgBlock argBlock = new ArgBlock();
+ argBlock.set("cert_request_type", "pkcs10");
+ argBlock.set("cert_request", pkcs10String);
+ CertEnrollmentRequest certRequest =
+ CertEnrollmentRequestFactory.create(argBlock, profile, locale);
+ EnrollmentProcessor processor =
+ new EnrollmentProcessor("createSubCA", locale);
+ Map<String, Object> resultMap = processor.processEnrollment(
+ certRequest, null, authorityID, null, authToken);
+ IRequest requests[] = (IRequest[]) resultMap.get(CAProcessor.ARG_REQUESTS);
+ IRequest request = requests[0];
+ Integer result = request.getExtDataInInteger(IRequest.RESULT);
+ if (result != null && !result.equals(IRequest.RES_SUCCESS))
+ throw new EBaseException("createSubCA: certificate request submission resulted in error: " + result);
+ RequestStatus requestStatus = request.getRequestStatus();
+ if (requestStatus != RequestStatus.COMPLETE)
+ throw new EBaseException("createSubCA: certificate request did not complete; status: " + requestStatus);
// Add certificate to nssdb
+ X509CertImpl cert = request.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
cryptoManager.importCertPackage(cert.getEncoded(), nickname);
} catch (Exception e) {
// something went wrong; delete just-added entry
conn.delete(dn);
+ CMS.debug("Error creating lightweight CA certificate");
+ CMS.debug(e);
throw new ECAException("Error creating lightweight CA certificate: " + e);
}
} catch (LDAPException e) {
diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/AuthorityService.java b/base/ca/src/org/dogtagpki/server/ca/rest/AuthorityService.java
index b77788378..85203cb03 100644
--- a/base/ca/src/org/dogtagpki/server/ca/rest/AuthorityService.java
+++ b/base/ca/src/org/dogtagpki/server/ca/rest/AuthorityService.java
@@ -49,6 +49,7 @@ import com.netscape.certsrv.ca.CANotLeafException;
import com.netscape.certsrv.ca.CATypeException;
import com.netscape.certsrv.ca.ICertificateAuthority;
import com.netscape.certsrv.ca.IssuerUnavailableException;
+import com.netscape.cms.realm.PKIPrincipal;
import com.netscape.cms.servlet.base.PKIService;
import com.netscape.cmsutil.util.Utils;
@@ -179,8 +180,12 @@ public class AuthorityService extends PKIService implements AuthorityResource {
throw new BadRequestException("Bad Authority ID: " + parentAIDString);
}
+ PKIPrincipal principal =
+ (PKIPrincipal) servletRequest.getUserPrincipal();
+
try {
ICertificateAuthority subCA = hostCA.createCA(
+ principal.getAuthToken(),
data.getDN(), parentAID, data.getDescription());
return createOKResponse(readAuthorityData(subCA));
} catch (IllegalArgumentException e) {
diff --git a/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java b/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
index 96bc39229..376654e98 100644
--- a/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
+++ b/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
@@ -34,6 +34,7 @@ import netscape.security.x509.X509CertInfo;
import org.mozilla.jss.crypto.SignatureAlgorithm;
+import com.netscape.certsrv.authentication.IAuthToken;
import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.IConfigStore;
import com.netscape.certsrv.base.ISubsystem;
@@ -562,6 +563,7 @@ public interface ICertificateAuthority extends ISubsystem {
* Create a new sub-CA under the specified parent CA.
*/
public ICertificateAuthority createCA(
+ IAuthToken authToken,
String dn, AuthorityID parentAID, String desc)
throws EBaseException;
@@ -572,6 +574,7 @@ public interface ICertificateAuthority extends ISubsystem {
* caller's responsibility.
*/
public ICertificateAuthority createSubCA(
+ IAuthToken authToken,
String dn, String desc)
throws EBaseException;
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/CertEnrollmentRequestFactory.java b/base/server/cms/src/com/netscape/cms/servlet/cert/CertEnrollmentRequestFactory.java
index d74a285f3..2b608259f 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/CertEnrollmentRequestFactory.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/CertEnrollmentRequestFactory.java
@@ -37,6 +37,17 @@ public class CertEnrollmentRequestFactory {
throws EProfileException {
IArgBlock params = cmsReq.getHttpParams();
+ CertEnrollmentRequest request = create(params, profile, locale);
+
+ HttpServletRequest httpRequest = cmsReq.getHttpReq();
+ request.setRemoteHost(httpRequest.getRemoteHost());
+ request.setRemoteAddr(httpRequest.getRemoteAddr());
+
+ return request;
+ }
+
+ public static CertEnrollmentRequest create(IArgBlock params, IProfile profile, Locale locale)
+ throws EProfileException {
CertEnrollmentRequest request = new CertEnrollmentRequest();
request.setProfileId(profile.getId());
@@ -48,10 +59,6 @@ public class CertEnrollmentRequestFactory {
request.addInput(addInput);
}
- HttpServletRequest httpRequest = cmsReq.getHttpReq();
- request.setRemoteHost(httpRequest.getRemoteHost());
- request.setRemoteAddr(httpRequest.getRemoteAddr());
-
return request;
}
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 dadd34cfe..3e92d5948 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
@@ -83,6 +83,15 @@ public class EnrollmentProcessor extends CertProcessor {
}
+ public HashMap<String, Object> processEnrollment(
+ CertEnrollmentRequest data,
+ HttpServletRequest request,
+ AuthorityID aid,
+ AuthCredentials credentials)
+ throws EBaseException {
+ return processEnrollment(data, request, aid, credentials, null);
+ }
+
/**
* Process the HTTP request
* <P>
@@ -104,7 +113,8 @@ public class EnrollmentProcessor extends CertProcessor {
CertEnrollmentRequest data,
HttpServletRequest request,
AuthorityID aid,
- AuthCredentials credentials)
+ AuthCredentials credentials,
+ IAuthToken authToken)
throws EBaseException {
try {
@@ -153,7 +163,8 @@ public class EnrollmentProcessor extends CertProcessor {
CMS.debug("EnrollmentProcessor: set sslClientCertProvider");
// before creating the request, authenticate the request
- IAuthToken authToken = authenticate(request, null, authenticator, context, false, credentials);
+ if (authToken == null)
+ authToken = authenticate(request, null, authenticator, context, false, credentials);
// authentication success, now authorize
authorize(profileId, profile, authToken);