summaryrefslogtreecommitdiffstats
path: root/pki
diff options
context:
space:
mode:
authorcfu <cfu@c9f7a03b-bd48-0410-a16d-cbbf54688b0b>2008-11-18 23:39:12 +0000
committercfu <cfu@c9f7a03b-bd48-0410-a16d-cbbf54688b0b>2008-11-18 23:39:12 +0000
commitab68b8dc0a485e2b4bf505cbdea8da786a13ce41 (patch)
treeb665054fd8b4749578137f3e72998f701bef0a7a /pki
parent0e913677fe84263495a20c1fe4f47508f762a1ad (diff)
downloadpki-ab68b8dc0a485e2b4bf505cbdea8da786a13ce41.tar.gz
pki-ab68b8dc0a485e2b4bf505cbdea8da786a13ce41.tar.xz
pki-ab68b8dc0a485e2b4bf505cbdea8da786a13ce41.zip
Bugzilla Bug #471622 - Need Renewal feature via enrollment profile Framework (Phase 1)
git-svn-id: svn+ssh://svn.fedorahosted.org/svn/pki/trunk@141 c9f7a03b-bd48-0410-a16d-cbbf54688b0b
Diffstat (limited to 'pki')
-rw-r--r--pki/base/ca/shared/conf/CS.cfg11
-rw-r--r--pki/base/ca/shared/conf/registry.cfg10
-rw-r--r--pki/base/ca/shared/profiles/ca/caDirUserCert.cfg8
-rwxr-xr-xpki/base/ca/shared/profiles/ca/caDirUserRenewal.cfg12
-rwxr-xr-xpki/base/ca/shared/profiles/ca/caManualRenewal.cfg11
-rwxr-xr-xpki/base/ca/shared/profiles/ca/caSSLClientSelfRenewal.cfg9
-rw-r--r--pki/base/ca/shared/profiles/ca/caUserCert.cfg8
-rw-r--r--pki/base/common/src/UserMessages_en.properties12
-rw-r--r--pki/base/common/src/com/netscape/certsrv/profile/IProfile.java5
-rw-r--r--pki/base/common/src/com/netscape/cms/authentication/SSLclientCertAuthentication.java353
-rw-r--r--pki/base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java1
-rw-r--r--pki/base/common/src/com/netscape/cms/evaluators/UserAccessEvaluator.java1
-rw-r--r--pki/base/common/src/com/netscape/cms/evaluators/UserOrigReqAccessEvaluator.java171
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/common/BasicProfile.java12
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java2
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java158
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/constraint/SubjectNameConstraint.java8
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/AuthTokenSubjectNameDefault.java8
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/SubjectNameDefault.java5
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/input/SerialNumRenewInput.java94
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSelectServlet.java1
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/profile/ProfileServlet.java2
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java552
-rw-r--r--pki/linux/ca-ui/pki-ca-ui.spec4
-rw-r--r--pki/linux/ca-ui/shared/webapps/ca/ee/ca/ProfileSelect.template2
-rw-r--r--pki/linux/ca/pki-ca.spec4
-rw-r--r--pki/linux/common/pki-common.spec4
27 files changed, 1446 insertions, 22 deletions
diff --git a/pki/base/ca/shared/conf/CS.cfg b/pki/base/ca/shared/conf/CS.cfg
index b552a6b29..7d8fd4140 100644
--- a/pki/base/ca/shared/conf/CS.cfg
+++ b/pki/base/ca/shared/conf/CS.cfg
@@ -106,6 +106,7 @@ CrossCertPair.ldap=internaldb
accessEvaluator.impl.group.class=com.netscape.cms.evaluators.GroupAccessEvaluator
accessEvaluator.impl.ipaddress.class=com.netscape.cms.evaluators.IPAddressAccessEvaluator
accessEvaluator.impl.user.class=com.netscape.cms.evaluators.UserAccessEvaluator
+accessEvaluator.impl.user_origreq.class=com.netscape.cms.evaluators.UserOrigReqAccessEvaluator
auths._000=##
auths._001=## new authentication
auths._002=##
@@ -116,6 +117,7 @@ auths.impl.AgentCertAuth.class=com.netscape.cms.authentication.AgentCertAuthenti
auths.impl.CMCAuth.class=com.netscape.cms.authentication.CMCAuth
auths.impl.NISAuth.class=com.netscape.cms.authentication.NISAuth
auths.impl.PortalEnroll.class=com.netscape.cms.authentication.PortalEnroll
+auths.impl.SSLclientCertAuth.class=com.netscape.cms.authentication.SSLclientCertAuthentication
auths.impl.UdnPwdDirAuth.class=com.netscape.cms.authentication.UdnPwdDirAuthentication
auths.impl.UidPwdDirAuth.class=com.netscape.cms.authentication.UidPwdDirAuthentication
auths.impl.UidPwdPinDirAuth.class=com.netscape.cms.authentication.UidPwdPinDirAuthentication
@@ -129,6 +131,7 @@ auths.instance.raCertAuth.agentGroup=Registration Manager Agents
auths.instance.raCertAuth.pluginName=AgentCertAuth
auths.instance.flatFileAuth.pluginName=FlatFileAuth
auths.instance.flatFileAuth.fileName=[PKI_INSTANCE_PATH]/conf/flatfile.txt
+auths.instance.SSLclientCertAuth.pluginName=SSLclientCertAuth
auths.revocationChecking.bufferSize=50
auths.revocationChecking.ca=ca
auths.revocationChecking.enabled=true
@@ -796,9 +799,15 @@ oidmap.pse.oid=2.16.840.1.113730.1.18
oidmap.subject_info_access.class=netscape.security.extensions.SubjectInfoAccessExtension
oidmap.subject_info_access.oid=1.3.6.1.5.5.7.1.11
os.userid=nobody
-profile.list=caUserCert,caDualCert,caSignedLogCert,caTPSCert,caRARouterCert,caRouterCert,caServerCert,caOtherCert,caCACert,caInstallCACert,caRACert,caOCSPCert,caTransportCert,caDirUserCert,caAgentServerCert,caAgentFileSigning,caCMCUserCert,caFullCMCUserCert,caSimpleCMCUserCert,caTokenDeviceKeyEnrollment,caTokenUserEncryptionKeyEnrollment,caTokenUserSigningKeyEnrollment,caTempTokenDeviceKeyEnrollment,caTempTokenUserEncryptionKeyEnrollment,caTempTokenUserSigningKeyEnrollment,caAdminCert,caInternalAuthServerCert,caInternalAuthTransportCert,caInternalAuthDRMstorageCert,caInternalAuthSubsystemCert,caInternalAuthOCSPCert,DomainController,caDualRAuserCert,caRAagentCert,caRAserverCert,caUUIDdeviceCert
+profile.list=caUserCert,caDualCert,caSignedLogCert,caTPSCert,caRARouterCert,caRouterCert,caServerCert,caOtherCert,caCACert,caInstallCACert,caRACert,caOCSPCert,caTransportCert,caDirUserCert,caAgentServerCert,caAgentFileSigning,caCMCUserCert,caFullCMCUserCert,caSimpleCMCUserCert,caTokenDeviceKeyEnrollment,caTokenUserEncryptionKeyEnrollment,caTokenUserSigningKeyEnrollment,caTempTokenDeviceKeyEnrollment,caTempTokenUserEncryptionKeyEnrollment,caTempTokenUserSigningKeyEnrollment,caAdminCert,caInternalAuthServerCert,caInternalAuthTransportCert,caInternalAuthDRMstorageCert,caInternalAuthSubsystemCert,caInternalAuthOCSPCert,DomainController,caDualRAuserCert,caRAagentCert,caRAserverCert,caUUIDdeviceCert,caSSLClientSelfRenewal,caDirUserRenewal,caManualRenewal
profile.caUUIDdeviceCert.class_id=caEnrollImpl
profile.caUUIDdeviceCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caUUIDdeviceCert.cfg
+profile.caManualRenewal.class_id=caEnrollImpl
+profile.caManualRenewal.config=[PKI_INSTANCE_PATH]/profiles/ca/caManualRenewal.cfg
+profile.caDirUserRenewal.class_id=caEnrollImpl
+profile.caDirUserRenewal.config=[PKI_INSTANCE_PATH]/profiles/ca/caDirUserRenewal.cfg
+profile.caSSLClientSelfRenewal.class_id=caEnrollImpl
+profile.caSSLClientSelfRenewal.config=[PKI_INSTANCE_PATH]/profiles/ca/caSSLClientSelfRenewal.cfg
profile.DomainController.class_id=caEnrollImpl
profile.DomainController.config=[PKI_INSTANCE_PATH]/profiles/ca/DomainController.cfg
profile.caAgentFileSigning.class_id=caEnrollImpl
diff --git a/pki/base/ca/shared/conf/registry.cfg b/pki/base/ca/shared/conf/registry.cfg
index 807ebdd4d..5cb40faba 100644
--- a/pki/base/ca/shared/conf/registry.cfg
+++ b/pki/base/ca/shared/conf/registry.cfg
@@ -1,5 +1,5 @@
types=profile,defaultPolicy,constraintPolicy,profileInput,profileOutput,profileUpdater
-constraintPolicy.ids=noConstraintImpl,subjectNameConstraintImpl,uniqueSubjectNameConstraintImpl,validityConstraintImpl,keyUsageExtConstraintImpl,nsCertTypeExtConstraintImpl,extendedKeyUsageExtConstraintImpl,keyConstraintImpl,basicConstraintsExtConstraintImpl,extensionConstraintImpl,signingAlgConstraintImpl,uniqueKeyConstraintImpl
+constraintPolicy.ids=noConstraintImpl,subjectNameConstraintImpl,uniqueSubjectNameConstraintImpl,validityConstraintImpl,keyUsageExtConstraintImpl,nsCertTypeExtConstraintImpl,extendedKeyUsageExtConstraintImpl,keyConstraintImpl,basicConstraintsExtConstraintImpl,extensionConstraintImpl,signingAlgConstraintImpl,uniqueKeyConstraintImpl,renewGracePeriodConstraintImpl
constraintPolicy.signingAlgConstraintImpl.class=com.netscape.cms.profile.constraint.SigningAlgConstraint
constraintPolicy.signingAlgConstraintImpl.desc=Signing Algorithm Constraint
constraintPolicy.signingAlgConstraintImpl.name=Signing Algorithm Constraint
@@ -33,6 +33,9 @@ constraintPolicy.uniqueSubjectNameConstraintImpl.name=Unique Subject Name Constr
constraintPolicy.validityConstraintImpl.class=com.netscape.cms.profile.constraint.ValidityConstraint
constraintPolicy.validityConstraintImpl.desc=Validity Constraint
constraintPolicy.validityConstraintImpl.name=Validity Constraint
+constraintPolicy.renewGracePeriodConstraintImpl.class=com.netscape.cms.profile.constraint.RenewGracePeriodConstraint
+constraintPolicy.renewGracePeriodConstraintImpl.desc=Renewal Grace Period Constraint
+constraintPolicy.renewGracePeriodConstraintImpl.name=Renewal Grace Period Constraint
constraintPolicy.uniqueKeyConstraintImpl.class=com.netscape.cms.profile.constraint.UniqueKeyConstraint
constraintPolicy.uniqueKeyConstraintImpl.desc=Unique Public Key Constraint
constraintPolicy.uniqueKeyConstraintImpl.name=Unique Public Key Constraint
@@ -161,7 +164,7 @@ profile.caServerCertEnrollImpl.name=Server Certificate Enrollment Profile
profile.caUserCertEnrollImpl.class=com.netscape.cms.profile.common.UserCertCAEnrollProfile
profile.caUserCertEnrollImpl.desc=Certificate Authority User Certificate Enrollment Profile
profile.caUserCertEnrollImpl.name=User Certificate Enrollment Profile
-profileInput.ids=cmcCertReqInputImpl,certReqInputImpl,keyGenInputImpl,dualKeyGenInputImpl,subjectNameInputImpl,submitterInfoInputImpl,genericInputImpl,fileSigningInputImpl,imageInputImpl,subjectDNInputImpl,nsNKeyCertReqInputImpl,nsHKeyCertReqInputImpl
+profileInput.ids=cmcCertReqInputImpl,certReqInputImpl,keyGenInputImpl,dualKeyGenInputImpl,subjectNameInputImpl,submitterInfoInputImpl,genericInputImpl,fileSigningInputImpl,imageInputImpl,subjectDNInputImpl,nsNKeyCertReqInputImpl,nsHKeyCertReqInputImpl,serialNumRenewInputImpl
profileInput.fileSigningInputImpl.class=com.netscape.cms.profile.input.FileSigningInput
profileInput.fileSigningInputImpl.desc=File Signing Input
profileInput.fileSigningInputImpl.name=File Signing Input
@@ -192,6 +195,9 @@ profileInput.nsNKeyCertReqInputImpl.name=nsNKeyCertReqInputImpl
profileInput.nsHKeyCertReqInputImpl.class=com.netscape.cms.profile.input.nsHKeyCertReqInput
profileInput.nsHKeyCertReqInputImpl.desc=nsHKeyCertReqInputImpl
profileInput.nsHKeyCertReqInputImpl.name=nsHKeyCertReqInputImpl
+profileInput.serialNumRenewInputImpl.class=com.netscape.cms.profile.input.SerialNumRenewInput
+profileInput.serialNumRenewInputImpl.desc=Certificate Renewal Request Serial Number Input
+profileInput.serialNumRenewInputImpl.name=Certificate Renewal Request Serial Number Input
profileInput.subjectDNInputImpl.class=com.netscape.cms.profile.input.SubjectDNInput
profileInput.subjectDNInputImpl.desc=Subject DN Input
profileInput.subjectDNInputImpl.name=Subject DN Input
diff --git a/pki/base/ca/shared/profiles/ca/caDirUserCert.cfg b/pki/base/ca/shared/profiles/ca/caDirUserCert.cfg
index 3806d0b21..693f3dc9e 100644
--- a/pki/base/ca/shared/profiles/ca/caDirUserCert.cfg
+++ b/pki/base/ca/shared/profiles/ca/caDirUserCert.cfg
@@ -9,7 +9,7 @@ input.i1.class_id=keyGenInputImpl
output.list=o1
output.o1.class_id=certOutputImpl
policyset.list=userCertSet
-policyset.userCertSet.list=1,2,3,4,5,6,7,8,9
+policyset.userCertSet.list=1,10,2,3,4,5,6,7,8,9
policyset.userCertSet.1.constraint.class_id=subjectNameConstraintImpl
policyset.userCertSet.1.constraint.name=Subject Name Constraint
policyset.userCertSet.1.constraint.params.pattern=UID=.*
@@ -17,6 +17,12 @@ policyset.userCertSet.1.constraint.params.accept=true
policyset.userCertSet.1.default.class_id=authTokenSubjectNameDefaultImpl
policyset.userCertSet.1.default.name=Subject Name Default
policyset.userCertSet.1.default.params.name=
+policyset.userCertSet.10.constraint.class_id=renewGracePeriodConstraintImpl
+policyset.userCertSet.10.constraint.name=Renewal Grace Period Constraint
+policyset.userCertSet.10.constraint.params.renewal.graceBefore=30
+policyset.userCertSet.10.constraint.params.renewal.graceAfter=30
+policyset.userCertSet.10.default.class_id=noDefaultImpl
+policyset.userCertSet.10.default.name=No Default
policyset.userCertSet.2.constraint.class_id=validityConstraintImpl
policyset.userCertSet.2.constraint.name=Validity Constraint
policyset.userCertSet.2.constraint.params.range=365
diff --git a/pki/base/ca/shared/profiles/ca/caDirUserRenewal.cfg b/pki/base/ca/shared/profiles/ca/caDirUserRenewal.cfg
new file mode 100755
index 000000000..f0ec21388
--- /dev/null
+++ b/pki/base/ca/shared/profiles/ca/caDirUserRenewal.cfg
@@ -0,0 +1,12 @@
+desc=This certificate profile is for renewing a certificate by serial number by using directory based authentication.
+visible=true
+enable=true
+enableBy=admin
+renewal=true
+auth.instance_id=UserDirEnrollment
+authz.acl=user_origreq="auth_token.uid"
+name=Directory-Authenticated User Certificate Self-Renew profile
+input.list=i1
+input.i1.class_id=serialNumRenewInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
diff --git a/pki/base/ca/shared/profiles/ca/caManualRenewal.cfg b/pki/base/ca/shared/profiles/ca/caManualRenewal.cfg
new file mode 100755
index 000000000..b691b4d10
--- /dev/null
+++ b/pki/base/ca/shared/profiles/ca/caManualRenewal.cfg
@@ -0,0 +1,11 @@
+desc=This certificate profile is for renewing certificates to be approved manually by agents.
+visible=true
+enable=true
+enableBy=admin
+renewal=true
+auth.instance_id=
+name=Renew certificate to be manually approved by agents
+input.list=i1
+input.i1.class_id=serialNumRenewInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
diff --git a/pki/base/ca/shared/profiles/ca/caSSLClientSelfRenewal.cfg b/pki/base/ca/shared/profiles/ca/caSSLClientSelfRenewal.cfg
new file mode 100755
index 000000000..f89c1b143
--- /dev/null
+++ b/pki/base/ca/shared/profiles/ca/caSSLClientSelfRenewal.cfg
@@ -0,0 +1,9 @@
+desc=This certificate profile is for renewing SSL client certificates.
+visible=true
+enable=true
+enableBy=admin
+renewal=true
+auth.instance_id=SSLclientCertAuth
+name=Self-renew user SSL client certificates
+output.list=o1
+output.o1.class_id=certOutputImpl
diff --git a/pki/base/ca/shared/profiles/ca/caUserCert.cfg b/pki/base/ca/shared/profiles/ca/caUserCert.cfg
index bd5932a76..56780ac62 100644
--- a/pki/base/ca/shared/profiles/ca/caUserCert.cfg
+++ b/pki/base/ca/shared/profiles/ca/caUserCert.cfg
@@ -11,7 +11,7 @@ input.i3.class_id=submitterInfoInputImpl
output.list=o1
output.o1.class_id=certOutputImpl
policyset.list=userCertSet
-policyset.userCertSet.list=1,2,3,4,5,6,7,8,9
+policyset.userCertSet.list=1,10,2,3,4,5,6,7,8,9
policyset.userCertSet.1.constraint.class_id=subjectNameConstraintImpl
policyset.userCertSet.1.constraint.name=Subject Name Constraint
policyset.userCertSet.1.constraint.params.pattern=UID=.*
@@ -19,6 +19,12 @@ policyset.userCertSet.1.constraint.params.accept=true
policyset.userCertSet.1.default.class_id=userSubjectNameDefaultImpl
policyset.userCertSet.1.default.name=Subject Name Default
policyset.userCertSet.1.default.params.name=
+policyset.userCertSet.10.constraint.class_id=renewGracePeriodConstraintImpl
+policyset.userCertSet.10.constraint.name=Renewal Grace Period Constraint
+policyset.userCertSet.10.constraint.params.renewal.graceBefore=30
+policyset.userCertSet.10.constraint.params.renewal.graceAfter=30
+policyset.userCertSet.10.default.class_id=noDefaultImpl
+policyset.userCertSet.10.default.name=No Default
policyset.userCertSet.2.constraint.class_id=validityConstraintImpl
policyset.userCertSet.2.constraint.name=Validity Constraint
policyset.userCertSet.2.constraint.params.range=365
diff --git a/pki/base/common/src/UserMessages_en.properties b/pki/base/common/src/UserMessages_en.properties
index 1ea7ebd88..e0081fb06 100644
--- a/pki/base/common/src/UserMessages_en.properties
+++ b/pki/base/common/src/UserMessages_en.properties
@@ -305,6 +305,8 @@ CMS_AUTHENTICATION_NIS_NAME=NIS Authentication
CMS_AUTHENTICATION_NIS_TEXT=This plugin authenticates a user using NIS.
CMS_AUTHENTICATION_AGENT_NAME=Agent Authentication
CMS_AUTHENTICATION_AGENT_TEXT=This plugin authenticates agents using a certificate.
+CMS_AUTHENTICATION_SSL_CLIENT_NAME=SSL Client Authentication
+CMS_AUTHENTICATION_SSL_CLIENT_TEXT=This plugin authenticates users using a certificate.
CMS_AUTHENTICATION_CMC_SIGN_NAME=CMC Agent Signature Authentication
CMS_AUTHENTICATION_CMC_SIGN_TEXT=This plugin authenticates the signature in the CMC request against the CS internal database.
CMS_AUTHENTICATION_LDAP_UID_PIN_NAME=LDAP UID & Password & Pin Authentication
@@ -819,6 +821,10 @@ CMS_PROFILE_VALIDITY_CHECK_NOT_AFTER=Check Not After against Not Before
CMS_PROFILE_VALIDITY_RANGE=Validity Range (in days)
CMS_PROFILE_VALIDITY_START_TIME=Relative Start Time (in seconds)
CMS_PROFILE_VALIDITY_OUT_OF_RANGE=Validity Out of Range {0} days
+CMS_PROFILE_RENEW_GRACE_BEFORE=Renewal Grace Period Before
+CMS_PROFILE_RENEW_GRACE_AFTER=Renewal Grace Period After
+CMS_PROFILE_RENEW_OUTSIDE_GRACE_PERIOD=Outside of Renewal Grace Period: {0}
+CMS_PROFILE_RENEW_ORIG_EXP_NOT_FOUND=Renewal: Original Cert Expiration Date Not Found. Cannot validate.
CMS_PROFILE_INVALID_VALIDITY=Invalid Validity
CMS_PROFILE_NOT_BEFORE_BEFORE_CURRENT=Not Before is earlier than current time
CMS_PROFILE_NOT_AFTER_BEFORE_NOT_BEFORE=Not After is earlier than Not Before
@@ -915,7 +921,9 @@ CMS_PROFILE_CONSTRAINT_NO_CONSTRAINT_TEXT=No Constraint
CMS_PROFILE_CONSTRAINT_SIGNING_ALG_TEXT=This constraint accepts only the Signing Algorithms of {0}
CMS_PROFILE_CONSTRAINT_SUBJECT_NAME_TEXT=This constraint accepts the subject name that matches {0}
CMS_PROFILE_CONSTRAINT_UNIQUE_SUBJECT_NAME_TEXT=This constraint accepts unique subject name only
-CMS_PROFILE_CONSTRAINT_VALIDITY_TEXT=This constraint rejects the validity that is not between {0} days
+CMS_PROFILE_CONSTRAINT_VALIDITY_TEXT=This constraint rejects the validity that is not between {0} days.
+CMS_PROFILE_CONSTRAINT_RENEWAL_GRACE_PERIOD_TEXT=This constraint rejects the renewal requests that are outside of the grace period {0}
+CMS_PROFILE_CONSTRAINT_VALIDITY_RENEWAL_TEXT=This constraint rejects the validity that is not between {0} days. If renewal, grace period is {1} days before and {2} days after the expiration date of the original certificate.
CMS_PROFILE_DEF_SIA_TEXT=This default populates a Subject Info Access Extension (1.3.6.1.5.5.7.1.11) to the request. The default values are Criticality={0}, {1}
CMS_PROFILE_DEF_AIA_TEXT=This default populates a Authority Info Access Extension (1.3.6.1.5.5.7.1.1) to the request. The default values are Criticality={0}, {1}
CMS_PROFILE_DEF_IMAGE=This default populates the image from the user.
@@ -999,6 +1007,8 @@ CMS_PROFILE_IMAGE=Image
CMS_PROFILE_INPUT_IMAGE_NAME=Image
CMS_PROFILE_INPUT_IMAGE_TEXT=Image
CMS_PROFILE_INPUT_IMAGE_URL=Image URL
+CMS_PROFILE_INPUT_SERIAL_NUM_NAME=Serial Number of Certificate to Renew
+CMS_PROFILE_INPUT_SERIAL_NUM_TEXT=Serial Number of Certificate to Renew
CMS_PROFILE_INPUT_SUBMITTER_NAME=Requestor Information
CMS_PROFILE_INPUT_SUBMITTER_TEXT=Requestor Information
CMS_PROFILE_INPUT_GENERIC_NAME_NAME=Generic Input
diff --git a/pki/base/common/src/com/netscape/certsrv/profile/IProfile.java b/pki/base/common/src/com/netscape/certsrv/profile/IProfile.java
index 1c643a3df..c8ca1472f 100644
--- a/pki/base/common/src/com/netscape/certsrv/profile/IProfile.java
+++ b/pki/base/common/src/com/netscape/certsrv/profile/IProfile.java
@@ -184,6 +184,11 @@ public interface IProfile {
*/
public String getApprovedBy();
+ /*
+ * Is this a renewal profile
+ */
+ public String isRenewal();
+
/**
* Returns the profile name.
*
diff --git a/pki/base/common/src/com/netscape/cms/authentication/SSLclientCertAuthentication.java b/pki/base/common/src/com/netscape/cms/authentication/SSLclientCertAuthentication.java
new file mode 100644
index 000000000..7a3993cde
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/authentication/SSLclientCertAuthentication.java
@@ -0,0 +1,353 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2008 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.authentication;
+
+
+import netscape.ldap.*;
+import java.util.*;
+import java.lang.Class;
+import java.security.cert.*;
+import java.security.Principal;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.policy.*;
+
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.kra.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+
+/**
+ * Certificate server SSL client authentication.
+ *
+ * @author Christina Fu
+ * <P>
+ *
+ */
+public class SSLclientCertAuthentication implements IAuthManager,
+ IProfileAuthenticator {
+
+ /* result auth token attributes */
+ public static final String TOKEN_USERDN = "user";
+ public static final String TOKEN_USER_DN = "userdn";
+ public static final String TOKEN_USERID = "userid";
+ public static final String TOKEN_UID = "uid";
+
+ /* required credentials */
+ public static final String CRED_CERT = IAuthManager.CRED_SSL_CLIENT_CERT;
+ protected String[] mRequiredCreds = { CRED_CERT };
+
+ /* config parameters to pass to console (none) */
+ protected static String[] mConfigParams = null;
+
+ private String mName = null;
+ private String mImplName = null;
+ private IConfigStore mConfig = null;
+
+ private ILogger mLogger = CMS.getLogger();
+
+ private IConfigStore mRevocationChecking = null;
+ private String mRequestor = null;
+
+ public SSLclientCertAuthentication() {
+ }
+
+ /**
+ * initializes the SSLClientCertAuthentication auth manager
+ * <p>
+ * called by AuthSubsystem init() method, when initializing
+ * all available authentication managers.
+ * @param name The name of this authentication manager instance.
+ * @param implName The name of the authentication manager plugin.
+ * @param config The configuration store for this authentication manager.
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ mName = name;
+ mImplName = implName;
+ mConfig = config;
+ }
+
+ /**
+ * Gets the name of this authentication manager.
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Gets the plugin name of authentication manager.
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ public boolean isSSLClientRequired() {
+ return true;
+ }
+
+ /**
+ * authenticates user by certificate
+ * <p>
+ * called by other subsystems or their servlets to authenticate
+ * users
+ * @param authCred - authentication credential that contains
+ * an usrgrp.Certificates of the user (agent)
+ * @return the authentication token that contains the following
+ *
+ * @exception EMissingCredential If a required credential for this
+ * authentication manager is missing.
+ * @exception EInvalidCredentials If credentials cannot be authenticated.
+ * @exception EBaseException If an internal error occurred.
+ * @see com.netscape.certsrv.authentication.AuthToken
+ * @see com.netscape.certsrv.usrgrp.Certificates
+ */
+ public IAuthToken authenticate(IAuthCredentials authCred)
+ throws EMissingCredential, EInvalidCredentials, EBaseException {
+
+ CMS.debug("SSLclientCertAuthentication: start");
+ CMS.debug("authenticator instance name is "+getName());
+
+ // force SSL handshake
+ SessionContext context = SessionContext.getExistingContext();
+ ISSLClientCertProvider provider = (ISSLClientCertProvider)
+ context.get("sslClientCertProvider");
+
+ if (provider == null) {
+ CMS.debug("SSLclientCertAuthentication: No SSL Client Cert Provider Found");
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ CMS.debug("SSLclientCertAuthentication: got provider");
+ CMS.debug("SSLclientCertAuthentication: retrieving client certificate");
+ X509Certificate[] allCerts = provider.getClientCertificateChain();
+
+ if (allCerts == null) {
+ CMS.debug("SSLclientCertAuthentication: No SSL Client Certs Found");
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ CMS.debug("SSLclientCertAuthentication: got certificates");
+
+ // retreive certificate from socket
+ AuthToken authToken = new AuthToken(this);
+ X509Certificate[] x509Certs = allCerts;
+
+ // default certificate default has bugs in version
+ // version(3) is returned as 3, which should be 2
+ X509CertImpl ci[] = new X509CertImpl[x509Certs.length];
+
+ X509Certificate clientCert = null;
+ try {
+ for (int i = 0; i < x509Certs.length; i++) {
+ ci[i] = new X509CertImpl(x509Certs[i].getEncoded());
+ // find out which one is the leaf cert
+ clientCert = ci[i];
+
+ byte [] extBytes = clientCert.getExtensionValue("2.5.29.19");
+ // try to see if this is a leaf cert
+ // look for BasicConstraint extension
+ if (extBytes == null) {
+ // found leaf cert
+ CMS.debug("SSLclientCertAuthentication: authenticate: found leaf cert");
+ break;
+ } else {
+ CMS.debug("SSLclientCertAuthentication: authenticate: found cert having BasicConstraints ext");
+ // it's got BasicConstraints extension
+ // so it's not likely to be a leaf cert,
+ // however, check the isCA field regardless
+ try {
+ BasicConstraintsExtension bce =
+ new BasicConstraintsExtension(true, extBytes);
+ if (bce != null) {
+ if (!(Boolean)bce.get("is_ca")) {
+ CMS.debug("SSLclientCertAuthentication: authenticate: found CA cert in chain");
+ break;
+ } // else found a ca cert, continue
+ }
+ } catch (Exception e) {
+ CMS.debug("SSLclientCertAuthentication: authenticate: exception:"+
+ e.toString());
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ }
+ }
+ if (clientCert == null) {
+ CMS.debug("SSLclientCertAuthentication: authenticate: client cert not found");
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ } catch (CertificateException e) {
+ CMS.debug(e.toString());
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // check if certificate(s) is revoked
+ boolean checkRevocation = true;
+ try {
+ checkRevocation = mConfig.getBoolean("checkRevocation", true);
+ } catch (EBaseException e) {
+ // do nothing; default to true
+ }
+ if (checkRevocation) {
+ if (CMS.isRevoked(ci)) {
+ CMS.debug("SSLclientCertAuthentication: certificate revoked");
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+ }
+ Certificates certs = new Certificates(ci);
+ Principal p_dn = clientCert.getSubjectDN();
+ authToken.set(TOKEN_USERDN, p_dn.getName());
+ authToken.set("userdn", p_dn.getName());
+ String uid = getUidFromDN(p_dn.getName());
+ if (uid != null) {
+ authToken.set(TOKEN_UID, uid);
+ authToken.set(TOKEN_USERID, uid);
+ }
+/*
+ authToken.set(TOKEN_USER_DN, user.getUserDN());
+ authToken.set(TOKEN_USERID, user.getUserID());
+ authToken.set(TOKEN_UID, user.getUserID());
+ authToken.set(TOKEN_GROUP, groupname);
+*/
+ authToken.set(CRED_CERT, certs);
+
+ CMS.debug("SSLclientCertAuthentication: authenticated ");
+
+ return authToken;
+ }
+
+ String getUidFromDN(String userdn) {
+ StringTokenizer st = new StringTokenizer(userdn, ",");
+ while (st.hasMoreTokens()) {
+ String t = st.nextToken();
+ int i = t.indexOf("=");
+
+ if (i == -1) {
+ continue;
+ }
+ String n = t.substring(0, i);
+ if (n.equalsIgnoreCase("uid")) {
+ String v = t.substring(i + 1);
+ CMS.debug("SSLclientCertAuthentication: getUidFromDN(): uid found:"+v);
+ return v;
+ } else {
+ continue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * get the list of authentication credential attribute names
+ * required by this authentication manager. Generally used by
+ * the servlets that handle agent operations to authenticate its
+ * users. It calls this method to know which are the
+ * required credentials from the user (e.g. Javascript form data)
+ * @return attribute names in Vector
+ */
+ public String[] getRequiredCreds() {
+ return (mRequiredCreds);
+ }
+
+ /**
+ * get the list of configuration parameter names
+ * required by this authentication manager. Generally used by
+ * the Certificate Server Console to display the table for
+ * configuration purposes. CertUserDBAuthentication is currently not
+ * exposed in this case, so this method is not to be used.
+ * @return configuration parameter names in Hashtable of Vectors
+ * where each hashtable entry's key is the substore name, value is a
+ * Vector of parameter names. If no substore, the parameter name
+ * is the Hashtable key itself, with value same as key.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+
+ /**
+ * prepare this authentication manager for shutdown.
+ */
+ public void shutdown() {
+ }
+
+ /**
+ * gets the configuretion substore used by this authentication
+ * manager
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ // Profile-related methods
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ }
+
+ /**
+ * Retrieves the localizable name of this policy.
+ */
+ public String getName(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_AUTHENTICATION_SSL_CLIENT_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_AUTHENTICATION_SSL_CLIENT_TEXT");
+ }
+
+ /**
+ * Retrieves a list of names of the value parameter.
+ */
+ public Enumeration getValueNames() {
+ return null;
+ }
+
+ public boolean isValueWriteable(String name) {
+ return false;
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public void populate(IAuthToken token, IRequest request)
+ throws EProfileException {
+ request.setExtData(IProfileAuthenticator.AUTHENTICATED_NAME,
+ token.getInString(TOKEN_USERDN));
+ request.setExtData(IProfileAuthenticator.AUTHENTICATED_NAME,
+ token.getInString("userDN"));
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java b/pki/base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java
index d153dd88f..dc42b6fb1 100644
--- a/pki/base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java
+++ b/pki/base/common/src/com/netscape/cms/evaluators/GroupAccessEvaluator.java
@@ -58,6 +58,7 @@ public class GroupAccessEvaluator implements IAccessEvaluator {
* initialization. nothing for now.
*/
public void init() {
+ CMS.debug("GroupAccessEvaluator: init");
}
/**
diff --git a/pki/base/common/src/com/netscape/cms/evaluators/UserAccessEvaluator.java b/pki/base/common/src/com/netscape/cms/evaluators/UserAccessEvaluator.java
index 0885f66b6..37be1e624 100644
--- a/pki/base/common/src/com/netscape/cms/evaluators/UserAccessEvaluator.java
+++ b/pki/base/common/src/com/netscape/cms/evaluators/UserAccessEvaluator.java
@@ -53,6 +53,7 @@ public class UserAccessEvaluator implements IAccessEvaluator {
* initialization. nothing for now.
*/
public void init() {
+ CMS.debug("UserAccessEvaluator: init");
}
/**
diff --git a/pki/base/common/src/com/netscape/cms/evaluators/UserOrigReqAccessEvaluator.java b/pki/base/common/src/com/netscape/cms/evaluators/UserOrigReqAccessEvaluator.java
new file mode 100644
index 000000000..16b59b59b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/evaluators/UserOrigReqAccessEvaluator.java
@@ -0,0 +1,171 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2008 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.evaluators;
+
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.evaluators.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.acls.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.cmsutil.util.*;
+
+
+/**
+ * A class represents a user-origreq uid mapping acls evaluator.
+ * This is primarily used for renewal. During renewal, the orig_req
+ * uid is placed in the SessionContext of the renewal session context
+ * to be evaluated by this evaluator
+ * <P>
+ *
+ * @author Christina Fu
+ * @version $Revision: $, $Date:
+ */
+public class UserOrigReqAccessEvaluator implements IAccessEvaluator {
+ private String mType = "user_origreq";
+ private String mDescription = "user origreq matching evaluator";
+ private ILogger mLogger = CMS.getLogger();
+
+ private final static String ANYBODY = "anybody";
+ private final static String EVERYBODY = "everybody";
+
+ /**
+ * Class constructor.
+ */
+ public UserOrigReqAccessEvaluator() {
+ }
+
+ /**
+ * initialization. nothing for now.
+ */
+ public void init() {
+ CMS.debug("UserOrigReqAccessEvaluator: init");
+ }
+
+ /**
+ * gets the type name for this acl evaluator
+ * @return type for this acl evaluator: "user_origreq" or "at_user_origreq"
+ */
+ public String getType() {
+ return mType;
+ }
+
+ /**
+ * gets the description for this acl evaluator
+ * @return description for this acl evaluator
+ */
+ public String getDescription() {
+ return mDescription;
+ }
+
+ public String[] getSupportedOperators() {
+ String[] s = new String[2];
+
+ s[0] = "=";
+ s[1] = "!=";
+ return s;
+ }
+
+ /**
+ * Evaluates the user in AuthToken to see if it's equal to value
+ * @param authToken AuthToken from authentication
+ * @param type must be "at_userreq"
+ * @param op must be "="
+ * @param value the request param name
+ * @return true if AuthToken uid is same as value, false otherwise
+ */
+ public boolean evaluate(IAuthToken authToken, String type, String op, String value) {
+ CMS.debug("UserOrigReqAccessEvaluator: evaluate() begins");
+ if (type.equals(mType)) {
+ String s = Utils.stripQuotes(value);
+
+ if ((s.equals(ANYBODY) || s.equals(EVERYBODY)) && op.equals("="))
+ return true;
+
+ // should define "uid" at a common place
+ String uid = null;
+
+ uid = authToken.getInString("uid");
+
+ if (uid == null) {
+ CMS.debug("UserOrigReqAccessEvaluator: evaluate() uid in authtoken null");
+ return false;
+ } else
+ CMS.debug("UserOrigReqAccessEvaluator: evaluate() uid in authtoken ="+ uid);
+
+ // find value of param in request
+ SessionContext mSC = SessionContext.getContext();
+ CMS.debug("UserOrigReqAccessEvaluator: evaluate() getting "+"orig_req."+s+ " in SessionContext");
+ // "orig_req.auth_token.uid"
+ String orig_id = (String) mSC.get("orig_req."+s);
+
+ if (orig_id == null) {
+ CMS.debug("UserOrigReqAccessEvaluator: evaluate() orig_id null");
+ return false;
+ }
+ CMS.debug("UserOrigReqAccessEvaluator: evaluate() orig_id ="+ orig_id);
+ if (op.equals("="))
+ return uid.equalsIgnoreCase(orig_id);
+ else if (op.equals("!="))
+ return !(uid.equalsIgnoreCase(orig_id));
+ }
+
+ return false;
+ }
+
+ /**
+ * Evaluates the user in session context to see if it's equal to value
+ * @param type must be "user_origreq"
+ * @param op must be "="
+ * @param value the user id
+ * @return true if SessionContext uid is same as value, false otherwise
+ */
+ public boolean evaluate(String type, String op, String value) {
+
+ SessionContext mSC = SessionContext.getContext();
+
+ if (type.equals(mType)) {
+// what do I do with s here?
+ String s = Utils.stripQuotes(value);
+
+ if (s.equals(ANYBODY) && op.equals("="))
+ return true;
+
+ IUser id = (IUser) mSC.get(SessionContext.USER);
+ // "orig_req.auth_token.uid"
+ String orig_id = (String) mSC.get("orig_req"+s);
+
+ if (op.equals("="))
+ return id.getName().equalsIgnoreCase(orig_id);
+ else if (op.equals("!="))
+ return !(id.getName().equalsIgnoreCase(orig_id));
+ }
+
+ return false;
+ }
+ private void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_ACLS,
+ level, "UserOrigReqAccessEvaluator: " + msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/common/BasicProfile.java b/pki/base/common/src/com/netscape/cms/profile/common/BasicProfile.java
index fb03725a0..d96bec0b9 100644
--- a/pki/base/common/src/com/netscape/cms/profile/common/BasicProfile.java
+++ b/pki/base/common/src/com/netscape/cms/profile/common/BasicProfile.java
@@ -40,6 +40,7 @@ public abstract class BasicProfile implements IProfile {
public static final String PROP_ENABLE = "enable";
public static final String PROP_ENABLE_BY = "enableBy";
+ public static final String PROP_IS_RENEWAL = "renewal";
public static final String PROP_VISIBLE = "visible";
public static final String PROP_INPUT_LIST = "list";
public static final String PROP_OUTPUT_LIST = "list";
@@ -86,6 +87,14 @@ public abstract class BasicProfile implements IProfile {
}
}
+ public String isRenewal() {
+ try {
+ return mConfig.getString(PROP_IS_RENEWAL, "false");
+ } catch (EBaseException e) {
+ return "false";
+ }
+ }
+
public String getApprovedBy() {
try {
return mConfig.getString(PROP_ENABLE_BY, "");
@@ -953,6 +962,7 @@ public abstract class BasicProfile implements IProfile {
throws EProfileException {
String setId = getPolicySetId(request);
Vector policies = getPolicies(setId);
+ CMS.debug("BasicProfile: populate() policy setid ="+ setId);
for (int i = 0; i < policies.size(); i++) {
ProfilePolicy policy = (ProfilePolicy)
@@ -968,8 +978,8 @@ public abstract class BasicProfile implements IProfile {
*/
public void validate(IRequest request)
throws ERejectException {
- CMS.debug("BasicProfile: validate start");
String setId = getPolicySetId(request);
+ CMS.debug("BasicProfile: validate start on setId="+ setId);
Vector policies = getPolicies(setId);
for (int i = 0; i < policies.size(); i++) {
diff --git a/pki/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java b/pki/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java
index 9a8183a5e..e889904a0 100644
--- a/pki/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java
+++ b/pki/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java
@@ -268,6 +268,7 @@ public abstract class EnrollProfile extends BasicProfile
}
if (token == null) {
+ CMS.debug("EnrollProfile: auth token is null");
CMS.debug("EnrollProfile: validating request");
validate(request);
try {
@@ -280,6 +281,7 @@ public abstract class EnrollProfile extends BasicProfile
} else {
// this profile executes request that is authenticated
// by non NoAuth
+ CMS.debug("EnrollProfile: auth token is not null");
validate(request);
execute(request);
}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java
new file mode 100644
index 000000000..29a5c232c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java
@@ -0,0 +1,158 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.profile.constraint;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.BigInteger;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.cms.profile.def.*;
+import netscape.security.x509.*;
+
+
+/**
+ * This class supports renewal grace period, which has two
+ * parameters: graceBefore and graceAfter
+ *
+ * @author Christina Fu
+ * @version $Revision: $, $Date: $
+ */
+public class RenewGracePeriodConstraint extends EnrollConstraint {
+
+ // for renewal: # of days before the orig cert expiration date
+ public static final String CONFIG_RENEW_GRACE_BEFORE = "renewal.graceBefore";
+ // for renewal: # of days after the orig cert expiration date
+ public static final String CONFIG_RENEW_GRACE_AFTER = "renewal.graceAfter";
+
+ public RenewGracePeriodConstraint() {
+ super();
+ addConfigName(CONFIG_RENEW_GRACE_BEFORE);
+ addConfigName(CONFIG_RENEW_GRACE_AFTER);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ if ( name.equals(CONFIG_RENEW_GRACE_BEFORE) ||
+ name.equals(CONFIG_RENEW_GRACE_AFTER)) {
+ try {
+ Integer.parseInt(value);
+ } catch (Exception e) {
+ throw new EPropertyException(CMS.getUserMessage(
+ "CMS_INVALID_PROPERTY", CONFIG_RENEW_GRACE_BEFORE +" or "+ CONFIG_RENEW_GRACE_AFTER));
+ }
+ }
+ super.setConfig(name, value);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ if (name.equals(CONFIG_RENEW_GRACE_BEFORE)) {
+ return new Descriptor(IDescriptor.INTEGER, null, "30",
+ CMS.getUserMessage(locale, "CMS_PROFILE_RENEW_GRACE_BEFORE"));
+ } else if (name.equals(CONFIG_RENEW_GRACE_AFTER)) {
+ return new Descriptor(IDescriptor.INTEGER, null, "30",
+ CMS.getUserMessage(locale, "CMS_PROFILE_RENEW_GRACE_AFTER"));
+ }
+ return null;
+ }
+
+ public void validate(IRequest req, X509CertInfo info)
+ throws ERejectException {
+ String origExpDate_s = req.getExtDataInString("origNotAfter");
+ // probably not for renewal
+ if (origExpDate_s == null) {
+ return;
+ } else {
+ CMS.debug("validate RenewGracePeriod: original cert expiration date found... renewing");
+ }
+ CMS.debug("ValidilityConstraint: validateRenewGraceperiod begins");
+ BigInteger origExpDate_BI = new BigInteger(origExpDate_s);
+ Date origExpDate = new Date(origExpDate_BI.longValue());
+ String renew_grace_before_s = getConfig(CONFIG_RENEW_GRACE_BEFORE);
+ String renew_grace_after_s = getConfig(CONFIG_RENEW_GRACE_AFTER);
+ int renew_grace_before = 0;
+ int renew_grace_after = 0;
+ // -1 means no limit
+ if (renew_grace_before_s == "")
+ renew_grace_before = -1;
+ else
+ renew_grace_before = Integer.parseInt(renew_grace_before_s);
+
+ if (renew_grace_after_s == "")
+ renew_grace_after = -1;
+ else
+ renew_grace_after = Integer.parseInt(renew_grace_after_s);
+
+ Date current = CMS.getCurrentDate();
+ long millisDiff = origExpDate.getTime() - current.getTime();
+ CMS.debug("validateRenewGracePeriod: millisDiff=" + millisDiff + " origExpDate=" + origExpDate.getTime() + " current=" + current.getTime());
+ long long_days = (millisDiff / 1000 ) / 86400;
+ CMS.debug("validateRenewGracePeriod: long_days: "+long_days);
+ int days = (int)long_days;
+ CMS.debug("validateRenewGracePeriod: days: "+days);
+
+ /*
+ * "days", if positive, has to be less than renew_grace_before
+ * "days", if negative, means already past expiration date,
+ * (abs value) has to be less than renew_grace_after
+ * if renew_grace_before or renew_grace_after are negative
+ * the one with negative value is ignored
+ */
+ if (days >= 0) {
+ if ((renew_grace_before>0) && (days > renew_grace_before)) {
+ throw new ERejectException(CMS.getUserMessage(getLocale(req),
+ "CMS_PROFILE_RENEW_OUTSIDE_GRACE_PERIOD",
+ renew_grace_before+" days before and "+
+ renew_grace_after+" days after original cert expiration date"));
+ }
+ } else {
+ if ((renew_grace_after > 0) && ((0-days) > renew_grace_after)) {
+ throw new ERejectException(CMS.getUserMessage(getLocale(req),
+ "CMS_PROFILE_RENEW_OUTSIDE_GRACE_PERIOD",
+ renew_grace_before+" days before and "+
+ renew_grace_after+" days after original cert expiration date"));
+ }
+ }
+ }
+
+
+ public String getText(Locale locale) {
+ String renew_grace_before_s = getConfig(CONFIG_RENEW_GRACE_BEFORE);
+ String renew_grace_after_s= getConfig(CONFIG_RENEW_GRACE_AFTER);
+ return CMS.getUserMessage(locale, "CMS_PROFILE_CONSTRAINT_VALIDITY_TEXT",
+ renew_grace_before_s+" days before and "+
+ renew_grace_after_s+" days after original cert expiration date");
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ if (def instanceof NoDefault)
+ return true;
+ return false;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/SubjectNameConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/SubjectNameConstraint.java
index d15710481..a37687021 100644
--- a/pki/base/common/src/com/netscape/cms/profile/constraint/SubjectNameConstraint.java
+++ b/pki/base/common/src/com/netscape/cms/profile/constraint/SubjectNameConstraint.java
@@ -77,6 +77,8 @@ public class SubjectNameConstraint extends EnrollConstraint {
try {
sn = (CertificateSubjectName) info.get(X509CertInfo.SUBJECT);
+ CMS.debug("SubjectNameConstraint: validate cert subject ="+
+ sn.toString());
} catch (Exception e) {
throw new ERejectException(
CMS.getUserMessage(getLocale(request),
@@ -92,11 +94,17 @@ public class SubjectNameConstraint extends EnrollConstraint {
"CMS_PROFILE_SUBJECT_NAME_NOT_FOUND"));
}
if (sn500 == null) {
+ CMS.debug("SubjectNameConstraint: validate() - sn500 is null");
throw new ERejectException(
CMS.getUserMessage(getLocale(request),
"CMS_PROFILE_SUBJECT_NAME_NOT_FOUND"));
+ } else {
+ CMS.debug("SubjectNameConstraint: validate() - sn500 "+
+ CertificateSubjectName.DN_NAME + " = "+
+ sn500.toString());
}
if (!sn500.toString().matches(getConfig(CONFIG_PATTERN))) {
+ CMS.debug("SubjectNameConstraint: validate() - sn500 not matching pattern "+ getConfig(CONFIG_PATTERN));
throw new ERejectException(
CMS.getUserMessage(getLocale(request),
"CMS_PROFILE_SUBJECT_NAME_NOT_MATCHED",
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/AuthTokenSubjectNameDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/AuthTokenSubjectNameDefault.java
index 35a7507d3..4d15a0db0 100644
--- a/pki/base/common/src/com/netscape/cms/profile/def/AuthTokenSubjectNameDefault.java
+++ b/pki/base/common/src/com/netscape/cms/profile/def/AuthTokenSubjectNameDefault.java
@@ -63,6 +63,7 @@ public class AuthTokenSubjectNameDefault extends EnrollDefault {
public void setValue(String name, Locale locale,
X509CertInfo info, String value)
throws EPropertyException {
+ CMS.debug("AuthTokenSubjectNameDefault: begins");
if (name == null) {
throw new EPropertyException(CMS.getUserMessage(locale,
"CMS_INVALID_PROPERTY", name));
@@ -72,11 +73,17 @@ public class AuthTokenSubjectNameDefault extends EnrollDefault {
try {
x500name = new X500Name(value);
+ if (x500name != null) {
+ CMS.debug("AuthTokenSubjectNameDefault: setValue x500name=" + x500name.toString());
+ } else {
+ CMS.debug("AuthTokenSubjectNameDefault: setValue x500name=null");
+ }
} catch (IOException e) {
CMS.debug("AuthTokenSubjectNameDefault: setValue " +
e.toString());
// failed to build x500 name
}
+ CMS.debug("AuthTokenSubjectNameDefault: setValue name=" + x500name.toString());
try {
info.set(X509CertInfo.SUBJECT,
new CertificateSubjectName(x500name));
@@ -133,6 +140,7 @@ public class AuthTokenSubjectNameDefault extends EnrollDefault {
X500Name name = new X500Name(
request.getExtDataInString(IProfileAuthenticator.AUTHENTICATED_NAME));
+ CMS.debug("AuthTokenSubjectNameDefault: X500Name=" + name.toString());
info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(name));
} catch (Exception e) {
// failed to insert subject name
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/SubjectNameDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/SubjectNameDefault.java
index 2c3123fb1..c78509931 100644
--- a/pki/base/common/src/com/netscape/cms/profile/def/SubjectNameDefault.java
+++ b/pki/base/common/src/com/netscape/cms/profile/def/SubjectNameDefault.java
@@ -86,11 +86,14 @@ public class SubjectNameDefault extends EnrollDefault {
try {
x500name = new X500Name(value);
+ if (x500name != null) {
+ CMS.debug("SubjectNameDefault: setValue x500name=" + x500name.toString());
+ }
} catch (IOException e) {
CMS.debug("SubjectNameDefault: setValue " + e.toString());
// failed to build x500 name
}
- CMS.debug("SubjectNameDefault: setValue name=" + x500name);
+ CMS.debug("SubjectNameDefault: setValue name=" + x500name.toString());
try {
info.set(X509CertInfo.SUBJECT,
new CertificateSubjectName(x500name));
diff --git a/pki/base/common/src/com/netscape/cms/profile/input/SerialNumRenewInput.java b/pki/base/common/src/com/netscape/cms/profile/input/SerialNumRenewInput.java
new file mode 100644
index 000000000..2eeaac114
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/input/SerialNumRenewInput.java
@@ -0,0 +1,94 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.profile.input;
+
+
+import java.security.cert.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.apps.*;
+
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+
+import com.netscape.cms.profile.common.*;
+
+
+/**
+ * This class implements the serial number input
+ * for renewal
+ * <p>
+ *
+ * @author Christina Fu
+ */
+public class SerialNumRenewInput extends EnrollInput implements IProfileInput {
+
+ public static final String SERIAL_NUM = "serial_num";
+
+ public SerialNumRenewInput() {
+ addValueName(SERIAL_NUM);
+ }
+
+ /**
+ * Initializes this default policy.
+ */
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ /**
+ * Retrieves the localizable name of this policy.
+ */
+ public String getName(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_SERIAL_NUM_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_SERIAL_NUM_TEXT");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IProfileContext ctx, IRequest request)
+ throws EProfileException {
+ //
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(SERIAL_NUM)) {
+ return new Descriptor(IDescriptor.STRING, null,
+ null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_SERIAL_NUM_NAME"));
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSelectServlet.java b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSelectServlet.java
index 83904279c..dd1860ee4 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSelectServlet.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSelectServlet.java
@@ -333,6 +333,7 @@ public class ProfileSelectServlet extends ProfileServlet {
}
args.set(ARG_INPUT_LIST, inputlist);
args.set(ARG_INPUT_PLUGIN_LIST, inputPluginlist);
+ args.set(ARG_IS_RENEWAL, profile.isRenewal());
// (5) return info as template
outputTemplate(request, response, args);
diff --git a/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileServlet.java b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileServlet.java
index 0aa6155a6..9ce0d55bc 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileServlet.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileServlet.java
@@ -75,6 +75,7 @@ public class ProfileServlet extends CMSServlet {
public final static String ARG_PROFILE = "profile";
public final static String ARG_REQUEST_NOTES = "requestNotes";
public final static String ARG_PROFILE_ID = "profileId";
+ public final static String ARG_RENEWAL_PROFILE_ID = "rprofileId";
public final static String ARG_PROFILE_IS_ENABLED = "profileIsEnable";
public final static String ARG_PROFILE_IS_VISIBLE = "profileIsVisible";
public final static String ARG_PROFILE_ENABLED_BY = "profileEnableBy";
@@ -106,6 +107,7 @@ public class ProfileServlet extends CMSServlet {
public final static String ARG_INPUT_CONSTRAINT = "inputConstraint";
public final static String ARG_INPUT_NAME = "inputName";
public final static String ARG_INPUT_VAL = "inputVal";
+ public final static String ARG_IS_RENEWAL = "renewal";
public final static String ARG_OUTPUT_LIST = "outputList";
public final static String ARG_OUTPUT_ID = "outputId";
public final static String ARG_OUTPUT_SYNTAX = "outputSyntax";
diff --git a/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java
index 79c63be92..3e270a036 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java
@@ -19,12 +19,15 @@ package com.netscape.cms.servlet.profile;
import java.util.*;
+import java.math.BigInteger;
import java.security.cert.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.netscape.certsrv.apps.*;
import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
import com.netscape.certsrv.util.*;
import com.netscape.certsrv.template.*;
import com.netscape.certsrv.property.*;
@@ -32,6 +35,7 @@ import com.netscape.certsrv.profile.*;
import com.netscape.certsrv.request.*;
import com.netscape.certsrv.authentication.*;
import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.authority.*;
import com.netscape.certsrv.logging.*;
import com.netscape.cms.servlet.common.*;
import com.netscape.cms.servlet.common.AuthCredentials;
@@ -44,6 +48,7 @@ import netscape.security.x509.*;
/**
* This servlet submits end-user request into the profile framework.
*
+ * @author Christina Fu (renewal support)
* @version $Revision: 14561 $, $Date: 2007-05-01 10:28:56 -0700 (Tue, 01 May 2007) $
*/
public class ProfileSubmitServlet extends ProfileServlet {
@@ -112,18 +117,149 @@ public class ProfileSubmitServlet extends ProfileServlet {
}
+ /*
+ * fill input info from "request" to context.
+ * This is expected to be used by renewal where the request
+ * is retrieved from request record
+ */
+ private void setInputsIntoContext(IRequest request, IProfile profile, IProfileContext ctx, Locale locale) {
+ // passing inputs into context
+ Enumeration inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = (String) inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration inputNames = profileInput.getValueNames();
+
+ while (inputNames.hasMoreElements()) {
+ String inputName = (String) inputNames.nextElement();
+ String inputValue = "";
+ CMS.debug("ProfileSubmitServlet: setInputsIntoContext() getting input name= " + inputName);
+ try {
+ inputValue = profileInput.getValue(inputName, locale, request);
+ } catch (Exception e) {
+ CMS.debug("ProfileSubmitServlet: setInputsIntoContext() getvalue() failed: " + e.toString());
+ }
+
+ if (inputValue != null) {
+ CMS.debug("ProfileSubmitServlet: setInputsIntoContext() setting value in ctx:"+ inputValue);
+ ctx.set(inputName, inputValue);
+ } else {
+ CMS.debug("ProfileSubmitServlet: setInputsIntoContext() value null");
+ }
+ }
+ }
+ }
+
+ }
+
+
+
private void setCredentialsIntoContext(HttpServletRequest request, IProfileAuthenticator authenticator, IProfileContext ctx) {
Enumeration authIds = authenticator.getValueNames();
if (authIds != null) {
+ CMS.debug("ProfileSubmitServlet:setCredentialsIntoContext() authNames not null");
while (authIds.hasMoreElements()) {
String authName = (String) authIds.nextElement();
+ CMS.debug("ProfileSubmitServlet:setCredentialsIntoContext() authName:"+
+ authName);
if (request.getParameter(authName) != null) {
+ CMS.debug("ProfileSubmitServlet:setCredentialsIntoContext() authName found in request");
ctx.set(authName, request.getParameter(authName));
+ } else {
+ CMS.debug("ProfileSubmitServlet:setCredentialsIntoContext() authName not found in request");
}
}
+ } else {
+ CMS.debug("ProfileSubmitServlet:setCredentialsIntoContext() authIds` null");
+ }
+ }
+
+ String getUidFromDN(String userdn) {
+ StringTokenizer st = new StringTokenizer(userdn, ",");
+ while (st.hasMoreTokens()) {
+ String t = st.nextToken();
+ int i = t.indexOf("=");
+
+ if (i == -1) {
+ continue;
+ }
+ String n = t.substring(0, i);
+ if (n.equalsIgnoreCase("uid")) {
+ String v = t.substring(i + 1);
+ CMS.debug("ProfileSubmitServlet:: getUidFromDN(): uid found:"+v);
+ return v;
+ } else {
+ continue;
+ }
}
+ return null;
+ }
+
+ /*
+ * authenticate for renewal - more to add necessary params/values
+ * to the session context
+ */
+ public IAuthToken authenticate(IProfileAuthenticator authenticator,
+ HttpServletRequest request, IRequest origReq, SessionContext context)
+ throws EBaseException {
+ IAuthToken authToken = authenticate(authenticator, request);
+ // For renewal, fill in necessary params
+ if (authToken!= null) {
+ String ouid = origReq.getExtDataInString("auth_token.uid");
+ // if the orig cert was manually approved, then there was
+ // no auth token uid. Try to get the uid from the cert dn
+ // itself, if possible
+ if (ouid == null) {
+ String sdn = (String) context.get("origSubjectDN");
+ if (sdn != null) {
+ ouid = getUidFromDN(sdn);
+ if (ouid != null)
+ CMS.debug("ProfileSubmitServlet: renewal: authToken original uid not found");
+ }
+ } else {
+ CMS.debug("ProfileSubmitServlet: renewal: authToken original uid found in orig request auth_token");
+ }
+ String auid = authToken.getInString("uid");
+ if (auid != null) { // not through ssl client auth
+ CMS.debug("ProfileSubmitServlet: renewal: authToken uid found:"+auid);
+ // authenticated with uid
+ // put "orig_req.auth_token.uid" so that authz with
+ // UserOrigReqAccessEvaluator will work
+ if (ouid != null) {
+ context.put("orig_req.auth_token.uid", ouid);
+ CMS.debug("ProfileSubmitServlet: renewal: authToken original uid found:"+ouid);
+ } else {
+ CMS.debug("ProfileSubmitServlet: renewal: authToken original uid not found");
+ }
+ } else { // through ssl client auth?
+ CMS.debug("ProfileSubmitServlet: renewal: authToken uid not found:");
+ // put in orig_req's uid
+ if (ouid != null) {
+ CMS.debug("ProfileSubmitServlet: renewal: origReq uid not null:" +ouid+". Setting authtoken");
+ authToken.set("uid", ouid);
+ context.put(SessionContext.USER_ID, ouid);
+ } else {
+ CMS.debug("ProfileSubmitServlet: renewal: origReq uid not found");
+// throw new EBaseException("origReq uid not found");
+ }
+ }
+
+ String userdn = origReq.getExtDataInString("auth_token.userdn");
+ if (userdn != null) {
+ CMS.debug("ProfileSubmitServlet: renewal: origReq userdn not null:"+userdn+". Setting authtoken");
+ authToken.set("userdn", userdn);
+ } else {
+ CMS.debug("ProfileSubmitServlet: renewal: origReq userdn not found");
+// throw new EBaseException("origReq userdn not found");
+ }
+ } else {
+ CMS.debug("ProfileSubmitServlet: renewal: authToken null");
+ }
+ return authToken;
}
public IAuthToken authenticate(IProfileAuthenticator authenticator,
@@ -178,6 +314,44 @@ public class ProfileSubmitServlet extends ProfileServlet {
}
}
+ /*
+ * fill input info from orig request to the renew request.
+ * This is expected to be used by renewal where the request
+ * is retrieved from request record
+ */
+ private void setInputsIntoRequest(IRequest request, IProfile profile, IRequest req, Locale locale) {
+ // passing inputs into request
+ Enumeration inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = (String) inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration inputNames = profileInput.getValueNames();
+
+ while (inputNames.hasMoreElements()) {
+ String inputName = (String) inputNames.nextElement();
+ String inputValue = "";
+ CMS.debug("ProfileSubmitServlet: setInputsIntoRequest() getting input name= " + inputName);
+ try {
+ inputValue = profileInput.getValue(inputName, locale, request);
+ } catch (Exception e) {
+ CMS.debug("ProfileSubmitServlet: setInputsIntoRequest() getvalue() failed: " + e.toString());
+ }
+
+ if (inputValue != null) {
+ CMS.debug("ProfileSubmitServlet: setInputsIntoRequest() setting value in ctx:"+ inputValue);
+ req.setExtData(inputName, inputValue);
+ } else {
+ CMS.debug("ProfileSubmitServlet: setInputsIntoRequest() value null");
+ }
+ }
+ }
+ }
+
+ }
+
+
private void setOutputIntoArgs(IProfile profile, ArgList outputlist, Locale locale, IRequest req) {
Enumeration outputIds = profile.getProfileOutputIds();
@@ -255,6 +429,8 @@ public class ProfileSubmitServlet extends ProfileServlet {
Locale locale = getLocale(request);
ArgSet args = new ArgSet();
+//xxx this ought to be removed. pwds are logged
+/*
if (CMS.debugOn()) {
CMS.debug("Start of Input Parameters");
Enumeration paramNames = request.getParameterNames();
@@ -267,6 +443,7 @@ public class ProfileSubmitServlet extends ProfileServlet {
}
CMS.debug("End of Input Parameters");
}
+*/
CMS.debug("ProfileSubmitServlet: start serving");
@@ -294,6 +471,31 @@ public class ProfileSubmitServlet extends ProfileServlet {
return;
}
+ /*
+ * Renewal - Renewal is retrofitted into the Profile Enrollment
+ * Framework. The authentication and authorization are taken from
+ * the renewal profile, while the input (with requests) and grace
+ * period constraint are taken from the original cert's request record.
+ *
+ * Things to note:
+ * * the renew request will contain the original profile instead
+ * of the new
+ * * there is no request for system and admin certs generated at
+ * time of installation configuration.
+ */
+ String renewal = request.getParameter("renewal");
+ boolean isRenewal = false;
+ if ((renewal!= null) && (renewal.equalsIgnoreCase("true"))) {
+ CMS.debug("ProfileSubmitServlet: isRenewal true");
+ isRenewal = true;
+ request.setAttribute("reqType", (Object)"renewal");
+ } else {
+ CMS.debug("ProfileSubmitServlet: isRenewal false");
+ }
+
+ String renewProfileId = null;
+ IRequest origReq = null;
+
// if we did not configure profileId in xml file,
// then accept the user-provided one
String profileId = null;
@@ -304,14 +506,258 @@ public class ProfileSubmitServlet extends ProfileServlet {
profileId = mProfileId;
}
+ CMS.debug("ProfileSubmitServlet: profileId " + profileId);
+ // This is the expiration date of the orig. cert that will
+ // be used in the RenewGracePeriodConstraint
+ Date origNotAfter = null;
+ String origSubjectDN = null;
+
+ if (isRenewal) {
+ // dig up the original request to "clone"
+ renewProfileId = profileId;
+ CMS.debug("ProfileSubmitServlet: renewProfileId ="+renewProfileId);
+ IAuthority authority = (IAuthority) CMS.getSubsystem(mAuthorityId);
+ if (authority == null) {
+ CMS.debug("ProfileSubmitServlet: renewal: Authority " + mAuthorityId +
+ " not found");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+ IRequestQueue queue = authority.getRequestQueue();
+
+ if (queue == null) {
+ CMS.debug("ProfileSubmitServlet: renewal: Request Queue of " +
+ mAuthorityId + " not found");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ String serial = request.getParameter("serial_num");
+ BigInteger certSerial = null;
+ // if serial number is sent with request, then the authentication
+ // method is not ssl client auth. In this case, an alternative
+ // authentication method is used (default: ldap based)
+ if (serial != null) {
+ CMS.debug("ProfileSubmitServlet: renewal: found serial_num");
+ certSerial = new BigInteger(serial);
+ // usr_origreq evaluator should be used to authorize ownership
+ // of the cert
+ } else {
+ CMS.debug("ProfileSubmitServlet: renewal: serial_num not found, must do ssl client auth");
+ // ssl client auth is to be used
+ // this is not authentication. Just use the cert to search
+ // for orig request and find the right profile
+ SSLClientCertProvider sslCCP = new SSLClientCertProvider(request);
+ X509Certificate[] certs = sslCCP.getClientCertificateChain();
+ certSerial = null;
+ if (certs == null || certs.length == 0) {
+ CMS.debug("ProfileSubmitServlet: renewal: no ssl client cert chain");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ } else { // has ssl client cert
+ CMS.debug("ProfileSubmitServlet: renewal: has ssl client cert chain");
+ // shouldn't expect leaf cert to be always at the
+ // same location
+ X509Certificate clientCert = null;
+ for (int i = 0; i< certs.length; i++) {
+ clientCert = certs[i];
+ byte [] extBytes = clientCert.getExtensionValue("2.5.29.19");
+ // try to see if this is a leaf cert
+ // look for BasicConstraint extension
+ if (extBytes == null) {
+ // found leaf cert
+ CMS.debug("ProfileSubmitServlet: renewal: found leaf cert");
+ break;
+ } else {
+ CMS.debug("ProfileSubmitServlet: renewal: found cert having BasicConstraints ext");
+ // it's got BasicConstraints extension
+ // so it's not likely to be a leaf cert,
+ // however, check the isCA field regardless
+ try {
+ BasicConstraintsExtension bce =
+ new BasicConstraintsExtension(true, extBytes);
+ if (bce != null) {
+ if (!(Boolean)bce.get("is_ca")) {
+ CMS.debug("ProfileSubmitServlet: renewal: found CA cert in chain");
+ break;
+ } // else found a ca cert, continue
+ }
+ } catch (Exception e) {
+ CMS.debug("ProfileSubmitServlet: renewal: exception:"+
+ e.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+ }
+ }
+ if (clientCert == null) {
+ CMS.debug("ProfileSubmitServlet: renewal: no client cert in chain");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+ // convert to java X509 cert interface
+ try {
+ byte[] certEncoded = clientCert.getEncoded();
+
+ clientCert = new X509CertImpl(certEncoded);
+ } catch (Exception e) {
+ CMS.debug("ProfileSubmitServlet: renewal: exception:"+e.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+
+ certSerial = clientCert.getSerialNumber();
+ }
+ }
+
+ CMS.debug("ProfileSubmitServlet: renewal: serial number of cert to renew:"+ certSerial.toString());
+
+ try {
+ ICertificateRepository certDB = null;
+ if (authority instanceof ICertificateAuthority) {
+ certDB = ((ICertificateAuthority) authority).getCertificateRepository();
+ }
+ if (certDB == null) {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+ ICertRecord rec = (ICertRecord) certDB.readCertificateRecord(certSerial);
+ if (rec == null) {
+ CMS.debug("ProfileSubmitServlet: renewal cert record not found for serial number "+ certSerial.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ } else {
+ CMS.debug("ProfileSubmitServlet: renewal cert record found for serial number:"+ certSerial.toString());
+ // check to see if the cert is revoked
+ if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ CMS.debug("ProfileSubmitServlet: renewal cert found to be revoked. Serial number = "+ certSerial.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_CA_CANNOT_RENEW_REVOKED_CERT", certSerial.toString()));
+ outputTemplate(request, response, args);
+ return;
+ }
+ MetaInfo metaInfo = (MetaInfo) rec.get(ICertRecord.ATTR_META_INFO);
+ // note: CA's internal certs don't have request ids
+ // so some other way needs to be done
+ if (metaInfo != null) {
+ String rid = (String) metaInfo.get(ICertRecord.META_REQUEST_ID);
+
+ if (rid != null) {
+ origReq = queue.findRequest(new RequestId(rid));
+ if (origReq != null) {
+ CMS.debug("ProfileSubmitServlet: renewal: found original enrollment request id:"+ rid);
+ // debug: print the extData keys
+ Enumeration en = origReq.getExtDataKeys();
+/*
+ CMS.debug("ProfileSubmitServlet: renewal: origRequest extdata key print BEGINS");
+ while (en.hasMoreElements()) {
+ String next = (String) en.nextElement();
+ CMS.debug("ProfileSubmitServlet: renewal: origRequest extdata key:"+ next);
+ }
+ CMS.debug("ProfileSubmitServlet: renewal: origRequest extdata key print ENDS");
+*/
+ String requestorE = origReq.getExtDataInString("requestor_email");
+ CMS.debug("ProfileSubmitServlet: renewal original requestor email="+requestorE);
+ profileId = origReq.getExtDataInString("profileId");
+ if (profileId != null)
+ CMS.debug("ProfileSubmitServlet: renewal original profileId="+profileId);
+ else {
+ CMS.debug("ProfileSubmitServlet: renewal original profileId not found");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+ } else { //if origReq
+ CMS.debug("ProfileSubmitServlet: renewal original request not found for request id "+ rid);
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+ } else {
+ CMS.debug("ProfileSubmitServlet: renewal: cert record locating request id in MetaInfo failed for serial number "+ certSerial.toString());
+ CMS.debug("ProfileSubmitServlet: renewal: cert may be bootstrapped system cert during installation/configuration - no request record exists");
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"+": original request not found"));
+ outputTemplate(request, response, args);
+ return;
+ }
+ } else {
+ CMS.debug("ProfileSubmitServlet: renewal: cert record locating MetaInfo failed for serial number "+ certSerial.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+ // get orig cert expiration date
+ CMS.debug("ProfileSubmitServlet: renewal: before getting origNotAfter");
+ X509CertImpl origCert = rec.getCertificate();
+ origNotAfter = origCert.getNotAfter();
+ CMS.debug("ProfileSubmitServlet: renewal: origNotAfter ="+
+ origNotAfter.toString());
+ origSubjectDN = origCert.getSubjectDN().getName();
+ CMS.debug("ProfileSubmitServlet: renewal: orig subj dn ="+
+ origSubjectDN);
+ }
+ } catch (Exception e) {
+ CMS.debug("ProfileSubmitServlet: renewal: exception:"+e.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
+ }
+ } // end isRenewal
+
IProfile profile = null;
+ IProfile renewProfile = null;
try {
- CMS.debug("ProfileSubmitServlet: profileId " + profileId);
profile = ps.getProfile(profileId);
+ if (isRenewal) {
+ // in case of renew, "profile" is the orig profile
+ // while "renewProfile" is the current profile used for renewal
+ renewProfile = ps.getProfile(renewProfileId);
+ }
} catch (EProfileException e) {
- CMS.debug("ProfileSubmitServlet: profile not found profileId " +
- profileId + " " + e.toString());
+ if(profile == null) {
+ CMS.debug("ProfileSubmitServlet: profile not found profileId " +
+ profileId + " " + e.toString());
+ }
+ if (renewProfile == null) {
+ CMS.debug("ProfileSubmitServlet: profile not found renewProfileId " +
+ renewProfileId + " " + e.toString());
+ }
}
if (profile == null) {
if (xmlOutput) {
@@ -324,6 +770,17 @@ public class ProfileSubmitServlet extends ProfileServlet {
}
return;
}
+ if (isRenewal && (renewProfile == null)) {
+ if (xmlOutput) {
+ outputError(response, CMS.getUserMessage(locale,"CMS_PROFILE_NOT_FOUND", renewProfileId));
+ } else {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_NOT_FOUND", renewProfileId));
+ outputTemplate(request, response, args);
+ }
+ return;
+ }
if (!ps.isProfileEnable(profileId)) {
CMS.debug("ProfileSubmitServlet: Profile " + profileId +
@@ -342,14 +799,42 @@ public class ProfileSubmitServlet extends ProfileServlet {
return;
}
+ if (isRenewal) {
+ if (!ps.isProfileEnable(renewProfileId)) {
+ CMS.debug("ProfileSubmitServlet: renewal Profile " + renewProfileId +
+ " not enabled");
+ if (xmlOutput) {
+ outputError(response, CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", renewProfileId));
+ } else {
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_PROFILE_NOT_FOUND", renewProfileId));
+ outputTemplate(request, response, args);
+ }
+ return;
+ }
+ }
+
IProfileContext ctx = profile.createContext();
// passing auths into context
IProfileAuthenticator authenticator = null;
+ IProfileAuthenticator origAuthenticator = null;
try {
- authenticator = profile.getAuthenticator();
+ if (isRenewal) {
+ authenticator = renewProfile.getAuthenticator();
+ origAuthenticator = profile.getAuthenticator();
+ } else {
+ authenticator = profile.getAuthenticator();
+ }
} catch (EProfileException e) {
// authenticator not installed correctly
+ CMS.debug("ProfileSubmitServlet: renewal: exception:"+e.toString());
+ args.set(ARG_ERROR_CODE, "1");
+ args.set(ARG_ERROR_REASON, CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR"));
+ outputTemplate(request, response, args);
+ return;
}
if (authenticator == null) {
CMS.debug("ProfileSubmitServlet: authenticator not found");
@@ -359,8 +844,27 @@ public class ProfileSubmitServlet extends ProfileServlet {
setCredentialsIntoContext(request, authenticator, ctx);
}
- setInputsIntoContext(request, profile, ctx);
- CMS.debug("ProfileSubmistServlet: set Inputs into Context");
+ // for renewal, this will override or add auth info to the profile context
+ if (isRenewal) {
+ if (origAuthenticator!= null) {
+ CMS.debug("ProfileSubmitServlet: for renewal, original authenticator " +
+ origAuthenticator.getName() + " found");
+ setCredentialsIntoContext(request, origAuthenticator, ctx);
+ } else {
+ CMS.debug("ProfileSubmitServlet: for renewal, original authenticator not found");
+ }
+ }
+
+ CMS.debug("ProfileSubmistServlet: set Inputs into profile Context");
+ if (isRenewal) {
+ // for renewal, input needs to be retrieved from the orig req record
+ CMS.debug("ProfileSubmitServlet: set original Inputs into profile Context");
+ setInputsIntoContext(origReq, profile, ctx, locale);
+ ctx.set("renewal", "true");
+ ctx.set("renewProfileId", renewProfileId);
+ } else {
+ setInputsIntoContext(request, profile, ctx);
+ }
// before creating the request, authenticate the request
@@ -375,13 +879,20 @@ public class ProfileSubmitServlet extends ProfileServlet {
context.put("sslClientCertProvider",
new SSLClientCertProvider(request));
CMS.debug("ProfileSubmitServlet: set sslClientCertProvider");
+ if ((isRenewal == true) && (origSubjectDN != null))
+ context.put("origSubjectDN", origSubjectDN);
if (statsSub != null) {
statsSub.startTiming("profile_authentication");
}
if (authenticator != null) {
try {
- authToken = authenticate(authenticator, request);
- // authentication success
+ if (isRenewal) {
+ CMS.debug("ProfileSubmitServlet: renewal authenticate begins");
+ authToken = authenticate(authenticator, request, origReq, context);
+ CMS.debug("ProfileSubmitServlet: renewal authenticate ends");
+ } else {
+ authToken = authenticate(authenticator, request);
+ }
} catch (EBaseException e) {
CMS.debug("ProfileSubmitServlet: authentication error " +
e.toString());
@@ -407,9 +918,16 @@ public class ProfileSubmitServlet extends ProfileServlet {
statsSub.endTiming("profile_authentication");
}
+ // authentication success
if (authToken != null) {
+ CMS.debug("ProfileSubmitServlet authToken not null");
// do profile authorization
- String acl = profile.getAuthzAcl();
+ String acl = null;
+ if (isRenewal)
+ acl = renewProfile.getAuthzAcl();
+ else
+ acl = profile.getAuthzAcl();
+ CMS.debug("ProfileSubmitServlet: authz using acl: "+acl);
if (acl != null && acl.length() > 0) {
try {
AuthzToken authzToken = authorize(mAclMethod, authToken, acl);
@@ -482,9 +1000,19 @@ public class ProfileSubmitServlet extends ProfileServlet {
for (int k = 0; k < reqs.length; k++) {
boolean fromRA = false;
String uid = "";
-
+
// adding parameters to request
- setInputsIntoRequest(request, profile, reqs[k]);
+ if (isRenewal) {
+ setInputsIntoRequest(origReq, profile, reqs[k], locale);
+ // set orig expiration date to be used in Validity constraint
+ reqs[k].setExtData("origNotAfter",
+ BigInteger.valueOf(origNotAfter.getTime()));
+ // set subjectDN to be used in subject name default
+ reqs[k].setExtData(IProfileAuthenticator.AUTHENTICATED_NAME, origSubjectDN);
+ // set request type
+ reqs[k].setExtData("requestType", "renewal");
+ } else
+ setInputsIntoRequest(request, profile, reqs[k]);
// serial auth token into request
if (authToken != null) {
@@ -522,6 +1050,8 @@ public class ProfileSubmitServlet extends ProfileServlet {
// put profile framework parameters into the request
reqs[k].setExtData(ARG_PROFILE, "true");
reqs[k].setExtData(ARG_PROFILE_ID, profileId);
+ if (isRenewal)
+ reqs[k].setExtData(ARG_RENEWAL_PROFILE_ID, request.getParameter("profileId"));
reqs[k].setExtData(ARG_PROFILE_APPROVED_BY, profile.getApprovedBy());
String setId = profile.getPolicySetId(reqs[k]);
diff --git a/pki/linux/ca-ui/pki-ca-ui.spec b/pki/linux/ca-ui/pki-ca-ui.spec
index 19ab74249..1daee1fc2 100644
--- a/pki/linux/ca-ui/pki-ca-ui.spec
+++ b/pki/linux/ca-ui/pki-ca-ui.spec
@@ -34,7 +34,7 @@
## Package Header Definitions
%define base_name %{base_prefix}-%{base_component}
%define base_version 1.0.0
-%define base_release 4
+%define base_release 5
%define base_group System Environment/Base
%define base_vendor Red Hat, Inc.
%define base_license GPLv2 with exceptions
@@ -221,6 +221,8 @@ rm -rf ${RPM_BUILD_ROOT}
###############################################################################
%changelog
+* Tue Nov 18 2008 Christina Fu <cfu@redhat.com> 1.0.0-5
+- Bugzilla Bug #471622 - Need Renewal feature via enrollment profile Framework (phase 1)
* Wed Oct 15 2008 Andrew Wnuk <awnuk@redhat.com> 1.0.0-4
- Fix for Bug 466064: Search filters built by CA servlets are not always correct
* Wed Oct 8 2008 Jack Magne <jmagne@redhat.com> 1.0.0-3
diff --git a/pki/linux/ca-ui/shared/webapps/ca/ee/ca/ProfileSelect.template b/pki/linux/ca-ui/shared/webapps/ca/ee/ca/ProfileSelect.template
index 95a978e91..a3557fcd6 100644
--- a/pki/linux/ca-ui/shared/webapps/ca/ee/ca/ProfileSelect.template
+++ b/pki/linux/ca-ui/shared/webapps/ca/ee/ca/ProfileSelect.template
@@ -439,6 +439,8 @@ document.writeln('</table>');
document.writeln('<p>');
document.writeln('<input type=hidden name=profileId value="' +
profileId + '">');
+document.writeln('<input type=hidden name=renewal value="' +
+ renewal + '">');
} else {
document.write('Sorry, your request is not submitted. The error code is "' + errorReason + '".');
}
diff --git a/pki/linux/ca/pki-ca.spec b/pki/linux/ca/pki-ca.spec
index b6349228c..2f1149751 100644
--- a/pki/linux/ca/pki-ca.spec
+++ b/pki/linux/ca/pki-ca.spec
@@ -34,7 +34,7 @@
## Package Header Definitions
%define base_name %{base_prefix}-%{base_component}
%define base_version 1.0.0
-%define base_release 13
+%define base_release 14
%define base_group System Environment/Daemons
%define base_vendor Red Hat, Inc.
%define base_license GPLv2 with exceptions
@@ -282,6 +282,8 @@ fi
###############################################################################
%changelog
+* Tue Nov 18 2008 Christina Fu <cfu@redhat.com> 1.0.0-14
+- Bugzilla Bug #471622 - Need Renewal feature via enrollment profile Framework (phase 1)
* Fri Oct 10 2008 Jack Magne <jmagne@redhat.com> 1.0.0-13
- Fix for port separation bug #466188.
* Fri Oct 9 2008 Ade Lee <alee@redhat.com> 1.0.0-12
diff --git a/pki/linux/common/pki-common.spec b/pki/linux/common/pki-common.spec
index 016fe171d..cdb2afd7b 100644
--- a/pki/linux/common/pki-common.spec
+++ b/pki/linux/common/pki-common.spec
@@ -33,7 +33,7 @@
## Package Header Definitions
%define base_name %{base_prefix}-%{base_component}
%define base_version 1.0.0
-%define base_release 25
+%define base_release 26
%define base_group System Environment/Base
%define base_vendor Red Hat, Inc.
%define base_license GPLv2 with exceptions
@@ -298,6 +298,8 @@ chmod 00755 %{_datadir}/%{base_prefix}/setup/postinstall
###############################################################################
%changelog
+* Tue Nov 18 2008 Christina Fu <cfu@redhat.com> 1.0.0-26
+- Bugzilla Bug #471622 - Need Renewal feature via enrollment profile Framework (Phase 1)
* Mon Oct 27 2008 Ade Lee <alee@redhat.com> 1.0.0-25
- Fix for Bugs: 223324, 430745, 224765, 223309
* Fri Oct 17 2008 Andrew Wnuk <awnuk@redhat.com> 1.0.0-24